From 74780dc2756ed1c2052f0d6b836799dcad1217e7 Mon Sep 17 00:00:00 2001 From: Dominik Vogt Date: Wed, 4 Nov 2015 03:16:24 +0100 Subject: [PATCH] S/390: Fix warnings in "*setmem_long..." patterns. --- gcc/config/s390/s390.c | 7 ++- gcc/config/s390/s390.md | 50 ++++++++++++++++----- gcc/testsuite/gcc.target/s390/md/setmem_long-1.c | 56 ++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/md/setmem_long-1.c diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 7e7ed45..1a77437 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -5203,7 +5203,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 diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index bc24a36..ef1ec92 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -70,6 +70,9 @@ ; Copy CC as is into the lower 2 bits of an integer register UNSPEC_CC_TO_INT + ; Convert Pmode to BLKmode + UNSPEC_REPLICATE_BYTE + ; GOT/PLT and lt-relative accesses UNSPEC_LTREL_OFFSET UNSPEC_LTREL_BASE @@ -727,6 +730,9 @@ ;; In place of GET_MODE_BITSIZE (mode) (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")]) +;; In place of GET_MODE_SIZE (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]) @@ -3280,12 +3286,12 @@ ; Initialize a block of arbitrary length with (operands[2] % 256). -(define_expand "setmem_long" +(define_expand "setmem_long_" [(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" "Y") + (match_dup 4)] UNSPEC_REPLICATE_BYTE)) (use (match_dup 3)) (clobber (reg:CC CC_REGNUM))])] "" @@ -3306,13 +3312,17 @@ 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: 0 "register_operand" "=d")) (set (mem:BLK (subreg:P (match_operand: 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) )] + UNSPEC_REPLICATE_BYTE)) (use (match_operand: 1 "register_operand" "d")) (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT || !TARGET_ZARCH" @@ -3323,9 +3333,11 @@ (define_insn "*setmem_long_and" [(clobber (match_operand: 0 "register_operand" "=d")) (set (mem:BLK (subreg:P (match_operand: 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) )] + UNSPEC_REPLICATE_BYTE)) (use (match_operand: 1 "register_operand" "d")) (clobber (reg:CC CC_REGNUM))] "(TARGET_64BIT || !TARGET_ZARCH) && @@ -3334,11 +3346,14 @@ [(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" @@ -3346,6 +3361,21 @@ [(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). ; 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 index 0000000..933a698 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/md/setmem_long-1.c @@ -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); +} -- 2.3.0