""
"
{
- /* 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))
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" "")
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,*,*,*")])
\f
;; Next come the multi-word integer load and store and the load and store
;; multiple insns.