diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1994-11-18 19:15:47 -0500 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1994-11-18 19:15:47 -0500 |
commit | 35068b435fb8c09fff2cbc4eb8a3e1dd904aae0e (patch) | |
tree | ec8309c869394e8fc2d6d5b201899fa77e689be8 | |
parent | d5e4fa5e173ff180b66524db80e4392051dfa479 (diff) | |
download | gcc-35068b435fb8c09fff2cbc4eb8a3e1dd904aae0e.zip gcc-35068b435fb8c09fff2cbc4eb8a3e1dd904aae0e.tar.gz gcc-35068b435fb8c09fff2cbc4eb8a3e1dd904aae0e.tar.bz2 |
(addrs_ok_for_quad_peep): New function.
(output_prolog): Use liu mnemonic.
From-SVN: r8516
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a572d74..4895219 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -719,6 +719,78 @@ includes_rshift_p (shiftop, andop) return (INTVAL (andop) & ~ shift_mask) == 0; } + +/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates + for lfq and stfq insns. + + Note reg1 and reg2 *must* be hard registers. To be sure we will + abort if we are passed pseudo registers. */ + +int +registers_ok_for_quad_peep (reg1, reg2) + rtx reg1, reg2; +{ + /* We might have been passed a SUBREG. */ + if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG) + return 0; + + return (REGNO (reg1) == REGNO (reg2) - 1); +} + +/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn. addr1 and + addr2 must be in consecutive memory locations (addr2 == addr1 + 8). */ + +int +addrs_ok_for_quad_peep (addr1, addr2) + register rtx addr1; + register rtx addr2; +{ + int reg1; + int offset1; + + /* Extract an offset (if used) from the first addr. */ + if (GET_CODE (addr1) == PLUS) + { + /* If not a REG, return zero. */ + if (GET_CODE (XEXP (addr1, 0)) != REG) + return 0; + else + { + reg1 = REGNO (XEXP (addr1, 0)); + /* The offset must be constant! */ + if (GET_CODE (XEXP (addr1, 1)) != CONST_INT) + return 0; + offset1 = INTVAL (XEXP (addr1, 1)); + } + } + else if (GET_CODE (addr1) != REG) + return 0; + else + { + reg1 = REGNO (addr1); + /* This was a simple (mem (reg)) expression. Offset is 0. */ + offset1 = 0; + } + + /* Make sure the second address is a (mem (plus (reg) (const_int). */ + if (GET_CODE (addr2) != PLUS) + return 0; + + if (GET_CODE (XEXP (addr2, 0)) != REG + || GET_CODE (XEXP (addr2, 1)) != CONST_INT) + return 0; + + if (reg1 != REGNO (XEXP (addr2, 0))) + return 0; + + /* The offset for the second addr must be 8 more than the first addr. */ + if (INTVAL (XEXP (addr2, 1)) != offset1 + 8) + return 0; + + /* All the tests passed. addr1 and addr2 are valid for lfq or stfq + instructions. */ + return 1; +} /* Return the register class of a scratch register needed to copy IN into or out of a register in CLASS in MODE. If it can be done directly, @@ -1502,7 +1574,7 @@ output_prolog (file, size) asm_fprintf (file, "\t{stu|stwu} 1,%d(1)\n", - total_size); else { - asm_fprintf (file, "\t{cau 0,0,%d|lis 0,%d}\n\t{oril|ori} 0,0,%d\n", + asm_fprintf (file, "\t{liu|lis} 0,%d\n\t{oril|ori} 0,0,%d\n", (total_size >> 16) & 0xffff, total_size & 0xffff); if (TARGET_POWERPC) asm_fprintf (file, "\tsubf 12,0,1\n"); |