Hi,

Here is the patch, it is for gcc-3.4.1 but it does work with gcc-3.4.0.  I
have tested it under the Cygwin environment and it appears to produce valid
output.  The peephole optimisation to replace the mov/and with a bit
operation isn't working even though (at a quick look) it seems to match the
generated RTL.

If you're planning on using this for anything important I would recommend
that you test it more thoroughly.

To stop the compiler doing the conversion to shifts you need to add
'-fno-fold-single-bit' to the compiler command line.

Regards

Phil.
diff -aur gcc-3.4.1/gcc/common.opt hacked-gcc-3.4.1/gcc/common.opt
--- gcc-3.4.1/gcc/common.opt    2004-02-18 00:09:04.000000000 +0000
+++ hacked-gcc-3.4.1/gcc/common.opt     2004-07-14 20:11:00.000000000 +0100
@@ -337,6 +337,10 @@
 Common
 Do not store floats in registers
 
+ffold-single-bit
+Common
+Convert single bit constant bit tests to shift/and operations. On by default.
+
 fforce-addr
 Common
 Copy memory address constants into registers before use
diff -aur gcc-3.4.1/gcc/flags.h hacked-gcc-3.4.1/gcc/flags.h
--- gcc-3.4.1/gcc/flags.h       2004-02-18 00:09:04.000000000 +0000
+++ hacked-gcc-3.4.1/gcc/flags.h        2004-07-14 20:11:00.000000000 +0100
@@ -317,6 +317,11 @@
    perform miscellaneous relatively-expensive optimizations.  */
 extern int flag_expensive_optimizations;
 
+/* Zero for -ffold-single-bit:
+   Don't perform folding on single bit constants.  This produces inefficient
+   code for CPUs that can only shift by one bit per instruction. */
+extern int flag_dont_fold_single_bit;
+
 /* Nonzero for -fwritable-strings:
    store string constants in data segment and don't uniquize them.  */
 
diff -aur gcc-3.4.1/gcc/fold-const.c hacked-gcc-3.4.1/gcc/fold-const.c
--- gcc-3.4.1/gcc/fold-const.c  2004-06-01 00:15:12.000000000 +0100
+++ hacked-gcc-3.4.1/gcc/fold-const.c   2004-07-14 20:11:00.000000000 +0100
@@ -5148,6 +5143,10 @@
 fold_single_bit_test (enum tree_code code, tree arg0, tree arg1,
                      tree result_type)
 {
+  if (flag_dont_fold_single_bit)
+    {
+    return NULL_TREE;
+    }
   /* If this is a TRUTH_NOT_EXPR, it may have a single bit test inside
      operand 0.  */
   if (code == TRUTH_NOT_EXPR)
diff -aur gcc-3.4.1/gcc/opts.c hacked-gcc-3.4.1/gcc/opts.c
--- gcc-3.4.1/gcc/opts.c        2004-02-18 00:09:04.000000000 +0000
+++ hacked-gcc-3.4.1/gcc/opts.c 2004-07-14 20:11:00.000000000 +0100
@@ -1008,6 +1008,10 @@
       flag_float_store = value;
       break;
 
+    case OPT_ffold_single_bit:
+      flag_dont_fold_single_bit = !value;
+      break;
+
     case OPT_fforce_addr:
       flag_force_addr = value;
       break;
diff -aur gcc-3.4.1/gcc/toplev.c hacked-gcc-3.4.1/gcc/toplev.c
--- gcc-3.4.1/gcc/toplev.c      2004-02-20 08:40:50.000000000 +0000
+++ hacked-gcc-3.4.1/gcc/toplev.c       2004-07-14 20:11:00.000000000 +0100
@@ -524,6 +524,11 @@
    perform miscellaneous relatively-expensive optimizations.  */
 int flag_expensive_optimizations;
 
+/* Zero for -ffold-single-bit:
+   Don't perform folding on single bit constants.  This produces inefficient
+   code for CPUs that can only shift by one bit per instruction. */
+int flag_dont_fold_single_bit;
+
 /* Nonzero for -fthread-jumps:
    have jump optimize output of loop.  */
 
@@ -1047,6 +1052,7 @@
   {"cse-follow-jumps", &flag_cse_follow_jumps, 1 },
   {"cse-skip-blocks", &flag_cse_skip_blocks, 1 },
   {"expensive-optimizations", &flag_expensive_optimizations, 1 },
+  {"fold-single-bit", &flag_dont_fold_single_bit, 1 },
   {"thread-jumps", &flag_thread_jumps, 1 },
   {"strength-reduce", &flag_strength_reduce, 1 },
   {"unroll-loops", &flag_unroll_loops, 1 },

Reply via email to