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
This commit is contained in:
Chris Lattner 2007-02-25 05:34:32 +00:00
parent eb95d41cd3
commit 9f0bc659c8
8 changed files with 343 additions and 102 deletions

View File

@ -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;

View File

@ -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);
}
};

View File

@ -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

View File

@ -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<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 @@ 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<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 @@ 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<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 @@ 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<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 @@ 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);

View File

@ -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,

View File

@ -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.

View File

@ -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)>;

View File

@ -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)