diff options
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 3910612..6e61e9a 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2166,7 +2166,8 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, { /* If we have been unable to open-code this by a rotation, do it as the IOR of two shifts. I.e., to rotate A - by N bits, compute (A << N) | ((unsigned) A >> (C - N)) + by N bits, compute + (A << N) | ((unsigned) A >> ((-N) & (C - 1))) where C is the bitsize of A. It is theoretically possible that the target machine might @@ -2181,14 +2182,22 @@ expand_shift_1 (enum tree_code code, enum machine_mode mode, rtx shifted, rtx temp1; new_amount = op1; - if (CONST_INT_P (op1)) + if (op1 == const0_rtx) + return shifted; + else if (CONST_INT_P (op1)) other_amount = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1)); else - other_amount - = simplify_gen_binary (MINUS, GET_MODE (op1), - GEN_INT (GET_MODE_PRECISION (mode)), - op1); + { + other_amount + = simplify_gen_unary (NEG, GET_MODE (op1), + op1, GET_MODE (op1)); + other_amount + = simplify_gen_binary (AND, GET_MODE (op1), + other_amount, + GEN_INT (GET_MODE_PRECISION (mode) + - 1)); + } shifted = force_reg (mode, shifted); |