rs6000.c (find_addr_reg): New function.
* rs6000.c (find_addr_reg): New function. * rs6000.h (find_addr_reg): Declare. (offsettable_addr_operand): Delete. * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads from and stores to GPRs. From-SVN: r27602
This commit is contained in:
parent
0b8a1e58d9
commit
000034eb46
@ -1,3 +1,11 @@
|
||||
Fri Jun 18 23:47:06 1999 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* rs6000.c (find_addr_reg): New function.
|
||||
* rs6000.h (find_addr_reg): Declare.
|
||||
(offsettable_addr_operand): Delete.
|
||||
* rs6000.md (movdf_hardfloat32): Handle non-offsettable loads
|
||||
from and stores to GPRs.
|
||||
|
||||
Fri Jun 18 15:44:18 1999 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* alpha.c (alpha_expand_block_move): Use get_insns rather than
|
||||
|
@ -5681,7 +5681,33 @@ rs6000_encode_section_info (decl)
|
||||
}
|
||||
|
||||
#endif /* USING_SVR4_H */
|
||||
|
||||
|
||||
/* Return a REG that occurs in ADDR with coefficient 1.
|
||||
ADDR can be effectively incremented by incrementing REG. */
|
||||
|
||||
struct rtx_def *
|
||||
find_addr_reg (addr)
|
||||
rtx addr;
|
||||
{
|
||||
while (GET_CODE (addr) == PLUS)
|
||||
{
|
||||
if (GET_CODE (XEXP (addr, 0)) == REG)
|
||||
addr = XEXP (addr, 0);
|
||||
else if (GET_CODE (XEXP (addr, 1)) == REG)
|
||||
addr = XEXP (addr, 1);
|
||||
else if (CONSTANT_P (XEXP (addr, 0)))
|
||||
addr = XEXP (addr, 1);
|
||||
else if (CONSTANT_P (XEXP (addr, 1)))
|
||||
addr = XEXP (addr, 0);
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
if (GET_CODE (addr) == REG)
|
||||
return addr;
|
||||
abort ();
|
||||
}
|
||||
|
||||
void
|
||||
rs6000_fatal_bad_address (op)
|
||||
rtx op;
|
||||
|
@ -3224,13 +3224,13 @@ extern int flag_expensive_optimizations;
|
||||
extern int frame_pointer_needed;
|
||||
|
||||
/* Declare functions in rs6000.c */
|
||||
extern int offsettable_mem_operand ();
|
||||
extern void optimization_options ();
|
||||
extern void output_options ();
|
||||
extern void rs6000_override_options ();
|
||||
extern void rs6000_file_start ();
|
||||
extern struct rtx_def *rs6000_float_const ();
|
||||
extern struct rtx_def *rs6000_got_register ();
|
||||
extern struct rtx_def *find_addr_reg();
|
||||
extern int direct_return ();
|
||||
extern int get_issue_rate ();
|
||||
extern int any_operand ();
|
||||
@ -3249,7 +3249,7 @@ extern int got_no_const_operand ();
|
||||
extern int num_insns_constant ();
|
||||
extern int easy_fp_constant ();
|
||||
extern int volatile_mem_operand ();
|
||||
extern int offsettable_addr_operand ();
|
||||
extern int offsettable_mem_operand ();
|
||||
extern int mem_or_easy_const_operand ();
|
||||
extern int add_operand ();
|
||||
extern int non_add_cint_operand ();
|
||||
|
@ -6307,8 +6307,8 @@
|
||||
;; The "??" is a kludge until we can figure out a more reasonable way
|
||||
;; of handling these non-offsettable values.
|
||||
(define_insn "*movdf_hardfloat32"
|
||||
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,o,!r,!r,!r,f,f,m")
|
||||
(match_operand:DF 1 "input_operand" "r,o,r,G,H,F,f,m,f"))]
|
||||
[(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,!r,!r,!r,f,f,m")
|
||||
(match_operand:DF 1 "input_operand" "r,m,r,G,H,F,f,m,f"))]
|
||||
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT
|
||||
&& (gpc_reg_operand (operands[0], DFmode)
|
||||
|| gpc_reg_operand (operands[1], DFmode))"
|
||||
@ -6320,24 +6320,70 @@
|
||||
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. */
|
||||
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\";
|
||||
if (offsettable_memref_p (operands[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\";
|
||||
}
|
||||
else
|
||||
return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
|
||||
{
|
||||
rtx addreg;
|
||||
|
||||
if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
|
||||
|| GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
|
||||
abort ();
|
||||
|
||||
addreg = find_addr_reg (XEXP (operands[1], 0));
|
||||
if (refers_to_regno_p (REGNO (operands[0]),
|
||||
REGNO (operands[0]) + 1,
|
||||
operands[1], 0))
|
||||
{
|
||||
output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
||||
output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
|
||||
output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
||||
return \"{lx|lwzx} %0,%1\";
|
||||
}
|
||||
else
|
||||
{
|
||||
output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
|
||||
output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
||||
output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
|
||||
output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
||||
return \"\";
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
|
||||
if (offsettable_memref_p (operands[0]))
|
||||
return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
|
||||
else
|
||||
{
|
||||
rtx addreg;
|
||||
|
||||
if (GET_CODE (XEXP (operands[1], 0)) == PRE_INC
|
||||
|| GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
|
||||
abort ();
|
||||
|
||||
addreg = find_addr_reg (XEXP (operands[0], 0));
|
||||
output_asm_insn (\"{stx|stwx} %1,%0\", operands);
|
||||
output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
|
||||
output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
|
||||
output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
|
||||
return \"\";
|
||||
}
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
|
Loading…
Reference in New Issue
Block a user