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