From 31838f66e13ef4480e69104284ee846406320281 Mon Sep 17 00:00:00 2001 From: uweigand Date: Wed, 22 Oct 2003 16:19:54 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72807 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 24 +++++ gcc/config/s390/s390.c | 86 +++------------ gcc/config/s390/s390.md | 281 +++++++++++++++++++++++++++--------------------- 3 files changed, 198 insertions(+), 193 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 580c3d0..adc1bc0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2003-10-22 Ulrich Weigand + + * 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. + 2003-10-22 Mark Mitchell * c-pch.c (struct c_pch_validity): Add pch_init field. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 10a6967..be564d6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2970,34 +2970,15 @@ legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED, 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))); + emit_insn (gen_movstr_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)); + emit_insn (gen_movstr_long (dst, src, convert_to_mode (Pmode, len, 1))); } else @@ -3009,7 +2990,7 @@ s390_expand_movstr (rtx dst, rtx src, rtx len) mode = GET_MODE (len); if (mode == VOIDmode) - mode = word_mode; + mode = Pmode; type = lang_hooks.types.type_for_mode (mode, 1); if (!type) @@ -3042,7 +3023,7 @@ s390_expand_movstr (rtx dst, rtx src, rtx len) make_tree (type, blocks), make_tree (type, const0_rtx))); - emit_insn (gen_short (dst, src, GEN_INT (255))); + 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, @@ -3054,7 +3035,8 @@ s390_expand_movstr (rtx dst, rtx src, rtx len) expand_end_loop (); - emit_insn (gen_short (dst, src, convert_to_mode (word_mode, count, 1))); + emit_insn (gen_movstr_short (dst, src, + convert_to_mode (Pmode, count, 1))); emit_label (end_label); } } @@ -3064,33 +3046,15 @@ s390_expand_movstr (rtx dst, rtx src, rtx len) 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))); + emit_insn (gen_clrstr_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)); + emit_insn (gen_clrstr_long (dst, convert_to_mode (Pmode, len, 1))); } else @@ -3102,7 +3066,7 @@ s390_expand_clrstr (rtx dst, rtx len) mode = GET_MODE (len); if (mode == VOIDmode) - mode = word_mode; + mode = Pmode; type = lang_hooks.types.type_for_mode (mode, 1); if (!type) @@ -3133,7 +3097,7 @@ s390_expand_clrstr (rtx dst, rtx len) make_tree (type, blocks), make_tree (type, const0_rtx))); - emit_insn (gen_short (dst, GEN_INT (255))); + emit_insn (gen_clrstr_short (dst, GEN_INT (255))); s390_load_address (dst_addr, gen_rtx_PLUS (Pmode, dst_addr, GEN_INT (256))); @@ -3143,7 +3107,7 @@ s390_expand_clrstr (rtx dst, rtx len) expand_end_loop (); - emit_insn (gen_short (dst, convert_to_mode (word_mode, count, 1))); + emit_insn (gen_clrstr_short (dst, convert_to_mode (Pmode, count, 1))); emit_label (end_label); } } @@ -3154,10 +3118,6 @@ s390_expand_clrstr (rtx dst, rtx len) 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; @@ -3169,7 +3129,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) { if (INTVAL (len) > 0) { - emit_insn (gen_short (op0, op1, GEN_INT (INTVAL (len) - 1))); + emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1))); emit_insn (gen_result (target)); } else @@ -3178,20 +3138,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) 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_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1))); emit_insn (gen_result (target)); } @@ -3207,7 +3154,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) mode = GET_MODE (len); if (mode == VOIDmode) - mode = word_mode; + mode = Pmode; type = lang_hooks.types.type_for_mode (mode, 1); if (!type) @@ -3240,7 +3187,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) make_tree (type, blocks), make_tree (type, const0_rtx))); - emit_insn (gen_short (op0, op1, GEN_INT (255))); + 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); @@ -3258,7 +3205,8 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) expand_end_loop (); - emit_insn (gen_short (op0, op1, convert_to_mode (word_mode, count, 1))); + emit_insn (gen_cmpmem_short (op0, op1, + convert_to_mode (Pmode, count, 1))); emit_label (end_label); emit_insn (gen_result (target)); diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 9b3d009..1e1b08d 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1785,38 +1785,22 @@ ; 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_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_31" +(define_insn "*movstr_short" [(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" + (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,17 +1823,46 @@ ; 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))) +(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,17 +1870,13 @@ (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))) +(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,15 +1905,26 @@ "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. +; The block length is taken as (operands[1] % 256) + 1. -(define_insn "clrstr_short_64" +(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:DI 1 "nonmemory_operand" "n,a")) - (clobber (match_scratch:DI 2 "=X,&a")) + (use (match_operand 1 "nonmemory_operand" "n,a")) + (clobber (match_scratch 2 "=X,&a")) (clobber (reg:CC 33))] - "TARGET_64BIT" + "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode) + && GET_MODE (operands[2]) == Pmode" { switch (which_alternative) { @@ -1925,42 +1945,40 @@ (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" +; 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))])] + "" { - switch (which_alternative) - { - case 0: - return "xc\t%O0(%b1+1,%R0),%0"; + 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); - 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)"; + 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]); - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) + emit_move_insn (reg1, const0_rtx); -; Clear a block of arbitrary length. + operands[0] = replace_equiv_address_nv (operands[0], addr0); + operands[1] = reg0; + operands[2] = reg1; +}) -(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)) +(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,13 +1987,11 @@ (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)) +(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,40 +2027,24 @@ ; 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_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_31" +(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:SI 2 "nonmemory_operand" "n,a")) - (clobber (match_scratch:SI 3 "=X,&a"))] - "!TARGET_64BIT" + (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,7 +2067,40 @@ ; Compare a block of arbitrary length. -(define_insn "cmpmem_long_64" +(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,7 +2113,7 @@ [(set_attr "op_type" "RR") (set_attr "type" "vs")]) -(define_insn "cmpmem_long_31" +(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) -- 2.7.4