[(set_attr "op_type" "RIE")
(set_attr "z10prop" "z10_super_E1")])
-; 32 bit: (a & -16) | ((b >> 8) & 15)
-(define_insn "*<risbg_n>_ior_and_sr_ze"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (ior:SI (and:SI
- (match_operand:SI 1 "register_operand" "0")
- (match_operand:SI 2 "const_int_operand" ""))
- (subreg:SI
- (zero_extract:DI
- (match_operand:DI 3 "register_operand" "d")
- (match_operand 4 "const_int_operand" "") ; size
+; (a & -16) | ((b >> 8) & 15)
+(define_insn "*<risbg_n>_ior_and_sr_ze<mode>"
+ [(set (match_operand:DSI 0 "register_operand" "=d")
+ (ior:DSI (and:DSI
+ (match_operand:DSI 1 "register_operand" "0")
+ (match_operand:DSI 2 "const_int_operand" ""))
+ (zero_extract:DSI
+ (match_operand:DSI 3 "register_operand" "d")
+ (match_operand 4 "const_int_operand" "") ; size
(match_operand 5 "const_int_operand" "")) ; start
- 4)))]
+ ))]
"<z10_or_zEC12_cond>
- && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
+ && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), <DSI:bitsize>)
&& UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
- "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
+ "<risbg_n>\t%0,%3,64-%4,63,(64-<DSI:bitsize>)+%4+%5"
[(set_attr "op_type" "RIE")
(set_attr "z10prop" "z10_super_E1")])
[(set_attr "op_type" "RIE")
(set_attr "z10prop" "z10_super_E1")])
+; (ui32)(((ui64)x) >> 12) & -4
+(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")
+ (const_int 32)
+ (match_operand:SI 2 "nonzero_shift_count_operand" "")) 4)
+ (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
+ "<z10_or_zEC12_cond>"
+ "<risbg_n>\t%0,%1,%t3,128+%f3,32+%2"
+ [(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;
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch --save-temps" } */
+/* { dg-options "-O3 -march=z13 -mzarch --save-temps" } */
#include <stddef.h>
#include <limits.h>
/* { dg-do run } */
-/* { dg-options "-O3 -mzarch --save-temps" } */
+/* { dg-options "-O3 -march=z13 -mzarch --save-temps" } */
#include <stddef.h>
#include <limits.h>
{
return __builtin_bswap64 (u64);
}
-/* { dg-final { scan-assembler-times "lrvg\t%r2,0\\(%r\[0-9\]*\\)" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "lrvg\t%r2,\[0-9\]+\\(%r\[0-9\]*\\)" 1 { target lp64 } } } */
void
foo64c (uint64_t a)
{
u64 = __builtin_bswap64 (a);
}
-/* { dg-final { scan-assembler-times "strvg\t%r2,0\\(%r\[0-9\]*\\)" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "strvg\t%r2,\[0-9\]+\\(%r\[0-9\]*\\)" 1 { target lp64 } } } */
{
return __builtin_bswap32 (u32);
}
-/* { dg-final { scan-assembler-times "lrv\t%r2,0\\(%r\[0-9\]*\\)" 1 } } */
+/* { dg-final { scan-assembler-times "lrv\t%r2,\[0-9\]+\\(%r\[0-9\]*\\)" 1 } } */
void
foo32c (uint32_t a)
{
u32 = __builtin_bswap32 (a);
}
-/* { dg-final { scan-assembler-times "strv\t%r2,0\\(%r\[0-9\]*\\)" 1 } } */
+/* { dg-final { scan-assembler-times "strv\t%r2,\[0-9\]+\\(%r\[0-9\]*\\)" 1 } } */
void c()
{
b = a + 4;
- /* { dg-final { scan-assembler {(?n)\n\tlgrl\t%r\d+,a@GOTENT\n} } } */
- /* { dg-final { scan-assembler-not {(?n)\n\tlarl\t%r\d+,a[^@]} } } */
+ /* { dg-final { scan-assembler "(?n)\n\tlgrl\t%r\\d+,a@GOTENT\n" } } */
+ /* { dg-final { scan-assembler-not "(?n)\n\tlarl\t%r\\d+,a\[^@\]" } } */
}
/* Check if load-relative instructions are created */
/* { dg-do compile { target { s390*-*-* } } } */
-/* { dg-options "-O2 -march=z10 -mzarch" } */
+/* { dg-options "-O2 -march=z10 -mzarch -fno-section-anchors" } */
/* { dg-final { scan-assembler "lgfrl\t%r.?,b.4" { target { lp64 } } } } */
/* { dg-final { scan-assembler "lgfrl\t%r.?,s.12" { target { lp64 } } } } */
pointer being correct. */
/* { dg-do run } */
-/* { dg-options "" } */
+/* { dg-options "-O2 -fsplit-stack" } */
#include <stdlib.h>
gl += bar (i);
}
+void __attribute__((noinline,noclone))
+baz (int a)
+{
+ int i;
+
+ for (i = 0; i < a; i++)
+ gl += bar (i);
+}
+
int
main ()
{
return 0;
}
-/* 1 x foo, 1 x main
-/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 2 } } */
+/* 1 x foo, 1 x baz, 1 x main */
+/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 3 } } */
-/* 1 x foo, conditional return, shrink wrapped
+/* 1 x foo, conditional return, shrink wrapped */
/* { dg-final { scan-assembler "jge\t__s390_indirect_jump" } } */
-/* 1 x foo, conditional return, shrink wrapped
+/* 1 x baz, conditional return, shrink wrapped */
/* { dg-final { scan-assembler "jgle\t__s390_indirect_jump" } } */
/* { dg-final { scan-assembler "ex\t" } } */
}
// Test an arithmetic shift right in which some of the sign bits are kept.
-// This needs a separate shift and mask.
+// This needs a separate shift and mask on 31 bit.
i32 f19 (i32 v_foo)
{
- /* Should be
- { dg-final { scan-assembler "f19:\n\tsra\t%r2,28\n\tnilf\t%r2,30" { xfail { lp64 } } } }
- but because a zeroextend is merged into the pattern it is actually
- { dg-final { scan-assembler "f19:\n\tsra\t%r2,28\n\trisbg\t%r2,%r2,59,128\\\+62,0" { target { lp64 } } } }
- { dg-final { scan-assembler "f19:\n\tsra\t%r2,28\n\tnilf\t%r2,30" { target { ! lp64 } } } } */
+ /* { dg-final { scan-assembler "f19:\n\trisbg\t%r2,%r2,59,128\\+62,64-28" { target { lp64 } } } } */
+ /* { dg-final { scan-assembler "f19:\n\tsra\t%r2,28\n\tnilf\t%r2,30" { target { ! lp64 } } } } */
i32 v_shr = v_foo >> 28;
i32 v_and = v_shr & 30;
return v_and;
// mask and rotate.
i32 f24 (i32 v_foo)
{
- /* { dg-final { scan-assembler "f24:\n\tnilf\t%r2,254\n\trll\t%r2,%r2,29" } } */
+ /* { dg-final { scan-assembler "f24:\n\tnilf\t%r2,254\n\trll\t%r2,%r2,29\n" } } */
i32 v_and = v_foo & 254;
i32 v_parta = ((ui32)v_and) >> 3;
i32 v_partb = v_and << 29;
// 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%r2,%r2,32,128\\+61,32\\+20\n\tlgfr\t%r2,%r2" { 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 } } } } */
i64 v_shr3 = ((ui64)v_x) >> 12;
i32 v_shr3_tr = (ui32)v_shr3;
// Test a case with two ANDs and a shift.
i32 f3 (i32 v_a, i32 v_b)
{
- /* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,4\\\+52" } } */
+ /* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,\\(64-32\\)\\+4\\+20\n\tlgfr\t%r2,%r2" } } */
i32 v_anda = v_a & -16;
i32 v_shr = ((ui32)v_b) >> 8;
i32 v_andb = v_shr & 15;
// ...and again with i64.
i64 f4 (i64 v_a, i64 v_b)
{
- /* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,60,60\\\+4-1,128-60-4-8" { target { lp64 } } } } */
- /* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trisbg\t%r5,%r5,64-4,128\\\+63,52\\\+4" { target { ! lp64 } } } } */
+ /* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,64-4,63,\\(64-64\\)\\+4\\+52" { target { lp64 } } } } */
+ /* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trisbg\t%r5,%r5,64-4,128\\+63,\\(64-64\\)\\+52\\+4" { target { ! lp64 } } } } */
i64 v_anda = v_a & -16;
i64 v_shr = ((ui64)v_b) >> 8;
i64 v_andb = v_shr & 15;
// On zEC12, we generally prefer RISBGN.
i64 f1 (i64 v_a, i64 v_b)
{
-/* { dg-final { scan-assembler "f1:\n\trisbgn\t%r2,%r3,60,60\\\+3-1,128-60-3-1" { target { lp64 } } } } */
+/* { dg-final { scan-assembler "f1:\n\trisbgn\t%r2,%r3,60,62,0" { target { lp64 } } } } */
/* { dg-final { scan-assembler "f1:\n\trisbgn\t%r3,%r2,0,0\\\+32-1,64-0-32\n\trisbgn\t%r3,%r5,60,62,0\n" { target { ! lp64 } } } } */
i64 v_anda = v_a & -15;
i64 v_andb = v_b & 14;
/* Inlining needs to be rejected. foo3 performs HW FP operation. */
-int __attribute__ ((always_inline)) foo3 (int a) /* { dg-error "inlining failed in call to always_inline" } */
+int __attribute__ ((always_inline)) foo3 (int a) /* { dg-error "inlining failed in call to 'always_inline'" } */
{
g = (double) a / 2.0;
return 0;