@@ -3755,6 +3755,24 @@
}
})
+; Special case where zero_extract can be written as a right-shift.
+(define_insn_and_split "*extzvdi_top"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extract:DI
+ (match_operand:DI 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "") ; size
+ (const_int 0))) ; start
+ ]
+ "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), 0, 64)"
+ "#"
+ ""
+ [(set (match_dup 0)
+ (lshiftrt:DI (match_dup 1) (match_dup 2)))]
+{
+ operands[2] = GEN_INT (64 - INTVAL (operands[2]));
+})
+
+; In all other cases try risbg.
(define_insn "*extzv<mode><clobbercc_or_nocc>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extract:GPR
@@ -4045,6 +4063,21 @@
[(set_attr "op_type" "RIE")
(set_attr "z10prop" "z10_super_E1")])
+(define_insn "*trunc_sidi_and_subreg_ze<clobbercc_or_nocc>"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI
+ (subreg:SI (zero_extract:DI
+ (match_operand:DI 1 "register_operand" "d")
+ (match_operand 2 "const_int_operand" "") ; size
+ (match_operand 3 "const_int_operand" "")) ; pos
+ 4)
+ (match_operand:SI 4 "contiguous_bitmask_nowrap_operand" "")))]
+ "<z10_or_zEC12_cond>
+ && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64)"
+ "<risbg_n>\t%0,%1,%t4,128+%f4,%2+%3"
+ [(set_attr "op_type" "RIE")
+ (set_attr "z10prop" "z10_super_E1")])
+
; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
; -> z = y >> d; z = risbg;
@@ -478,8 +478,8 @@ i64 f42 (t42 v_x)
// Check that we get the case where a 64-bit shift is used by a 32-bit and.
i32 f43 (i64 v_x)
{
- /* { dg-final { scan-assembler "f43:\n\trisbg\t%r2,%r2,32,128\\\+61,64-12" { target { lp64 } } } } */
- /* { dg-final { scan-assembler "f43:\n\trisbg\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r2,%r3,32,128\\\+61,64-12" { target { ! lp64 } } } } */
+ /* { dg-final { scan-assembler "f43:\n\trisbg\t%r2,%r2,32,128\\\+61,32\\\+20" { target { lp64 } } } } */
+ /* { dg-final { scan-assembler "f43:\n\trisbg\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbg\t%r2,%r3,32,128\\\+61,32\\\+20" { target { ! lp64 } } } } */
i64 v_shr3 = ((ui64)v_x) >> 12;
i32 v_shr3_tr = (ui32)v_shr3;
i32 v_conv = v_shr3_tr & -4;
@@ -489,8 +489,8 @@ i32 f43 (i64 v_x)
// Check that we don't get the case where the 32-bit and mask is not contiguous
i32 f44 (i64 v_x)
{
- /* { dg-final { scan-assembler "f44:\n\tsrlg\t%r2,%r2,12" { target { lp64 } } } } */
- /* { dg-final { scan-assembler "f44:\n\tsrlg\t%r2,%r3,12\n\tnilf\t%r2,10" { target { ! lp64 } } } } */
+ /* { dg-final { scan-assembler "f44:\n\(\t.*\n\)*\tngr\t" { target { lp64 } } } } */
+ /* { dg-final { scan-assembler "f44:\n\(\t.*\n\)*\tnilf\t" { target { ! lp64 } } } } */
i64 v_shr4 = ((ui64)v_x) >> 12;
i32 v_conv = (ui32)v_shr4;
i32 v_and = v_conv & 10;
@@ -100,7 +100,7 @@ i64 f8 (i64 v_a, i64 v_b)
// ands with complement masks.
i32 f9 (i64 v_x, i32 v_y)
{
- /* { dg-final { scan-assembler "f9:\n\trisbg\t%r3,%r2,48,63,64-48" { target { lp64 } }} } */
+ /* { dg-final { scan-assembler "f9:\n\trisbg\t%r3,%r2,64-16,63,16\\\+0" { target { lp64 } }} } */
/* { dg-final { scan-assembler "f9:\n\trisbg\t%r4,%r2,32\\+16,63,64-16" { target { ! lp64 } }} } */
i64 v_shr6 = ((ui64)v_x) >> 48;
i32 v_conv = (ui32)v_shr6;