Commit 3a1f863f by David Edelsohn Committed by David Edelsohn

rs6000.c (altivec_in_gprs_p): Rename to ...

        * config/rs6000/rs6000.c (altivec_in_gprs_p): Rename to ...
        (gpr_or_gpr_p): Change to bool.
        (rs6000_split_altivec_in_gprs): Rename to ...
        (rs6000_split_multireg_move): Add support for update addressing.
        * config/rs6000/rs6000-protos.h: Same.
        * config/rs6000/altivec.md: Same.
        * config/rs6000/rs6000.md (movdi_internal32): Use new splitter for
        multiple GPRs.
        (movti): Remove TARGET_STRING || TARGET_POWERPC64 final condition.
        (movti_power): Use new splitter for multiple GPRs.
        (movti_string): Same.
        (movti_ppc64): Same.

Co-Authored-By: Hartmut Penner <hpenner@de.ibm.com>

From-SVN: r71673
parent 2f2846ab
2003-09-22 David Edelsohn <edelsohn@gnu.org>
Hartmut Penner <hpenner@de.ibm.com>
* config/rs6000/rs6000.c (altivec_in_gprs_p): Rename to ...
(gpr_or_gpr_p): Change to bool.
(rs6000_split_altivec_in_gprs): Rename to ...
(rs6000_split_multireg_move): Add support for update addressing.
* config/rs6000/rs6000-protos.h: Same.
* config/rs6000/altivec.md: Same.
* config/rs6000/rs6000.md (movdi_internal32): Use new splitter for
multiple GPRs.
(movti): Remove TARGET_STRING || TARGET_POWERPC64 final condition.
(movti_power): Use new splitter for multiple GPRs.
(movti_string): Same.
(movti_ppc64): Same.
2003-09-22 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa-protos.h: Convert to ISO C90.
......
......@@ -114,24 +114,24 @@
[(set (match_operand:V4SI 0 "nonimmediate_operand" "")
(match_operand:V4SI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:V4SI 0 "nonimmediate_operand" "")
(match_operand:V4SI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 6))
(set (match_dup 3) (match_dup 7))
(set (match_dup 4) (match_dup 8))
(set (match_dup 5) (match_dup 9))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
......@@ -176,24 +176,24 @@
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
(match_operand:V8HI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:V8HI 0 "nonimmediate_operand" "")
(match_operand:V8HI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 6))
(set (match_dup 3) (match_dup 7))
(set (match_dup 4) (match_dup 8))
(set (match_dup 5) (match_dup 9))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
......@@ -238,24 +238,24 @@
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
(match_operand:V16QI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:V16QI 0 "nonimmediate_operand" "")
(match_operand:V16QI 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 6))
(set (match_dup 3) (match_dup 7))
(set (match_dup 4) (match_dup 8))
(set (match_dup 5) (match_dup 9))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
......@@ -300,24 +300,24 @@
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
(match_operand:V4SF 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:V4SF 0 "nonimmediate_operand" "")
(match_operand:V4SF 1 "input_operand" ""))]
"TARGET_ALTIVEC && reload_completed && !TARGET_POWERPC64
&& altivec_in_gprs_p (operands[0], operands[1])"
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 6))
(set (match_dup 3) (match_dup 7))
(set (match_dup 4) (match_dup 8))
(set (match_dup 5) (match_dup 9))]
"{
rs6000_split_altivec_in_gprs (operands);
rs6000_split_multireg_move (operands);
}")
(define_insn "get_vrsave_internal"
......
......@@ -100,16 +100,16 @@ extern int includes_rldic_lshift_p (rtx, rtx);
extern int includes_rldicr_lshift_p (rtx, rtx);
extern int registers_ok_for_quad_peep (rtx, rtx);
extern int addrs_ok_for_quad_peep (rtx, rtx);
extern int altivec_in_gprs_p (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern enum reg_class secondary_reload_class (enum reg_class,
enum machine_mode, rtx);
enum machine_mode, rtx);
extern int ccr_bit (rtx, int);
extern int extract_MB (rtx);
extern int extract_ME (rtx);
extern void print_operand (FILE *, rtx, int);
extern void print_operand_address (FILE *, rtx);
extern enum rtx_code rs6000_reverse_condition (enum machine_mode,
enum rtx_code);
enum rtx_code);
extern void rs6000_emit_sCOND (enum rtx_code, rtx);
extern void rs6000_emit_cbranch (enum rtx_code, rtx);
extern char * output_cbranch (rtx, const char *, int, rtx);
......@@ -125,7 +125,7 @@ extern int mfcr_operation (rtx, enum machine_mode);
extern int mtcrf_operation (rtx, enum machine_mode);
extern int lmw_operation (rtx, enum machine_mode);
extern struct rtx_def *create_TOC_reference (rtx);
extern void rs6000_split_altivec_in_gprs (rtx *);
extern void rs6000_split_multireg_move (rtx *);
extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
......
......@@ -2200,18 +2200,13 @@ small_data_operand (rtx op ATTRIBUTE_UNUSED,
#endif
}
/* Return 1 for all valid move insn operand combination involving altivec
vectors in gprs. */
/* Return true if either operand is a general purpose register. */
int
altivec_in_gprs_p (rtx op0, rtx op1)
bool
gpr_or_gpr_p (rtx op0, rtx op1)
{
if (REG_P (op0) && REGNO_REG_CLASS (REGNO (op0)) == GENERAL_REGS)
return 1;
if (REG_P (op1) && REGNO_REG_CLASS (REGNO (op1)) == GENERAL_REGS)
return 1;
return 0;
return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
|| (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
}
......@@ -9462,14 +9457,16 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
emit_move_insn (dest, target);
}
/* Called by altivec splitter.
/* Called by splitter for multireg moves.
Input:
operands[0] : Destination of move
operands[1] : Source of move
noperands : Size of operands vector
Output:
operands[2-5] ([2-3] in 64 bit) : Destination slots
operands[6-9] ([4-5] in 64 bit) : Source slots
operands[2-n] : Destination slots
operands[n-m] : Source slots
where n = 2 + HARD_REGNO_NREGS (reg, GET_MODE (operands[0]))
m = 2 + 2 * HARD_REGNO_NREGS (reg, GET_MODE (operands[0])) - 1
Splits the move of operands[1] to operands[0].
This is done, if GPRs are one of the operands. In this case
......@@ -9479,10 +9476,13 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
*/
void
rs6000_split_altivec_in_gprs (rtx *operands)
rs6000_split_multireg_move (rtx *operands)
{
int nregs, reg, i, j;
int nregs, reg, i, j, used_update = 0;
enum machine_mode mode;
rtx dst = operands[0];
rtx src = operands[1];
rtx insn = 0;
/* Calculate number to move (2/4 for 32/64 bit mode). */
......@@ -9500,8 +9500,8 @@ rs6000_split_altivec_in_gprs (rtx *operands)
for (i = 0; i < nregs; i++)
{
j--;
operands[i + 2] = operand_subword (operands[0], j, 0, mode);
operands[i + 2 + nregs] =
operands[i+2] = operand_subword (operands[0], j, 0, mode);
operands[i+2+nregs] =
operand_subword (operands[1], j, 0, mode);
}
}
......@@ -9512,29 +9512,87 @@ rs6000_split_altivec_in_gprs (rtx *operands)
if (GET_CODE (operands[1]) == MEM)
{
rtx breg;
/* We have offsettable addresses only. If we use one of the
registers to address memory, we have change that register last. */
breg = GET_CODE (XEXP (operands[1], 0)) == PLUS ?
XEXP (XEXP (operands[1], 0), 0) :
XEXP (operands[1], 0);
if (REGNO (breg) >= REGNO (operands[0])
&& REGNO (breg) < REGNO (operands[0]) + nregs)
j = REGNO (breg) - REGNO (operands[0]);
if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
|| GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
{
rtx delta_rtx;
breg = XEXP (XEXP (operands[1], 0), 0);
delta_rtx = GET_CODE (XEXP (operands[1], 0)) == PRE_INC
? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])))
: GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[1])));
insn = emit_insn (TARGET_32BIT
? gen_addsi3 (breg, breg, delta_rtx)
: gen_adddi3 (breg, breg, delta_rtx));
src = gen_rtx_MEM (mode, breg);
}
/* We have now address involving an base register only.
If we use one of the registers to address memory,
we have change that register last. */
breg = (GET_CODE (XEXP (src, 0)) == PLUS
? XEXP (XEXP (src, 0), 0)
: XEXP (src, 0));
if (!REG_P (breg))
abort();
if (REGNO (breg) >= REGNO (dst)
&& REGNO (breg) < REGNO (dst) + nregs)
j = REGNO (breg) - REGNO (dst);
}
if (GET_CODE (operands[0]) == MEM)
{
rtx breg;
if (GET_CODE (XEXP (operands[0], 0)) == PRE_INC
|| GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
{
rtx delta_rtx;
breg = XEXP (XEXP (operands[0], 0), 0);
delta_rtx = GET_CODE (XEXP (operands[0], 0)) == PRE_INC
? GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])))
: GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));
/* We have to update the breg before doing the store.
Use store with update, if available. */
if (TARGET_UPDATE)
{
insn = emit_insn (TARGET_32BIT
? gen_movsi_update (breg, breg, delta_rtx,
operand_subword (src, 0, 0, mode))
: gen_movdi_update (breg, breg, delta_rtx,
operand_subword (src, 0, 0, mode)));
used_update = 1;
}
else
insn = emit_insn (TARGET_32BIT
? gen_addsi3 (breg, breg, delta_rtx)
: gen_adddi3 (breg, breg, delta_rtx));
dst = gen_rtx_MEM (mode, breg);
}
}
for (i = 0; i < nregs; i++)
{
/* Calculate index to next subword. */
j++;
if (j == nregs)
j = 0;
{
/* Calculate index to next subword. */
++j;
if (j == nregs)
j = 0;
operands[i + 2] = operand_subword (operands[0], j, 0, mode);
operands[i + 2 + nregs] =
operand_subword (operands[1], j, 0, mode);
operands[i+2] = operand_subword (dst, j, 0, mode);
operands[i+2+nregs] = operand_subword (src, j, 0, mode);
}
if (j == 0 && used_update)
{
/* Already emited move of first word by
store with update -> emit dead insn instead (r := r). */
operands[i+2] = operands[i+2+nregs];
}
}
}
}
......
......@@ -8462,25 +8462,9 @@
default:
abort ();
case 0:
/* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of
operand 1, we must copy in the opposite order. */
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
return \"mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\";
case 1:
/* If the low-address word is used in the address, we must load it
last. Otherwise, load it first. Note that we cannot have
auto-increment in that case since the address register is known to be
dead. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
else
return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
case 2:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
return \"#\";
case 3:
return \"fmr %0,%1\";
case 4:
......@@ -8495,8 +8479,7 @@
return \"#\";
}
}"
[(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")
(set_attr "length" "8,8,8,4,4,4,8,12,8,12,16")])
[(set_attr "type" "*,load,store,fp,fpload,fpstore,*,*,*,*,*")])
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
......@@ -8536,6 +8519,17 @@
}")
(define_split
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(match_operand:DI 1 "input_operand" ""))]
"reload_completed && !TARGET_POWERPC64
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:TI 0 "gpc_reg_operand" "")
(match_operand:TI 1 "const_double_operand" ""))]
"TARGET_POWERPC64"
......@@ -8677,7 +8671,7 @@
[(parallel [(set (match_operand:TI 0 "general_operand" "")
(match_operand:TI 1 "general_operand" ""))
(clobber (scratch:SI))])]
"TARGET_STRING || TARGET_POWERPC64"
""
"{ rs6000_emit_move (operands[0], operands[1], TImode); DONE; }")
;; We say that MQ is clobbered in the last alternative because the first
......@@ -8685,11 +8679,12 @@
;; while the 2nd alternative would not. We put memory cases first so they
;; are preferred. Otherwise, we'd try to reload the output instead of
;; giving the SCRATCH mq.
(define_insn "*movti_power"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
(clobber (match_scratch:SI 2 "=q,q#X,X,X,X"))]
"TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
"TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
......@@ -8699,18 +8694,12 @@
abort ();
case 0:
return \"{stsi|stswi} %1,%P0,16\";
if (TARGET_STRING)
return \"{stsi|stswi} %1,%P0,16\";
case 1:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
return \"#\";
case 2:
/* Normally copy registers with lowest numbered register copied first.
But copy in the other order if the first register of the output
is the second, third, or fourth register in the input. */
if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
&& REGNO (operands[0]) <= REGNO (operands[1]) + 3)
return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
......@@ -8718,29 +8707,15 @@
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
/* If the address register is the same as the register for the lowest-
addressed word, load it last. Similarly for the next two words.
Otherwise load lowest address to highest. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
else if (refers_to_regno_p (REGNO (operands[0]) + 1,
REGNO (operands[0]) + 2, operands[1], 0))
return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
else if (refers_to_regno_p (REGNO (operands[0]) + 2,
REGNO (operands[0]) + 3, operands[1], 0))
return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
else
return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
return \"#\";
}
}"
[(set_attr "type" "store,store,*,load,load")
(set_attr "length" "4,16,16,4,16")])
[(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_string"
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))]
"TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
"! TARGET_POWER && ! TARGET_POWERPC64
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
"*
{
......@@ -8748,81 +8723,62 @@
{
default:
abort ();
case 0:
return \"{stsi|stswi} %1,%P0,16\";
if (TARGET_STRING)
return \"{stsi|stswi} %1,%P0,16\";
case 1:
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\;{st|stw} %Y1,%Y0\;{st|stw} %Z1,%Z0\";
return \"#\";
case 2:
/* Normally copy registers with lowest numbered register copied first.
But copy in the other order if the first register of the output
is the second, third, or fourth register in the input. */
if (REGNO (operands[0]) >= REGNO (operands[1]) + 1
&& REGNO (operands[0]) <= REGNO (operands[1]) + 3)
return \"mr %Z0,%Z1\;mr %Y0,%Y1\;mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\;mr %Y0,%Y1\;mr %Z0,%Z1\";
return \"#\";
case 3:
/* If the address is not used in the output, we can use lsi. Otherwise,
fall through to generating four loads. */
if (! reg_overlap_mentioned_p (operands[0], operands[1]))
if (TARGET_STRING
&& ! reg_overlap_mentioned_p (operands[0], operands[1]))
return \"{lsi|lswi} %0,%P1,16\";
/* ... fall through ... */
case 4:
/* If the address register is the same as the register for the lowest-
addressed word, load it last. Similarly for the next two words.
Otherwise load lowest address to highest. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
return \"{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %0,%1\";
else if (refers_to_regno_p (REGNO (operands[0]) + 1,
REGNO (operands[0]) + 2, operands[1], 0))
return \"{l|lwz} %0,%1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\;{l|lwz} %L0,%L1\";
else if (refers_to_regno_p (REGNO (operands[0]) + 2,
REGNO (operands[0]) + 3, operands[1], 0))
return \"{l|lwz} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Z0,%Z1\;{l|lwz} %Y0,%Y1\";
else
return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\;{l|lwz} %Y0,%Y1\;{l|lwz} %Z0,%Z1\";
return \"#\";
}
}"
[(set_attr "type" "store,store,*,load,load")
(set_attr "length" "4,16,16,4,16")])
[(set_attr "type" "store,store,*,load,load")])
(define_insn "*movti_ppc64"
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,m")
(match_operand:TI 1 "input_operand" "r,m,r"))]
[(set (match_operand:TI 0 "nonimmediate_operand" "=r,m,r")
(match_operand:TI 1 "input_operand" "r,r,o"))]
"TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
|| gpc_reg_operand (operands[1], TImode))"
"*
{
switch (which_alternative)
{
default:
abort ();
case 0:
/* We normally copy the low-numbered register first. However, if
the first register operand 0 is the same as the second register of
operand 1, we must copy in the opposite order. */
if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
return \"mr %L0,%L1\;mr %0,%1\";
else
return \"mr %0,%1\;mr %L0,%L1\";
case 1:
/* If the low-address word is used in the address, we must load it
last. Otherwise, load it first. Note that we cannot have
auto-increment in that case since the address register is known to be
dead. */
if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
operands[1], 0))
return \"ld %L0,%L1\;ld %0,%1\";
else
return \"ld%U1 %0,%1\;ld %L0,%L1\";
case 2:
return \"std%U0 %1,%0\;std %L1,%L0\";
}
}"
[(set_attr "type" "*,load,store")
(set_attr "length" "8,8,8")])
"@
#
#
#"
[(set_attr "type" "*,load,store")])
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "input_operand" ""))]
"reload_completed && TARGET_POWERPC64
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 4))
(set (match_dup 3) (match_dup 5))]
"{
rs6000_split_multireg_move (operands);
}")
(define_split
[(set (match_operand:TI 0 "nonimmediate_operand" "")
(match_operand:TI 1 "input_operand" ""))]
"reload_completed && !TARGET_POWERPC64
&& gpr_or_gpr_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 6))
(set (match_dup 3) (match_dup 7))
(set (match_dup 4) (match_dup 8))
(set (match_dup 5) (match_dup 9))]
"{
rs6000_split_multireg_move (operands);
}")
(define_expand "load_multiple"
[(match_par_dup 3 [(set (match_operand:SI 0 "" "")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment