S/390: arch13: Support new bit operations
authorAndreas Krebbel <krebbel@linux.ibm.com>
Tue, 2 Apr 2019 10:51:53 +0000 (10:51 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Tue, 2 Apr 2019 10:51:53 +0000 (10:51 +0000)
Make use of the new bit operation instructions when generating code
for the arch13 level.

gcc/ChangeLog:

2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>

* config/s390/s390.c (s390_canonicalize_comparison): Convert
certain compares for arch13 in order to make use of the condition
code result produced by the new instructions.
(s390_rtx_costs): Adjust the costs for nnrk, nngrk, nork, nogrk,
nxrk, and nxgrk instruction patterns.
* config/s390/s390.md (ANDOR, bitops_name, inv_bitops_name)
(inv_no): Add new code iterator together with some attributes.
("*andc_split_<mode>"): Disable splitter for arch13.
("*<ANDOR:bitops_name>c<GPR:mode>_cc")
("*<ANDOR:bitops_name>c<GPR:mode>_cconly")
("*<ANDOR:bitops_name>c<GPR:mode>")
("*n<ANDOR:inv_bitops_name><GPR:mode>_cc")
("*n<ANDOR:inv_bitops_name><mode>_cconly")
("*n<ANDOR:inv_bitops_name><mode>", "*nxor<GPR:mode>_cc")
("*nxor<mode>_cconly", "*nxor<mode>"): New insn definitions.

gcc/testsuite/ChangeLog:

2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>

* gcc.target/s390/arch13/bitops-1.c: New test.
* gcc.target/s390/arch13/bitops-2.c: New test.
* gcc.target/s390/md/andc-splitter-1.c: Add -march=z14 build
option and adjust line numbers.
* gcc.target/s390/md/andc-splitter-2.c: Likewise.

From-SVN: r270078

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/arch13/bitops-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/arch13/bitops-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/s390/md/andc-splitter-1.c
gcc/testsuite/gcc.target/s390/md/andc-splitter-2.c

index 2ab9586762e1fc0c27507060441c07b1a8dee99c..f9ed2b0a38ca21ce9ef4b3a1277b22d4c7ca0bfa 100644 (file)
@@ -1,3 +1,21 @@
+2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * config/s390/s390.c (s390_canonicalize_comparison): Convert
+       certain compares for arch13 in order to make use of the condition
+       code result produced by the new instructions.
+       (s390_rtx_costs): Adjust the costs for nnrk, nngrk, nork, nogrk,
+       nxrk, and nxgrk instruction patterns.
+       * config/s390/s390.md (ANDOR, bitops_name, inv_bitops_name)
+       (inv_no): Add new code iterator together with some attributes.
+       ("*andc_split_<mode>"): Disable splitter for arch13.
+       ("*<ANDOR:bitops_name>c<GPR:mode>_cc")
+       ("*<ANDOR:bitops_name>c<GPR:mode>_cconly")
+       ("*<ANDOR:bitops_name>c<GPR:mode>")
+       ("*n<ANDOR:inv_bitops_name><GPR:mode>_cc")
+       ("*n<ANDOR:inv_bitops_name><mode>_cconly")
+       ("*n<ANDOR:inv_bitops_name><mode>", "*nxor<GPR:mode>_cc")
+       ("*nxor<mode>_cconly", "*nxor<mode>"): New insn definitions.
+
 2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * common/config/s390/s390-common.c (processor_flags_table): New
index 5c55ebe32981e9ad3c28d8ce72bb7b744d44bd7f..7cf1d67e98532a78c5442944083ece65533ad119 100644 (file)
@@ -1793,6 +1793,38 @@ s390_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
          *op0 = XEXP (*op0, 0);
        }
     }
+
+  /* ~a==b -> ~(a^b)==0   ~a!=b -> ~(a^b)!=0 */
+  if (TARGET_ARCH13
+      && (*code == EQ || *code == NE)
+      && (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
+      && GET_CODE (*op0) == NOT)
+    {
+      machine_mode mode = GET_MODE (*op0);
+      *op0 = gen_rtx_XOR (mode, XEXP (*op0, 0), *op1);
+      *op0 = gen_rtx_NOT (mode, *op0);
+      *op1 = const0_rtx;
+    }
+
+  /* a&b == -1 -> ~a|~b == 0    a|b == -1 -> ~a&~b == 0  */
+  if (TARGET_ARCH13
+      && (*code == EQ || *code == NE)
+      && (GET_CODE (*op0) == AND || GET_CODE (*op0) == IOR)
+      && (GET_MODE (*op0) == DImode || GET_MODE (*op0) == SImode)
+      && CONST_INT_P (*op1)
+      && *op1 == constm1_rtx)
+    {
+      machine_mode mode = GET_MODE (*op0);
+      rtx op00 = gen_rtx_NOT (mode, XEXP (*op0, 0));
+      rtx op01 = gen_rtx_NOT (mode, XEXP (*op0, 1));
+
+      if (GET_CODE (*op0) == AND)
+       *op0 = gen_rtx_IOR (mode, op00, op01);
+      else
+       *op0 = gen_rtx_AND (mode, op00, op01);
+
+      *op1 = const0_rtx;
+    }
 }
 
 
@@ -3516,6 +3548,21 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
        return true;
       }
     case IOR:
+
+      /* nnrk, nngrk */
+      if (TARGET_ARCH13
+         && (mode == SImode || mode == DImode)
+         && GET_CODE (XEXP (x, 0)) == NOT
+         && GET_CODE (XEXP (x, 1)) == NOT)
+       {
+         *total = COSTS_N_INSNS (1);
+         if (!REG_P (XEXP (XEXP (x, 0), 0)))
+           *total += 1;
+         if (!REG_P (XEXP (XEXP (x, 1), 0)))
+           *total += 1;
+         return true;
+       }
+
       /* risbg */
       if (GET_CODE (XEXP (x, 0)) == AND
          && GET_CODE (XEXP (x, 1)) == ASHIFT
@@ -3544,19 +3591,33 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
          *total = COSTS_N_INSNS (1);
          return true;
        }
+
+      *total = COSTS_N_INSNS (1);
+      return false;
+
+    case AND:
+      /* nork, nogrk */
+      if (TARGET_ARCH13
+         && (mode == SImode || mode == DImode)
+         && GET_CODE (XEXP (x, 0)) == NOT
+         && GET_CODE (XEXP (x, 1)) == NOT)
+       {
+         *total = COSTS_N_INSNS (1);
+         if (!REG_P (XEXP (XEXP (x, 0), 0)))
+           *total += 1;
+         if (!REG_P (XEXP (XEXP (x, 1), 0)))
+           *total += 1;
+         return true;
+       }
       /* fallthrough */
     case ASHIFT:
     case ASHIFTRT:
     case LSHIFTRT:
     case ROTATE:
     case ROTATERT:
-    case AND:
     case XOR:
     case NEG:
     case NOT:
-      *total = COSTS_N_INSNS (1);
-      return false;
-
     case PLUS:
     case MINUS:
       *total = COSTS_N_INSNS (1);
@@ -3706,6 +3767,38 @@ s390_rtx_costs (rtx x, machine_mode mode, int outer_code,
 
     case COMPARE:
       *total = COSTS_N_INSNS (1);
+
+      /* nxrk, nxgrk ~(a^b)==0 */
+      if (TARGET_ARCH13
+         && GET_CODE (XEXP (x, 0)) == NOT
+         && XEXP (x, 1) == const0_rtx
+         && GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR
+         && (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
+         && mode == CCZmode)
+       {
+         if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
+           *total += 1;
+         if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 1)))
+           *total += 1;
+         return true;
+       }
+
+      /* nnrk, nngrk, nork, nogrk */
+      if (TARGET_ARCH13
+         && (GET_CODE (XEXP (x, 0)) == AND || GET_CODE (XEXP (x, 0)) == IOR)
+         && XEXP (x, 1) == const0_rtx
+         && (GET_MODE (XEXP (x, 0)) == SImode || GET_MODE (XEXP (x, 0)) == DImode)
+         && GET_CODE (XEXP (XEXP (x, 0), 0)) == NOT
+         && GET_CODE (XEXP (XEXP (x, 0), 1)) == NOT
+         && mode == CCZmode)
+       {
+         if (!REG_P (XEXP (XEXP (XEXP (x, 0), 0), 0)))
+           *total += 1;
+         if (!REG_P (XEXP (XEXP (XEXP (x, 0), 1), 0)))
+           *total += 1;
+         return true;
+       }
+
       if (GET_CODE (XEXP (x, 0)) == AND
          && GET_CODE (XEXP (x, 1)) == CONST_INT
          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
index bbe1ea5f01ccbb6a58333652fc3eea9af6fc3b09..d635f849f18517d108bfdb30e2c7435d6b25c30f 100644 (file)
 ;; This iterator allows r[ox]sbg to be defined with the same template
 (define_code_iterator IXOR [ior xor])
 
+;; This is used for merging the nand/nor and and/or with complement patterns
+(define_code_iterator ANDOR [and ior])
+(define_code_attr bitops_name [(and "and") (ior "or")])
+(define_code_attr inv_bitops_name [(and "or") (ior "and")])
+(define_code_attr inv_no [(and "o") (ior "n")])
+
 ;; This iterator is used to expand the patterns for the nearest
 ;; integer functions.
 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
        (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
                 (match_operand:GPR 2 "general_operand" "")))
    (clobber (reg:CC CC_REGNUM))]
-  "! reload_completed
+  "!TARGET_ARCH13
+   && ! reload_completed
    && (GET_CODE (operands[0]) != MEM
       /* Ensure that s390_logical_operator_ok_p will succeed even
         on the split xor if (b & a) is stored into a pseudo.  */
   [(set_attr "op_type"  "RR,SI,SS")
    (set_attr "z10prop" "z10_super_E1,z10_super,*")])
 
+;
+; And/Or with complement
+;
+
+; ncrk, ncgrk, ocrk, ocgrk
+(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
+  [(set (reg CC_REGNUM)
+       (compare
+        (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                   (match_operand:GPR 2 "register_operand" "d"))
+        (const_int 0)))
+   (set (match_operand:GPR 0 "register_operand" "=d")
+       (ANDOR:GPR (not:GPR (match_dup 1))
+                  (match_dup 2)))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
+  [(set_attr "op_type" "RRF")])
+
+; ncrk, ncgrk, ocrk, ocgrk
+(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
+  [(set (reg CC_REGNUM)
+       (compare
+        (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                   (match_operand:GPR 2 "register_operand" "d"))
+        (const_int 0)))
+   (clobber (match_scratch:GPR 0 "=d"))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
+  [(set_attr "op_type" "RRF")])
+
+; ncrk, ncgrk, ocrk, ocgrk
+(define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+       (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                  (match_operand:GPR 2 "register_operand" "d")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_ARCH13"
+  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
+  [(set_attr "op_type" "RRF")])
+
+;
+;- Nand/Nor instructions.
+;
+
+; nnrk, nngrk, nork, nogrk
+(define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
+  [(set (reg CC_REGNUM)
+       (compare
+        (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                   (not:GPR (match_operand:GPR 2 "register_operand" "d")))
+        (const_int 0)))
+   (set (match_operand:GPR 0 "register_operand" "=d")
+       (ANDOR:GPR (not:GPR (match_dup 1))
+                  (not:GPR (match_dup 2))))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
+
+; nnrk, nngrk, nork, nogrk
+(define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
+  [(set (reg CC_REGNUM)
+       (compare
+        (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                   (not:GPR (match_operand:GPR 2 "register_operand" "d")))
+        (const_int 0)))
+   (clobber (match_scratch:GPR 0 "=d"))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
+
+; nnrk, nngrk, nork, nogrk
+(define_insn "*n<ANDOR:inv_bitops_name><mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+       (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
+                  (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_ARCH13"
+  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
+
+
 ;
 ; Block inclusive or (OC) patterns.
 ;
   "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
    operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
 
+;
+;- Nxor instructions.
+;
+
+; nxrk, nxgrk
+(define_insn "*nxor<GPR:mode>_cc"
+  [(set (reg CC_REGNUM)
+       (compare
+        (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
+                          (match_operand:GPR 2 "register_operand" "d")))
+        (const_int 0)))
+   (set (match_operand:GPR 0 "register_operand" "=d")
+       (xor:GPR (not:GPR (match_dup 1))
+                   (match_dup 2)))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "nx<GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
+
+; nxrk, nxgrk
+(define_insn "*nxor<mode>_cconly"
+  [(set (reg CC_REGNUM)
+       (compare
+        (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
+                          (match_operand:GPR 2 "register_operand" "d")))
+        (const_int 0)))
+   (clobber (match_scratch:GPR 0 "=d"))]
+  "TARGET_ARCH13 && s390_match_ccmode(insn, CCTmode)"
+  "nx<GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
+
+; nxrk, nxgrk
+(define_insn "*nxor<mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=d")
+       (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
+                         (match_operand:GPR 2 "register_operand" "d"))))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_ARCH13"
+  "nx<GPR:g>rk\t%0,%1,%2"
+  [(set_attr "op_type" "RRF")])
 
 ;;
 ;;- Negate instructions.
index 35eb6fe09ce5021ebe7ea066d338202e01fbbfbc..f7f1883c1fec64d56cb304bf689980837c5f48c0 100644 (file)
@@ -1,3 +1,11 @@
+2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>
+
+       * gcc.target/s390/arch13/bitops-1.c: New test.
+       * gcc.target/s390/arch13/bitops-2.c: New test.
+       * gcc.target/s390/md/andc-splitter-1.c: Add -march=z14 build
+       option and adjust line numbers.
+       * gcc.target/s390/md/andc-splitter-2.c: Likewise.
+
 2019-04-02  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * gcc.target/s390/s390.exp: Run tests in arch13 subdir.
diff --git a/gcc/testsuite/gcc.target/s390/arch13/bitops-1.c b/gcc/testsuite/gcc.target/s390/arch13/bitops-1.c
new file mode 100644 (file)
index 0000000..fd49fb9
--- /dev/null
@@ -0,0 +1,91 @@
+/* { dg-compile } */
+
+/* and with complement */
+
+int
+ncrk (int a, int b)
+{
+  return a & ~b;
+}
+
+/* { dg-final { scan-assembler-times "\tncrk\t" 1 } } */
+
+long long
+ncgrk (long long a, long long b)
+{
+  return a & ~b;
+}
+
+/* { dg-final { scan-assembler-times "\tncgrk\t" 1 } } */
+
+/* or with complement */
+
+int
+ocrk (int a, int b)
+{
+  return a | ~b;
+}
+
+/* { dg-final { scan-assembler-times "\tocrk\t" 1 } } */
+
+long long
+ocgrk (long long a, long long b)
+{
+  return a | ~b;
+}
+
+/* { dg-final { scan-assembler-times "\tocgrk\t" 1 } } */
+
+/* nand */
+
+int
+nnrk (int a, int b)
+{
+  return ~(a & b);
+}
+
+/* { dg-final { scan-assembler-times "\tnnrk\t" 1 } } */
+
+long long
+nngrk (long long a, long long b)
+{
+  return ~(a & b);
+}
+
+/* { dg-final { scan-assembler-times "\tnngrk\t" 1 } } */
+
+/* nor */
+
+int
+nork (int a, int b)
+{
+  return ~(a | b);
+}
+
+/* { dg-final { scan-assembler-times "\tnork\t" 1 } } */
+
+long long
+nogrk (long long a, long long b)
+{
+  return ~(a | b);
+}
+
+/* { dg-final { scan-assembler-times "\tnogrk\t" 1 } } */
+
+/* nxor */
+
+int
+nxrk (int a, int b)
+{
+  return ~(a ^ b);
+}
+
+/* { dg-final { scan-assembler-times "\tnxrk\t" 1 } } */
+
+long long
+nxgrk (long long a, long long b)
+{
+  return ~(a ^ b);
+}
+
+/* { dg-final { scan-assembler-times "\tnxgrk\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/arch13/bitops-2.c b/gcc/testsuite/gcc.target/s390/arch13/bitops-2.c
new file mode 100644 (file)
index 0000000..fde9603
--- /dev/null
@@ -0,0 +1,93 @@
+/* { dg-compile } */
+
+/* Check if the instruction are being used also for compares.  */
+
+/* and with complement */
+
+int
+ncrk (int a, int b)
+{
+  return (a & ~b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tncrk\t" 1 } } */
+
+int
+ncgrk (long long a, long long b)
+{
+  return (a & ~b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tncgrk\t" 1 } } */
+
+/* or with complement */
+
+int
+ocrk (int a, int b)
+{
+  return (a | ~b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tocrk\t" 1 } } */
+
+int
+ocgrk (long long a, long long b)
+{
+  return (a | ~b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tocgrk\t" 1 } } */
+
+/* nand */
+
+int
+nnrk (int a, int b)
+{
+  return ~(a & b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tnnrk\t" 1 } } */
+
+int
+nngrk (long long a, long long b)
+{
+  return ~(a & b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tnngrk\t" 1 } } */
+
+/* nor */
+
+int
+nork (int a, int b)
+{
+  return ~(a | b);
+}
+
+/* { dg-final { scan-assembler-times "\tnork\t" 1 } } */
+
+int
+nogrk (long long a, long long b)
+{
+  return ~(a | b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tnogrk\t" 1 } } */
+
+/* nxor */
+
+int
+nxrk (int a, int b)
+{
+  return ~(a ^ b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tnxrk\t" 1 } } */
+
+int
+nxgrk (long long a, long long b)
+{
+  return ~(a ^ b) ? 23 : 42;
+}
+
+/* { dg-final { scan-assembler-times "\tnxgrk\t" 1 } } */
index 36f2cfc53de6d6aa0415ac701514d74e7a40a023..f4e28f6218733b062ae93adaffe436229828ecc9 100644 (file)
@@ -1,7 +1,9 @@
 /* Machine description pattern tests.  */
 
 /* { dg-do compile { target { lp64 } } } */
-/* { dg-options "-mzarch -save-temps -dP" } */
+/* Starting with arch13 the and with complement instruction is
+   available and the splitter is disabled.  */
+/* { dg-options "-march=z14 -mzarch -save-temps -dP" } */
 /* { dg-do run { target { lp64 && s390_useable_hw } } } */
 /* Skip test if -O0 is present on the command line:
 
 __attribute__ ((noinline))
 unsigned long andc_vv(unsigned long a, unsigned long b)
 { return ~b & a; }
-/* { dg-final { scan-assembler ":16:.\* \{\\*anddi3\}" } } */
-/* { dg-final { scan-assembler ":16:.\* \{\\*xordi3\}" } } */
+/* { dg-final { scan-assembler ":18:.\* \{\\*anddi3\}" } } */
+/* { dg-final { scan-assembler ":18:.\* \{\\*xordi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned long andc_pv(unsigned long *a, unsigned long b)
 { return ~b & *a; }
-/* { dg-final { scan-assembler ":22:.\* \{\\*anddi3\}" } } */
-/* { dg-final { scan-assembler ":22:.\* \{\\*xordi3\}" } } */
+/* { dg-final { scan-assembler ":24:.\* \{\\*anddi3\}" } } */
+/* { dg-final { scan-assembler ":24:.\* \{\\*xordi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned long andc_vp(unsigned long a, unsigned long *b)
 { return ~*b & a; }
-/* { dg-final { scan-assembler ":28:.\* \{\\*anddi3\}" } } */
-/* { dg-final { scan-assembler ":28:.\* \{\\*xordi3\}" } } */
+/* { dg-final { scan-assembler ":30:.\* \{\\*anddi3\}" } } */
+/* { dg-final { scan-assembler ":30:.\* \{\\*xordi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned long andc_pp(unsigned long *a, unsigned long *b)
 { return ~*b & *a; }
-/* { dg-final { scan-assembler ":34:.\* \{\\*anddi3\}" } } */
-/* { dg-final { scan-assembler ":34:.\* \{\\*xordi3\}" } } */
+/* { dg-final { scan-assembler ":36:.\* \{\\*anddi3\}" } } */
+/* { dg-final { scan-assembler ":36:.\* \{\\*xordi3\}" } } */
 
 /* { dg-final { scan-assembler-times "\tngr\?k\?\t" 4 } } */
 /* { dg-final { scan-assembler-times "\txgr\?\t" 4 } } */
index 75ab75b5273d2587ff37baa30751523bba42d68a..03df7b214db11e58d58f96078d041724fe1d8d58 100644 (file)
@@ -1,7 +1,9 @@
 /* Machine description pattern tests.  */
 
 /* { dg-do compile } */
-/* { dg-options "-save-temps -dP" } */
+/* Starting with arch13 the and with complement instruction is
+   available and the splitter is disabled.  */
+/* { dg-options "-march=z14 -save-temps -dP" } */
 /* { dg-do run { target { s390_useable_hw } } } */
 /* Skip test if -O0 is present on the command line:
 
 __attribute__ ((noinline))
 unsigned int andc_vv(unsigned int a, unsigned int b)
 { return ~b & a; }
-/* { dg-final { scan-assembler ":16:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
-/* { dg-final { scan-assembler ":16:.\* \{\\*xorsi3\}" } } */
+/* { dg-final { scan-assembler ":18:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
+/* { dg-final { scan-assembler ":18:.\* \{\\*xorsi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned int andc_pv(unsigned int *a, unsigned int b)
 { return ~b & *a; }
-/* { dg-final { scan-assembler ":22:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
-/* { dg-final { scan-assembler ":22:.\* \{\\*xorsi3\}" } } */
+/* { dg-final { scan-assembler ":24:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
+/* { dg-final { scan-assembler ":24:.\* \{\\*xorsi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned int andc_vp(unsigned int a, unsigned int *b)
 { return ~*b & a; }
-/* { dg-final { scan-assembler ":28:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
-/* { dg-final { scan-assembler ":28:.\* \{\\*xorsi3\}" } } */
+/* { dg-final { scan-assembler ":30:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
+/* { dg-final { scan-assembler ":30:.\* \{\\*xorsi3\}" } } */
 
 __attribute__ ((noinline))
 unsigned int andc_pp(unsigned int *a, unsigned int *b)
 { return ~*b & *a; }
-/* { dg-final { scan-assembler ":34:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
-/* { dg-final { scan-assembler ":34:.\* \{\\*xorsi3\}" } } */
+/* { dg-final { scan-assembler ":36:.\* \{\\*andsi3_\(esa\|zarch\)\}" } } */
+/* { dg-final { scan-assembler ":36:.\* \{\\*xorsi3\}" } } */
 
 /* { dg-final { scan-assembler-times "\tnr\?k\?\t" 4 } } */
 /* { dg-final { scan-assembler-times "\txr\?k\?\t" 4 } } */