S/390: Fix warnings in "*setmem_long..." patterns.
authorDominik Vogt <vogt@linux.vnet.ibm.com>
Fri, 11 Dec 2015 11:16:13 +0000 (11:16 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Fri, 11 Dec 2015 11:16:13 +0000 (11:16 +0000)
gcc/ChangeLog

* config/s390/s390.c (s390_expand_setmem): Use new expanders.
* config/s390/s390.md ("*setmem_long")
("*setmem_long_and", "*setmem_long_31z"): Fix warnings.
("*setmem_long_and_31z"): New define_insn.
("setmem_long_<P:mode>"): New expanders.
* (<modesize>): New mode attribute

gcc/testsuite/ChangeLog

* gcc.target/s390/md/setmem_long-1.c: New test.

From-SVN: r231558

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/s390/md/setmem_long-1.c [new file with mode: 0644]

index 91690698cbdce22c3ecae1e27e648ec693b62716..da9e02f247d38c76cf67e68d6a75d16a7294da0a 100644 (file)
@@ -1,3 +1,12 @@
+2015-12-11  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       * config/s390/s390.c (s390_expand_setmem): Use new expanders.
+       * config/s390/s390.md ("*setmem_long")
+       ("*setmem_long_and", "*setmem_long_31z"): Fix warnings.
+       ("*setmem_long_and_31z"): New define_insn.
+       ("setmem_long_<P:mode>"): New expanders.
+       * (<modesize>): New mode attribute
+       
 2015-12-11  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        * config/s390/s390.md ("movstr", "*movstr"): Fix warning.
index f8928b9ac3eb3e982c4680f39adb6bf2faa40aba..1695dfbac30d4a91b3d7fa10db4e964e5e041f13 100644 (file)
@@ -5237,7 +5237,12 @@ s390_expand_setmem (rtx dst, rtx len, rtx val)
   else if (TARGET_MVCLE)
     {
       val = force_not_mem (convert_modes (Pmode, QImode, val, 1));
-      emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val));
+      if (TARGET_64BIT)
+       emit_insn (gen_setmem_long_di (dst, convert_to_mode (Pmode, len, 1),
+                                      val));
+      else
+       emit_insn (gen_setmem_long_si (dst, convert_to_mode (Pmode, len, 1),
+                                      val));
     }
 
   else
index bc24a3665fb9f20474304bbbc4fbeb73708ff90e..a1fc96a0adc34029cfc944a9e17be3765ed7776d 100644 (file)
@@ -70,6 +70,9 @@
    ; Copy CC as is into the lower 2 bits of an integer register
    UNSPEC_CC_TO_INT
 
+   ; The right hand side of an setmem
+   UNSPEC_REPLICATE_BYTE
+
    ; GOT/PLT and lt-relative accesses
    UNSPEC_LTREL_OFFSET
    UNSPEC_LTREL_BASE
 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
 
+;; In place of GET_MODE_SIZE (<MODE>mode)
+(define_mode_attr modesize [(DI "8") (SI "4")])
+
 ;; Allow return and simple_return to be defined from a single template.
 (define_code_iterator ANY_RETURN [return simple_return])
 
 
 ; Initialize a block of arbitrary length with (operands[2] % 256).
 
-(define_expand "setmem_long"
+(define_expand "setmem_long_<P:mode>"
   [(parallel
     [(clobber (match_dup 1))
      (set (match_operand:BLK 0 "memory_operand" "")
-          (match_operand 2 "shift_count_or_setmem_operand" ""))
-     (use (match_operand 1 "general_operand" ""))
+         (unspec:BLK [(match_operand:P 2 "shift_count_or_setmem_operand" "")
+                     (match_dup 4)] UNSPEC_REPLICATE_BYTE))
      (use (match_dup 3))
      (clobber (reg:CC CC_REGNUM))])]
   ""
   operands[0] = replace_equiv_address_nv (operands[0], addr0);
   operands[1] = reg0;
   operands[3] = reg1;
+  operands[4] = gen_lowpart (Pmode, operands[1]);
 })
 
+; Patterns for 31 bit + Esa and 64 bit + Zarch.
+
 (define_insn "*setmem_long"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (match_operand 2 "shift_count_or_setmem_operand" "Y"))
-   (use (match_dup 3))
+        (unspec:BLK [(match_operand:P 2 "shift_count_or_setmem_operand" "Y")
+                    (subreg:P (match_dup 3) <modesize>)]
+                    UNSPEC_REPLICATE_BYTE))
    (use (match_operand:<DBL> 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_64BIT || !TARGET_ZARCH"
 (define_insn "*setmem_long_and"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
-            (match_operand 4 "const_int_operand"             "n")))
-   (use (match_dup 3))
+        (unspec:BLK [(and:P
+                     (match_operand:P 2 "shift_count_or_setmem_operand" "Y")
+                     (match_operand:P 4 "const_int_operand"             "n"))
+                   (subreg:P (match_dup 3) <modesize>)]
+                   UNSPEC_REPLICATE_BYTE))
    (use (match_operand:<DBL> 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
   "(TARGET_64BIT || !TARGET_ZARCH) &&
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
+; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
+; of the SImode subregs.
+
 (define_insn "*setmem_long_31z"
   [(clobber (match_operand:TI 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
-        (match_operand 2 "shift_count_or_setmem_operand" "Y"))
-   (use (match_dup 3))
+        (unspec:BLK [(match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+                    (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
    (use (match_operand:TI 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]
   "!TARGET_64BIT && TARGET_ZARCH"
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
+(define_insn "*setmem_long_and_31z"
+  [(clobber (match_operand:TI 0 "register_operand" "=d"))
+   (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
+        (unspec:BLK [(and:SI
+                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
+                     (match_operand:SI 4 "const_int_operand"             "n"))
+                   (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
+   (use (match_operand:TI 1 "register_operand" "d"))
+   (clobber (reg:CC CC_REGNUM))]
+  "(!TARGET_64BIT && TARGET_ZARCH) &&
+   (INTVAL (operands[4]) & 255) == 255"
+  "mvcle\t%0,%1,%Y2\;jo\t.-4"
+  [(set_attr "length" "8")
+   (set_attr "type" "vs")])
+
 ;
 ; cmpmemM instruction pattern(s).
 ;
index 36132762600f59fc84703a0ba430e4563554bdb0..283da3bbf2d9e017eca4a0bf469fcc487f6f8656 100644 (file)
@@ -1,3 +1,7 @@
+2015-12-11  Dominik Vogt  <vogt@linux.vnet.ibm.com>
+
+       * gcc.target/s390/md/setmem_long-1.c: New test.
+
 2015-12-11  Dominik Vogt  <vogt@linux.vnet.ibm.com>
 
        * gcc.target/s390/md/movstr-1.c: New test.
diff --git a/gcc/testsuite/gcc.target/s390/md/setmem_long-1.c b/gcc/testsuite/gcc.target/s390/md/setmem_long-1.c
new file mode 100644 (file)
index 0000000..933a698
--- /dev/null
@@ -0,0 +1,56 @@
+/* Machine description pattern tests.  */
+
+/* { dg-do run } */
+/* { dg-options "-mmvcle -dP -save-temps" } */
+
+__attribute__ ((noinline))
+void test(char *p, char c, int len)
+{
+  __builtin_memset(p, c, len);
+}
+
+__attribute__ ((noinline))
+void test2(char *p, int c, int len)
+{
+  __builtin_memset(p, (char)c, len);
+}
+
+/* Check that the right patterns are used.  */
+/* { dg-final { scan-assembler-times {c:9 .*{[*]setmem_long_?3?1?z?}} 1 } } */
+/* { dg-final { scan-assembler-times {c:15 .*{[*]setmem_long_and_?3?1?z?}} 1 { xfail *-*-* } } } */
+
+#define LEN 500
+char buf[LEN + 2];
+
+void init_buf(void)
+{
+  int i;
+
+  buf[0] = 0;
+  for (i = 1; i <= LEN; i++)
+    buf[i] = (0x10 + (i & 0x3f));
+  buf[LEN + 1] = 0x7f;
+}
+
+void validate_buf(char val)
+{
+  int i;
+
+  if (buf[0] != 0)
+    __builtin_abort();
+  for (i = 1; i <= LEN; i++)
+    if (buf[i] != val)
+      __builtin_abort();
+  if (buf[LEN + 1] != 0x7f)
+    __builtin_abort();
+}
+
+int main(void)
+{
+  init_buf();
+  test(buf + 1, 55, LEN);
+  validate_buf(55);
+  init_buf();
+  test(buf + 1, 66, LEN);
+  validate_buf(66);
+}