From 9f0bc659c8d2f1e401a9690e4900b0fd2a70bdfe Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 25 Feb 2007 05:34:32 +0000 Subject: [PATCH] implement support for the linux/ppc function call ABI. Patch by Nicolas Geoffray! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34574 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCCodeEmitter.cpp | 7 +- lib/Target/PowerPC/PPCFrameInfo.h | 50 +++++-- lib/Target/PowerPC/PPCHazardRecognizers.cpp | 2 +- lib/Target/PowerPC/PPCISelLowering.cpp | 149 +++++++++++++------- lib/Target/PowerPC/PPCISelLowering.h | 2 +- lib/Target/PowerPC/PPCInstr64Bit.td | 44 ++++-- lib/Target/PowerPC/PPCInstrInfo.td | 64 +++++++-- lib/Target/PowerPC/PPCRegisterInfo.cpp | 127 +++++++++++++++-- 8 files changed, 343 insertions(+), 102 deletions(-) diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 60ee403931f..6e3d68d0477 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -133,7 +133,8 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { } else if (MO.isGlobalAddress() || MO.isExternalSymbol() || MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { unsigned Reloc = 0; - if (MI.getOpcode() == PPC::BL || MI.getOpcode() == PPC::BL8) + if (MI.getOpcode() == PPC::BL_Macho || MI.getOpcode() == PPC::BL8_Macho || + MI.getOpcode() == PPC::BL_ELF || MI.getOpcode() == PPC::BL8_ELF) Reloc = PPC::reloc_pcrel_bx; else { if (TM.getRelocationModel() == Reloc::PIC_) { @@ -213,7 +214,9 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { } else if (MO.isMachineBasicBlock()) { unsigned Reloc = 0; unsigned Opcode = MI.getOpcode(); - if (Opcode == PPC::B || Opcode == PPC::BL || Opcode == PPC::BLA) + if (Opcode == PPC::B || Opcode == PPC::BL_Macho || + Opcode == PPC::BLA_Macho || Opcode == PPC::BL_ELF || + Opcode == PPC::BLA_ELF) Reloc = PPC::reloc_pcrel_bx; else // BCC instruction Reloc = PPC::reloc_pcrel_bcx; diff --git a/lib/Target/PowerPC/PPCFrameInfo.h b/lib/Target/PowerPC/PPCFrameInfo.h index 22b945ea208..0c728247301 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.h +++ b/lib/Target/PowerPC/PPCFrameInfo.h @@ -29,41 +29,61 @@ public: /// getReturnSaveOffset - Return the previous frame offset to save the /// return address. - static unsigned getReturnSaveOffset(bool LP64) { - return LP64 ? 16 : 8; + static unsigned getReturnSaveOffset(bool LP64, bool isMacho) { + if (isMacho) + return LP64 ? 16 : 8; + // For ELF ABI: + return LP64 ? 8 : 4; } /// getFramePointerSaveOffset - Return the previous frame offset to save the /// frame pointer. - static unsigned getFramePointerSaveOffset(bool LP64) { + static unsigned getFramePointerSaveOffset(bool LP64, bool isMacho) { + // For MachO ABI: // Use the TOC save slot in the PowerPC linkage area for saving the frame // pointer (if needed.) LLVM does not generate code that uses the TOC (R2 // is treated as a caller saved register.) - return LP64 ? 40 : 20; + if (isMacho) + return LP64 ? 40 : 20; + + // For ELF ABI: + // Save it right before the link register + return LP64 ? -8 : -4; } /// getLinkageSize - Return the size of the PowerPC ABI linkage area. /// - static unsigned getLinkageSize(bool LP64) { - return 6 * (LP64 ? 8 : 4); + static unsigned getLinkageSize(bool LP64, bool isMacho) { + if (isMacho) + return 6 * (LP64 ? 8 : 4); + + // For ELF ABI: + return LP64 ? 16 : 8; } /// getMinCallArgumentsSize - Return the size of the minium PowerPC ABI /// argument area. - static unsigned getMinCallArgumentsSize(bool LP64) { - // The prolog code of the callee may store up to 8 GPR argument registers to - // the stack, allowing va_start to index over them in memory if its varargs. - // Because we cannot tell if this is needed on the caller side, we have to - // conservatively assume that it is needed. As such, make sure we have at - // least enough stack space for the caller to store the 8 GPRs. - return 8 * (LP64 ? 8 : 4); + static unsigned getMinCallArgumentsSize(bool LP64, bool isMacho) { + // For Macho ABI: + // The prolog code of the callee may store up to 8 GPR argument registers to + // the stack, allowing va_start to index over them in memory if its varargs. + // Because we cannot tell if this is needed on the caller side, we have to + // conservatively assume that it is needed. As such, make sure we have at + // least enough stack space for the caller to store the 8 GPRs. + if (isMacho) + return 8 * (LP64 ? 8 : 4); + + // For Linux ABI: + // There is no default stack allocated for the 8 first GPR arguments. + return 0; } /// getMinCallFrameSize - Return the minimum size a call frame can be using /// the PowerPC ABI. - static unsigned getMinCallFrameSize(bool LP64) { + static unsigned getMinCallFrameSize(bool LP64, bool isMacho) { // The call frame needs to be at least big enough for linkage and 8 args. - return getLinkageSize(LP64) + getMinCallArgumentsSize(LP64); + return getLinkageSize(LP64, isMacho) + + getMinCallArgumentsSize(LP64, isMacho); } }; diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/lib/Target/PowerPC/PPCHazardRecognizers.cpp index 69ad1ea86ec..428bdeac925 100644 --- a/lib/Target/PowerPC/PPCHazardRecognizers.cpp +++ b/lib/Target/PowerPC/PPCHazardRecognizers.cpp @@ -157,7 +157,7 @@ getHazardType(SDNode *Node) { } // Do not allow MTCTR and BCTRL to be in the same dispatch group. - if (HasCTRSet && Opcode == PPC::BCTRL) + if (HasCTRSet && Opcode == PPC::BCTRL_Macho || Opcode == PPC::BCTRL_ELF) return NoopHazard; // If this is a load following a store, make sure it's not to the same or diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 342dd46ae28..c7ab474de4b 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -328,7 +328,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::STD_32: return "PPCISD::STD_32"; case PPCISD::CALL: return "PPCISD::CALL"; case PPCISD::MTCTR: return "PPCISD::MTCTR"; - case PPCISD::BCTRL: return "PPCISD::BCTRL"; + case PPCISD::BCTRL_Macho: return "PPCISD::BCTRL_Macho"; + case PPCISD::BCTRL_ELF: return "PPCISD::BCTRL_ELF"; case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG"; case PPCISD::MFCR: return "PPCISD::MFCR"; case PPCISD::VCMP: return "PPCISD::VCMP"; @@ -1094,8 +1095,28 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG, SV->getOffset()); } +/// GetFPR - Get the set of FP registers that should be allocated for arguments, +/// depending on which subtarget is selected. +static const unsigned *GetFPR(const PPCSubtarget &Subtarget) { + if (Subtarget.isMachoABI()) { + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 + }; + return FPR; + } + + + static const unsigned FPR[] = { + PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, + PPC::F8, PPC::F9, PPC::F10 + }; + return FPR; +} + static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, - int &VarArgsFrameIndex) { + int &VarArgsFrameIndex, + const PPCSubtarget &Subtarget) { // TODO: add description of PPC stack frame format, or at least some docs. // MachineFunction &MF = DAG.getMachineFunction(); @@ -1106,9 +1127,10 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; + bool isMachoABI = Subtarget.isMachoABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; - unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64); + unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. PPC::R3, PPC::R4, PPC::R5, PPC::R6, @@ -1118,17 +1140,16 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, PPC::X3, PPC::X4, PPC::X5, PPC::X6, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; + + static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13 }; const unsigned Num_GPR_Regs = sizeof(GPR_32)/sizeof(GPR_32[0]); - const unsigned Num_FPR_Regs = sizeof(FPR)/sizeof(FPR[0]); + const unsigned Num_FPR_Regs = isMachoABI ? 13 : 10; const unsigned Num_VR_Regs = sizeof( VR)/sizeof( VR[0]); unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; @@ -1149,9 +1170,6 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, switch (ObjectVT) { default: assert(0 && "Unhandled argument type!"); case MVT::i32: - // All int arguments reserve stack space. - ArgOffset += PtrByteSize; - if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap->createVirtualRegister(&PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); @@ -1161,11 +1179,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, needsLoad = true; ArgSize = PtrByteSize; } + // All int arguments reserve stack space in Macho ABI. + if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; break; - case MVT::i64: // PPC64 - // All int arguments reserve stack space. - ArgOffset += 8; + case MVT::i64: // PPC64 if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap->createVirtualRegister(&PPC::G8RCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); @@ -1174,12 +1192,12 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, } else { needsLoad = true; } + // All int arguments reserve stack space in Macho ABI. + if (isMachoABI || needsLoad) ArgOffset += 8; break; + case MVT::f32: case MVT::f64: - // All FP arguments reserve stack space. - ArgOffset += isPPC64 ? 8 : ObjSize; - // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. if (GPR_idx != Num_GPR_Regs) { @@ -1199,6 +1217,9 @@ static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, } else { needsLoad = true; } + + // All FP arguments reserve stack space in Macho ABI. + if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; break; case MVT::v4f32: case MVT::v4i32: @@ -1290,11 +1311,15 @@ static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) { return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val; } -static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { - SDOperand Chain = Op.getOperand(0); - bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; - SDOperand Callee = Op.getOperand(4); - unsigned NumOps = (Op.getNumOperands() - 5) / 2; + +static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG, + const PPCSubtarget &Subtarget) { + SDOperand Chain = Op.getOperand(0); + bool isVarArg = cast(Op.getOperand(2))->getValue() != 0; + SDOperand Callee = Op.getOperand(4); + unsigned NumOps = (Op.getNumOperands() - 5) / 2; + + bool isMachoABI = Subtarget.isMachoABI(); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; @@ -1307,7 +1332,7 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { // Count how many bytes are to be pushed on the stack, including the linkage // area, and parameter passing area. We start with 24/48 bytes, which is // prereserved space for [SP][CR][LR][3 x unused]. - unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64); + unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); // Add up all the space actually used. for (unsigned i = 0; i != NumOps; ++i) { @@ -1321,7 +1346,8 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { // Because we cannot tell if this is needed on the caller side, we have to // conservatively assume that it is needed. As such, make sure we have at // least enough stack space for the caller to store the 8 GPRs. - NumBytes = std::max(NumBytes, PPCFrameInfo::getMinCallFrameSize(isPPC64)); + NumBytes = std::max(NumBytes, + PPCFrameInfo::getMinCallFrameSize(isPPC64, isMachoABI)); // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass @@ -1341,7 +1367,7 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { // memory. Also, if this is a vararg function, floating point operations // must be stored to our stack, and loaded into integer regs as well, if // any integer regs are available for argument passing. - unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64); + unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); unsigned GPR_idx = 0, FPR_idx = 0, VR_idx = 0; static const unsigned GPR_32[] = { // 32-bit registers. @@ -1352,16 +1378,14 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { PPC::X3, PPC::X4, PPC::X5, PPC::X6, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; + static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, PPC::V9, PPC::V10, PPC::V11, PPC::V12, PPC::V13 }; const unsigned NumGPRs = sizeof(GPR_32)/sizeof(GPR_32[0]); - const unsigned NumFPRs = sizeof(FPR)/sizeof(FPR[0]); + const unsigned NumFPRs = isMachoABI ? 13 : 10; const unsigned NumVRs = sizeof( VR)/sizeof( VR[0]); const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; @@ -1369,6 +1393,7 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { std::vector > RegsToPass; SmallVector MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { + bool inMem = false; SDOperand Arg = Op.getOperand(5+2*i); // PtrOff will be used to store the current argument to the stack if a @@ -1392,8 +1417,9 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg)); } else { MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + inMem = true; } - ArgOffset += PtrByteSize; + if (inMem || isMachoABI) ArgOffset += PtrByteSize; break; case MVT::f32: case MVT::f64: @@ -1414,31 +1440,39 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { if (GPR_idx != NumGPRs) { SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0); MemOpChains.push_back(Load.getValue(1)); - RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load)); + if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], + Load)); } if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64){ SDOperand ConstFour = DAG.getConstant(4, PtrOff.getValueType()); PtrOff = DAG.getNode(ISD::ADD, PtrVT, PtrOff, ConstFour); SDOperand Load = DAG.getLoad(PtrVT, Store, PtrOff, NULL, 0); MemOpChains.push_back(Load.getValue(1)); - RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Load)); + if (isMachoABI) RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], + Load)); } } else { // If we have any FPRs remaining, we may also have GPRs remaining. // Args passed in FPRs consume either 1 (f32) or 2 (f64) available // GPRs. - if (GPR_idx != NumGPRs) - ++GPR_idx; - if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && !isPPC64) - ++GPR_idx; + if (isMachoABI) { + if (GPR_idx != NumGPRs) + ++GPR_idx; + if (GPR_idx != NumGPRs && Arg.getValueType() == MVT::f64 && + !isPPC64) // PPC64 has 64-bit GPR's obviously :) + ++GPR_idx; + } } } else { MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); + inMem = true; + } + if (inMem || isMachoABI) { + if (isPPC64) + ArgOffset += 8; + else + ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8; } - if (isPPC64) - ArgOffset += 8; - else - ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8; break; case MVT::v4f32: case MVT::v4i32: @@ -1463,7 +1497,14 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { InFlag); InFlag = Chain.getValue(1); } - + + // With the ELF ABI, set CR6 to true if this is a vararg call. + if (isVarArg && !isMachoABI) { + SDOperand SetCR(DAG.getTargetNode(PPC::SETCR, MVT::i32), 0); + Chain = DAG.getCopyToReg(Chain, PPC::CR6, SetCR, InFlag); + InFlag = Chain.getValue(1); + } + std::vector NodeTys; NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. @@ -1489,14 +1530,16 @@ static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { InFlag = Chain.getValue(1); // Copy the callee address into R12 on darwin. - Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag); - InFlag = Chain.getValue(1); + if (isMachoABI) { + Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag); + InFlag = Chain.getValue(1); + } NodeTys.clear(); NodeTys.push_back(MVT::Other); NodeTys.push_back(MVT::Flag); Ops.push_back(Chain); - CallOpc = PPCISD::BCTRL; + CallOpc = isMachoABI ? PPCISD::BCTRL_Macho : PPCISD::BCTRL_ELF; Callee.Val = 0; } @@ -1656,18 +1699,20 @@ static SDOperand LowerDYNAMIC_STACKALLOC(SDOperand Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget) { MachineFunction &MF = DAG.getMachineFunction(); bool IsPPC64 = Subtarget.isPPC64(); + bool isMachoABI = Subtarget.isMachoABI(); // Get current frame pointer save index. The users of this index will be // primarily DYNALLOC instructions. PPCFunctionInfo *FI = MF.getInfo(); int FPSI = FI->getFramePointerSaveIndex(); - + // If the frame pointer save index hasn't been defined yet. if (!FPSI) { // Find out what the fix offset of the frame pointer save area. - int Offset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64); + int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, isMachoABI); + // Allocate the frame index for frame pointer save area. - FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, Offset); + FPSI = MF.getFrameInfo()->CreateFixedObject(IsPPC64? 8 : 4, FPOffset); // Save the result. FI->setFramePointerSaveIndex(FPSI); } @@ -2630,12 +2675,12 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); case ISD::FORMAL_ARGUMENTS: - return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); - case ISD::CALL: return LowerCALL(Op, DAG); + return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex, PPCSubTarget); + case ISD::CALL: return LowerCALL(Op, DAG, PPCSubTarget); case ISD::RET: return LowerRET(Op, DAG); case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG, PPCSubTarget); - case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG, - PPCSubTarget); + case ISD::DYNAMIC_STACKALLOC: + return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG); diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index f7e5b65dde0..00e65f62fdb 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -90,7 +90,7 @@ namespace llvm { /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a /// BCTRL instruction. - BCTRL, + BCTRL_Macho, BCTRL_ELF, /// Return with a flag operand, matched by 'blr' RET_FLAG, diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 56d02cc146c..89e883a6968 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -69,6 +69,7 @@ let Defs = [LR8] in def MovePCtoLR8 : Pseudo<(ops piclabel:$label), "bl $label", []>, PPC970_Unit_BRU; +// Macho ABI Calls. let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the PPC64 non-callee saved registers. Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12, @@ -77,18 +78,45 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7, LR8,CTR8, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def BL8 : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), - "bl $func", BrB, []>; // See Pat patterns below. + def BL8_Macho : IForm<18, 0, 1, + (ops calltarget:$func, variable_ops), + "bl $func", BrB, []>; // See Pat patterns below. - def BLA8 : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), - "bla $func", BrB, [(PPCcall (i64 imm:$func))]>; + def BLA8_Macho : IForm<18, 1, 1, + (ops aaddr:$func, variable_ops), + "bla $func", BrB, [(PPCcall_Macho (i64 imm:$func))]>; } +// ELF ABI Calls. +let isCall = 1, noResults = 1, PPC970_Unit = 7, + // All calls clobber the PPC64 non-callee saved registers. + Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12, + F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10, + V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, + LR8,CTR8, + CR0,CR1,CR5,CR6,CR7] in { + // Convenient aliases for call instructions + def BL8_ELF : IForm<18, 0, 1, + (ops calltarget:$func, variable_ops), + "bl $func", BrB, []>; // See Pat patterns below. + + def BLA8_ELF : IForm<18, 1, 1, + (ops aaddr:$func, variable_ops), + "bla $func", BrB, [(PPCcall_ELF (i64 imm:$func))]>; +} + + // Calls -def : Pat<(PPCcall (i64 tglobaladdr:$dst)), - (BL8 tglobaladdr:$dst)>; -def : Pat<(PPCcall (i64 texternalsym:$dst)), - (BL8 texternalsym:$dst)>; +def : Pat<(PPCcall_Macho (i64 tglobaladdr:$dst)), + (BL8_Macho tglobaladdr:$dst)>; +def : Pat<(PPCcall_Macho (i64 texternalsym:$dst)), + (BL8_Macho texternalsym:$dst)>; + +def : Pat<(PPCcall_ELF (i64 tglobaladdr:$dst)), + (BL8_ELF tglobaladdr:$dst)>; +def : Pat<(PPCcall_ELF (i64 texternalsym:$dst)), + (BL8_ELF texternalsym:$dst)>; + //===----------------------------------------------------------------------===// // 64-bit SPR manipulation instrs. diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 7b03f92eef0..0f9e9bd13ae 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -81,11 +81,16 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq, [SDNPHasChain, SDNPOutFlag]>; def SDT_PPCCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>; -def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall, +def PPCcall_Macho : SDNode<"PPCISD::CALL", SDT_PPCCall, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def PPCcall_ELF : SDNode<"PPCISD::CALL", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -def PPCbctrl : SDNode<"PPCISD::BCTRL", SDTRet, +def PPCbctrl_Macho : SDNode<"PPCISD::BCTRL_Macho", SDTRet, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + +def PPCbctrl_ELF : SDNode<"PPCISD::BCTRL_ELF", SDTRet, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def retflag : SDNode<"PPCISD::RET_FLAG", SDTRet, @@ -366,6 +371,7 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, /*[(PPCcondbranch CRRC:$crS, imm:$opc, bb:$dst)]*/>; } +// Macho ABI Calls. let isCall = 1, noResults = 1, PPC970_Unit = 7, // All calls clobber the non-callee saved registers... Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12, @@ -374,12 +380,38 @@ let isCall = 1, noResults = 1, PPC970_Unit = 7, LR,CTR, CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions - def BL : IForm<18, 0, 1, (ops calltarget:$func, variable_ops), - "bl $func", BrB, []>; // See Pat patterns below. - def BLA : IForm<18, 1, 1, (ops aaddr:$func, variable_ops), - "bla $func", BrB, [(PPCcall (i32 imm:$func))]>; - def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops variable_ops), "bctrl", BrB, - [(PPCbctrl)]>; + def BL_Macho : IForm<18, 0, 1, + (ops calltarget:$func, variable_ops), + "bl $func", BrB, []>; // See Pat patterns below. + def BLA_Macho : IForm<18, 1, 1, + (ops aaddr:$func, variable_ops), + "bla $func", BrB, [(PPCcall_Macho (i32 imm:$func))]>; + def BCTRL_Macho : XLForm_2_ext<19, 528, 20, 0, 1, + (ops variable_ops), + "bctrl", BrB, + [(PPCbctrl_Macho)]>; +} + +// ELF ABI Calls. +let isCall = 1, noResults = 1, PPC970_Unit = 7, + // All calls clobber the non-callee saved registers... + Defs = [R0,R2,R3,R4,R5,R6,R7,R8,R9,R10,R11,R12, + F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10, + V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19, + LR,CTR, + CR0,CR1,CR5,CR6,CR7] in { + // Convenient aliases for call instructions + def BL_ELF : IForm<18, 0, 1, + (ops calltarget:$func, variable_ops), + "bl $func", BrB, []>; // See Pat patterns below. + def BLA_ELF : IForm<18, 1, 1, + (ops aaddr:$func, variable_ops), + "bla $func", BrB, + [(PPCcall_ELF (i32 imm:$func))]>; + def BCTRL_ELF : XLForm_2_ext<19, 528, 20, 0, 1, + (ops variable_ops), + "bctrl", BrB, + [(PPCbctrl_ELF)]>; } // DCB* instructions. @@ -791,6 +823,14 @@ def MCRF : XLForm_3<19, 0, (ops CRRC:$BF, CRRC:$BFA), "mcrf $BF, $BFA", BrMCR>, PPC970_DGroup_First, PPC970_Unit_CRU; +def CREQV : XLForm_1<19, 289, (ops CRRC:$CRD, CRRC:$CRA, CRRC:$CRB), + "creqv $CRD, $CRA, $CRB", BrCR, + []>; + +def SETCR : XLForm_1_ext<19, 289, (ops CRRC:$dst), + "creqv $dst, $dst, $dst", BrCR, + []>; + // XFX-Form instructions. Instructions that deal with SPRs. // def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>, @@ -1060,10 +1100,10 @@ def : Pat<(and (rotl GPRC:$in, GPRC:$sh), maskimm32:$imm), (RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>; // Calls -def : Pat<(PPCcall (i32 tglobaladdr:$dst)), - (BL tglobaladdr:$dst)>; -def : Pat<(PPCcall (i32 texternalsym:$dst)), - (BL texternalsym:$dst)>; +def : Pat<(PPCcall_Macho (i32 tglobaladdr:$dst)), + (BL_Macho tglobaladdr:$dst)>; +def : Pat<(PPCcall_ELF (i32 texternalsym:$dst)), + (BL_ELF texternalsym:$dst)>; // Hi and Lo for Darwin Global Addresses. def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 86d17f6fa3c..b600c17f3ae 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -261,6 +261,28 @@ const unsigned* PPCRegisterInfo::getCalleeSavedRegs() const { PPC::LR, 0 }; + + static const unsigned ELF32_CalleeSavedRegs[] = { + PPC::R13, PPC::R14, PPC::R15, + PPC::R16, PPC::R17, PPC::R18, PPC::R19, + PPC::R20, PPC::R21, PPC::R22, PPC::R23, + PPC::R24, PPC::R25, PPC::R26, PPC::R27, + PPC::R28, PPC::R29, PPC::R30, PPC::R31, + + PPC::F11, PPC::F12, PPC::F13, + PPC::F14, PPC::F15, PPC::F16, PPC::F17, + PPC::F18, PPC::F19, PPC::F20, PPC::F21, + PPC::F22, PPC::F23, PPC::F24, PPC::F25, + PPC::F26, PPC::F27, PPC::F28, PPC::F29, + PPC::F30, PPC::F31, + + PPC::CR2, PPC::CR3, PPC::CR4, + PPC::V20, PPC::V21, PPC::V22, PPC::V23, + PPC::V24, PPC::V25, PPC::V26, PPC::V27, + PPC::V28, PPC::V29, PPC::V30, PPC::V31, + + PPC::LR, 0 + }; // 64-bit Darwin calling convention. static const unsigned Darwin64_CalleeSavedRegs[] = { PPC::X14, PPC::X15, @@ -283,8 +305,34 @@ const unsigned* PPCRegisterInfo::getCalleeSavedRegs() const { PPC::LR8, 0 }; - return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs : - Darwin32_CalleeSavedRegs; + static const unsigned ELF64_CalleeSavedRegs[] = { + PPC::X14, PPC::X15, + PPC::X16, PPC::X17, PPC::X18, PPC::X19, + PPC::X20, PPC::X21, PPC::X22, PPC::X23, + PPC::X24, PPC::X25, PPC::X26, PPC::X27, + PPC::X28, PPC::X29, PPC::X30, PPC::X31, + + PPC::F11, PPC::F12, PPC::F13, + PPC::F14, PPC::F15, PPC::F16, PPC::F17, + PPC::F18, PPC::F19, PPC::F20, PPC::F21, + PPC::F22, PPC::F23, PPC::F24, PPC::F25, + PPC::F26, PPC::F27, PPC::F28, PPC::F29, + PPC::F30, PPC::F31, + + PPC::CR2, PPC::CR3, PPC::CR4, + PPC::V20, PPC::V21, PPC::V22, PPC::V23, + PPC::V24, PPC::V25, PPC::V26, PPC::V27, + PPC::V28, PPC::V29, PPC::V30, PPC::V31, + + PPC::LR8, 0 + }; + + if (Subtarget.isMachoABI()) + return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs : + Darwin32_CalleeSavedRegs; + + // ELF. + return Subtarget.isPPC64() ? ELF64_CalleeSavedRegs : ELF32_CalleeSavedRegs; } const TargetRegisterClass* const* @@ -312,6 +360,29 @@ PPCRegisterInfo::getCalleeSavedRegClasses() const { &PPC::GPRCRegClass, 0 }; + static const TargetRegisterClass * const ELF32_CalleeSavedRegClasses[] = { + &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, + &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, + &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, + &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, + &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, + + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass, + + &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass, + + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + + &PPC::GPRCRegClass, 0 + }; + // 64-bit Darwin calling convention. static const TargetRegisterClass * const Darwin64_CalleeSavedRegClasses[] = { &PPC::G8RCRegClass,&PPC::G8RCRegClass, @@ -334,9 +405,37 @@ PPCRegisterInfo::getCalleeSavedRegClasses() const { &PPC::G8RCRegClass, 0 }; + + static const TargetRegisterClass * const ELF64_CalleeSavedRegClasses[] = { + &PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass, + + &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass, + + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + + &PPC::G8RCRegClass, 0 + }; - return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses : - Darwin32_CalleeSavedRegClasses; + if (Subtarget.isMachoABI()) + return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses : + Darwin32_CalleeSavedRegClasses; + + // ELF. + return Subtarget.isPPC64() ? ELF64_CalleeSavedRegClasses : + ELF32_CalleeSavedRegClasses; } // needsFP - Return true if the specified function should have a dedicated frame @@ -753,7 +852,8 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const { // Maximum call frame needs to be at least big enough for linkage and 8 args. unsigned minCallFrameSize = - PPCFrameInfo::getMinCallFrameSize(Subtarget.isPPC64()); + PPCFrameInfo::getMinCallFrameSize(Subtarget.isPPC64(), + Subtarget.isMachoABI()); maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize); // If we have dynamic alloca then maxCallFrameSize needs to be aligned so @@ -766,7 +866,7 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const { // Include call frame size in total. FrameSize += maxCallFrameSize; - + // Make sure the frame is aligned. FrameSize = (FrameSize + AlignMask) & ~AlignMask; @@ -815,13 +915,15 @@ void PPCRegisterInfo::emitPrologue(MachineFunction &MF) const { // Get processor type. bool IsPPC64 = Subtarget.isPPC64(); + // Get operating system + bool IsMachoABI = Subtarget.isMachoABI(); // Check if the link register (LR) has been used. bool UsesLR = MFI->hasCalls() || usesLR(MF); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF); - int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64); - int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64); + int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI); + int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI); if (IsPPC64) { if (UsesLR) @@ -976,11 +1078,16 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, // Get processor type. bool IsPPC64 = Subtarget.isPPC64(); + // Get operating system + bool IsMachoABI = Subtarget.isMachoABI(); // Check if the link register (LR) has been used. bool UsesLR = MFI->hasCalls() || usesLR(MF); // Do we have a frame pointer for this function? bool HasFP = hasFP(MF); - + + int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI); + int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI); + // The loaded (or persistent) stack pointer value is offset by the 'stwu' // on entry to the function. Add this offset back now. if (!Subtarget.isPPC64()) { @@ -1001,8 +1108,6 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF, } } - int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64); - int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64); if (IsPPC64) { if (UsesLR)