[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp PPCFrameInfo.h PPCHazardRecognizers.cpp PPCISelLowering.cpp PPCISelLowering.h PPCInstr64Bit.td PPCInstrInfo.td PPCRegisterInfo.cpp
Chris Lattner
sabre at nondot.org
Sat Feb 24 21:34:49 PST 2007
Changes in directory llvm/lib/Target/PowerPC:
PPCCodeEmitter.cpp updated: 1.74 -> 1.75
PPCFrameInfo.h updated: 1.12 -> 1.13
PPCHazardRecognizers.cpp updated: 1.18 -> 1.19
PPCISelLowering.cpp updated: 1.253 -> 1.254
PPCISelLowering.h updated: 1.58 -> 1.59
PPCInstr64Bit.td updated: 1.38 -> 1.39
PPCInstrInfo.td updated: 1.272 -> 1.273
PPCRegisterInfo.cpp updated: 1.111 -> 1.112
---
Log message:
implement support for the linux/ppc function call ABI. Patch by
Nicolas Geoffray!
---
Diffs of the changes: (+343 -102)
PPCCodeEmitter.cpp | 7 +-
PPCFrameInfo.h | 50 +++++++++++----
PPCHazardRecognizers.cpp | 2
PPCISelLowering.cpp | 149 ++++++++++++++++++++++++++++++-----------------
PPCISelLowering.h | 2
PPCInstr64Bit.td | 44 +++++++++++--
PPCInstrInfo.td | 64 ++++++++++++++++----
PPCRegisterInfo.cpp | 127 ++++++++++++++++++++++++++++++++++++----
8 files changed, 343 insertions(+), 102 deletions(-)
Index: llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp
diff -u llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.74 llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.75
--- llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp:1.74 Fri Dec 15 10:44:10 2006
+++ llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp Sat Feb 24 23:34:32 2007
@@ -133,7 +133,8 @@
} 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 @@
} 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;
Index: llvm/lib/Target/PowerPC/PPCFrameInfo.h
diff -u llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.12 llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.13
--- llvm/lib/Target/PowerPC/PPCFrameInfo.h:1.12 Wed Dec 6 11:42:06 2006
+++ llvm/lib/Target/PowerPC/PPCFrameInfo.h Sat Feb 24 23:34:32 2007
@@ -29,41 +29,61 @@
/// 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);
}
};
Index: llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp
diff -u llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.18 llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.19
--- llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp:1.18 Thu Dec 7 16:21:48 2006
+++ llvm/lib/Target/PowerPC/PPCHazardRecognizers.cpp Sat Feb 24 23:34:32 2007
@@ -157,7 +157,7 @@
}
// 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
Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.253 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.254
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.253 Thu Feb 22 08:56:36 2007
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Sat Feb 24 23:34:32 2007
@@ -328,7 +328,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
} 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 @@
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<ConstantSDNode>(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<ConstantSDNode>(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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
std::vector<std::pair<unsigned, SDOperand> > RegsToPass;
SmallVector<SDOperand, 8> 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 @@
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 @@
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 @@
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<MVT::ValueType> 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 @@
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 @@
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<PPCFunctionInfo>();
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 @@
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);
Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.58 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.59
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.58 Fri Jan 26 16:40:50 2007
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h Sat Feb 24 23:34:32 2007
@@ -90,7 +90,7 @@
/// 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,
Index: llvm/lib/Target/PowerPC/PPCInstr64Bit.td
diff -u llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.38 llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.39
--- llvm/lib/Target/PowerPC/PPCInstr64Bit.td:1.38 Fri Dec 15 15:39:31 2006
+++ llvm/lib/Target/PowerPC/PPCInstr64Bit.td Sat Feb 24 23:34:32 2007
@@ -69,6 +69,7 @@
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 @@
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.
Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.272 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.273
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.272 Fri Jan 26 08:34:51 2007
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Sat Feb 24 23:34:32 2007
@@ -81,11 +81,16 @@
[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 @@
/*[(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 @@
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 @@
"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 @@
(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)>;
Index: llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
diff -u llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.111 llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.112
--- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp:1.111 Fri Feb 23 14:34:16 2007
+++ llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp Sat Feb 24 23:34:32 2007
@@ -261,6 +261,28 @@
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 @@
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 @@
&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 @@
&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 @@
// 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 @@
// Include call frame size in total.
FrameSize += maxCallFrameSize;
-
+
// Make sure the frame is aligned.
FrameSize = (FrameSize + AlignMask) & ~AlignMask;
@@ -815,13 +915,15 @@
// 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 @@
// 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 @@
}
}
- int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64);
- int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64);
if (IsPPC64) {
if (UsesLR)
More information about the llvm-commits
mailing list