mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-13 01:15:32 +00:00
PPC: Add base-pointer support to builtin setjmp/longjmp
First, this changes the base-pointer implementation to remove an unnecessary complication (and one that is incompatible with how builtin SjLj is implemented): instead of using r31 as the base pointer when it is not needed as a frame pointer, now the base pointer will always be r30 when needed. Second, we introduce another pseudo register, BP, which is used just like the FP pseudo register to refer to the base register before we know for certain what register it will be. Third, we now save BP into the jmp_buf, and restore r30 from that slot in longjmp. If the function that called setjmp did not use a base pointer, then r30 will be overwritten by the setjmp-calling-function's restore code. FP restoration (which is restored into r31) works the same way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@186545 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
36ee010b9d
commit
0541722de4
@ -297,6 +297,12 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
|
|||||||
unsigned FPReg = is31 ? PPC::R31 : PPC::R1;
|
unsigned FPReg = is31 ? PPC::R31 : PPC::R1;
|
||||||
unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
|
unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;
|
||||||
|
|
||||||
|
const PPCRegisterInfo *RegInfo =
|
||||||
|
static_cast<const PPCRegisterInfo*>(MF.getTarget().getRegisterInfo());
|
||||||
|
bool HasBP = RegInfo->hasBasePointer(MF);
|
||||||
|
unsigned BPReg = HasBP ? (unsigned) PPC::R30 : FPReg;
|
||||||
|
unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FPReg;
|
||||||
|
|
||||||
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
|
for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
|
||||||
BI != BE; ++BI)
|
BI != BE; ++BI)
|
||||||
for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) {
|
for (MachineBasicBlock::iterator MBBI = BI->end(); MBBI != BI->begin(); ) {
|
||||||
@ -313,6 +319,13 @@ void PPCFrameLowering::replaceFPWithRealFP(MachineFunction &MF) const {
|
|||||||
case PPC::FP8:
|
case PPC::FP8:
|
||||||
MO.setReg(FP8Reg);
|
MO.setReg(FP8Reg);
|
||||||
break;
|
break;
|
||||||
|
case PPC::BP:
|
||||||
|
MO.setReg(BPReg);
|
||||||
|
break;
|
||||||
|
case PPC::BP8:
|
||||||
|
MO.setReg(BP8Reg);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -393,8 +406,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
BPOffset = FFI->getObjectOffset(BPIndex);
|
BPOffset = FFI->getObjectOffset(BPIndex);
|
||||||
} else {
|
} else {
|
||||||
BPOffset =
|
BPOffset =
|
||||||
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI,
|
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
|
||||||
HasFP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,7 +429,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
|
|
||||||
if (HasBP)
|
if (HasBP)
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STD))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STD))
|
||||||
.addReg(HasFP ? PPC::X30 : PPC::X31)
|
.addReg(PPC::X30)
|
||||||
.addImm(BPOffset)
|
.addImm(BPOffset)
|
||||||
.addReg(PPC::X1);
|
.addReg(PPC::X1);
|
||||||
|
|
||||||
@ -448,7 +460,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
// FIXME: On PPC32 SVR4, FPOffset is negative and access to negative
|
// FIXME: On PPC32 SVR4, FPOffset is negative and access to negative
|
||||||
// offsets of R1 is not allowed.
|
// offsets of R1 is not allowed.
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::STW))
|
||||||
.addReg(HasFP ? PPC::R30 : PPC::R31)
|
.addReg(PPC::R30)
|
||||||
.addImm(BPOffset)
|
.addImm(BPOffset)
|
||||||
.addReg(PPC::R1);
|
.addReg(PPC::R1);
|
||||||
|
|
||||||
@ -475,8 +487,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
|
|
||||||
if (HasBP) {
|
if (HasBP) {
|
||||||
// Save a copy of r1 as the base pointer.
|
// Save a copy of r1 as the base pointer.
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR),
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR), PPC::R30)
|
||||||
HasFP ? PPC::R30 : PPC::R31)
|
|
||||||
.addReg(PPC::R1)
|
.addReg(PPC::R1)
|
||||||
.addReg(PPC::R1);
|
.addReg(PPC::R1);
|
||||||
}
|
}
|
||||||
@ -527,8 +538,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
} else { // PPC64.
|
} else { // PPC64.
|
||||||
if (HasBP) {
|
if (HasBP) {
|
||||||
// Save a copy of r1 as the base pointer.
|
// Save a copy of r1 as the base pointer.
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8),
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::OR8), PPC::X30)
|
||||||
HasFP ? PPC::X30 : PPC::X31)
|
|
||||||
.addReg(PPC::X1)
|
.addReg(PPC::X1)
|
||||||
.addReg(PPC::X1);
|
.addReg(PPC::X1);
|
||||||
}
|
}
|
||||||
@ -597,8 +607,7 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (HasBP) {
|
if (HasBP) {
|
||||||
unsigned Reg = isPPC64 ? (HasFP ? PPC::X30 : PPC::X31) :
|
unsigned Reg = isPPC64 ? PPC::X30 : PPC::R30;
|
||||||
(HasFP ? PPC::R30 : PPC::R31);
|
|
||||||
Reg = MRI->getDwarfRegNum(Reg, true);
|
Reg = MRI->getDwarfRegNum(Reg, true);
|
||||||
MMI.addFrameInst(
|
MMI.addFrameInst(
|
||||||
MCCFIInstruction::createOffset(FrameLabel, Reg, BPOffset));
|
MCCFIInstruction::createOffset(FrameLabel, Reg, BPOffset));
|
||||||
@ -739,8 +748,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
BPOffset = FFI->getObjectOffset(BPIndex);
|
BPOffset = FFI->getObjectOffset(BPIndex);
|
||||||
} else {
|
} else {
|
||||||
BPOffset =
|
BPOffset =
|
||||||
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI,
|
PPCFrameLowering::getBasePointerSaveOffset(isPPC64, isDarwinABI);
|
||||||
HasFP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,7 +844,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
.addImm(FPOffset).addReg(PPC::X1);
|
.addImm(FPOffset).addReg(PPC::X1);
|
||||||
|
|
||||||
if (HasBP)
|
if (HasBP)
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), HasFP ? PPC::X30 : PPC::X31)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::LD), PPC::X30)
|
||||||
.addImm(BPOffset).addReg(PPC::X1);
|
.addImm(BPOffset).addReg(PPC::X1);
|
||||||
|
|
||||||
if (!MustSaveCRs.empty())
|
if (!MustSaveCRs.empty())
|
||||||
@ -859,7 +867,7 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
|
|||||||
.addImm(FPOffset).addReg(PPC::R1);
|
.addImm(FPOffset).addReg(PPC::R1);
|
||||||
|
|
||||||
if (HasBP)
|
if (HasBP)
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), HasFP ? PPC::R30 : PPC::R31)
|
BuildMI(MBB, MBBI, dl, TII.get(PPC::LWZ), PPC::R30)
|
||||||
.addImm(FPOffset).addReg(PPC::R1);
|
.addImm(FPOffset).addReg(PPC::R1);
|
||||||
|
|
||||||
if (MustSaveLR)
|
if (MustSaveLR)
|
||||||
@ -968,7 +976,7 @@ PPCFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
|
|
||||||
int BPSI = FI->getBasePointerSaveIndex();
|
int BPSI = FI->getBasePointerSaveIndex();
|
||||||
if (!BPSI && RegInfo->hasBasePointer(MF)) {
|
if (!BPSI && RegInfo->hasBasePointer(MF)) {
|
||||||
int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI, needsFP(MF));
|
int BPOffset = getBasePointerSaveOffset(isPPC64, isDarwinABI);
|
||||||
// Allocate the frame index for the base pointer save area.
|
// Allocate the frame index for the base pointer save area.
|
||||||
BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
|
BPSI = MFI->CreateFixedObject(isPPC64? 8 : 4, BPOffset, true);
|
||||||
// Save the result.
|
// Save the result.
|
||||||
|
@ -96,11 +96,7 @@ public:
|
|||||||
|
|
||||||
/// getBasePointerSaveOffset - Return the previous frame offset to save the
|
/// getBasePointerSaveOffset - Return the previous frame offset to save the
|
||||||
/// base pointer.
|
/// base pointer.
|
||||||
static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI,
|
static unsigned getBasePointerSaveOffset(bool isPPC64, bool isDarwinABI) {
|
||||||
bool hasFP) {
|
|
||||||
if (!hasFP)
|
|
||||||
return getFramePointerSaveOffset(isPPC64, isDarwinABI);
|
|
||||||
|
|
||||||
if (isDarwinABI)
|
if (isDarwinABI)
|
||||||
return isPPC64 ? -16U : -8U;
|
return isPPC64 ? -16U : -8U;
|
||||||
|
|
||||||
|
@ -6084,6 +6084,7 @@ PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
// thisMBB:
|
// thisMBB:
|
||||||
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
||||||
const int64_t TOCOffset = 3 * PVT.getStoreSize();
|
const int64_t TOCOffset = 3 * PVT.getStoreSize();
|
||||||
|
const int64_t BPOffset = 4 * PVT.getStoreSize();
|
||||||
|
|
||||||
// Prepare IP either in reg.
|
// Prepare IP either in reg.
|
||||||
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
|
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
|
||||||
@ -6095,10 +6096,25 @@ PPCTargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
.addReg(PPC::X2)
|
.addReg(PPC::X2)
|
||||||
.addImm(TOCOffset)
|
.addImm(TOCOffset)
|
||||||
.addReg(BufReg);
|
.addReg(BufReg);
|
||||||
|
|
||||||
MIB.setMemRefs(MMOBegin, MMOEnd);
|
MIB.setMemRefs(MMOBegin, MMOEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Naked functions never have a base pointer, and so we use r1. For all
|
||||||
|
// other functions, this decision must be delayed until during PEI.
|
||||||
|
unsigned BaseReg;
|
||||||
|
if (MF->getFunction()->getAttributes().hasAttribute(
|
||||||
|
AttributeSet::FunctionIndex, Attribute::Naked))
|
||||||
|
BaseReg = PPCSubTarget.isPPC64() ? PPC::X1 : PPC::R1;
|
||||||
|
else
|
||||||
|
BaseReg = PPCSubTarget.isPPC64() ? PPC::BP8 : PPC::BP;
|
||||||
|
|
||||||
|
MIB = BuildMI(*thisMBB, MI, DL,
|
||||||
|
TII->get(PPCSubTarget.isPPC64() ? PPC::STD : PPC::STW))
|
||||||
|
.addReg(BaseReg)
|
||||||
|
.addImm(BPOffset)
|
||||||
|
.addReg(BufReg);
|
||||||
|
MIB.setMemRefs(MMOBegin, MMOEnd);
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::BCLalways)).addMBB(mainMBB);
|
MIB = BuildMI(*thisMBB, MI, DL, TII->get(PPC::BCLalways)).addMBB(mainMBB);
|
||||||
const PPCRegisterInfo *TRI =
|
const PPCRegisterInfo *TRI =
|
||||||
@ -6170,12 +6186,14 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
|
|||||||
// Since FP is only updated here but NOT referenced, it's treated as GPR.
|
// Since FP is only updated here but NOT referenced, it's treated as GPR.
|
||||||
unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
|
unsigned FP = (PVT == MVT::i64) ? PPC::X31 : PPC::R31;
|
||||||
unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
|
unsigned SP = (PVT == MVT::i64) ? PPC::X1 : PPC::R1;
|
||||||
|
unsigned BP = (PVT == MVT::i64) ? PPC::X30 : PPC::R30;
|
||||||
|
|
||||||
MachineInstrBuilder MIB;
|
MachineInstrBuilder MIB;
|
||||||
|
|
||||||
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
||||||
const int64_t SPOffset = 2 * PVT.getStoreSize();
|
const int64_t SPOffset = 2 * PVT.getStoreSize();
|
||||||
const int64_t TOCOffset = 3 * PVT.getStoreSize();
|
const int64_t TOCOffset = 3 * PVT.getStoreSize();
|
||||||
|
const int64_t BPOffset = 4 * PVT.getStoreSize();
|
||||||
|
|
||||||
unsigned BufReg = MI->getOperand(0).getReg();
|
unsigned BufReg = MI->getOperand(0).getReg();
|
||||||
|
|
||||||
@ -6217,8 +6235,17 @@ PPCTargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
|
|||||||
}
|
}
|
||||||
MIB.setMemRefs(MMOBegin, MMOEnd);
|
MIB.setMemRefs(MMOBegin, MMOEnd);
|
||||||
|
|
||||||
// FIXME: When we also support base pointers, that register must also be
|
// Reload BP
|
||||||
// restored here.
|
if (PVT == MVT::i64) {
|
||||||
|
MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LD), BP)
|
||||||
|
.addImm(BPOffset)
|
||||||
|
.addReg(BufReg);
|
||||||
|
} else {
|
||||||
|
MIB = BuildMI(*MBB, MI, DL, TII->get(PPC::LWZ), BP)
|
||||||
|
.addImm(BPOffset)
|
||||||
|
.addReg(BufReg);
|
||||||
|
}
|
||||||
|
MIB.setMemRefs(MMOBegin, MMOEnd);
|
||||||
|
|
||||||
// Reload TOC
|
// Reload TOC
|
||||||
if (PVT == MVT::i64 && PPCSubTarget.isSVR4ABI()) {
|
if (PVT == MVT::i64 && PPCSubTarget.isSVR4ABI()) {
|
||||||
|
@ -152,6 +152,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|||||||
Reserved.set(PPC::FP);
|
Reserved.set(PPC::FP);
|
||||||
Reserved.set(PPC::FP8);
|
Reserved.set(PPC::FP8);
|
||||||
|
|
||||||
|
// The BP register is also not really a register, but is the representation
|
||||||
|
// of the base pointer register used by setjmp.
|
||||||
|
Reserved.set(PPC::BP);
|
||||||
|
Reserved.set(PPC::BP8);
|
||||||
|
|
||||||
// The counter registers must be reserved so that counter-based loops can
|
// The counter registers must be reserved so that counter-based loops can
|
||||||
// be correctly formed (and the mtctr instructions are not DCE'd).
|
// be correctly formed (and the mtctr instructions are not DCE'd).
|
||||||
Reserved.set(PPC::CTR);
|
Reserved.set(PPC::CTR);
|
||||||
@ -178,14 +183,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|||||||
Reserved.set(PPC::X1);
|
Reserved.set(PPC::X1);
|
||||||
Reserved.set(PPC::X13);
|
Reserved.set(PPC::X13);
|
||||||
|
|
||||||
if (PPCFI->needsFP(MF) || hasBasePointer(MF)) {
|
if (PPCFI->needsFP(MF))
|
||||||
Reserved.set(PPC::X31);
|
Reserved.set(PPC::X31);
|
||||||
|
|
||||||
// If we need a base pointer, and we also have a frame pointer, then use
|
if (hasBasePointer(MF))
|
||||||
// r30 as the base pointer.
|
Reserved.set(PPC::X30);
|
||||||
if (PPCFI->needsFP(MF) && hasBasePointer(MF))
|
|
||||||
Reserved.set(PPC::X30);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 64-bit SVR4 ABI reserves r2 for the TOC pointer.
|
// The 64-bit SVR4 ABI reserves r2 for the TOC pointer.
|
||||||
if (Subtarget.isSVR4ABI()) {
|
if (Subtarget.isSVR4ABI()) {
|
||||||
@ -193,12 +195,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PPCFI->needsFP(MF) || hasBasePointer(MF)) {
|
if (PPCFI->needsFP(MF))
|
||||||
Reserved.set(PPC::R31);
|
Reserved.set(PPC::R31);
|
||||||
|
|
||||||
if (PPCFI->needsFP(MF) && hasBasePointer(MF))
|
if (hasBasePointer(MF))
|
||||||
Reserved.set(PPC::R30);
|
Reserved.set(PPC::R30);
|
||||||
}
|
|
||||||
|
|
||||||
// Reserve Altivec registers when Altivec is unavailable.
|
// Reserve Altivec registers when Altivec is unavailable.
|
||||||
if (!Subtarget.hasAltivec())
|
if (!Subtarget.hasAltivec())
|
||||||
@ -675,15 +676,10 @@ unsigned PPCRegisterInfo::getEHHandlerRegister() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned PPCRegisterInfo::getBaseRegister(const MachineFunction &MF) const {
|
unsigned PPCRegisterInfo::getBaseRegister(const MachineFunction &MF) const {
|
||||||
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
|
|
||||||
|
|
||||||
if (!hasBasePointer(MF))
|
if (!hasBasePointer(MF))
|
||||||
return getFrameRegister(MF);
|
return getFrameRegister(MF);
|
||||||
|
|
||||||
if (!Subtarget.isPPC64())
|
return Subtarget.isPPC64() ? PPC::X30 : PPC::R30;
|
||||||
return TFI->hasFP(MF) ? PPC::R30 : PPC::R31;
|
|
||||||
else
|
|
||||||
return TFI->hasFP(MF) ? PPC::X30 : PPC::X31;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
bool PPCRegisterInfo::hasBasePointer(const MachineFunction &MF) const {
|
||||||
|
@ -94,6 +94,10 @@ def ZERO8 : GP8<ZERO, "0">;
|
|||||||
def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">;
|
def FP : GPR<0 /* arbitrary */, "**FRAME POINTER**">;
|
||||||
def FP8 : GP8<FP, "**FRAME POINTER**">;
|
def FP8 : GP8<FP, "**FRAME POINTER**">;
|
||||||
|
|
||||||
|
// Representations of the base pointer used by setjmp.
|
||||||
|
def BP : GPR<0 /* arbitrary */, "**BASE POINTER**">;
|
||||||
|
def BP8 : GP8<BP, "**BASE POINTER**">;
|
||||||
|
|
||||||
// Condition register bits
|
// Condition register bits
|
||||||
def CR0LT : CRBIT< 0, "0">;
|
def CR0LT : CRBIT< 0, "0">;
|
||||||
def CR0GT : CRBIT< 1, "1">;
|
def CR0GT : CRBIT< 1, "1">;
|
||||||
@ -172,11 +176,11 @@ def RM: SPR<512, "**ROUNDING MODE**">;
|
|||||||
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
// then nonvolatiles in reverse order since stmw/lmw save from rN to r31
|
||||||
def GPRC : RegisterClass<"PPC", [i32], 32, (add (sequence "R%u", 2, 12),
|
def GPRC : RegisterClass<"PPC", [i32], 32, (add (sequence "R%u", 2, 12),
|
||||||
(sequence "R%u", 30, 13),
|
(sequence "R%u", 30, 13),
|
||||||
R31, R0, R1, FP)>;
|
R31, R0, R1, FP, BP)>;
|
||||||
|
|
||||||
def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12),
|
def G8RC : RegisterClass<"PPC", [i64], 64, (add (sequence "X%u", 2, 12),
|
||||||
(sequence "X%u", 30, 14),
|
(sequence "X%u", 30, 14),
|
||||||
X31, X13, X0, X1, FP8)>;
|
X31, X13, X0, X1, FP8, BP8)>;
|
||||||
|
|
||||||
// For some instructions r0 is special (representing the value 0 instead of
|
// For some instructions r0 is special (representing the value 0 instead of
|
||||||
// the value in the r0 register), and we use these register subclasses to
|
// the value in the r0 register), and we use these register subclasses to
|
||||||
|
@ -20,6 +20,7 @@ entry:
|
|||||||
; CHECK: ld [[REG2:[0-9]+]], 8([[REG]])
|
; CHECK: ld [[REG2:[0-9]+]], 8([[REG]])
|
||||||
; CHECK: ld 1, 16([[REG]])
|
; CHECK: ld 1, 16([[REG]])
|
||||||
; CHECK: mtctr [[REG2]]
|
; CHECK: mtctr [[REG2]]
|
||||||
|
; CHECK: ld 30, 32([[REG]])
|
||||||
; CHECK: ld 2, 24([[REG]])
|
; CHECK: ld 2, 24([[REG]])
|
||||||
; CHECK: bctr
|
; CHECK: bctr
|
||||||
|
|
||||||
@ -99,6 +100,52 @@ return: ; preds = %if.end, %if.then
|
|||||||
; CHECK-NOAV: blr
|
; CHECK-NOAV: blr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define signext i32 @main2() #0 {
|
||||||
|
entry:
|
||||||
|
%a = alloca i8, align 64
|
||||||
|
call void @bar(i8* %a)
|
||||||
|
%retval = alloca i32, align 4
|
||||||
|
store i32 0, i32* %retval
|
||||||
|
%0 = call i8* @llvm.frameaddress(i32 0)
|
||||||
|
store i8* %0, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**)
|
||||||
|
%1 = call i8* @llvm.stacksave()
|
||||||
|
store i8* %1, i8** getelementptr (i8** bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8**), i32 2)
|
||||||
|
%2 = call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @env_sigill to i8*))
|
||||||
|
%tobool = icmp ne i32 %2, 0
|
||||||
|
br i1 %tobool, label %if.then, label %if.else
|
||||||
|
|
||||||
|
if.then: ; preds = %entry
|
||||||
|
store i32 1, i32* %retval
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
if.else: ; preds = %entry
|
||||||
|
call void @foo()
|
||||||
|
br label %if.end
|
||||||
|
|
||||||
|
if.end: ; preds = %if.else
|
||||||
|
store i32 0, i32* %retval
|
||||||
|
br label %return
|
||||||
|
|
||||||
|
return: ; preds = %if.end, %if.then
|
||||||
|
%3 = load i32* %retval
|
||||||
|
ret i32 %3
|
||||||
|
|
||||||
|
; CHECK: @main2
|
||||||
|
|
||||||
|
; CHECK: addis [[REG:[0-9]+]], 2, env_sigill@toc@ha
|
||||||
|
; CHECK: std 31, env_sigill@toc@l([[REG]])
|
||||||
|
; CHECK: addi [[REG]], [[REG]], env_sigill@toc@l
|
||||||
|
; CHECK: std [[REG]], [[OFF:[0-9]+]](31) # 8-byte Folded Spill
|
||||||
|
; CHECK: std 1, 16([[REG]])
|
||||||
|
; CHECK: std 2, 24([[REG]])
|
||||||
|
; CHECK: std 30, 32([[REG]])
|
||||||
|
; CHECK: bcl 20, 31,
|
||||||
|
|
||||||
|
; CHECK: blr
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @bar(i8*) #3
|
||||||
|
|
||||||
declare i8* @llvm.frameaddress(i32) #2
|
declare i8* @llvm.frameaddress(i32) #2
|
||||||
|
|
||||||
declare i8* @llvm.stacksave() #3
|
declare i8* @llvm.stacksave() #3
|
||||||
|
@ -26,20 +26,20 @@ entry:
|
|||||||
|
|
||||||
; CHECK-DAG: mflr 0
|
; CHECK-DAG: mflr 0
|
||||||
; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59
|
; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59
|
||||||
; CHECK-DAG: std 31, -8(1)
|
; CHECK-DAG: std 30, -16(1)
|
||||||
; CHECK-DAG: mr 31, 1
|
; CHECK-DAG: mr 30, 1
|
||||||
; CHECK-DAG: std 0, 16(1)
|
; CHECK-DAG: std 0, 16(1)
|
||||||
; CHECK-DAG: subfic 0, [[REG]], -160
|
; CHECK-DAG: subfic 0, [[REG]], -160
|
||||||
; CHECK: stdux 1, 1, 0
|
; CHECK: stdux 1, 1, 0
|
||||||
|
|
||||||
; CHECK: .cfi_offset r31, -8
|
; CHECK: .cfi_offset r30, -16
|
||||||
; CHECK: .cfi_offset lr, 16
|
; CHECK: .cfi_offset lr, 16
|
||||||
|
|
||||||
; CHECK: std 3, 48(31)
|
; CHECK: std 3, 48(30)
|
||||||
|
|
||||||
; CHECK: ld 1, 0(1)
|
; CHECK: ld 1, 0(1)
|
||||||
; CHECK-DAG: ld 0, 16(1)
|
; CHECK-DAG: ld 0, 16(1)
|
||||||
; CHECK-DAG: ld 31, -8(1)
|
; CHECK-DAG: ld 30, -16(1)
|
||||||
; CHECK-DAG: mtlr 0
|
; CHECK-DAG: mtlr 0
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
|
|
||||||
@ -91,8 +91,8 @@ entry:
|
|||||||
; CHECK-DAG: rldicl [[REG3:[0-9]+]], 1, 0, 59
|
; CHECK-DAG: rldicl [[REG3:[0-9]+]], 1, 0, 59
|
||||||
; CHECK-DAG: mflr 0
|
; CHECK-DAG: mflr 0
|
||||||
; CHECK-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51808
|
; CHECK-DAG: ori [[REG2:[0-9]+]], [[REG1]], 51808
|
||||||
; CHECK-DAG: std 31, -8(1)
|
; CHECK-DAG: std 30, -16(1)
|
||||||
; CHECK-DAG: mr 31, 1
|
; CHECK-DAG: mr 30, 1
|
||||||
; CHECK-DAG: std 0, 16(1)
|
; CHECK-DAG: std 0, 16(1)
|
||||||
; CHECK-DAG: subfc 0, [[REG3]], [[REG2]]
|
; CHECK-DAG: subfc 0, [[REG3]], [[REG2]]
|
||||||
; CHECK: stdux 1, 1, 0
|
; CHECK: stdux 1, 1, 0
|
||||||
@ -121,13 +121,13 @@ entry:
|
|||||||
|
|
||||||
; CHECK-DAG: mflr 0
|
; CHECK-DAG: mflr 0
|
||||||
; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59
|
; CHECK-DAG: rldicl [[REG:[0-9]+]], 1, 0, 59
|
||||||
; CHECK-DAG: std 31, -24(1)
|
; CHECK-DAG: std 30, -32(1)
|
||||||
; CHECK-DAG: mr 31, 1
|
; CHECK-DAG: mr 30, 1
|
||||||
; CHECK-DAG: std 0, 16(1)
|
; CHECK-DAG: std 0, 16(1)
|
||||||
; CHECK-DAG: subfic 0, [[REG]], -160
|
; CHECK-DAG: subfic 0, [[REG]], -192
|
||||||
; CHECK: stdux 1, 1, 0
|
; CHECK: stdux 1, 1, 0
|
||||||
|
|
||||||
; CHECK: stfd 30, -16(31)
|
; CHECK: stfd 30, -16(30)
|
||||||
|
|
||||||
; CHECK: blr
|
; CHECK: blr
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user