aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PowerPC/PPCInstr64Bit.td5
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp106
2 files changed, 81 insertions, 30 deletions
diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td
index 1147680941..af20c1c7a7 100644
--- a/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -322,6 +322,10 @@ def STDX : XForm_8<31, 149, (ops G8RC:$rS, memrr:$dst),
"stdx $rS, $dst", LdStSTD,
[(store G8RC:$rS, xaddr:$dst)]>, isPPC64,
PPC970_DGroup_Cracked;
+
+def STDU : DSForm_1<62, 1, (ops G8RC:$rS, memrix:$dst),
+ "stdu $rS, $dst", LdStSTD,
+ []>, isPPC64;
def STDUX : XForm_8<31, 181, (ops G8RC:$rS, memrr:$dst),
"stdux $rS, $dst", LdStSTD,
[]>, isPPC64;
@@ -335,6 +339,7 @@ def STDX_32 : XForm_8<31, 149, (ops GPRC:$rT, memrr:$dst),
[(PPCstd_32 GPRC:$rT, xaddr:$dst)]>, isPPC64,
PPC970_DGroup_Cracked;
+
// Truncating stores.
def STB8 : DForm_3<38, (ops G8RC:$rS, memri:$src),
"stb $rS, $src", LdStGeneral,
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 931dac1761..3e79d04f65 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -636,7 +636,7 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
// Add the size of R1 to NumBytes size for the store of R1 to the bottom
// of the stack and round the size to a multiple of the alignment.
unsigned Align = std::max(TargetAlign, MaxAlign);
- unsigned GPRSize = 4;
+ unsigned GPRSize = Subtarget.isPPC64() ? 8 : 4;
unsigned Size = HasFP ? GPRSize + GPRSize : GPRSize;
NumBytes = (NumBytes+Size+Align-1)/Align*Align;
@@ -646,24 +646,47 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
// Adjust stack pointer: r1 -= numbytes.
// If there is a preferred stack alignment, align R1 now
- if (MaxAlign > TargetAlign) {
- assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767 && "Invalid alignment!");
- assert(isInt16(0-NumBytes) && "Unhandled stack size and alignment!");
- BuildMI(MBB, MBBI, PPC::RLWINM, 4, PPC::R0)
- .addReg(PPC::R1).addImm(0).addImm(32-Log2_32(MaxAlign)).addImm(31);
- BuildMI(MBB, MBBI, PPC::SUBFIC,2,PPC::R0).addReg(PPC::R0)
- .addImm(0-NumBytes);
- BuildMI(MBB, MBBI, PPC::STWUX, 3)
- .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
- } else if (NumBytes <= 32768) {
- BuildMI(MBB, MBBI, PPC::STWU, 3).addReg(PPC::R1).addImm(NegNumbytes)
- .addReg(PPC::R1);
- } else {
- BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addImm(NegNumbytes >> 16);
- BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
- .addImm(NegNumbytes & 0xFFFF);
- BuildMI(MBB, MBBI, PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1)
- .addReg(PPC::R0);
+ if (!Subtarget.isPPC64()) {
+ // PPC32.
+ if (MaxAlign > TargetAlign) {
+ assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767&&"Invalid alignment!");
+ assert(isInt16(0-NumBytes) && "Unhandled stack size and alignment!");
+ BuildMI(MBB, MBBI, PPC::RLWINM, 4, PPC::R0)
+ .addReg(PPC::R1).addImm(0).addImm(32-Log2_32(MaxAlign)).addImm(31);
+ BuildMI(MBB, MBBI, PPC::SUBFIC,2,PPC::R0).addReg(PPC::R0)
+ .addImm(0-NumBytes);
+ BuildMI(MBB, MBBI, PPC::STWUX, 3)
+ .addReg(PPC::R1).addReg(PPC::R1).addReg(PPC::R0);
+ } else if (NumBytes <= 32768) {
+ BuildMI(MBB, MBBI, PPC::STWU, 3).addReg(PPC::R1).addImm(NegNumbytes)
+ .addReg(PPC::R1);
+ } else {
+ BuildMI(MBB, MBBI, PPC::LIS, 1, PPC::R0).addImm(NegNumbytes >> 16);
+ BuildMI(MBB, MBBI, PPC::ORI, 2, PPC::R0).addReg(PPC::R0)
+ .addImm(NegNumbytes & 0xFFFF);
+ BuildMI(MBB, MBBI, PPC::STWUX, 3).addReg(PPC::R1).addReg(PPC::R1)
+ .addReg(PPC::R0);
+ }
+ } else { // PPC64.
+ if (MaxAlign > TargetAlign) {
+ assert(isPowerOf2_32(MaxAlign) && MaxAlign < 32767&&"Invalid alignment!");
+ assert(isInt16(0-NumBytes) && "Unhandled stack size and alignment!");
+ BuildMI(MBB, MBBI, PPC::RLDICL, 3, PPC::X0)
+ .addReg(PPC::X1).addImm(0).addImm(64-Log2_32(MaxAlign));
+ BuildMI(MBB, MBBI, PPC::SUBFIC8, 2, PPC::X0).addReg(PPC::X0)
+ .addImm(0-NumBytes);
+ BuildMI(MBB, MBBI, PPC::STDUX, 3)
+ .addReg(PPC::X1).addReg(PPC::X1).addReg(PPC::X0);
+ } else if (NumBytes <= 32768*4) {
+ BuildMI(MBB, MBBI, PPC::STDU, 3).addReg(PPC::X1).addImm(NegNumbytes/4)
+ .addReg(PPC::X1);
+ } else {
+ BuildMI(MBB, MBBI, PPC::LIS8, 1, PPC::X0).addImm(NegNumbytes >> 16);
+ BuildMI(MBB, MBBI, PPC::ORI8, 2, PPC::X0).addReg(PPC::X0)
+ .addImm(NegNumbytes & 0xFFFF);
+ BuildMI(MBB, MBBI, PPC::STDUX, 3).addReg(PPC::X1).addReg(PPC::X1)
+ .addReg(PPC::X0);
+ }
}
if (DebugInfo && DebugInfo->hasInfo()) {
@@ -690,9 +713,15 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
// If there is a frame pointer, copy R1 (SP) into R31 (FP)
if (HasFP) {
- BuildMI(MBB, MBBI, PPC::STW, 3)
- .addReg(PPC::R31).addImm(GPRSize).addReg(PPC::R1);
- BuildMI(MBB, MBBI, PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
+ if (!Subtarget.isPPC64()) {
+ BuildMI(MBB, MBBI, PPC::STW, 3)
+ .addReg(PPC::R31).addImm(GPRSize).addReg(PPC::R1);
+ BuildMI(MBB, MBBI, PPC::OR, 2, PPC::R31).addReg(PPC::R1).addReg(PPC::R1);
+ } else {
+ BuildMI(MBB, MBBI, PPC::STD, 3)
+ .addReg(PPC::X31).addImm(GPRSize/4).addReg(PPC::X1);
+ BuildMI(MBB, MBBI, PPC::OR8, 2, PPC::X31).addReg(PPC::X1).addReg(PPC::X1);
+ }
}
}
@@ -714,17 +743,31 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
// If this function has a frame pointer, load the saved stack pointer from
// its stack slot.
if (hasFP(MF)) {
- BuildMI(MBB, MBBI, PPC::LWZ, 2, PPC::R31)
- .addImm(GPRSize).addReg(PPC::R31);
+ if (!Subtarget.isPPC64()) {
+ BuildMI(MBB, MBBI, PPC::LWZ, 2, PPC::R31)
+ .addImm(GPRSize).addReg(PPC::R31);
+ } else {
+ BuildMI(MBB, MBBI, PPC::LD, 2, PPC::X31)
+ .addImm(GPRSize/4).addReg(PPC::X31);
+ }
}
- // The loaded (or persistent) stack pointer value is offseted by the 'stwu'
+ // The loaded (or persistent) stack pointer value is offset by the 'stwu'
// on entry to the function. Add this offset back now.
- if (NumBytes < 32768 && TargetAlign >= MFI->getMaxAlignment()) {
- BuildMI(MBB, MBBI, PPC::ADDI, 2, PPC::R1)
- .addReg(PPC::R1).addImm(NumBytes);
+ if (!Subtarget.isPPC64()) {
+ if (NumBytes < 32768 && TargetAlign >= MFI->getMaxAlignment()) {
+ BuildMI(MBB, MBBI, PPC::ADDI, 2, PPC::R1)
+ .addReg(PPC::R1).addImm(NumBytes);
+ } else {
+ BuildMI(MBB, MBBI, PPC::LWZ, 2, PPC::R1).addImm(0).addReg(PPC::R1);
+ }
} else {
- BuildMI(MBB, MBBI, PPC::LWZ, 2, PPC::R1).addImm(0).addReg(PPC::R1);
+ if (NumBytes < 32768 && TargetAlign >= MFI->getMaxAlignment()) {
+ BuildMI(MBB, MBBI, PPC::ADDI8, 2, PPC::X1)
+ .addReg(PPC::X1).addImm(NumBytes);
+ } else {
+ BuildMI(MBB, MBBI, PPC::LD, 2, PPC::X1).addImm(0).addReg(PPC::X1);
+ }
}
}
}
@@ -734,7 +777,10 @@ unsigned PPCRegisterInfo::getRARegister() const {
}
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
- return hasFP(MF) ? PPC::R31 : PPC::R1;
+ if (!Subtarget.isPPC64())
+ return hasFP(MF) ? PPC::R31 : PPC::R1;
+ else
+ return hasFP(MF) ? PPC::X31 : PPC::X1;
}
void PPCRegisterInfo::getInitialFrameState(std::vector<MachineMove *> &Moves)