From 805a133b6f279ab4e82b8749f0feaff0febe8b42 Mon Sep 17 00:00:00 2001 From: uweigand Date: Thu, 7 Jul 2005 10:34:57 +0000 Subject: [PATCH] 2005-07-07 Adrian Straetling * config/s390/s390-protos.h (s390_expand_clrmem): Delete. (s390_expand_setmem): New. * config/s390/s390.c: Likewise. (print_shift_count_operand): Truncate to 12 bits instead of 6. Adapt comments. * config/s390/s390.md: ("setmem"): Accept character as general_operand. Call new function "s390_expand_setmem". ("clrmem_long", "*clrmem_long"): Rewrite to ... ("setmem_long", "*setmem_long"): ... this. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101705 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 ++++++++ gcc/config/s390/s390-protos.h | 2 +- gcc/config/s390/s390.c | 71 +++++++++++++++++++++++++++++++++++-------- gcc/config/s390/s390.md | 31 ++++++++----------- 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f6cee36729b..6fc9d8f25ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,16 @@ 2005-07-07 Adrian Straetling + + * config/s390/s390-protos.h (s390_expand_clrmem): Delete. + (s390_expand_setmem): New. + * config/s390/s390.c: Likewise. + (print_shift_count_operand): Truncate to 12 bits instead of 6. + Adapt comments. + * config/s390/s390.md: ("setmem"): Accept character as + general_operand. Call new function "s390_expand_setmem". + ("clrmem_long", "*clrmem_long"): Rewrite to ... + ("setmem_long", "*setmem_long"): ... this. + +2005-07-07 Adrian Straetling * config/s390/s390.c: (optimization_options): Enable TARGET_MVCLE at -Os. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 87cf98ed469..7d63c7503e3 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -69,7 +69,7 @@ extern void s390_expand_plus_operand (rtx, rtx, rtx); extern void emit_symbolic_move (rtx *); extern void s390_load_address (rtx, rtx); extern void s390_expand_movmem (rtx, rtx, rtx); -extern void s390_expand_clrmem (rtx, rtx); +extern void s390_expand_setmem (rtx, rtx, rtx); extern void s390_expand_cmpmem (rtx, rtx, rtx, rtx); extern bool s390_expand_addcc (enum rtx_code, rtx, rtx, rtx, rtx, rtx); extern rtx s390_return_addr_rtx (int, rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 07022a2a463..3573db59e41 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3225,25 +3225,49 @@ s390_expand_movmem (rtx dst, rtx src, rtx len) } } -/* Emit code to clear LEN bytes at DST. */ +/* Emit code to set LEN bytes at DST to VAL. + Make use of clrmem if VAL is zero. */ void -s390_expand_clrmem (rtx dst, rtx len) +s390_expand_setmem (rtx dst, rtx len, rtx val) { - if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256) + gcc_assert (GET_CODE (len) != CONST_INT || INTVAL (len) > 0); + gcc_assert (GET_CODE (val) == CONST_INT || GET_MODE (val) == QImode); + + if (GET_CODE (len) == CONST_INT && INTVAL (len) <= 257) { - if (INTVAL (len) > 0) + if (val == const0_rtx && INTVAL (len) <= 256) emit_insn (gen_clrmem_short (dst, GEN_INT (INTVAL (len) - 1))); + else + { + /* Initialize memory by storing the first byte. */ + emit_move_insn (adjust_address (dst, QImode, 0), val); + + if (INTVAL (len) > 1) + { + /* Initiate 1 byte overlap move. + The first byte of DST is propagated through DSTP1. + Prepare a movmem for: DST+1 = DST (length = LEN - 1). + DST is set to size 1 so the rest of the memory location + does not count as source operand. */ + rtx dstp1 = adjust_address (dst, VOIDmode, 1); + set_mem_size (dst, const1_rtx); + + emit_insn (gen_movmem_short (dstp1, dst, + GEN_INT (INTVAL (len) - 2))); + } + } } else if (TARGET_MVCLE) { - emit_insn (gen_clrmem_long (dst, convert_to_mode (Pmode, len, 1))); + val = force_not_mem (convert_modes (Pmode, QImode, val, 1)); + emit_insn (gen_setmem_long (dst, convert_to_mode (Pmode, len, 1), val)); } else { - rtx dst_addr, src_addr, count, blocks, temp; + rtx dst_addr, src_addr, count, blocks, temp, dstp1 = NULL_RTX; rtx loop_start_label = gen_label_rtx (); rtx loop_end_label = gen_label_rtx (); rtx end_label = gen_label_rtx (); @@ -3265,7 +3289,22 @@ s390_expand_clrmem (rtx dst, rtx len) emit_move_insn (dst_addr, force_operand (XEXP (dst, 0), NULL_RTX)); dst = change_address (dst, VOIDmode, dst_addr); - temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0); + if (val == const0_rtx) + temp = expand_binop (mode, add_optab, count, constm1_rtx, count, 1, 0); + else + { + dstp1 = adjust_address (dst, VOIDmode, 1); + set_mem_size (dst, const1_rtx); + + /* Initialize memory by storing the first byte. */ + emit_move_insn (adjust_address (dst, QImode, 0), val); + + /* If count is 1 we are done. */ + emit_cmp_and_jump_insns (count, const1_rtx, + EQ, NULL_RTX, mode, 1, end_label); + + temp = expand_binop (mode, add_optab, count, GEN_INT (-2), count, 1, 0); + } if (temp != count) emit_move_insn (count, temp); @@ -3278,7 +3317,10 @@ s390_expand_clrmem (rtx dst, rtx len) emit_label (loop_start_label); - emit_insn (gen_clrmem_short (dst, GEN_INT (255))); + if (val == const0_rtx) + emit_insn (gen_clrmem_short (dst, GEN_INT (255))); + else + emit_insn (gen_movmem_short (dstp1, dst, GEN_INT (255))); s390_load_address (dst_addr, gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256))); @@ -3292,7 +3334,10 @@ s390_expand_clrmem (rtx dst, rtx len) emit_jump (loop_start_label); emit_label (loop_end_label); - emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1))); + if (val == const0_rtx) + emit_insn (gen_clrmem_short (dst, convert_to_mode (Pmode, count, 1))); + else + emit_insn (gen_movmem_short (dstp1, dst, convert_to_mode (Pmode, count, 1))); emit_label (end_label); } } @@ -3637,7 +3682,9 @@ s390_delegitimize_address (rtx orig_x) return orig_x; } -/* Output shift count operand OP to stdio stream FILE. */ +/* Output operand OP to stdio stream FILE. + OP is an address (register + offset) which is not used to address data; + instead the rightmost bits are interpreted as the value. */ static void print_shift_count_operand (FILE *file, rtx op) @@ -3667,8 +3714,8 @@ print_shift_count_operand (FILE *file, rtx op) gcc_assert (REGNO_REG_CLASS (REGNO (op)) == ADDR_REGS); } - /* Shift counts are truncated to the low six bits anyway. */ - fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & 63); + /* Offsets are constricted to twelve bits. */ + fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset & ((1 << 12) - 1)); if (op) fprintf (file, "(%s)", reg_names[REGNO (op)]); } diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 8a3e1a41810..6d8c107fa52 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1924,18 +1924,11 @@ (define_expand "setmem" [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand 2 "const_int_operand" "")) + (match_operand:QI 2 "general_operand" "")) (use (match_operand:GPR 1 "general_operand" "")) (match_operand 3 "" "")] "" -{ - /* If value to set is not zero, use the library routine. */ - if (operands[2] != const0_rtx) - FAIL; - - s390_expand_clrmem (operands[0], operands[1]); - DONE; -}) + "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;") ; Clear a block that is up to 256 bytes in length. ; The block length is taken as (operands[1] % 256) + 1. @@ -2010,15 +2003,15 @@ (clobber (reg:CC CC_REGNUM))])] "operands[3] = gen_label_rtx ();") -; Clear a block of arbitrary length. +; Initialize a block of arbitrary length with (operands[2] % 256). -(define_expand "clrmem_long" +(define_expand "setmem_long" [(parallel [(clobber (match_dup 1)) (set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) + (match_operand 2 "shift_count_operand" "")) (use (match_operand 1 "general_operand" "")) - (use (match_dup 2)) + (use (match_dup 3)) (clobber (reg:CC CC_REGNUM))])] "" { @@ -2036,18 +2029,18 @@ operands[0] = replace_equiv_address_nv (operands[0], addr0); operands[1] = reg0; - operands[2] = reg1; + operands[3] = reg1; }) -(define_insn "*clrmem_long" +(define_insn "*setmem_long" [(clobber (match_operand: 0 "register_operand" "=d")) - (set (mem:BLK (subreg:P (match_operand: 2 "register_operand" "0") 0)) - (const_int 0)) - (use (match_dup 2)) + (set (mem:BLK (subreg:P (match_operand: 3 "register_operand" "0") 0)) + (match_operand 2 "shift_count_operand" "Y")) + (use (match_dup 3)) (use (match_operand: 1 "register_operand" "d")) (clobber (reg:CC CC_REGNUM))] "" - "mvcle\t%0,%1,0\;jo\t.-4" + "mvcle\t%0,%1,%Y2\;jo\t.-4" [(set_attr "length" "8") (set_attr "type" "vs")]) -- 2.11.0