S/390: Tweak string instructions

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Fri Oct 24 15:29:00 GMT 2003


Hello,

this modifies the string instruction patterns a bit, in order to
 - preserve MEM attributes when generating the _long patterns
 - simplify the expander interface
 - remove some redundancy
 - prepare for removing word_mode == Pmode assumptions

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux (standard
and with -mmvcle forced on), committed to CVS head.

Bye,
Ulrich 

ChangeLog:

	* config/s390/s390.md ("movstr_short_64", "movstr_short_31"): Merge ...
	("*movstr_short"): ... into this insn pattern.
	("movstr_short"): New expander.
	("*movstr_long_64"): Rename from "movstr_long_64", simplify.
	("*movstr_long_31"): Rename from "movstr_long_31", simplify.
	("movstr_long"): New expander.
	("clrstr_short_64", "clrstr_short_31"): Merge ...
	("*clrstr_short"): ... into this insn pattern.
	("clrstr_short"): New expander.
	("*clrstr_long_64"): Rename from "clrstr_long_64", simplify.
	("*clrstr_long_31"): Rename from "clrstr_long_31", simplify.
	("clrstr_long"): New expander.
	("cmpmem_short_64", "cmpmem_short_31"): Merge ...
	("*cmpmem_short"): ... into this insn pattern.
	("cmpmem_short"): New expander.
	("*cmpmem_long_64"): Rename from "cmpmem_long_64".
	("*cmpmem_long_31"): Rename from "cmpmem_long_31".
	("cmpmem_long"): New expander.
	* config/s390/s390.c (s390_expand_movstr): Use new expanders.
	(s390_expand_clrstr): Likewise.
	(s390_expand_cmpmem): Likewise.



Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.116
diff -c -p -r1.116 s390.c
*** gcc/config/s390/s390.c	18 Oct 2003 22:24:37 -0000	1.116
--- gcc/config/s390/s390.c	22 Oct 2003 15:24:05 -0000
*************** legitimize_address (register rtx x, regi
*** 2970,3003 ****
  void
  s390_expand_movstr (rtx dst, rtx src, rtx len)
  {
-   rtx (*gen_short) (rtx, rtx, rtx) =
-     TARGET_64BIT ? gen_movstr_short_64 : gen_movstr_short_31;
-   rtx (*gen_long) (rtx, rtx, rtx, rtx) =
-     TARGET_64BIT ? gen_movstr_long_64 : gen_movstr_long_31;
- 
- 
    if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
      {
        if (INTVAL (len) > 0)
!         emit_insn (gen_short (dst, src, GEN_INT (INTVAL (len) - 1)));
      }
  
    else if (TARGET_MVCLE)
      {
!       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
!       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
!       rtx reg0 = gen_reg_rtx (double_mode);
!       rtx reg1 = gen_reg_rtx (double_mode);
! 
!       emit_move_insn (gen_highpart (single_mode, reg0),
! 		      force_operand (XEXP (dst, 0), NULL_RTX));
!       emit_move_insn (gen_highpart (single_mode, reg1),
! 		      force_operand (XEXP (src, 0), NULL_RTX));
! 
!       convert_move (gen_lowpart (single_mode, reg0), len, 1);
!       convert_move (gen_lowpart (single_mode, reg1), len, 1);
! 
!       emit_insn (gen_long (reg0, reg1, reg0, reg1));
      }
  
    else
--- 2970,2984 ----
  void
  s390_expand_movstr (rtx dst, rtx src, rtx len)
  {
    if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
      {
        if (INTVAL (len) > 0)
!         emit_insn (gen_movstr_short (dst, src, GEN_INT (INTVAL (len) - 1)));
      }
  
    else if (TARGET_MVCLE)
      {
!       emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1)));
      }
  
    else
*************** s390_expand_movstr (rtx dst, rtx src, rt
*** 3009,3015 ****
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = word_mode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
--- 2990,2996 ----
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = Pmode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
*************** s390_expand_movstr (rtx dst, rtx src, rt
*** 3042,3048 ****
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_short (dst, src, GEN_INT (255)));
        s390_load_address (dst_addr,
  			 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
        s390_load_address (src_addr,
--- 3023,3029 ----
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_movstr_short (dst, src, GEN_INT (255)));
        s390_load_address (dst_addr,
  			 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
        s390_load_address (src_addr,
*************** s390_expand_movstr (rtx dst, rtx src, rt
*** 3054,3060 ****
  
        expand_end_loop ();
  
!       emit_insn (gen_short (dst, src, convert_to_mode (word_mode, count, 1)));
        emit_label (end_label);
      }
  }
--- 3035,3042 ----
  
        expand_end_loop ();
  
!       emit_insn (gen_movstr_short (dst, src, 
! 				   convert_to_mode (Pmode, count, 1)));
        emit_label (end_label);
      }
  }
*************** s390_expand_movstr (rtx dst, rtx src, rt
*** 3064,3096 ****
  void
  s390_expand_clrstr (rtx dst, rtx len)
  {
-   rtx (*gen_short) (rtx, rtx) =
-     TARGET_64BIT ? gen_clrstr_short_64 : gen_clrstr_short_31;
-   rtx (*gen_long) (rtx, rtx, rtx) =
-     TARGET_64BIT ? gen_clrstr_long_64 : gen_clrstr_long_31;
- 
- 
    if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
      {
        if (INTVAL (len) > 0)
!         emit_insn (gen_short (dst, GEN_INT (INTVAL (len) - 1)));
      }
  
    else if (TARGET_MVCLE)
      {
!       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
!       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
!       rtx reg0 = gen_reg_rtx (double_mode);
!       rtx reg1 = gen_reg_rtx (double_mode);
! 
!       emit_move_insn (gen_highpart (single_mode, reg0),
! 		      force_operand (XEXP (dst, 0), NULL_RTX));
!       convert_move (gen_lowpart (single_mode, reg0), len, 1);
! 
!       emit_move_insn (gen_highpart (single_mode, reg1), const0_rtx);
!       emit_move_insn (gen_lowpart (single_mode, reg1), const0_rtx);
! 
!       emit_insn (gen_long (reg0, reg1, reg0));
      }
  
    else
--- 3046,3060 ----
  void
  s390_expand_clrstr (rtx dst, rtx len)
  {
    if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
      {
        if (INTVAL (len) > 0)
!         emit_insn (gen_clrstr_short (dst, GEN_INT (INTVAL (len) - 1)));
      }
  
    else if (TARGET_MVCLE)
      {
!       emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1)));
      }
  
    else
*************** s390_expand_clrstr (rtx dst, rtx len)
*** 3102,3108 ****
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = word_mode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
--- 3066,3072 ----
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = Pmode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
*************** s390_expand_clrstr (rtx dst, rtx len)
*** 3133,3139 ****
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_short (dst, GEN_INT (255)));
        s390_load_address (dst_addr,
  			 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
  
--- 3097,3103 ----
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_clrstr_short (dst, GEN_INT (255)));
        s390_load_address (dst_addr,
  			 gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256)));
  
*************** s390_expand_clrstr (rtx dst, rtx len)
*** 3143,3149 ****
  
        expand_end_loop ();
  
!       emit_insn (gen_short (dst, convert_to_mode (word_mode, count, 1)));
        emit_label (end_label);
      }
  }
--- 3107,3113 ----
  
        expand_end_loop ();
  
!       emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1)));
        emit_label (end_label);
      }
  }
*************** s390_expand_clrstr (rtx dst, rtx len)
*** 3154,3163 ****
  void
  s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
  {
-   rtx (*gen_short) (rtx, rtx, rtx) =
-     TARGET_64BIT ? gen_cmpmem_short_64 : gen_cmpmem_short_31;
-   rtx (*gen_long) (rtx, rtx, rtx, rtx) =
-     TARGET_64BIT ? gen_cmpmem_long_64 : gen_cmpmem_long_31;
    rtx (*gen_result) (rtx) =
      GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
  
--- 3118,3123 ----
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3169,3175 ****
      {
        if (INTVAL (len) > 0)
          {
!           emit_insn (gen_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
            emit_insn (gen_result (target));
          }
        else
--- 3129,3135 ----
      {
        if (INTVAL (len) > 0)
          {
!           emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
            emit_insn (gen_result (target));
          }
        else
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3178,3197 ****
  
    else /* if (TARGET_MVCLE) */
      {
!       enum machine_mode double_mode = TARGET_64BIT ? TImode : DImode;
!       enum machine_mode single_mode = TARGET_64BIT ? DImode : SImode;
!       rtx reg0 = gen_reg_rtx (double_mode);
!       rtx reg1 = gen_reg_rtx (double_mode);
! 
!       emit_move_insn (gen_highpart (single_mode, reg0),
! 		      force_operand (XEXP (op0, 0), NULL_RTX));
!       emit_move_insn (gen_highpart (single_mode, reg1),
! 		      force_operand (XEXP (op1, 0), NULL_RTX));
! 
!       convert_move (gen_lowpart (single_mode, reg0), len, 1);
!       convert_move (gen_lowpart (single_mode, reg1), len, 1);
! 
!       emit_insn (gen_long (reg0, reg1, reg0, reg1));
        emit_insn (gen_result (target));
      }
  
--- 3138,3144 ----
  
    else /* if (TARGET_MVCLE) */
      {
!       emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
        emit_insn (gen_result (target));
      }
  
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3207,3213 ****
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = word_mode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
--- 3154,3160 ----
  
        mode = GET_MODE (len);
        if (mode == VOIDmode)
!         mode = Pmode;
  
        type = lang_hooks.types.type_for_mode (mode, 1);
        if (!type)
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3240,3246 ****
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_short (op0, op1, GEN_INT (255)));
        temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
        temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
  			gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
--- 3187,3193 ----
  					   make_tree (type, blocks),
  					   make_tree (type, const0_rtx)));
  
!       emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
        temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
        temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
  			gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
*************** s390_expand_cmpmem (rtx target, rtx op0,
*** 3258,3264 ****
  
        expand_end_loop ();
  
!       emit_insn (gen_short (op0, op1, convert_to_mode (word_mode, count, 1)));
        emit_label (end_label);
  
        emit_insn (gen_result (target));
--- 3205,3212 ----
  
        expand_end_loop ();
  
!       emit_insn (gen_cmpmem_short (op0, op1, 
! 				   convert_to_mode (Pmode, count, 1)));
        emit_label (end_label);
  
        emit_insn (gen_result (target));
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.81
diff -c -p -r1.81 s390.md
*** gcc/config/s390/s390.md	18 Oct 2003 22:24:37 -0000	1.81
--- gcc/config/s390/s390.md	22 Oct 2003 15:24:08 -0000
***************
*** 1785,1822 ****
  ; Move a block that is up to 256 bytes in length.
  ; The block length is taken as (operands[2] % 256) + 1.
  
! (define_insn "movstr_short_64"
!   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
!         (match_operand:BLK 1 "memory_operand" "Q,Q"))
!    (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:DI 3 "=X,&a"))]
!   "TARGET_64BIT"
! {
!   switch (which_alternative)
!     {
!       case 0:
! 	return "mvc\t%O0(%b2+1,%R0),%1";
! 
!       case 1:
! 	output_asm_insn ("bras\t%3,.+10", operands);
! 	output_asm_insn ("mvc\t%O0(1,%R0),%1", operands);
! 	return "ex\t%2,0(%3)";
! 
!       default:
!         abort ();
!     }
! }
!   [(set_attr "op_type" "SS,NN")
!    (set_attr "type"    "cs,cs")
!    (set_attr "atype"   "*,agen")
!    (set_attr "length"  "*,14")])
  
! (define_insn "movstr_short_31"
    [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
          (match_operand:BLK 1 "memory_operand" "Q,Q"))
!    (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:SI 3 "=X,&a"))]
!   "!TARGET_64BIT"
  {
    switch (which_alternative)
      {
--- 1785,1806 ----
  ; Move a block that is up to 256 bytes in length.
  ; The block length is taken as (operands[2] % 256) + 1.
  
! (define_expand "movstr_short"
!   [(parallel
!     [(set (match_operand:BLK 0 "memory_operand" "")
!           (match_operand:BLK 1 "memory_operand" ""))
!      (use (match_operand 2 "nonmemory_operand" ""))
!      (clobber (match_dup 3))])]
!   ""
!   "operands[3] = gen_rtx_SCRATCH (Pmode);")
  
! (define_insn "*movstr_short"
    [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
          (match_operand:BLK 1 "memory_operand" "Q,Q"))
!    (use (match_operand 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch 3 "=X,&a"))]
!   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
!    && GET_MODE (operands[3]) == Pmode"
  {
    switch (which_alternative)
      {
***************
*** 1839,1855 ****
  
  ; Move a block of arbitrary length.
  
! (define_insn "movstr_long_64"
!   [(set (match_operand:TI 0 "register_operand" "=d")
!         (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
!                             (lshiftrt:TI (match_dup 2) (const_int 64)))
!                    (const_int 64)))
!    (set (match_operand:TI 1 "register_operand" "=d")
!         (ashift:TI (plus:TI (match_operand:TI 3 "register_operand" "1")
!                             (lshiftrt:TI (match_dup 3) (const_int 64)))
!                    (const_int 64)))
!    (set (mem:BLK (subreg:DI (match_dup 2) 0))
!         (mem:BLK (subreg:DI (match_dup 3) 0)))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
    "mvcle\t%0,%1,0\;jo\t.-4"
--- 1823,1868 ----
  
  ; Move a block of arbitrary length.
  
! (define_expand "movstr_long"
!   [(parallel
!     [(clobber (match_dup 2))
!      (clobber (match_dup 3))
!      (set (match_operand:BLK 0 "memory_operand" "")
!           (match_operand:BLK 1 "memory_operand" ""))
!      (use (match_operand 2 "general_operand" ""))
!      (use (match_dup 3))
!      (clobber (reg:CC 33))])]
!   ""
! {
!   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
!   rtx reg0 = gen_reg_rtx (dword_mode);
!   rtx reg1 = gen_reg_rtx (dword_mode);
!   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
!   rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
!   rtx len0 = gen_lowpart (Pmode, reg0);
!   rtx len1 = gen_lowpart (Pmode, reg1);
! 
!   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
!   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
!   emit_move_insn (len0, operands[2]);
! 
!   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
!   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
!   emit_move_insn (len1, operands[2]);
! 
!   operands[0] = replace_equiv_address_nv (operands[0], addr0);
!   operands[1] = replace_equiv_address_nv (operands[1], addr1);
!   operands[2] = reg0;
!   operands[3] = reg1;
! })
! 
! (define_insn "*movstr_long_64"
!   [(clobber (match_operand:TI 0 "register_operand" "=d"))
!    (clobber (match_operand:TI 1 "register_operand" "=d"))
!    (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
!         (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))
!    (use (match_dup 2))
!    (use (match_dup 3))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
    "mvcle\t%0,%1,0\;jo\t.-4"
***************
*** 1857,1873 ****
     (set_attr "type"    "vs")
     (set_attr "length"  "8")])
  
! (define_insn "movstr_long_31"
!   [(set (match_operand:DI 0 "register_operand" "=d")
!         (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
!                             (lshiftrt:DI (match_dup 2) (const_int 32)))
!                    (const_int 32)))
!    (set (match_operand:DI 1 "register_operand" "=d")
!         (ashift:DI (plus:DI (match_operand:DI 3 "register_operand" "1")
!                             (lshiftrt:DI (match_dup 3) (const_int 32)))
!                    (const_int 32)))
!    (set (mem:BLK (subreg:SI (match_dup 2) 0))
!         (mem:BLK (subreg:SI (match_dup 3) 0)))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
    "mvcle\t%0,%1,0\;jo\t.-4"
--- 1870,1882 ----
     (set_attr "type"    "vs")
     (set_attr "length"  "8")])
  
! (define_insn "*movstr_long_31"
!   [(clobber (match_operand:DI 0 "register_operand" "=d"))
!    (clobber (match_operand:DI 1 "register_operand" "=d"))
!    (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
!         (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))
!    (use (match_dup 2))
!    (use (match_dup 3))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
    "mvcle\t%0,%1,0\;jo\t.-4"
***************
*** 1896,1937 ****
    "s390_expand_clrstr (operands[0], operands[1]); DONE;")
  
  ; Clear a block that is up to 256 bytes in length.
! ; The block length is taken as (operands[2] % 256) + 1.
  
! (define_insn "clrstr_short_64"
!   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
!         (const_int 0))
!    (use (match_operand:DI 1 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:DI 2 "=X,&a"))
!    (clobber (reg:CC 33))]
!   "TARGET_64BIT"
! {
!   switch (which_alternative)
!     {
!       case 0:
! 	return "xc\t%O0(%b1+1,%R0),%0";
! 
!       case 1:
! 	output_asm_insn ("bras\t%2,.+10", operands);
! 	output_asm_insn ("xc\t%O0(1,%R0),%0", operands);
! 	return "ex\t%1,0(%2)";
! 
!       default:
!         abort ();
!     }
! }
!   [(set_attr "op_type" "SS,NN")
!    (set_attr "type"    "cs,cs")
!    (set_attr "atype"   "*,agen")
!    (set_attr "length"  "*,14")])
  
! (define_insn "clrstr_short_31"
    [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
          (const_int 0))
!    (use (match_operand:SI 1 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:SI 2 "=X,&a"))
     (clobber (reg:CC 33))]
!   "!TARGET_64BIT"
  {
    switch (which_alternative)
      {
--- 1905,1930 ----
    "s390_expand_clrstr (operands[0], operands[1]); DONE;")
  
  ; Clear a block that is up to 256 bytes in length.
! ; The block length is taken as (operands[1] % 256) + 1.
  
! (define_expand "clrstr_short"
!   [(parallel
!     [(set (match_operand:BLK 0 "memory_operand" "")
!           (const_int 0))
!      (use (match_operand 1 "nonmemory_operand" ""))
!      (clobber (match_dup 2))
!      (clobber (reg:CC 33))])]
!   ""
!   "operands[2] = gen_rtx_SCRATCH (Pmode);")
  
! (define_insn "*clrstr_short"
    [(set (match_operand:BLK 0 "memory_operand" "=Q,Q")
          (const_int 0))
!    (use (match_operand 1 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch 2 "=X,&a"))
     (clobber (reg:CC 33))]
!   "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
!    && GET_MODE (operands[2]) == Pmode"
  {
    switch (which_alternative)
      {
***************
*** 1954,1966 ****
  
  ; Clear a block of arbitrary length.
  
! (define_insn "clrstr_long_64"
!   [(set (match_operand:TI 0 "register_operand" "=d")
!         (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
!                             (lshiftrt:TI (match_dup 2) (const_int 64)))
!                    (const_int 64)))
!    (set (mem:BLK (subreg:DI (match_dup 2) 0))
          (const_int 0))
     (use (match_operand:TI 1 "register_operand" "d"))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
--- 1947,1984 ----
  
  ; Clear a block of arbitrary length.
  
! (define_expand "clrstr_long"
!   [(parallel
!     [(clobber (match_dup 1))
!      (set (match_operand:BLK 0 "memory_operand" "")
!           (const_int 0))
!      (use (match_operand 1 "general_operand" ""))
!      (use (match_dup 2))
!      (clobber (reg:CC 33))])]
!   ""
! {
!   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
!   rtx reg0 = gen_reg_rtx (dword_mode);
!   rtx reg1 = gen_reg_rtx (dword_mode);
!   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
!   rtx len0 = gen_lowpart (Pmode, reg0);
! 
!   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
!   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
!   emit_move_insn (len0, operands[1]);
! 
!   emit_move_insn (reg1, const0_rtx);
! 
!   operands[0] = replace_equiv_address_nv (operands[0], addr0);
!   operands[1] = reg0;
!   operands[2] = reg1;
! })
! 
! (define_insn "*clrstr_long_64"
!   [(clobber (match_operand:TI 0 "register_operand" "=d"))
!    (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
          (const_int 0))
+    (use (match_dup 2))
     (use (match_operand:TI 1 "register_operand" "d"))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
***************
*** 1969,1981 ****
     (set_attr "type"    "vs")
     (set_attr "length"  "8")])
  
! (define_insn "clrstr_long_31"
!   [(set (match_operand:DI 0 "register_operand" "=d")
!         (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
!                             (lshiftrt:DI (match_dup 2) (const_int 32)))
!                    (const_int 32)))
!    (set (mem:BLK (subreg:SI (match_dup 2) 0))
          (const_int 0))
     (use (match_operand:DI 1 "register_operand" "d"))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
--- 1987,1997 ----
     (set_attr "type"    "vs")
     (set_attr "length"  "8")])
  
! (define_insn "*clrstr_long_31"
!   [(clobber (match_operand:DI 0 "register_operand" "=d"))
!    (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
          (const_int 0))
+    (use (match_dup 2))
     (use (match_operand:DI 1 "register_operand" "d"))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
***************
*** 2011,2050 ****
  ; Compare a block that is up to 256 bytes in length.
  ; The block length is taken as (operands[2] % 256) + 1.
  
! (define_insn "cmpmem_short_64"
!   [(set (reg:CCS 33)
!         (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
!                      (match_operand:BLK 1 "memory_operand" "Q,Q")))
!    (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:DI 3 "=X,&a"))]
!   "TARGET_64BIT"
! {
!   switch (which_alternative)
!     {
!       case 0:
! 	return "clc\t%O0(%b2+1,%R0),%1";
! 
!       case 1:
! 	output_asm_insn ("bras\t%3,.+10", operands);
! 	output_asm_insn ("clc\t%O0(1,%R0),%1", operands);
! 	return "ex\t%2,0(%3)";
! 
!       default:
!         abort ();
!     }
! }
!   [(set_attr "op_type" "SS,NN")
!    (set_attr "type"    "cs,cs")
!    (set_attr "atype"   "*,agen")
!    (set_attr "length"  "*,14")])
  
! (define_insn "cmpmem_short_31"
    [(set (reg:CCS 33)
          (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
                       (match_operand:BLK 1 "memory_operand" "Q,Q")))
!    (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch:SI 3 "=X,&a"))]
!   "!TARGET_64BIT"
  {
    switch (which_alternative)
      {
--- 2027,2050 ----
  ; Compare a block that is up to 256 bytes in length.
  ; The block length is taken as (operands[2] % 256) + 1.
  
! (define_expand "cmpmem_short"
!   [(parallel
!     [(set (reg:CCS 33)
!           (compare:CCS (match_operand:BLK 0 "memory_operand" "")
!                        (match_operand:BLK 1 "memory_operand" "")))
!      (use (match_operand 2 "nonmemory_operand" ""))
!      (clobber (match_dup 3))])]
!   ""
!   "operands[3] = gen_rtx_SCRATCH (Pmode);")
  
! (define_insn "*cmpmem_short"
    [(set (reg:CCS 33)
          (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
                       (match_operand:BLK 1 "memory_operand" "Q,Q")))
!    (use (match_operand 2 "nonmemory_operand" "n,a"))
!    (clobber (match_scratch 3 "=X,&a"))]
!   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
!    && GET_MODE (operands[3]) == Pmode"
  {
    switch (which_alternative)
      {
***************
*** 2067,2073 ****
  
  ; Compare a block of arbitrary length.
  
! (define_insn "cmpmem_long_64"
    [(clobber (match_operand:TI 0 "register_operand" "=d"))
     (clobber (match_operand:TI 1 "register_operand" "=d"))
     (set (reg:CCS 33)
--- 2067,2106 ----
  
  ; Compare a block of arbitrary length.
  
! (define_expand "cmpmem_long"
!   [(parallel
!     [(clobber (match_dup 2))
!      (clobber (match_dup 3))
!      (set (reg:CCS 33)
!           (compare:CCS (match_operand:BLK 0 "memory_operand" "")
!                        (match_operand:BLK 1 "memory_operand" "")))
!      (use (match_operand 2 "general_operand" ""))
!      (use (match_dup 3))])]
!   ""
! {
!   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
!   rtx reg0 = gen_reg_rtx (dword_mode);
!   rtx reg1 = gen_reg_rtx (dword_mode);
!   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
!   rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
!   rtx len0 = gen_lowpart (Pmode, reg0);
!   rtx len1 = gen_lowpart (Pmode, reg1);
! 
!   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
!   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
!   emit_move_insn (len0, operands[2]);
! 
!   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
!   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
!   emit_move_insn (len1, operands[2]);
! 
!   operands[0] = replace_equiv_address_nv (operands[0], addr0);
!   operands[1] = replace_equiv_address_nv (operands[1], addr1);
!   operands[2] = reg0;
!   operands[3] = reg1;
! })
! 
! (define_insn "*cmpmem_long_64"
    [(clobber (match_operand:TI 0 "register_operand" "=d"))
     (clobber (match_operand:TI 1 "register_operand" "=d"))
     (set (reg:CCS 33)
***************
*** 2080,2086 ****
    [(set_attr "op_type" "RR")
     (set_attr "type"    "vs")])
  
! (define_insn "cmpmem_long_31"
    [(clobber (match_operand:DI 0 "register_operand" "=d"))
     (clobber (match_operand:DI 1 "register_operand" "=d"))
     (set (reg:CCS 33)
--- 2113,2119 ----
    [(set_attr "op_type" "RR")
     (set_attr "type"    "vs")])
  
! (define_insn "*cmpmem_long_31"
    [(clobber (match_operand:DI 0 "register_operand" "=d"))
     (clobber (match_operand:DI 1 "register_operand" "=d"))
     (set (reg:CCS 33)
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list