This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

S/390: Add patterns for r<nox>sbg instructions.


The attached patch adds some patterns using the r*sbg instructions
to the s390 machine description.  Bootstrapped and regression
tested on s390 and s390x.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

Attachment: 0001-ChangeLog
Description: Text document

>From 4f6e3da0bcb6adeff8acfaaeeec3261a92bac00c Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 4 Mar 2016 09:45:05 +0100
Subject: [PATCH] S/390: Add patterns for r<nox>sbg instructions.

Needs new ANDIXOR code iterator.
---
 gcc/config/s390/s390.md                           |  34 ++++-
 gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c | 151 ++++++++++++++++++++++
 gcc/testsuite/gcc.target/s390/s390.exp            |  11 ++
 3 files changed, 194 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c

diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 5a9f1c8..5f3b0f7 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3965,7 +3965,7 @@
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
   [(set_attr "op_type" "RIE")])
 
-(define_insn "*r<noxa>sbg_<mode>_srl"
+(define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
 	(IXOR:GPR
 	  (and:GPR
@@ -3981,7 +3981,7 @@
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
   [(set_attr "op_type" "RIE")])
 
-(define_insn "*r<noxa>sbg_<mode>_sll"
+(define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
 	(IXOR:GPR
 	  (and:GPR
@@ -3997,6 +3997,36 @@
   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
   [(set_attr "op_type" "RIE")])
 
+;; unsigned {int,long} a, b
+;; a = a | (b << const_int)
+;; a = a ^ (b << const_int)
+(define_insn "*r<noxa>sbg_<mode>_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"
+  "r<noxa>sbg\t%0,%1,64-<bitsize>,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 "*r<noxa>sbg_<mode>_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"
+  "r<noxa>sbg\t%0,%1,64-<bitsize>+%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/gcc.target/s390/md/rXsbg_mode_sXl.c b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c
new file mode 100644
index 0000000..178a537
--- /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 680e7d9..f4ad7a1 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.3.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]