------- Comment #3 from ubizjak at gmail dot com 2008-06-12 10:43 ------- (In reply to comment #2) > We have the SHIFT_COUNT_TRUNCATED macro for this (though I'm not sure if > that says negative values are ok).
They are, but there is a comment in the documentation: -- Macro: SHIFT_COUNT_TRUNCATED ... However, on some machines, such as the 80386 and the 680x0, truncation only applies to shift operations and not the (real or pretended) bit-field operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines. Instead, add patterns to the `md' file that include the implied truncation of the shift instructions. I don't know which "real or pretended" bit-field operations are referred here, since bt insn also truncate its bit-offset operand. OTOH, {SI,HI,QI}mode shifts all truncate to 0x1f, not to GET_MODE_SIZE(mode) - 1. I have a patch: Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 136692) +++ config/i386/i386.c (working copy) @@ -24681,6 +24681,22 @@ emit_insn (fn (dest, tmp2, tmp3)); } +/* Target hook for target_shift_trucnation_mask. */ +static unsigned HOST_WIDE_INT +ix86_shift_truncation_mask (enum machine_mode mode) +{ + if (TARGET_64BIT + && mode == DImode) + return 0x3f; + + if (mode == SImode + || mode == HImode + || mode == QImode) + return 0x1f; + + return 0; +} + /* Target hook for scalar_mode_supported_p. */ static bool ix86_scalar_mode_supported_p (enum machine_mode mode) @@ -26039,6 +26055,9 @@ #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg +#undef TARGET_SHIFT_TRUNCATION_MASK +#define TARGET_SHIFT_TRUNCATION_MASK ix86_shift_truncation_mask + #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P ix86_scalar_mode_supported_p But it does nothing for this optimization. I guess middle-end should be kicked to handle this optimization. BTW: Why does ffmpeg need inline asm for this optimization? Following code snipped also produces expected code: int shift32 (int i, int n) { return i >> (-n); } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36503