mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
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:
parent
eb95d41cd3
commit
9f0bc659c8
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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)>;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user