Commit 42fbe27f by Jeff Law

pa.c (emit_move_sequence): Handle secondary FP load/store reloads of the form…

pa.c (emit_move_sequence): Handle secondary FP load/store reloads of the form (subreg (mem (plus (reg)...

	* pa.c (emit_move_sequence): Handle secondary FP load/store
	reloads of the form (subreg (mem (plus (reg) (disp)))).
	(secondary_reload_class): A secondary register is needed to handle
	out-of-range FP loads and stores.
	* pa.md (reload_indf, reload_outdf): New expanders.
	(reload_insf, reload_outsf): Likewise.

From-SVN: r8077
parent 4b303b50
......@@ -769,26 +769,37 @@ emit_move_sequence (operands, mode, scratch_reg)
register rtx operand1 = operands[1];
/* Handle secondary reloads for loads/stores of FP registers from
REG+D addresses where D does not fit in 5 bits. */
REG+D addresses where D does not fit in 5 bits, including
(subreg (mem (addr)) cases. */
if (fp_reg_operand (operand0, mode)
&& GET_CODE (operand1) == MEM
/* Using DFmode forces only short displacements be be
recognized as valid in reg+d addressing modes. */
&& ! memory_address_p (DFmode, XEXP (operand1, 0))
&& ((GET_CODE (operand1) == MEM
&& ! memory_address_p (DFmode, XEXP (operand1, 0)))
|| ((GET_CODE (operand1) == SUBREG
&& GET_CODE (XEXP (operand1, 0)) == MEM
&& !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
&& scratch_reg)
{
if (GET_CODE (operand1) == SUBREG)
operand1 = XEXP (operand1, 0);
scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
emit_move_insn (scratch_reg, XEXP (operand1, 0));
emit_insn (gen_rtx (SET, VOIDmode, operand0, gen_rtx (MEM, mode,
scratch_reg)));
return 1;
}
else if (fp_reg_operand (operand1, mode)
&& GET_CODE (operand0) == MEM
/* Using DFmode forces only short displacements be be
recognized as valid in reg+d addressing modes. */
&& ! memory_address_p (DFmode, XEXP (operand0, 0))
&& ((GET_CODE (operand0) == MEM
&& ! memory_address_p (DFmode, XEXP (operand0, 0)))
|| ((GET_CODE (operand0) == SUBREG)
&& GET_CODE (XEXP (operand0, 0)) == MEM
&& !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
&& scratch_reg)
{
if (GET_CODE (operand0) == SUBREG)
operand0 = XEXP (operand0, 0);
scratch_reg = gen_rtx (REG, SImode, REGNO (scratch_reg));
emit_move_insn (scratch_reg, XEXP (operand0, 0));
emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (MEM, mode, scratch_reg),
operand1));
......@@ -3261,6 +3272,15 @@ secondary_reload_class (class, mode, in)
if (class != R1_REGS && symbolic_operand (in, VOIDmode))
return R1_REGS;
if (GET_CODE (in) == SUBREG)
in = SUBREG_REG (in);
if (FP_REG_CLASS_P (class)
&& GET_CODE (in) == MEM
&& !memory_address_p (DFmode, XEXP (in, 0))
&& memory_address_p (SImode, XEXP (in, 0)))
return GENERAL_REGS;
return NO_REGS;
}
......
......@@ -1480,6 +1480,39 @@
DONE;
}")
;; Reloading an SImode or DImode value requires a scratch register if
;; going in to or out of float point registers.
(define_expand "reload_indf"
[(set (match_operand:DF 0 "register_operand" "=Z")
(match_operand:DF 1 "general_operand" ""))
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
""
"
{
if (emit_move_sequence (operands, DFmode, operands[2]))
DONE;
/* We don't want the clobber emitted, so handle this ourselves. */
emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
DONE;
}")
(define_expand "reload_outdf"
[(set (match_operand:DF 0 "general_operand" "")
(match_operand:DF 1 "register_operand" "Z"))
(clobber (match_operand:DF 2 "register_operand" "=&r"))]
""
"
{
if (emit_move_sequence (operands, DFmode, operands[2]))
DONE;
/* We don't want the clobber emitted, so handle this ourselves. */
emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
DONE;
}")
(define_insn ""
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
"=f,*r,Q,?o,?Q,f,*&r,*&r")
......@@ -1720,6 +1753,39 @@
DONE;
}")
;; Reloading an SImode or DImode value requires a scratch register if
;; going in to or out of float point registers.
(define_expand "reload_insf"
[(set (match_operand:SF 0 "register_operand" "=Z")
(match_operand:SF 1 "general_operand" ""))
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
""
"
{
if (emit_move_sequence (operands, SFmode, operands[2]))
DONE;
/* We don't want the clobber emitted, so handle this ourselves. */
emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
DONE;
}")
(define_expand "reload_outsf"
[(set (match_operand:SF 0 "general_operand" "")
(match_operand:SF 1 "register_operand" "Z"))
(clobber (match_operand:SF 2 "register_operand" "=&r"))]
""
"
{
if (emit_move_sequence (operands, SFmode, operands[2]))
DONE;
/* We don't want the clobber emitted, so handle this ourselves. */
emit_insn (gen_rtx (SET, VOIDmode, operands[0], operands[1]));
DONE;
}")
(define_insn ""
[(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
"=f,r,f,r,Q,Q")
......
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