return simplify_gen_binary (code, mode, op0,
gen_int_shift_amount (mode, val));
}
+
+ /* Simplify:
+
+ (code:M1
+ (subreg:M1
+ ([al]shiftrt:M2
+ (subreg:M2
+ (ashift:M1 X C1))
+ C2))
+ C3)
+
+ to:
+
+ (code:M1
+ ([al]shiftrt:M1
+ (ashift:M1 X C1+N)
+ C2+N)
+ C3)
+
+ where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
+ directly would be arithmetically correct, but restricting the
+ simplification to shifts by constants is more conservative,
+ since it is more likely to lead to further simplifications. */
+ if (is_a<scalar_int_mode> (mode, &int_mode)
+ && paradoxical_subreg_p (op0)
+ && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
+ && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
+ || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
+ && CONST_INT_P (op1))
+ {
+ auto xcode = GET_CODE (SUBREG_REG (op0));
+ rtx xop0 = XEXP (SUBREG_REG (op0), 0);
+ rtx xop1 = XEXP (SUBREG_REG (op0), 1);
+ if (SUBREG_P (xop0)
+ && GET_MODE (SUBREG_REG (xop0)) == mode
+ && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
+ && CONST_INT_P (xop1)
+ && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
+ {
+ rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
+ rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
+ if (CONST_INT_P (yop1)
+ && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
+ {
+ auto bias = (GET_MODE_BITSIZE (int_mode)
+ - GET_MODE_BITSIZE (inner_mode));
+ tem = simplify_gen_binary (ASHIFT, mode, yop0,
+ GEN_INT (INTVAL (yop1) + bias));
+ tem = simplify_gen_binary (xcode, mode, tem,
+ GEN_INT (INTVAL (xop1) + bias));
+ return simplify_gen_binary (code, mode, tem, op1);
+ }
+ }
+ }
break;
case SS_ASHIFT:
#if __riscv_xlen == 64
// Below "slli ((32+16)-N); srai (32+16)" for rv64
-// or "slli (16-N); sraiw 16" for rv64
+// or "slli (16-N); srai 16" for rv64
SINT_EXT_SSHORT_RSHIFT_N_SINT(1)
SINT_EXT_SSHORT_RSHIFT_N_SINT(7)
SINT_EXT_SSHORT_RSHIFT_N_SINT(8)
// Below "slli (16-N); srai 16" for rv32
// Below "slli ((32+16)-N); srai (32+16)" for rv64
-// or "slli (16-N); sraiw 16" for rv64
+// or "slli (16-N); srai 16" for rv64
SINT_EXT_SSHORT_RSHIFT_N_SLONG(9)
SINT_EXT_SSHORT_RSHIFT_N_SLONG(15)
/* { dg-final { scan-assembler-times "srai\t" 26 { target { rv32 } } } } */
/* { dg-final { scan-assembler-times "slli\t" 44 { target { rv64 } } } } */
-/* { dg-final { scan-assembler-times "srai\t" 51 { target { rv64 } } } } */
-/* { dg-final { scan-assembler-times "sraiw\t" 10 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times "srai\t" 58 { target { rv64 } } } } */
+/* { dg-final { scan-assembler-times "sraiw\t" 3 { target { rv64 } } } } */