diff options
author | Jeff Law <law@gcc.gnu.org> | 1995-12-23 10:25:00 -0700 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1995-12-23 10:25:00 -0700 |
commit | bad883f8a12c6dd7f2136718f63cd6241bc064bc (patch) | |
tree | 65ff7dd567205d9727a42906feeaa147b78f26f6 /gcc/config/pa/pa.c | |
parent | 9151b3bf9265cb1739bf7e9144e7ed5a78ec590a (diff) | |
download | gcc-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/config/pa/pa.c')
-rw-r--r-- | gcc/config/pa/pa.c | 28 |
1 files changed, 18 insertions, 10 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) { |