s390-protos.h (s390_expand_clrmem): Delete.
authorAdrian Straetling <straetling@de.ibm.com>
Thu, 7 Jul 2005 10:34:57 +0000 (10:34 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Thu, 7 Jul 2005 10:34:57 +0000 (10:34 +0000)
2005-07-07  Adrian Straetling  <straetling@de.ibm.com>

* 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<mode>"): Accept character as
general_operand.  Call new function "s390_expand_setmem".
("clrmem_long", "*clrmem_long"): Rewrite to ...
("setmem_long", "*setmem_long"): ... this.

From-SVN: r101705

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index f6cee36729b800ff0bc107d04ba4b561c92e98a8..6fc9d8f25edab70347dbb8389da6796c6ad692f1 100644 (file)
@@ -1,3 +1,15 @@
+2005-07-07  Adrian Straetling  <straetling@de.ibm.com>
+
+       * 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<mode>"): 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  <straetling@de.ibm.com>
        
        * config/s390/s390.c: (optimization_options): Enable
index 87cf98ed4699db62675f77ce314a1443764e34ba..7d63c7503e332d38081a55376ae538624474e843 100644 (file)
@@ -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);
index 07022a2a4631eb813f71640d93209608f71fae58..3573db59e41b2b89fca1379c5b18ba6b62e253f0 100644 (file)
@@ -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)]);
 }
index 8a3e1a41810e16b97c502c8ec2b7092df61f54fc..6d8c107fa52ecd2ca89efcd28fc2b3e165debcb6 100644 (file)
 
 (define_expand "setmem<mode>"
   [(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.
      (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))])]
   ""
 {
 
   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:<DBL> 0 "register_operand" "=d"))
-   (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
-        (const_int 0))
-   (use (match_dup 2))
+   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
+        (match_operand 2 "shift_count_operand" "Y"))
+   (use (match_dup 3))
    (use (match_operand:<DBL> 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")])