From a94a203f346e65d40c4c3fe478c5d8d7a2ff5df6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 11 Nov 2006 19:05:28 +0000 Subject: [PATCH] implement proper PPC64 prolog/epilog codegen. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31684 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCInstr64Bit.td | 5 ++ lib/Target/PowerPC/PPCRegisterInfo.cpp | 106 ++++++++++++++++++------- 2 files changed, 81 insertions(+), 30 deletions(-) diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 1147680941c..af20c1c7a7b 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 931dac17612..3e79d04f650 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 &Moves)