aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>1995-12-23 10:25:00 -0700
committerJeff Law <law@gcc.gnu.org>1995-12-23 10:25:00 -0700
commitbad883f8a12c6dd7f2136718f63cd6241bc064bc (patch)
tree65ff7dd567205d9727a42906feeaa147b78f26f6 /gcc
parent9151b3bf9265cb1739bf7e9144e7ed5a78ec590a (diff)
downloadgcc-bad883f8a12c6dd7f2136718f63cd6241bc064bc.zip
gcc-bad883f8a12c6dd7f2136718f63cd6241bc064bc.tar.gz
gcc-bad883f8a12c6dd7f2136718f63cd6241bc064bc.tar.bz2
pa.c (output_move_double): Correctly identify and handle overlapping moves.
* pa.c (output_move_double): Correctly identify and handle overlapping moves. * pa.md (movdi patterns): Eliminate earlyclobbers in mem<->gr cases. (movdf patterns): Likewise. From-SVN: r10837
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/pa/pa.c28
-rw-r--r--gcc/config/pa/pa.md8
2 files changed, 22 insertions, 14 deletions
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 3b201cd..c6fb1ed 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1373,28 +1373,36 @@ output_move_double (operands)
/* If the first move would clobber the source of the second one,
do them in the other order.
- RMS says "This happens only for registers;
- such overlap can't happen in memory unless the user explicitly
- sets it up, and that is an undefined circumstance."
+ This can happen in two cases:
- but it happens on the HP-PA when loading parameter registers,
- so I am going to define that circumstance, and make it work
- as expected. */
+ mem -> register where the first half of the destination register
+ is the same register used in the memory's address. Reload
+ can create such insns.
- if (optype0 == REGOP && (optype1 == MEMOP || optype1 == OFFSOP)
- && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))
+ mem in this case will be either register indirect or register
+ indirect plus a valid offset.
+
+ register -> register move where REGNO(dst) == REGNO(src + 1)
+ someone (Tim/Tege?) claimed this can happen for parameter loads.
+
+ Handle mem -> register case first. */
+ if (optype0 == REGOP
+ && (optype1 == MEMOP || optype1 == OFFSOP)
+ && refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
+ operands[1], 0))
{
- /* XXX THIS PROBABLY DOESN'T WORK. */
/* Do the late half first. */
if (addreg1)
output_asm_insn ("ldo 4(%0),%0", &addreg1);
output_asm_insn (singlemove_string (latehalf), latehalf);
+
+ /* Then clobber. */
if (addreg1)
output_asm_insn ("ldo -4(%0),%0", &addreg1);
- /* Then clobber. */
return singlemove_string (operands);
}
+ /* Now handle register -> register case. */
if (optype0 == REGOP && optype1 == REGOP
&& REGNO (operands[0]) == REGNO (operands[1]) + 1)
{
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 80f5db3..8b23ea4 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2146,7 +2146,7 @@
(define_insn ""
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=f,*r,Q,?o,?Q,f,*&r,*&r")
+ "=f,*r,Q,?o,?Q,f,*r,*r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
"fG,*rG,f,*r,*r,Q,o,Q"))]
"(register_operand (operands[0], DFmode)
@@ -2164,7 +2164,7 @@
(define_insn ""
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=r,?o,?Q,&r,&r")
+ "=r,?o,?Q,r,r")
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
"rG,r,r,o,Q"))]
"(register_operand (operands[0], DFmode)
@@ -2375,7 +2375,7 @@
(define_insn ""
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,o,Q,&r,&r,&r,f,f,*T")
+ "=r,o,Q,r,r,r,f,f,*T")
(match_operand:DI 1 "general_operand"
"rM,r,r,o,Q,i,fM,*T,f"))]
"(register_operand (operands[0], DImode)
@@ -2393,7 +2393,7 @@
(define_insn ""
[(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,o,Q,&r,&r,&r")
+ "=r,o,Q,r,r,r")
(match_operand:DI 1 "general_operand"
"rM,r,r,o,Q,i"))]
"(register_operand (operands[0], DImode)