Commit e7113111 by Richard Kenner

(movdf): Simplify by taking advantage of having SECONDARY_MEMORY_NEEDED.

Fix bugs relating to order in which moves are done.

From-SVN: r5243
parent 7ea555a4
......@@ -2382,88 +2382,19 @@
""
"
{
/* If we are called from reload, we might be getting a SUBREG of a hard
reg. So expand it. */
if (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
&& REGNO (SUBREG_REG (operands[0])) < FIRST_PSEUDO_REGISTER)
operands[0] = alter_subreg (operands[0]);
if (GET_CODE (operands[1]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[1])) == REG
&& REGNO (SUBREG_REG (operands[1])) < FIRST_PSEUDO_REGISTER)
operands[1] = alter_subreg (operands[1]);
if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
{
rtx stack_slot;
/* If this is a store to memory or another integer register do the
move directly. Otherwise store to a temporary stack slot and
load from there into a floating point register. */
if (GET_CODE (operands[0]) == MEM
|| (GET_CODE (operands[0]) == REG
&& (REGNO (operands[0]) < 32
|| (reload_in_progress
&& REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))))
{
emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
operand_subword (operands[1], 0, 0, DFmode));
emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
operand_subword (operands[1], 1, 0, DFmode));
DONE;
}
stack_slot = gen_rtx (MEM, DFmode, plus_constant (stack_pointer_rtx, 8));
emit_move_insn (stack_slot, operands[1]);
emit_move_insn (operands[0], stack_slot);
emit_move_insn (operand_subword (operands[0], 1, 1, DFmode),
operand_subword_force (operands[1], 1, DFmode));
emit_move_insn (operand_subword (operands[0], 0, 1, DFmode),
operand_subword_force (operands[1], 0, DFmode));
DONE;
}
if (GET_CODE (operands[0]) == MEM)
{
if (GET_CODE (operands[1]) == MEM)
{
emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
operand_subword (operands[1], 0, 0, DFmode));
emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
operand_subword (operands[1], 1, 0, DFmode));
DONE;
}
operands[1] = force_reg (DFmode, operands[1]);
}
if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32)
{
rtx stack_slot;
if (GET_CODE (operands[1]) == MEM
#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT && ! defined(REAL_IS_NOT_DOUBLE)
|| GET_CODE (operands[1]) == CONST_DOUBLE
#endif
|| (GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32)
|| (reload_in_progress && GET_CODE (operands[1]) == REG
&& REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER))
{
emit_move_insn (operand_subword (operands[0], 0, 0, DFmode),
operand_subword (operands[1], 0, 0, DFmode));
emit_move_insn (operand_subword (operands[0], 1, 0, DFmode),
operand_subword (operands[1], 1, 0, DFmode));
DONE;
}
if (reload_in_progress)
stack_slot = gen_rtx (MEM, DFmode,
plus_constant (stack_pointer_rtx, 8));
else
stack_slot = assign_stack_temp (DFmode, 8, 0);
emit_move_insn (stack_slot, operands[1]);
emit_move_insn (operands[0], stack_slot);
DONE;
}
if (GET_CODE (operands[0]) != REG)
operands[1] = force_reg (DFmode, operands[1]);
if (CONSTANT_P (operands[1]))
if (CONSTANT_P (operands[1]) && ! easy_fp_constant (operands[1], DFmode))
{
operands[1] = force_const_mem (DFmode, operands[1]);
if (! memory_address_p (DFmode, XEXP (operands[1], 0))
......@@ -2471,17 +2402,8 @@
operands[1] = change_address (operands[1], DFmode,
XEXP (operands[1], 0));
}
}")
(define_insn ""
[(set (match_operand:DF 0 "gpc_reg_operand" "=r,r")
(match_operand:DF 1 "mem_or_easy_const_operand" "G,m"))]
"REGNO (operands[0]) <= 31"
"@
#
l %0,%1\;l %L0,%L1"
[(set_attr "type" "*,load")
(set_attr "length" "*,8")])
}")
(define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "")
......@@ -2494,17 +2416,48 @@
operands[3] = operand_subword (operands[1], 0, 0, DFmode);
operands[4] = operand_subword (operands[0], 1, 0, DFmode);
operands[5] = operand_subword (operands[1], 1, 0, DFmode); }")
(define_insn ""
[(set (match_operand:DF 0 "fp_reg_or_mem_operand" "=f,f,m")
(match_operand:DF 1 "fp_reg_or_mem_operand" "f,m,f"))]
"gpc_reg_operand (operands[0], DFmode)
|| gpc_reg_operand (operands[1], DFmode)"
"@
fmr %0,%1
lfd%U1%X1 %0,%1
stfd%U0%X0 %1,%0"
[(set_attr "type" "fp,load,*")])
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,r,o,r,f,f,m")
(match_operand:DF 1 "input_operand" "r,o,r,G,f,m,f"))]
"register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode)"
"*
{
switch (which_alternative)
{
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 \"oril %L0,%L1,0\;oril %0,%1,0\";
else
return \"oril %0,%1,0\;oril %L0,%L1,0\";
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 %L0,%L1\;l %0,%1\";
else
return \"l%U1 %0,%1\;l %L0,%L1\";
case 2:
return \"st%U0 %1,%0\;st %L1,%L0\";
case 3:
return \"#\";
case 4:
return \"fmr %0,%1\";
case 5:
return \"lfd%U1%X1 %0,%1\";
case 6:
return \"stfd%U0%X0 %1,%0\";
}
}"
[(set_attr "type" "*,load,*,*,fp,load,*")
(set_attr "length" "8,8,8,8,*,*,*")])
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.
......
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