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 },