From f3d9004571a9fa52f2aa2cbbee82a4e4c1e9e65b Mon Sep 17 00:00:00 2001 From: Dominik Vogt Date: Tue, 3 May 2016 13:30:33 +0000 Subject: [PATCH] S/390: Add patterns for rsbg instructions. gcc/ChangeLog: 2016-05-03 Dominik Vogt * config/s390/s390.md ("*rsbg__sll") ("*rsbg__srl"): New define_insns. ("*rsbg__srl_bitmask"): Rename by adding "_bitmask". ("*rsbg__sll_bitmask"): Likewise. gcc/testsuite/ChangeLog: 2016-05-03 Dominik Vogt * gcc.target/s390/md/rXsbg_mode_sXl.c: New test. * gcc.target/s390/s390.exp (check_effective_target_z10_instructions): Procedure to check for z10 instruction set. From-SVN: r235822 --- gcc/ChangeLog | 7 + gcc/config/s390/s390.md | 34 +++- gcc/testsuite/ChangeLog | 6 + .../gcc.target/s390/md/rXsbg_mode_sXl.c | 151 ++++++++++++++++++ gcc/testsuite/gcc.target/s390/s390.exp | 11 ++ 5 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6d8b0d620de..095e502adfa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-05-03 Dominik Vogt + + * config/s390/s390.md ("*rsbg__sll") + ("*rsbg__srl"): New define_insns. + ("*rsbg__srl_bitmask"): Rename by adding "_bitmask". + ("*rsbg__sll_bitmask"): Likewise. + 2016-05-03 Alan Modra * config/rs6000/rs6000.c (rs6000_savres_strategy): Correct condition diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 12a7f2a63c3..faaa7f3fc9f 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -3989,7 +3989,7 @@ "rsbg\t%0,%1,%2,%2,%b3" [(set_attr "op_type" "RIE")]) -(define_insn "*rsbg__srl" +(define_insn "*rsbg__srl_bitmask" [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") (IXOR:GPR (and:GPR @@ -4005,7 +4005,7 @@ "rsbg\t%0,%1,%2,%2,64-%3" [(set_attr "op_type" "RIE")]) -(define_insn "*rsbg__sll" +(define_insn "*rsbg__sll_bitmask" [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") (IXOR:GPR (and:GPR @@ -4021,6 +4021,36 @@ "rsbg\t%0,%1,%2,%2,%3" [(set_attr "op_type" "RIE")]) +;; unsigned {int,long} a, b +;; a = a | (b << const_int) +;; a = a ^ (b << const_int) +(define_insn "*rsbg__sll" + [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") + (IXOR:GPR + (ashift:GPR + (match_operand:GPR 1 "nonimmediate_operand" "d") + (match_operand:GPR 2 "nonzero_shift_count_operand" "")) + (match_operand:GPR 3 "nonimmediate_operand" "0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z10" + "rsbg\t%0,%1,64-,63-%2,%2" + [(set_attr "op_type" "RIE")]) + +;; unsigned {int,long} a, b +;; a = a | (b >> const_int) +;; a = a ^ (b >> const_int) +(define_insn "*rsbg__srl" + [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") + (IXOR:GPR + (lshiftrt:GPR + (match_operand:GPR 1 "nonimmediate_operand" "d") + (match_operand:GPR 2 "nonzero_shift_count_operand" "")) + (match_operand:GPR 3 "nonimmediate_operand" "0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z10" + "rsbg\t%0,%1,64-+%2,63,64-%2" + [(set_attr "op_type" "RIE")]) + ;; These two are generated by combine for s.bf &= val. ;; ??? For bitfields smaller than 32-bits, we wind up with SImode ;; shifts and ands, which results in some truly awful patterns diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d3eed07bc76..3ff4ea4d8f8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-05-03 Dominik Vogt + + * gcc.target/s390/md/rXsbg_mode_sXl.c: New test. + * gcc.target/s390/s390.exp (check_effective_target_z10_instructions): + Procedure to check for z10 instruction set. + 2016-05-03 Christophe Lyon * gcc.dg/ipa/inline-8.c: Require c99_runtime. diff --git a/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c new file mode 100644 index 00000000000..178a537b1de --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c @@ -0,0 +1,151 @@ +/* Machine description pattern tests. */ + +/* + { dg-options "-mzarch -save-temps" } + + Note that dejagnu-1.5.1 has a bug so that the action from the second dg-do + always wins, even if the condition is false. If this test is run on hardware + older than z10 with a buggy dejagnu release, the execution part will fail. + + { dg-do assemble { target { ! z10_instructions } } } + { dg-do run { target { z10_instructions } } } + + Skip test if -O0, -march=z900, -march=z9-109 or -march=z9-ec is present on + the command line: + + { dg-skip-if "" { *-*-* } { "-march=z9*" "-O0" } { "" } } + + Skip test if the -O or the -march= option is missing from the command line + because it's difficult to detect the default: + + { dg-skip-if "" { *-*-* } { "*" } { "-O*" } } + { dg-skip-if "" { *-*-* } { "*" } { "-march=*" } } +*/ + +__attribute__ ((noinline)) unsigned int +si_sll (unsigned int x) +{ + return (x << 1); +} + +__attribute__ ((noinline)) unsigned int +si_srl (unsigned int x) +{ + return (x >> 2); +} + +__attribute__ ((noinline)) unsigned int +rosbg_si_sll (unsigned int a, unsigned int b) +{ + return a | (b << 1); +} +/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-32,63-1,1" 1 } } */ + +__attribute__ ((noinline)) unsigned int +rosbg_si_srl (unsigned int a, unsigned int b) +{ + return a | (b >> 2); +} +/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-32\\+2,63,64-2" 1 } } */ + +__attribute__ ((noinline)) unsigned int +rxsbg_si_sll (unsigned int a, unsigned int b) +{ + return a ^ (b << 1); +} +/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-32,63-1,1" 1 } } */ + +__attribute__ ((noinline)) unsigned int +rxsbg_si_srl (unsigned int a, unsigned int b) +{ + return a ^ (b >> 2); +} +/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-32\\+2,63,64-2" 1 } } */ + +__attribute__ ((noinline)) unsigned long long +di_sll (unsigned long long x) +{ + return (x << 1); +} + +__attribute__ ((noinline)) unsigned long long +di_srl (unsigned long long x) +{ + return (x >> 2); +} + +__attribute__ ((noinline)) unsigned long long +rosbg_di_sll (unsigned long long a, unsigned long long b) +{ + return a | (b << 1); +} +/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-64,63-1,1" 1 } } */ + +__attribute__ ((noinline)) unsigned long long +rosbg_di_srl (unsigned long long a, unsigned long long b) +{ + return a | (b >> 2); +} +/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-64\\+2,63,64-2" 1 } } */ + +__attribute__ ((noinline)) unsigned long long +rxsbg_di_sll (unsigned long long a, unsigned long long b) +{ + return a ^ (b << 1); +} +/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-64,63-1,1" 1 } } */ + +__attribute__ ((noinline)) unsigned long long +rxsbg_di_srl (unsigned long long a, unsigned long long b) +{ + return a ^ (b >> 2); +} +/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-64\\+2,63,64-2" 1 } } */ + +int +main (void) +{ + /* SIMode */ + { + unsigned int r; + unsigned int a = 0x12488421u; + unsigned int b = 0x88881111u; + unsigned int csll = si_sll (b); + unsigned int csrl = si_srl (b); + + r = rosbg_si_sll (a, b); + if (r != (a | csll)) + __builtin_abort (); + r = rosbg_si_srl (a, b); + if (r != (a | csrl)) + __builtin_abort (); + r = rxsbg_si_sll (a, b); + if (r != (a ^ csll)) + __builtin_abort (); + r = rxsbg_si_srl (a, b); + if (r != (a ^ csrl)) + __builtin_abort (); + } + /* DIMode */ + { + unsigned long long r; + unsigned long long a = 0x1248357997538421lu; + unsigned long long b = 0x8888444422221111lu; + unsigned long long csll = di_sll (b); + unsigned long long csrl = di_srl (b); + + r = rosbg_di_sll (a, b); + if (r != (a | csll)) + __builtin_abort (); + r = rosbg_di_srl (a, b); + if (r != (a | csrl)) + __builtin_abort (); + r = rxsbg_di_sll (a, b); + if (r != (a ^ csll)) + __builtin_abort (); + r = rxsbg_di_srl (a, b); + if (r != (a ^ csrl)) + __builtin_abort (); + } + return 0; +} diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp index 680e7d95b71..f4ad7a1f25b 100644 --- a/gcc/testsuite/gcc.target/s390/s390.exp +++ b/gcc/testsuite/gcc.target/s390/s390.exp @@ -24,6 +24,17 @@ if ![istarget s390*-*-*] then { # Load support procs. load_lib gcc-dg.exp +# Return 1 if z10 instructions work. +proc check_effective_target_z10_instructions { } { + if { ![check_runtime s390_check_z10_instructions [subst { + int main (void) + { + asm ("rosbg %%r2,%%r2,0,0,0" : : ); + return 0; + } + }] "-march=z10 -mzarch" ] } { return 0 } else { return 1 } +} + # Return 1 if the the assembler understands .machine and .machinemode. The # target attribute needs that feature to work. proc check_effective_target_target_attribute { } { -- 2.30.2