mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[VE] Support SJLJ exception related instructions
Support EH_SJLJ_LONGJMP, EH_SJLJ_SETJMP, and EH_SJLJ_SETUP_DISPATCH for SjLj exception handling. NC++ uses SjLj exception handling, so implement it first. Add regression tests also. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D94071
This commit is contained in:
parent
c5a8d5ee85
commit
b4ca317c5c
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "VEISelLowering.h"
|
#include "VEISelLowering.h"
|
||||||
#include "MCTargetDesc/VEMCExpr.h"
|
#include "MCTargetDesc/VEMCExpr.h"
|
||||||
|
#include "VEInstrBuilder.h"
|
||||||
#include "VEMachineFunctionInfo.h"
|
#include "VEMachineFunctionInfo.h"
|
||||||
#include "VERegisterInfo.h"
|
#include "VERegisterInfo.h"
|
||||||
#include "VETargetMachine.h"
|
#include "VETargetMachine.h"
|
||||||
@ -276,6 +277,14 @@ void VETargetLowering::initSPUActions() {
|
|||||||
|
|
||||||
/// } Atomic instructions
|
/// } Atomic instructions
|
||||||
|
|
||||||
|
/// SJLJ instructions {
|
||||||
|
setOperationAction(ISD::EH_SJLJ_LONGJMP, MVT::Other, Custom);
|
||||||
|
setOperationAction(ISD::EH_SJLJ_SETJMP, MVT::i32, Custom);
|
||||||
|
setOperationAction(ISD::EH_SJLJ_SETUP_DISPATCH, MVT::Other, Custom);
|
||||||
|
if (TM.Options.ExceptionModel == ExceptionHandling::SjLj)
|
||||||
|
setLibcallName(RTLIB::UNWIND_RESUME, "_Unwind_SjLj_Resume");
|
||||||
|
/// } SJLJ instructions
|
||||||
|
|
||||||
// Intrinsic instructions
|
// Intrinsic instructions
|
||||||
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
|
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
|
||||||
}
|
}
|
||||||
@ -864,6 +873,9 @@ const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case VEISD::FIRST_NUMBER:
|
case VEISD::FIRST_NUMBER:
|
||||||
break;
|
break;
|
||||||
TARGET_NODE_CASE(CALL)
|
TARGET_NODE_CASE(CALL)
|
||||||
|
TARGET_NODE_CASE(EH_SJLJ_LONGJMP)
|
||||||
|
TARGET_NODE_CASE(EH_SJLJ_SETJMP)
|
||||||
|
TARGET_NODE_CASE(EH_SJLJ_SETUP_DISPATCH)
|
||||||
TARGET_NODE_CASE(GETFUNPLT)
|
TARGET_NODE_CASE(GETFUNPLT)
|
||||||
TARGET_NODE_CASE(GETSTACKTOP)
|
TARGET_NODE_CASE(GETSTACKTOP)
|
||||||
TARGET_NODE_CASE(GETTLSADDR)
|
TARGET_NODE_CASE(GETTLSADDR)
|
||||||
@ -1487,6 +1499,28 @@ SDValue VETargetLowering::lowerDYNAMIC_STACKALLOC(SDValue Op,
|
|||||||
return DAG.getMergeValues(Ops, DL);
|
return DAG.getMergeValues(Ops, DL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDValue VETargetLowering::lowerEH_SJLJ_LONGJMP(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
SDLoc DL(Op);
|
||||||
|
return DAG.getNode(VEISD::EH_SJLJ_LONGJMP, DL, MVT::Other, Op.getOperand(0),
|
||||||
|
Op.getOperand(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue VETargetLowering::lowerEH_SJLJ_SETJMP(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
SDLoc DL(Op);
|
||||||
|
return DAG.getNode(VEISD::EH_SJLJ_SETJMP, DL,
|
||||||
|
DAG.getVTList(MVT::i32, MVT::Other), Op.getOperand(0),
|
||||||
|
Op.getOperand(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue VETargetLowering::lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op,
|
||||||
|
SelectionDAG &DAG) const {
|
||||||
|
SDLoc DL(Op);
|
||||||
|
return DAG.getNode(VEISD::EH_SJLJ_SETUP_DISPATCH, DL, MVT::Other,
|
||||||
|
Op.getOperand(0));
|
||||||
|
}
|
||||||
|
|
||||||
static SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
|
static SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG,
|
||||||
const VETargetLowering &TLI,
|
const VETargetLowering &TLI,
|
||||||
const VESubtarget *Subtarget) {
|
const VESubtarget *Subtarget) {
|
||||||
@ -1599,6 +1633,12 @@ SDValue VETargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|||||||
return lowerConstantPool(Op, DAG);
|
return lowerConstantPool(Op, DAG);
|
||||||
case ISD::DYNAMIC_STACKALLOC:
|
case ISD::DYNAMIC_STACKALLOC:
|
||||||
return lowerDYNAMIC_STACKALLOC(Op, DAG);
|
return lowerDYNAMIC_STACKALLOC(Op, DAG);
|
||||||
|
case ISD::EH_SJLJ_LONGJMP:
|
||||||
|
return lowerEH_SJLJ_LONGJMP(Op, DAG);
|
||||||
|
case ISD::EH_SJLJ_SETJMP:
|
||||||
|
return lowerEH_SJLJ_SETJMP(Op, DAG);
|
||||||
|
case ISD::EH_SJLJ_SETUP_DISPATCH:
|
||||||
|
return lowerEH_SJLJ_SETUP_DISPATCH(Op, DAG);
|
||||||
case ISD::FRAMEADDR:
|
case ISD::FRAMEADDR:
|
||||||
return lowerFRAMEADDR(Op, DAG, *this, Subtarget);
|
return lowerFRAMEADDR(Op, DAG, *this, Subtarget);
|
||||||
case ISD::GlobalAddress:
|
case ISD::GlobalAddress:
|
||||||
@ -1699,6 +1739,677 @@ SDValue VETargetLowering::getPICJumpTableRelocBase(SDValue Table,
|
|||||||
return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
|
return DAG.getNode(ISD::ADD, DL, PtrTy, GlobalBase, HiLo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Register VETargetLowering::prepareMBB(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator I,
|
||||||
|
MachineBasicBlock *TargetBB,
|
||||||
|
const DebugLoc &DL) const {
|
||||||
|
MachineFunction *MF = MBB.getParent();
|
||||||
|
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
const VEInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
|
||||||
|
const TargetRegisterClass *RC = &VE::I64RegClass;
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp2 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Result = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
if (isPositionIndependent()) {
|
||||||
|
// Create following instructions for local linkage PIC code.
|
||||||
|
// lea %Tmp1, TargetBB@gotoff_lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %Result, TargetBB@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addMBB(TargetBB, VEMCExpr::VK_VE_GOTOFF_LO32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
|
||||||
|
.addReg(VE::SX15)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addMBB(TargetBB, VEMCExpr::VK_VE_GOTOFF_HI32);
|
||||||
|
} else {
|
||||||
|
// Create following instructions for non-PIC code.
|
||||||
|
// lea %Tmp1, TargetBB@lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %Result, TargetBB@hi(%Tmp2)
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addMBB(TargetBB, VEMCExpr::VK_VE_LO32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addImm(0)
|
||||||
|
.addMBB(TargetBB, VEMCExpr::VK_VE_HI32);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Register VETargetLowering::prepareSymbol(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator I,
|
||||||
|
StringRef Symbol, const DebugLoc &DL,
|
||||||
|
bool IsLocal = false,
|
||||||
|
bool IsCall = false) const {
|
||||||
|
MachineFunction *MF = MBB.getParent();
|
||||||
|
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
const VEInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
|
||||||
|
const TargetRegisterClass *RC = &VE::I64RegClass;
|
||||||
|
Register Result = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
if (isPositionIndependent()) {
|
||||||
|
if (IsCall && !IsLocal) {
|
||||||
|
// Create following instructions for non-local linkage PIC code function
|
||||||
|
// calls. These instructions uses IC and magic number -24, so we expand
|
||||||
|
// them in VEAsmPrinter.cpp from GETFUNPLT pseudo instruction.
|
||||||
|
// lea %Reg, Symbol@plt_lo(-24)
|
||||||
|
// and %Reg, %Reg, (32)0
|
||||||
|
// sic %s16
|
||||||
|
// lea.sl %Result, Symbol@plt_hi(%Reg, %s16) ; %s16 is PLT
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::GETFUNPLT), Result)
|
||||||
|
.addExternalSymbol("abort");
|
||||||
|
} else if (IsLocal) {
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp2 = MRI.createVirtualRegister(RC);
|
||||||
|
// Create following instructions for local linkage PIC code.
|
||||||
|
// lea %Tmp1, Symbol@gotoff_lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %Result, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_GOTOFF_LO32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Result)
|
||||||
|
.addReg(VE::SX15)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_GOTOFF_HI32);
|
||||||
|
} else {
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp2 = MRI.createVirtualRegister(RC);
|
||||||
|
// Create following instructions for not local linkage PIC code.
|
||||||
|
// lea %Tmp1, Symbol@got_lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %Tmp3, Symbol@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
|
||||||
|
// ld %Result, 0(%Tmp3)
|
||||||
|
Register Tmp3 = MRI.createVirtualRegister(RC);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_GOT_LO32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEASLrri), Tmp3)
|
||||||
|
.addReg(VE::SX15)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_GOT_HI32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LDrii), Result)
|
||||||
|
.addReg(Tmp3, getKillRegState(true))
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp2 = MRI.createVirtualRegister(RC);
|
||||||
|
// Create following instructions for non-PIC code.
|
||||||
|
// lea %Tmp1, Symbol@lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %Result, Symbol@hi(%Tmp2)
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_LO32);
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(MBB, I, DL, TII->get(VE::LEASLrii), Result)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addImm(0)
|
||||||
|
.addExternalSymbol(Symbol.data(), VEMCExpr::VK_VE_HI32);
|
||||||
|
}
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VETargetLowering::setupEntryBlockForSjLj(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB,
|
||||||
|
MachineBasicBlock *DispatchBB,
|
||||||
|
int FI, int Offset) const {
|
||||||
|
DebugLoc DL = MI.getDebugLoc();
|
||||||
|
const VEInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
|
||||||
|
Register LabelReg =
|
||||||
|
prepareMBB(*MBB, MachineBasicBlock::iterator(MI), DispatchBB, DL);
|
||||||
|
|
||||||
|
// Store an address of DispatchBB to a given jmpbuf[1] where has next IC
|
||||||
|
// referenced by longjmp (throw) later.
|
||||||
|
MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
|
||||||
|
addFrameReference(MIB, FI, Offset); // jmpbuf[1]
|
||||||
|
MIB.addReg(LabelReg, getKillRegState(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *
|
||||||
|
VETargetLowering::emitEHSjLjSetJmp(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB) const {
|
||||||
|
DebugLoc DL = MI.getDebugLoc();
|
||||||
|
MachineFunction *MF = MBB->getParent();
|
||||||
|
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
|
||||||
|
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
|
||||||
|
const BasicBlock *BB = MBB->getBasicBlock();
|
||||||
|
MachineFunction::iterator I = ++MBB->getIterator();
|
||||||
|
|
||||||
|
// Memory Reference.
|
||||||
|
SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
|
||||||
|
MI.memoperands_end());
|
||||||
|
Register BufReg = MI.getOperand(1).getReg();
|
||||||
|
|
||||||
|
Register DstReg;
|
||||||
|
|
||||||
|
DstReg = MI.getOperand(0).getReg();
|
||||||
|
const TargetRegisterClass *RC = MRI.getRegClass(DstReg);
|
||||||
|
assert(TRI->isTypeLegalForClass(*RC, MVT::i32) && "Invalid destination!");
|
||||||
|
(void)TRI;
|
||||||
|
Register MainDestReg = MRI.createVirtualRegister(RC);
|
||||||
|
Register RestoreDestReg = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
// For `v = call @llvm.eh.sjlj.setjmp(buf)`, we generate following
|
||||||
|
// instructions. SP/FP must be saved in jmpbuf before `llvm.eh.sjlj.setjmp`.
|
||||||
|
//
|
||||||
|
// ThisMBB:
|
||||||
|
// buf[3] = %s17 iff %s17 is used as BP
|
||||||
|
// buf[1] = RestoreMBB as IC after longjmp
|
||||||
|
// # SjLjSetup RestoreMBB
|
||||||
|
//
|
||||||
|
// MainMBB:
|
||||||
|
// v_main = 0
|
||||||
|
//
|
||||||
|
// SinkMBB:
|
||||||
|
// v = phi(v_main, MainMBB, v_restore, RestoreMBB)
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// RestoreMBB:
|
||||||
|
// %s17 = buf[3] = iff %s17 is used as BP
|
||||||
|
// v_restore = 1
|
||||||
|
// goto SinkMBB
|
||||||
|
|
||||||
|
MachineBasicBlock *ThisMBB = MBB;
|
||||||
|
MachineBasicBlock *MainMBB = MF->CreateMachineBasicBlock(BB);
|
||||||
|
MachineBasicBlock *SinkMBB = MF->CreateMachineBasicBlock(BB);
|
||||||
|
MachineBasicBlock *RestoreMBB = MF->CreateMachineBasicBlock(BB);
|
||||||
|
MF->insert(I, MainMBB);
|
||||||
|
MF->insert(I, SinkMBB);
|
||||||
|
MF->push_back(RestoreMBB);
|
||||||
|
RestoreMBB->setHasAddressTaken();
|
||||||
|
|
||||||
|
// Transfer the remainder of BB and its successor edges to SinkMBB.
|
||||||
|
SinkMBB->splice(SinkMBB->begin(), MBB,
|
||||||
|
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
|
||||||
|
SinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
|
||||||
|
|
||||||
|
// ThisMBB:
|
||||||
|
Register LabelReg =
|
||||||
|
prepareMBB(*MBB, MachineBasicBlock::iterator(MI), RestoreMBB, DL);
|
||||||
|
|
||||||
|
// Store BP in buf[3] iff this function is using BP.
|
||||||
|
const VEFrameLowering *TFI = Subtarget->getFrameLowering();
|
||||||
|
if (TFI->hasBP(*MF)) {
|
||||||
|
MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
|
||||||
|
MIB.addReg(BufReg);
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(24);
|
||||||
|
MIB.addReg(VE::SX17);
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store IP in buf[1].
|
||||||
|
MachineInstrBuilder MIB = BuildMI(*MBB, MI, DL, TII->get(VE::STrii));
|
||||||
|
MIB.add(MI.getOperand(1)); // we can preserve the kill flags here.
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(8);
|
||||||
|
MIB.addReg(LabelReg, getKillRegState(true));
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
|
||||||
|
// SP/FP are already stored in jmpbuf before `llvm.eh.sjlj.setjmp`.
|
||||||
|
|
||||||
|
// Insert setup.
|
||||||
|
MIB =
|
||||||
|
BuildMI(*ThisMBB, MI, DL, TII->get(VE::EH_SjLj_Setup)).addMBB(RestoreMBB);
|
||||||
|
|
||||||
|
const VERegisterInfo *RegInfo = Subtarget->getRegisterInfo();
|
||||||
|
MIB.addRegMask(RegInfo->getNoPreservedMask());
|
||||||
|
ThisMBB->addSuccessor(MainMBB);
|
||||||
|
ThisMBB->addSuccessor(RestoreMBB);
|
||||||
|
|
||||||
|
// MainMBB:
|
||||||
|
BuildMI(MainMBB, DL, TII->get(VE::LEAzii), MainDestReg)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0);
|
||||||
|
MainMBB->addSuccessor(SinkMBB);
|
||||||
|
|
||||||
|
// SinkMBB:
|
||||||
|
BuildMI(*SinkMBB, SinkMBB->begin(), DL, TII->get(VE::PHI), DstReg)
|
||||||
|
.addReg(MainDestReg)
|
||||||
|
.addMBB(MainMBB)
|
||||||
|
.addReg(RestoreDestReg)
|
||||||
|
.addMBB(RestoreMBB);
|
||||||
|
|
||||||
|
// RestoreMBB:
|
||||||
|
// Restore BP from buf[3] iff this function is using BP. The address of
|
||||||
|
// buf is in SX10.
|
||||||
|
// FIXME: Better to not use SX10 here
|
||||||
|
if (TFI->hasBP(*MF)) {
|
||||||
|
MachineInstrBuilder MIB =
|
||||||
|
BuildMI(RestoreMBB, DL, TII->get(VE::LDrii), VE::SX17);
|
||||||
|
MIB.addReg(VE::SX10);
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(24);
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
}
|
||||||
|
BuildMI(RestoreMBB, DL, TII->get(VE::LEAzii), RestoreDestReg)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(1);
|
||||||
|
BuildMI(RestoreMBB, DL, TII->get(VE::BRCFLa_t)).addMBB(SinkMBB);
|
||||||
|
RestoreMBB->addSuccessor(SinkMBB);
|
||||||
|
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return SinkMBB;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *
|
||||||
|
VETargetLowering::emitEHSjLjLongJmp(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB) const {
|
||||||
|
DebugLoc DL = MI.getDebugLoc();
|
||||||
|
MachineFunction *MF = MBB->getParent();
|
||||||
|
const TargetInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
|
||||||
|
// Memory Reference.
|
||||||
|
SmallVector<MachineMemOperand *, 2> MMOs(MI.memoperands_begin(),
|
||||||
|
MI.memoperands_end());
|
||||||
|
Register BufReg = MI.getOperand(0).getReg();
|
||||||
|
|
||||||
|
Register Tmp = MRI.createVirtualRegister(&VE::I64RegClass);
|
||||||
|
// Since FP is only updated here but NOT referenced, it's treated as GPR.
|
||||||
|
Register FP = VE::SX9;
|
||||||
|
Register SP = VE::SX11;
|
||||||
|
|
||||||
|
MachineInstrBuilder MIB;
|
||||||
|
|
||||||
|
MachineBasicBlock *ThisMBB = MBB;
|
||||||
|
|
||||||
|
// For `call @llvm.eh.sjlj.longjmp(buf)`, we generate following instructions.
|
||||||
|
//
|
||||||
|
// ThisMBB:
|
||||||
|
// %fp = load buf[0]
|
||||||
|
// %jmp = load buf[1]
|
||||||
|
// %s10 = buf ; Store an address of buf to SX10 for RestoreMBB
|
||||||
|
// %sp = load buf[2] ; generated by llvm.eh.sjlj.setjmp.
|
||||||
|
// jmp %jmp
|
||||||
|
|
||||||
|
// Reload FP.
|
||||||
|
MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), FP);
|
||||||
|
MIB.addReg(BufReg);
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
|
||||||
|
// Reload IP.
|
||||||
|
MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), Tmp);
|
||||||
|
MIB.addReg(BufReg);
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(8);
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
|
||||||
|
// Copy BufReg to SX10 for later use in setjmp.
|
||||||
|
// FIXME: Better to not use SX10 here
|
||||||
|
BuildMI(*ThisMBB, MI, DL, TII->get(VE::ORri), VE::SX10)
|
||||||
|
.addReg(BufReg)
|
||||||
|
.addImm(0);
|
||||||
|
|
||||||
|
// Reload SP.
|
||||||
|
MIB = BuildMI(*ThisMBB, MI, DL, TII->get(VE::LDrii), SP);
|
||||||
|
MIB.add(MI.getOperand(0)); // we can preserve the kill flags here.
|
||||||
|
MIB.addImm(0);
|
||||||
|
MIB.addImm(16);
|
||||||
|
MIB.setMemRefs(MMOs);
|
||||||
|
|
||||||
|
// Jump.
|
||||||
|
BuildMI(*ThisMBB, MI, DL, TII->get(VE::BCFLari_t))
|
||||||
|
.addReg(Tmp, getKillRegState(true))
|
||||||
|
.addImm(0);
|
||||||
|
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return ThisMBB;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *
|
||||||
|
VETargetLowering::emitSjLjDispatchBlock(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *BB) const {
|
||||||
|
DebugLoc DL = MI.getDebugLoc();
|
||||||
|
MachineFunction *MF = BB->getParent();
|
||||||
|
MachineFrameInfo &MFI = MF->getFrameInfo();
|
||||||
|
MachineRegisterInfo &MRI = MF->getRegInfo();
|
||||||
|
const VEInstrInfo *TII = Subtarget->getInstrInfo();
|
||||||
|
int FI = MFI.getFunctionContextIndex();
|
||||||
|
|
||||||
|
// Get a mapping of the call site numbers to all of the landing pads they're
|
||||||
|
// associated with.
|
||||||
|
DenseMap<unsigned, SmallVector<MachineBasicBlock *, 2>> CallSiteNumToLPad;
|
||||||
|
unsigned MaxCSNum = 0;
|
||||||
|
for (auto &MBB : *MF) {
|
||||||
|
if (!MBB.isEHPad())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MCSymbol *Sym = nullptr;
|
||||||
|
for (const auto &MI : MBB) {
|
||||||
|
if (MI.isDebugInstr())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(MI.isEHLabel() && "expected EH_LABEL");
|
||||||
|
Sym = MI.getOperand(0).getMCSymbol();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!MF->hasCallSiteLandingPad(Sym))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (unsigned CSI : MF->getCallSiteLandingPad(Sym)) {
|
||||||
|
CallSiteNumToLPad[CSI].push_back(&MBB);
|
||||||
|
MaxCSNum = std::max(MaxCSNum, CSI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get an ordered list of the machine basic blocks for the jump table.
|
||||||
|
std::vector<MachineBasicBlock *> LPadList;
|
||||||
|
SmallPtrSet<MachineBasicBlock *, 32> InvokeBBs;
|
||||||
|
LPadList.reserve(CallSiteNumToLPad.size());
|
||||||
|
|
||||||
|
for (unsigned CSI = 1; CSI <= MaxCSNum; ++CSI) {
|
||||||
|
for (auto &LP : CallSiteNumToLPad[CSI]) {
|
||||||
|
LPadList.push_back(LP);
|
||||||
|
InvokeBBs.insert(LP->pred_begin(), LP->pred_end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!LPadList.empty() &&
|
||||||
|
"No landing pad destinations for the dispatch jump table!");
|
||||||
|
|
||||||
|
// The %fn_context is allocated like below (from --print-after=sjljehprepare):
|
||||||
|
// %fn_context = alloca { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }
|
||||||
|
//
|
||||||
|
// This `[5 x i8*]` is jmpbuf, so jmpbuf[1] is FI+72.
|
||||||
|
// First `i64` is callsite, so callsite is FI+8.
|
||||||
|
static const int OffsetIC = 72;
|
||||||
|
static const int OffsetCS = 8;
|
||||||
|
|
||||||
|
// Create the MBBs for the dispatch code like following:
|
||||||
|
//
|
||||||
|
// ThisMBB:
|
||||||
|
// Prepare DispatchBB address and store it to buf[1].
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// DispatchBB:
|
||||||
|
// %s15 = GETGOT iff isPositionIndependent
|
||||||
|
// %callsite = load callsite
|
||||||
|
// brgt.l.t #size of callsites, %callsite, DispContBB
|
||||||
|
//
|
||||||
|
// TrapBB:
|
||||||
|
// Call abort.
|
||||||
|
//
|
||||||
|
// DispContBB:
|
||||||
|
// %breg = address of jump table
|
||||||
|
// %pc = load and calculate next pc from %breg and %callsite
|
||||||
|
// jmp %pc
|
||||||
|
|
||||||
|
// Shove the dispatch's address into the return slot in the function context.
|
||||||
|
MachineBasicBlock *DispatchBB = MF->CreateMachineBasicBlock();
|
||||||
|
DispatchBB->setIsEHPad(true);
|
||||||
|
|
||||||
|
// Trap BB will causes trap like `assert(0)`.
|
||||||
|
MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
|
||||||
|
DispatchBB->addSuccessor(TrapBB);
|
||||||
|
|
||||||
|
MachineBasicBlock *DispContBB = MF->CreateMachineBasicBlock();
|
||||||
|
DispatchBB->addSuccessor(DispContBB);
|
||||||
|
|
||||||
|
// Insert MBBs.
|
||||||
|
MF->push_back(DispatchBB);
|
||||||
|
MF->push_back(DispContBB);
|
||||||
|
MF->push_back(TrapBB);
|
||||||
|
|
||||||
|
// Insert code to call abort in the TrapBB.
|
||||||
|
Register Abort = prepareSymbol(*TrapBB, TrapBB->end(), "abort", DL,
|
||||||
|
/* Local */ false, /* Call */ true);
|
||||||
|
BuildMI(TrapBB, DL, TII->get(VE::BSICrii), VE::SX10)
|
||||||
|
.addReg(Abort, getKillRegState(true))
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0);
|
||||||
|
|
||||||
|
// Insert code into the entry block that creates and registers the function
|
||||||
|
// context.
|
||||||
|
setupEntryBlockForSjLj(MI, BB, DispatchBB, FI, OffsetIC);
|
||||||
|
|
||||||
|
// Create the jump table and associated information
|
||||||
|
unsigned JTE = getJumpTableEncoding();
|
||||||
|
MachineJumpTableInfo *JTI = MF->getOrCreateJumpTableInfo(JTE);
|
||||||
|
unsigned MJTI = JTI->createJumpTableIndex(LPadList);
|
||||||
|
|
||||||
|
const VERegisterInfo &RI = TII->getRegisterInfo();
|
||||||
|
// Add a register mask with no preserved registers. This results in all
|
||||||
|
// registers being marked as clobbered.
|
||||||
|
BuildMI(DispatchBB, DL, TII->get(VE::NOP))
|
||||||
|
.addRegMask(RI.getNoPreservedMask());
|
||||||
|
|
||||||
|
if (isPositionIndependent()) {
|
||||||
|
// Force to generate GETGOT, since current implementation doesn't store GOT
|
||||||
|
// register.
|
||||||
|
BuildMI(DispatchBB, DL, TII->get(VE::GETGOT), VE::SX15);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IReg is used as an index in a memory operand and therefore can't be SP
|
||||||
|
const TargetRegisterClass *RC = &VE::I64RegClass;
|
||||||
|
Register IReg = MRI.createVirtualRegister(RC);
|
||||||
|
addFrameReference(BuildMI(DispatchBB, DL, TII->get(VE::LDLZXrii), IReg), FI,
|
||||||
|
OffsetCS);
|
||||||
|
if (LPadList.size() < 64) {
|
||||||
|
BuildMI(DispatchBB, DL, TII->get(VE::BRCFLir_t))
|
||||||
|
.addImm(VECC::CC_ILE)
|
||||||
|
.addImm(LPadList.size())
|
||||||
|
.addReg(IReg)
|
||||||
|
.addMBB(TrapBB);
|
||||||
|
} else {
|
||||||
|
assert(LPadList.size() <= 0x7FFFFFFF && "Too large Landing Pad!");
|
||||||
|
Register TmpReg = MRI.createVirtualRegister(RC);
|
||||||
|
BuildMI(DispatchBB, DL, TII->get(VE::LEAzii), TmpReg)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(LPadList.size());
|
||||||
|
BuildMI(DispatchBB, DL, TII->get(VE::BRCFLrr_t))
|
||||||
|
.addImm(VECC::CC_ILE)
|
||||||
|
.addReg(TmpReg, getKillRegState(true))
|
||||||
|
.addReg(IReg)
|
||||||
|
.addMBB(TrapBB);
|
||||||
|
}
|
||||||
|
|
||||||
|
Register BReg = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp2 = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
if (isPositionIndependent()) {
|
||||||
|
// Create following instructions for local linkage PIC code.
|
||||||
|
// lea %Tmp1, .LJTI0_0@gotoff_lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %BReg, .LJTI0_0@gotoff_hi(%Tmp2, %s15) ; %s15 is GOT
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addJumpTableIndex(MJTI, VEMCExpr::VK_VE_GOTOFF_LO32);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LEASLrri), BReg)
|
||||||
|
.addReg(VE::SX15)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addJumpTableIndex(MJTI, VEMCExpr::VK_VE_GOTOFF_HI32);
|
||||||
|
} else {
|
||||||
|
// Create following instructions for non-PIC code.
|
||||||
|
// lea %Tmp1, .LJTI0_0@lo
|
||||||
|
// and %Tmp2, %Tmp1, (32)0
|
||||||
|
// lea.sl %BReg, .LJTI0_0@hi(%Tmp2)
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LEAzii), Tmp1)
|
||||||
|
.addImm(0)
|
||||||
|
.addImm(0)
|
||||||
|
.addJumpTableIndex(MJTI, VEMCExpr::VK_VE_LO32);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::ANDrm), Tmp2)
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(M0(32));
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LEASLrii), BReg)
|
||||||
|
.addReg(Tmp2, getKillRegState(true))
|
||||||
|
.addImm(0)
|
||||||
|
.addJumpTableIndex(MJTI, VEMCExpr::VK_VE_HI32);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (JTE) {
|
||||||
|
case MachineJumpTableInfo::EK_BlockAddress: {
|
||||||
|
// Generate simple block address code for no-PIC model.
|
||||||
|
// sll %Tmp1, %IReg, 3
|
||||||
|
// lds %TReg, 0(%Tmp1, %BReg)
|
||||||
|
// bcfla %TReg
|
||||||
|
|
||||||
|
Register TReg = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
|
||||||
|
.addReg(IReg, getKillRegState(true))
|
||||||
|
.addImm(3);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LDrri), TReg)
|
||||||
|
.addReg(BReg, getKillRegState(true))
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(0);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
|
||||||
|
.addReg(TReg, getKillRegState(true))
|
||||||
|
.addImm(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MachineJumpTableInfo::EK_Custom32: {
|
||||||
|
// Generate block address code using differences from the function pointer
|
||||||
|
// for PIC model.
|
||||||
|
// sll %Tmp1, %IReg, 2
|
||||||
|
// ldl.zx %OReg, 0(%Tmp1, %BReg)
|
||||||
|
// Prepare function address in BReg2.
|
||||||
|
// adds.l %TReg, %BReg2, %OReg
|
||||||
|
// bcfla %TReg
|
||||||
|
|
||||||
|
assert(isPositionIndependent());
|
||||||
|
Register OReg = MRI.createVirtualRegister(RC);
|
||||||
|
Register TReg = MRI.createVirtualRegister(RC);
|
||||||
|
Register Tmp1 = MRI.createVirtualRegister(RC);
|
||||||
|
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::SLLri), Tmp1)
|
||||||
|
.addReg(IReg, getKillRegState(true))
|
||||||
|
.addImm(2);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::LDLZXrri), OReg)
|
||||||
|
.addReg(BReg, getKillRegState(true))
|
||||||
|
.addReg(Tmp1, getKillRegState(true))
|
||||||
|
.addImm(0);
|
||||||
|
Register BReg2 =
|
||||||
|
prepareSymbol(*DispContBB, DispContBB->end(),
|
||||||
|
DispContBB->getParent()->getName(), DL, /* Local */ true);
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::ADDSLrr), TReg)
|
||||||
|
.addReg(OReg, getKillRegState(true))
|
||||||
|
.addReg(BReg2, getKillRegState(true));
|
||||||
|
BuildMI(DispContBB, DL, TII->get(VE::BCFLari_t))
|
||||||
|
.addReg(TReg, getKillRegState(true))
|
||||||
|
.addImm(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unexpected jump table encoding");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the jump table entries as successors to the MBB.
|
||||||
|
SmallPtrSet<MachineBasicBlock *, 8> SeenMBBs;
|
||||||
|
for (auto &LP : LPadList)
|
||||||
|
if (SeenMBBs.insert(LP).second)
|
||||||
|
DispContBB->addSuccessor(LP);
|
||||||
|
|
||||||
|
// N.B. the order the invoke BBs are processed in doesn't matter here.
|
||||||
|
SmallVector<MachineBasicBlock *, 64> MBBLPads;
|
||||||
|
const MCPhysReg *SavedRegs = MF->getRegInfo().getCalleeSavedRegs();
|
||||||
|
for (MachineBasicBlock *MBB : InvokeBBs) {
|
||||||
|
// Remove the landing pad successor from the invoke block and replace it
|
||||||
|
// with the new dispatch block.
|
||||||
|
// Keep a copy of Successors since it's modified inside the loop.
|
||||||
|
SmallVector<MachineBasicBlock *, 8> Successors(MBB->succ_rbegin(),
|
||||||
|
MBB->succ_rend());
|
||||||
|
// FIXME: Avoid quadratic complexity.
|
||||||
|
for (auto MBBS : Successors) {
|
||||||
|
if (MBBS->isEHPad()) {
|
||||||
|
MBB->removeSuccessor(MBBS);
|
||||||
|
MBBLPads.push_back(MBBS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MBB->addSuccessor(DispatchBB);
|
||||||
|
|
||||||
|
// Find the invoke call and mark all of the callee-saved registers as
|
||||||
|
// 'implicit defined' so that they're spilled. This prevents code from
|
||||||
|
// moving instructions to before the EH block, where they will never be
|
||||||
|
// executed.
|
||||||
|
for (auto &II : reverse(*MBB)) {
|
||||||
|
if (!II.isCall())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DenseMap<Register, bool> DefRegs;
|
||||||
|
for (auto &MOp : II.operands())
|
||||||
|
if (MOp.isReg())
|
||||||
|
DefRegs[MOp.getReg()] = true;
|
||||||
|
|
||||||
|
MachineInstrBuilder MIB(*MF, &II);
|
||||||
|
for (unsigned RI = 0; SavedRegs[RI]; ++RI) {
|
||||||
|
Register Reg = SavedRegs[RI];
|
||||||
|
if (!DefRegs[Reg])
|
||||||
|
MIB.addReg(Reg, RegState::ImplicitDefine | RegState::Dead);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark all former landing pads as non-landing pads. The dispatch is the only
|
||||||
|
// landing pad now.
|
||||||
|
for (auto &LP : MBBLPads)
|
||||||
|
LP->setIsEHPad(false);
|
||||||
|
|
||||||
|
// The instruction is gone now.
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return BB;
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineBasicBlock *
|
||||||
|
VETargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *BB) const {
|
||||||
|
switch (MI.getOpcode()) {
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unknown Custom Instruction!");
|
||||||
|
case VE::EH_SjLj_LongJmp:
|
||||||
|
return emitEHSjLjLongJmp(MI, BB);
|
||||||
|
case VE::EH_SjLj_SetJmp:
|
||||||
|
return emitEHSjLjSetJmp(MI, BB);
|
||||||
|
case VE::EH_SjLj_Setup_Dispatch:
|
||||||
|
return emitSjLjDispatchBlock(MI, BB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool isI32Insn(const SDNode *User, const SDNode *N) {
|
static bool isI32Insn(const SDNode *User, const SDNode *N) {
|
||||||
switch (User->getOpcode()) {
|
switch (User->getOpcode()) {
|
||||||
default:
|
default:
|
||||||
|
@ -24,19 +24,22 @@ namespace VEISD {
|
|||||||
enum NodeType : unsigned {
|
enum NodeType : unsigned {
|
||||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||||
|
|
||||||
CALL, // A call instruction.
|
CALL, // A call instruction.
|
||||||
GETFUNPLT, // Load function address through %plt insturction.
|
EH_SJLJ_LONGJMP, // SjLj exception handling longjmp.
|
||||||
GETTLSADDR, // Load address for TLS access.
|
EH_SJLJ_SETJMP, // SjLj exception handling setjmp.
|
||||||
GETSTACKTOP, // Retrieve address of stack top (first address of
|
EH_SJLJ_SETUP_DISPATCH, // SjLj exception handling setup_dispatch.
|
||||||
// locals and temporaries).
|
GETFUNPLT, // Load function address through %plt insturction.
|
||||||
GLOBAL_BASE_REG, // Global base reg for PIC.
|
GETTLSADDR, // Load address for TLS access.
|
||||||
Hi, // Hi/Lo operations, typically on a global address.
|
GETSTACKTOP, // Retrieve address of stack top (first address of
|
||||||
Lo, // Hi/Lo operations, typically on a global address.
|
// locals and temporaries).
|
||||||
MEMBARRIER, // Compiler barrier only; generate a no-op.
|
GLOBAL_BASE_REG, // Global base reg for PIC.
|
||||||
RET_FLAG, // Return with a flag operand.
|
Hi, // Hi/Lo operations, typically on a global address.
|
||||||
TS1AM, // A TS1AM instruction used for 1/2 bytes swap.
|
Lo, // Hi/Lo operations, typically on a global address.
|
||||||
VEC_BROADCAST, // A vector broadcast instruction.
|
MEMBARRIER, // Compiler barrier only; generate a no-op.
|
||||||
// 0: scalar value, 1: VL
|
RET_FLAG, // Return with a flag operand.
|
||||||
|
TS1AM, // A TS1AM instruction used for 1/2 bytes swap.
|
||||||
|
VEC_BROADCAST, // A vector broadcast instruction.
|
||||||
|
// 0: scalar value, 1: VL
|
||||||
|
|
||||||
// VVP_* nodes.
|
// VVP_* nodes.
|
||||||
#define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
|
#define ADD_VVP_OP(VVP_NAME, ...) VVP_NAME,
|
||||||
@ -113,6 +116,9 @@ public:
|
|||||||
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue lowerEH_SJLJ_LONGJMP(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue lowerEH_SJLJ_SETJMP(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
SDValue lowerEH_SJLJ_SETUP_DISPATCH(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
|
||||||
@ -132,6 +138,29 @@ public:
|
|||||||
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
|
||||||
SelectionDAG &DAG) const override;
|
SelectionDAG &DAG) const override;
|
||||||
|
|
||||||
|
/// Custom Inserter {
|
||||||
|
MachineBasicBlock *
|
||||||
|
EmitInstrWithCustomInserter(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB) const override;
|
||||||
|
MachineBasicBlock *emitEHSjLjLongJmp(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB) const;
|
||||||
|
MachineBasicBlock *emitEHSjLjSetJmp(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *MBB) const;
|
||||||
|
MachineBasicBlock *emitSjLjDispatchBlock(MachineInstr &MI,
|
||||||
|
MachineBasicBlock *BB) const;
|
||||||
|
|
||||||
|
void setupEntryBlockForSjLj(MachineInstr &MI, MachineBasicBlock *MBB,
|
||||||
|
MachineBasicBlock *DispatchBB, int FI,
|
||||||
|
int Offset) const;
|
||||||
|
// Setup basic block address.
|
||||||
|
Register prepareMBB(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||||
|
MachineBasicBlock *TargetBB, const DebugLoc &DL) const;
|
||||||
|
// Prepare function/variable address.
|
||||||
|
Register prepareSymbol(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
||||||
|
StringRef Symbol, const DebugLoc &DL, bool IsLocal,
|
||||||
|
bool IsCall) const;
|
||||||
|
/// } Custom Inserter
|
||||||
|
|
||||||
/// VVP Lowering {
|
/// VVP Lowering {
|
||||||
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;
|
SDValue lowerToVVP(SDValue Op, SelectionDAG &DAG) const;
|
||||||
/// } VVPLowering
|
/// } VVPLowering
|
||||||
|
41
lib/Target/VE/VEInstrBuilder.h
Normal file
41
lib/Target/VE/VEInstrBuilder.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//===-- VEInstrBuilder.h - Aides for building VE insts ----------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file exposes functions that may be used with BuildMI from the
|
||||||
|
// MachineInstrBuilder.h file to simplify generating frame and constant pool
|
||||||
|
// references.
|
||||||
|
//
|
||||||
|
// For reference, the order of operands for memory references is:
|
||||||
|
// (Operand), Dest Reg, Base Reg, and either Reg Index or Immediate
|
||||||
|
// Displacement.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_LIB_TARGET_VE_VEINSTRBUILDER_H
|
||||||
|
#define LLVM_LIB_TARGET_VE_VEINSTRBUILDER_H
|
||||||
|
|
||||||
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
/// addFrameReference - This function is used to add a reference to the base of
|
||||||
|
/// an abstract object on the stack frame of the current function. This
|
||||||
|
/// reference has base register as the FrameIndex offset until it is resolved.
|
||||||
|
/// This allows a constant offset to be specified as well...
|
||||||
|
///
|
||||||
|
static inline const MachineInstrBuilder &
|
||||||
|
addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0,
|
||||||
|
bool ThreeOp = true) {
|
||||||
|
if (ThreeOp)
|
||||||
|
return MIB.addFrameIndex(FI).addImm(0).addImm(Offset);
|
||||||
|
return MIB.addFrameIndex(FI).addImm(Offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
@ -446,6 +446,17 @@ def retflag : SDNode<"VEISD::RET_FLAG", SDTNone,
|
|||||||
|
|
||||||
def getGOT : Operand<iPTR>;
|
def getGOT : Operand<iPTR>;
|
||||||
|
|
||||||
|
def VEeh_sjlj_setjmp: SDNode<"VEISD::EH_SJLJ_SETJMP",
|
||||||
|
SDTypeProfile<1, 1, [SDTCisInt<0>,
|
||||||
|
SDTCisPtrTy<1>]>,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
def VEeh_sjlj_longjmp: SDNode<"VEISD::EH_SJLJ_LONGJMP",
|
||||||
|
SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
def VEeh_sjlj_setup_dispatch: SDNode<"VEISD::EH_SJLJ_SETUP_DISPATCH",
|
||||||
|
SDTypeProfile<0, 0, []>,
|
||||||
|
[SDNPHasChain, SDNPSideEffect]>;
|
||||||
|
|
||||||
// GETFUNPLT for PIC
|
// GETFUNPLT for PIC
|
||||||
def GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>;
|
def GetFunPLT : SDNode<"VEISD::GETFUNPLT", SDTIntUnaryOp>;
|
||||||
|
|
||||||
@ -1878,6 +1889,33 @@ def : Pat<(i32 (atomic_swap_32 ADDRri:$src, i32:$new)),
|
|||||||
def : Pat<(i64 (atomic_swap_64 ADDRri:$src, i64:$new)),
|
def : Pat<(i64 (atomic_swap_64 ADDRri:$src, i64:$new)),
|
||||||
(TS1AMLrir MEMriRRM:$src, (LEAzii 0, 0, 255), i64:$new)>;
|
(TS1AMLrir MEMriRRM:$src, (LEAzii 0, 0, 255), i64:$new)>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// SJLJ Exception handling patterns
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
let hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1,
|
||||||
|
usesCustomInserter = 1 in {
|
||||||
|
let isTerminator = 1 in
|
||||||
|
def EH_SjLj_LongJmp : Pseudo<(outs), (ins I64:$buf),
|
||||||
|
"# EH_SJLJ_LONGJMP",
|
||||||
|
[(VEeh_sjlj_longjmp I64:$buf)]>;
|
||||||
|
|
||||||
|
def EH_SjLj_SetJmp : Pseudo<(outs I32:$dst), (ins I64:$buf),
|
||||||
|
"# EH_SJLJ_SETJMP",
|
||||||
|
[(set I32:$dst, (VEeh_sjlj_setjmp I64:$buf))]>;
|
||||||
|
|
||||||
|
def EH_SjLj_Setup_Dispatch : Pseudo<(outs), (ins), "# EH_SJLJ_SETUP_DISPATCH",
|
||||||
|
[(VEeh_sjlj_setup_dispatch)]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let isTerminator = 1, isBranch = 1, isCodeGenOnly = 1 in
|
||||||
|
def EH_SjLj_Setup : Pseudo<(outs), (ins brtarget32:$dst),
|
||||||
|
"# EH_SJlJ_SETUP $dst">;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Branch related patterns
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Branches
|
// Branches
|
||||||
def : Pat<(br bb:$addr), (BRCFLa bb:$addr)>;
|
def : Pat<(br bb:$addr), (BRCFLa bb:$addr)>;
|
||||||
|
|
||||||
|
213
test/CodeGen/VE/Scalar/builtin_sjlj.ll
Normal file
213
test/CodeGen/VE/Scalar/builtin_sjlj.ll
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
; RUN: llc < %s -mtriple=ve | FileCheck %s
|
||||||
|
; RUN: llc < %s -mtriple=ve -relocation-model=pic | \
|
||||||
|
; RUN: FileCheck %s -check-prefix=PIC
|
||||||
|
|
||||||
|
%struct.__jmp_buf_tag = type { [25 x i64], i64, [16 x i64] }
|
||||||
|
|
||||||
|
@buf = common global [1 x %struct.__jmp_buf_tag] zeroinitializer, align 8
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone
|
||||||
|
define signext i32 @t_setjmp() {
|
||||||
|
; CHECK-LABEL: t_setjmp:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_5:
|
||||||
|
; CHECK-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: lea %s0, buf@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, buf@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s9, (, %s0)
|
||||||
|
; CHECK-NEXT: st %s11, 16(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s1, .LBB{{[0-9]+}}_3@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, .LBB{{[0-9]+}}_3@hi(, %s1)
|
||||||
|
; CHECK-NEXT: st %s1, 8(, %s0)
|
||||||
|
; CHECK-NEXT: # EH_SJlJ_SETUP .LBB{{[0-9]+}}_3
|
||||||
|
; CHECK-NEXT: # %bb.1:
|
||||||
|
; CHECK-NEXT: lea %s0, 0
|
||||||
|
; CHECK-NEXT: br.l.t .LBB{{[0-9]+}}_2
|
||||||
|
; CHECK-NEXT: .LBB{{[0-9]+}}_3: # Block address taken
|
||||||
|
; CHECK-NEXT: lea %s0, 1
|
||||||
|
; CHECK-NEXT: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: adds.w.sx %s0, %s0, (0)1
|
||||||
|
; CHECK-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
;
|
||||||
|
; PIC-LABEL: t_setjmp:
|
||||||
|
; PIC: # %bb.0:
|
||||||
|
; PIC-NEXT: st %s9, (, %s11)
|
||||||
|
; PIC-NEXT: st %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: st %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: st %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: or %s9, 0, %s11
|
||||||
|
; PIC-NEXT: lea %s11, -176(, %s11)
|
||||||
|
; PIC-NEXT: brge.l %s11, %s8, .LBB0_5
|
||||||
|
; PIC-NEXT: # %bb.4:
|
||||||
|
; PIC-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; PIC-NEXT: or %s62, 0, %s0
|
||||||
|
; PIC-NEXT: lea %s63, 315
|
||||||
|
; PIC-NEXT: shm.l %s63, (%s61)
|
||||||
|
; PIC-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; PIC-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; PIC-NEXT: monc
|
||||||
|
; PIC-NEXT: or %s0, 0, %s62
|
||||||
|
; PIC-NEXT: .LBB0_5:
|
||||||
|
; PIC-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: lea %s0, buf@got_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, buf@got_hi(, %s0)
|
||||||
|
; PIC-NEXT: ld %s0, (%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s9, (, %s0)
|
||||||
|
; PIC-NEXT: st %s11, 16(, %s0)
|
||||||
|
; PIC-NEXT: lea %s1, .LBB0_3@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s1, %s1, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s1, .LBB0_3@gotoff_hi(%s1, %s15)
|
||||||
|
; PIC-NEXT: st %s1, 8(, %s0)
|
||||||
|
; PIC-NEXT: # EH_SJlJ_SETUP .LBB0_3
|
||||||
|
; PIC-NEXT: # %bb.1:
|
||||||
|
; PIC-NEXT: lea %s0, 0
|
||||||
|
; PIC-NEXT: br.l.t .LBB0_2
|
||||||
|
; PIC-NEXT: .LBB0_3: # Block address taken
|
||||||
|
; PIC-NEXT: lea %s0, 1
|
||||||
|
; PIC-NEXT: .LBB0_2:
|
||||||
|
; PIC-NEXT: adds.w.sx %s0, %s0, (0)1
|
||||||
|
; PIC-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: or %s11, 0, %s9
|
||||||
|
; PIC-NEXT: ld %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: ld %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: ld %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: ld %s9, (, %s11)
|
||||||
|
; PIC-NEXT: b.l.t (, %s10)
|
||||||
|
%1 = call i8* @llvm.frameaddress(i32 0)
|
||||||
|
store i8* %1, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @buf to i8**), align 8
|
||||||
|
%2 = call i8* @llvm.stacksave()
|
||||||
|
store i8* %2, i8** getelementptr inbounds (i8*, i8** bitcast ([1 x %struct.__jmp_buf_tag]* @buf to i8**), i64 2), align 8
|
||||||
|
%3 = call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @buf to i8*))
|
||||||
|
ret i32 %3
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone
|
||||||
|
declare i8* @llvm.frameaddress(i32)
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
declare i8* @llvm.stacksave()
|
||||||
|
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
declare i32 @llvm.eh.sjlj.setjmp(i8*)
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone
|
||||||
|
define void @t_longjmp() {
|
||||||
|
; CHECK-LABEL: t_longjmp:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, buf@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, buf@hi(, %s0)
|
||||||
|
; CHECK-NEXT: ld %s9, (, %s0)
|
||||||
|
; CHECK-NEXT: ld %s1, 8(, %s0)
|
||||||
|
; CHECK-NEXT: or %s10, 0, %s0
|
||||||
|
; CHECK-NEXT: ld %s11, 16(, %s0)
|
||||||
|
; CHECK-NEXT: b.l.t (, %s1)
|
||||||
|
;
|
||||||
|
; PIC-LABEL: t_longjmp:
|
||||||
|
; PIC: # %bb.0:
|
||||||
|
; PIC-NEXT: st %s9, (, %s11)
|
||||||
|
; PIC-NEXT: st %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: st %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: st %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: or %s9, 0, %s11
|
||||||
|
; PIC-NEXT: lea %s11, -176(, %s11)
|
||||||
|
; PIC-NEXT: brge.l.t %s11, %s8, .LBB1_2
|
||||||
|
; PIC-NEXT: # %bb.1:
|
||||||
|
; PIC-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; PIC-NEXT: or %s62, 0, %s0
|
||||||
|
; PIC-NEXT: lea %s63, 315
|
||||||
|
; PIC-NEXT: shm.l %s63, (%s61)
|
||||||
|
; PIC-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; PIC-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; PIC-NEXT: monc
|
||||||
|
; PIC-NEXT: or %s0, 0, %s62
|
||||||
|
; PIC-NEXT: .LBB1_2:
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: lea %s0, buf@got_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, buf@got_hi(, %s0)
|
||||||
|
; PIC-NEXT: ld %s0, (%s0, %s15)
|
||||||
|
; PIC-NEXT: ld %s9, (, %s0)
|
||||||
|
; PIC-NEXT: ld %s1, 8(, %s0)
|
||||||
|
; PIC-NEXT: or %s10, 0, %s0
|
||||||
|
; PIC-NEXT: ld %s11, 16(, %s0)
|
||||||
|
; PIC-NEXT: b.l.t (, %s1)
|
||||||
|
call void @llvm.eh.sjlj.longjmp(i8* bitcast ([1 x %struct.__jmp_buf_tag]* @buf to i8*))
|
||||||
|
unreachable
|
||||||
|
; No predecessors!
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: noreturn nounwind
|
||||||
|
declare void @llvm.eh.sjlj.longjmp(i8*)
|
||||||
|
|
87
test/CodeGen/VE/Scalar/builtin_sjlj_bp.ll
Normal file
87
test/CodeGen/VE/Scalar/builtin_sjlj_bp.ll
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
; RUN: llc < %s -mtriple=ve | FileCheck %s
|
||||||
|
|
||||||
|
%Foo = type { [125 x i8] }
|
||||||
|
declare void @whatever(i64, %Foo*, i8**, i8*, i8*, i32) #0
|
||||||
|
declare i32 @llvm.eh.sjlj.setjmp(i8*) nounwind
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone
|
||||||
|
define i32 @t_setjmp(i64 %n, %Foo* byval(%Foo) nocapture readnone align 8 %f) {
|
||||||
|
; CHECK-LABEL: t_setjmp:
|
||||||
|
; CHECK: .LBB{{[0-9]+}}_5:
|
||||||
|
; CHECK-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s1, 312(, %s17) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s0, 304(, %s17) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: lea %s0, 15(, %s0)
|
||||||
|
; CHECK-NEXT: and %s0, -16, %s0
|
||||||
|
; CHECK-NEXT: lea %s1, __ve_grow_stack@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, __ve_grow_stack@hi(, %s1)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: lea %s1, 240(, %s11)
|
||||||
|
; CHECK-NEXT: st %s1, 328(, %s17)
|
||||||
|
; CHECK-NEXT: lea %s0, .LBB{{[0-9]+}}_3@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, .LBB{{[0-9]+}}_3@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s17, 24(, %s1)
|
||||||
|
; CHECK-NEXT: st %s1, 296(, %s17) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s0, 8(, %s1)
|
||||||
|
; CHECK-NEXT: # EH_SJlJ_SETUP .LBB{{[0-9]+}}_3
|
||||||
|
; CHECK-NEXT: # %bb.1:
|
||||||
|
; CHECK-NEXT: lea %s5, 0
|
||||||
|
; CHECK-NEXT: br.l.t .LBB{{[0-9]+}}_2
|
||||||
|
; CHECK-NEXT: .LBB{{[0-9]+}}_3: # Block address taken
|
||||||
|
; CHECK-NEXT: ld %s17, 24(, %s10)
|
||||||
|
; CHECK-NEXT: lea %s5, 1
|
||||||
|
; CHECK-NEXT: .LBB{{[0-9]+}}_2:
|
||||||
|
; CHECK-NEXT: lea %s0, whatever@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, whatever@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s2, 328(, %s17)
|
||||||
|
; CHECK-NEXT: lea %s3, 320(, %s17)
|
||||||
|
; CHECK-NEXT: ld %s0, 304(, %s17) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s1, 312(, %s17) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s4, 296(, %s17) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: or %s0, 0, (0)1
|
||||||
|
; CHECK-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
%buf = alloca [5 x i8*], align 16
|
||||||
|
%p = alloca i8*, align 8
|
||||||
|
%q = alloca i8, align 64
|
||||||
|
%r = bitcast [5 x i8*]* %buf to i8*
|
||||||
|
%s = alloca i8, i64 %n, align 1
|
||||||
|
store i8* %s, i8** %p, align 8
|
||||||
|
%t = call i32 @llvm.eh.sjlj.setjmp(i8* %s)
|
||||||
|
call void @whatever(i64 %n, %Foo* %f, i8** %p, i8* %q, i8* %s, i32 %t) #1
|
||||||
|
ret i32 0
|
||||||
|
}
|
282
test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll
Normal file
282
test/CodeGen/VE/Scalar/builtin_sjlj_callsite.ll
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc < %s -mtriple=ve -exception-model sjlj | FileCheck %s
|
||||||
|
; RUN: llc < %s -mtriple=ve -exception-model sjlj -relocation-model pic | \
|
||||||
|
; RUN: FileCheck %s -check-prefix=PIC
|
||||||
|
|
||||||
|
; Function Attrs: noinline nounwind optnone
|
||||||
|
define void @test_callsite() personality i32 (...)* @__gxx_personality_sj0 {
|
||||||
|
; CHECK-LABEL: test_callsite:
|
||||||
|
; CHECK: # %bb.0:
|
||||||
|
; CHECK-NEXT: st %s9, (, %s11)
|
||||||
|
; CHECK-NEXT: st %s10, 8(, %s11)
|
||||||
|
; CHECK-NEXT: or %s9, 0, %s11
|
||||||
|
; CHECK-NEXT: lea %s11, -432(, %s11)
|
||||||
|
; CHECK-NEXT: brge.l %s11, %s8, .LBB0_7
|
||||||
|
; CHECK-NEXT: # %bb.6:
|
||||||
|
; CHECK-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; CHECK-NEXT: or %s62, 0, %s0
|
||||||
|
; CHECK-NEXT: lea %s63, 315
|
||||||
|
; CHECK-NEXT: shm.l %s63, (%s61)
|
||||||
|
; CHECK-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; CHECK-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; CHECK-NEXT: monc
|
||||||
|
; CHECK-NEXT: or %s0, 0, %s62
|
||||||
|
; CHECK-NEXT: .LBB0_7:
|
||||||
|
; CHECK-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: lea %s0, __gxx_personality_sj0@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, __gxx_personality_sj0@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -56(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, GCC_except_table0@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, GCC_except_table0@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -48(, %s9)
|
||||||
|
; CHECK-NEXT: st %s9, -40(, %s9)
|
||||||
|
; CHECK-NEXT: st %s11, -24(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, .LBB0_3@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, .LBB0_3@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -32(, %s9)
|
||||||
|
; CHECK-NEXT: or %s0, 1, (0)1
|
||||||
|
; CHECK-NEXT: st %s0, -96(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, _Unwind_SjLj_Register@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, _Unwind_SjLj_Register@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: .Ltmp0:
|
||||||
|
; CHECK-NEXT: lea %s0, f@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, f@hi(, %s0)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: .Ltmp1:
|
||||||
|
; CHECK-NEXT: .LBB0_2: # %try.cont
|
||||||
|
; CHECK-NEXT: or %s0, -1, (0)1
|
||||||
|
; CHECK-NEXT: st %s0, -96(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, _Unwind_SjLj_Unregister@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s18, _Unwind_SjLj_Unregister@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s0, -192(, %s9)
|
||||||
|
; CHECK-NEXT: or %s12, 0, %s18
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; CHECK-NEXT: or %s12, 0, %s18
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
; CHECK-NEXT: ld %s10, 8(, %s11)
|
||||||
|
; CHECK-NEXT: ld %s9, (, %s11)
|
||||||
|
; CHECK-NEXT: b.l.t (, %s10)
|
||||||
|
; CHECK-NEXT: .LBB0_3:
|
||||||
|
; CHECK-NEXT: ldl.zx %s0, -96(, %s9)
|
||||||
|
; CHECK-NEXT: brgt.l 1, %s0, .LBB0_4
|
||||||
|
; CHECK-NEXT: # %bb.5:
|
||||||
|
; CHECK-NEXT: lea %s0, abort@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, abort@hi(, %s0)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s0)
|
||||||
|
; CHECK-NEXT: .LBB0_4:
|
||||||
|
; CHECK-NEXT: lea %s1, .LJTI0_0@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, .LJTI0_0@hi(, %s1)
|
||||||
|
; CHECK-NEXT: sll %s0, %s0, 3
|
||||||
|
; CHECK-NEXT: ld %s0, (%s0, %s1)
|
||||||
|
; CHECK-NEXT: b.l.t (, %s0)
|
||||||
|
; CHECK-NEXT: .LBB0_1: # %lpad
|
||||||
|
; CHECK-NEXT: .Ltmp2:
|
||||||
|
; CHECK-NEXT: ld %s0, -88(, %s9)
|
||||||
|
; CHECK-NEXT: ld %s0, -80(, %s9)
|
||||||
|
; CHECK-NEXT: br.l.t .LBB0_2
|
||||||
|
;
|
||||||
|
; PIC-LABEL: test_callsite:
|
||||||
|
; PIC: # %bb.0:
|
||||||
|
; PIC-NEXT: st %s9, (, %s11)
|
||||||
|
; PIC-NEXT: st %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: st %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: st %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: or %s9, 0, %s11
|
||||||
|
; PIC-NEXT: lea %s11, -432(, %s11)
|
||||||
|
; PIC-NEXT: brge.l %s11, %s8, .LBB0_7
|
||||||
|
; PIC-NEXT: # %bb.6:
|
||||||
|
; PIC-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; PIC-NEXT: or %s62, 0, %s0
|
||||||
|
; PIC-NEXT: lea %s63, 315
|
||||||
|
; PIC-NEXT: shm.l %s63, (%s61)
|
||||||
|
; PIC-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; PIC-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; PIC-NEXT: monc
|
||||||
|
; PIC-NEXT: or %s0, 0, %s62
|
||||||
|
; PIC-NEXT: .LBB0_7:
|
||||||
|
; PIC-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: lea %s0, __gxx_personality_sj0@got_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, __gxx_personality_sj0@got_hi(, %s0)
|
||||||
|
; PIC-NEXT: ld %s0, (%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -56(, %s9)
|
||||||
|
; PIC-NEXT: lea %s0, GCC_except_table0@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, GCC_except_table0@gotoff_hi(%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -48(, %s9)
|
||||||
|
; PIC-NEXT: st %s9, -40(, %s9)
|
||||||
|
; PIC-NEXT: st %s11, -24(, %s9)
|
||||||
|
; PIC-NEXT: lea %s0, .LBB0_3@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, .LBB0_3@gotoff_hi(%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -32(, %s9)
|
||||||
|
; PIC-NEXT: or %s0, 1, (0)1
|
||||||
|
; PIC-NEXT: st %s0, -96(, %s9)
|
||||||
|
; PIC-NEXT: lea %s12, _Unwind_SjLj_Register@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, _Unwind_SjLj_Register@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: .Ltmp0:
|
||||||
|
; PIC-NEXT: lea %s12, f@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, f@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: .Ltmp1:
|
||||||
|
; PIC-NEXT: .LBB0_2: # %try.cont
|
||||||
|
; PIC-NEXT: or %s0, -1, (0)1
|
||||||
|
; PIC-NEXT: st %s0, -96(, %s9)
|
||||||
|
; PIC-NEXT: lea %s18, _Unwind_SjLj_Unregister@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s18, %s18, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s18, _Unwind_SjLj_Unregister@plt_hi(%s16, %s18)
|
||||||
|
; PIC-NEXT: lea %s0, -192(, %s9)
|
||||||
|
; PIC-NEXT: or %s12, 0, %s18
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; PIC-NEXT: or %s12, 0, %s18
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: or %s11, 0, %s9
|
||||||
|
; PIC-NEXT: ld %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: ld %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: ld %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: ld %s9, (, %s11)
|
||||||
|
; PIC-NEXT: b.l.t (, %s10)
|
||||||
|
; PIC-NEXT: .LBB0_3:
|
||||||
|
; PIC-NEXT: ldl.zx %s0, -96(, %s9)
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: brgt.l 1, %s0, .LBB0_4
|
||||||
|
; PIC-NEXT: # %bb.5:
|
||||||
|
; PIC-NEXT: lea %s0, abort@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s0, abort@plt_hi(%s16, %s0)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s0)
|
||||||
|
; PIC-NEXT: .LBB0_4:
|
||||||
|
; PIC-NEXT: lea %s1, .LJTI0_0@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s1, %s1, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s1, .LJTI0_0@gotoff_hi(%s1, %s15)
|
||||||
|
; PIC-NEXT: sll %s0, %s0, 2
|
||||||
|
; PIC-NEXT: ldl.zx %s0, (%s0, %s1)
|
||||||
|
; PIC-NEXT: lea %s1, test_callsite@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s1, %s1, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s1, test_callsite@gotoff_hi(%s1, %s15)
|
||||||
|
; PIC-NEXT: adds.l %s0, %s0, %s1
|
||||||
|
; PIC-NEXT: b.l.t (, %s0)
|
||||||
|
; PIC-NEXT: .LBB0_1: # %lpad
|
||||||
|
; PIC-NEXT: .Ltmp2:
|
||||||
|
; PIC-NEXT: ld %s0, -88(, %s9)
|
||||||
|
; PIC-NEXT: ld %s0, -80(, %s9)
|
||||||
|
; PIC-NEXT: br.l.t .LBB0_2
|
||||||
|
%fn_context = alloca { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }, align 4
|
||||||
|
call void @llvm.eh.sjlj.callsite(i32 0)
|
||||||
|
invoke void @f()
|
||||||
|
to label %try.cont unwind label %lpad
|
||||||
|
|
||||||
|
lpad: ; preds = %entry
|
||||||
|
%1 = landingpad { i8*, i32 }
|
||||||
|
cleanup
|
||||||
|
;; %__data = getelementptr { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }, { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }* %fn_context, i32 0, i32 2
|
||||||
|
;; %exception_gep = getelementptr [4 x i32], [4 x i32]* %__data, i32 0, i32 0
|
||||||
|
;; %exn_val = load volatile i32, i32* %exception_gep, align 4
|
||||||
|
;; %2 = inttoptr i32 %exn_val to i8*
|
||||||
|
;; %exn_selector_gep = getelementptr [4 x i32], [4 x i32]* %__data, i32 0, i32 1
|
||||||
|
;; %exn_selector_val = load volatile i32, i32* %exn_selector_gep, align 4
|
||||||
|
br label %try.cont
|
||||||
|
|
||||||
|
try.cont: ; preds = %lpad, %entry
|
||||||
|
call void @_Unwind_SjLj_Unregister({ i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }* %fn_context)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @f()
|
||||||
|
|
||||||
|
declare i32 @__gxx_personality_sj0(...)
|
||||||
|
|
||||||
|
declare void @_Unwind_SjLj_Unregister({ i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }*)
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone
|
||||||
|
declare void @llvm.eh.sjlj.callsite(i32)
|
303
test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll
Normal file
303
test/CodeGen/VE/Scalar/builtin_sjlj_landingpad.ll
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
|
; RUN: llc -mtriple=ve -exception-model=sjlj < %s | FileCheck %s
|
||||||
|
; RUN: llc -mtriple=ve -exception-model=sjlj -relocation-model=pic < %s | \
|
||||||
|
; RUN: FileCheck --check-prefix=PIC %s
|
||||||
|
|
||||||
|
@SomeGlobal = external dso_local global i8
|
||||||
|
|
||||||
|
define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
|
||||||
|
; CHECK-LABEL: foo:
|
||||||
|
; CHECK: # %bb.0: # %entry
|
||||||
|
; CHECK-NEXT: st %s9, (, %s11)
|
||||||
|
; CHECK-NEXT: st %s10, 8(, %s11)
|
||||||
|
; CHECK-NEXT: or %s9, 0, %s11
|
||||||
|
; CHECK-NEXT: lea %s11, -352(, %s11)
|
||||||
|
; CHECK-NEXT: brge.l %s11, %s8, .LBB0_8
|
||||||
|
; CHECK-NEXT: # %bb.7: # %entry
|
||||||
|
; CHECK-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; CHECK-NEXT: or %s62, 0, %s0
|
||||||
|
; CHECK-NEXT: lea %s63, 315
|
||||||
|
; CHECK-NEXT: shm.l %s63, (%s61)
|
||||||
|
; CHECK-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; CHECK-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; CHECK-NEXT: monc
|
||||||
|
; CHECK-NEXT: or %s0, 0, %s62
|
||||||
|
; CHECK-NEXT: .LBB0_8: # %entry
|
||||||
|
; CHECK-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; CHECK-NEXT: lea %s0, __gxx_personality_sj0@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, __gxx_personality_sj0@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -56(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, GCC_except_table0@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, GCC_except_table0@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -48(, %s9)
|
||||||
|
; CHECK-NEXT: st %s9, -40(, %s9)
|
||||||
|
; CHECK-NEXT: st %s11, -24(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, .LBB0_3@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, .LBB0_3@hi(, %s0)
|
||||||
|
; CHECK-NEXT: st %s0, -32(, %s9)
|
||||||
|
; CHECK-NEXT: or %s0, 1, (0)1
|
||||||
|
; CHECK-NEXT: st %s0, -96(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, _Unwind_SjLj_Register@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, _Unwind_SjLj_Register@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: .Ltmp0:
|
||||||
|
; CHECK-NEXT: lea %s0, errorbar@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, errorbar@hi(, %s0)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: .Ltmp1:
|
||||||
|
; CHECK-NEXT: # %bb.1: # %exit
|
||||||
|
; CHECK-NEXT: lea %s0, _Unwind_SjLj_Unregister@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, _Unwind_SjLj_Unregister@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: or %s0, 0, (0)1
|
||||||
|
; CHECK-NEXT: .LBB0_2: # %exit
|
||||||
|
; CHECK-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; CHECK-NEXT: or %s11, 0, %s9
|
||||||
|
; CHECK-NEXT: ld %s10, 8(, %s11)
|
||||||
|
; CHECK-NEXT: ld %s9, (, %s11)
|
||||||
|
; CHECK-NEXT: b.l.t (, %s10)
|
||||||
|
; CHECK-NEXT: .LBB0_3:
|
||||||
|
; CHECK-NEXT: ldl.zx %s0, -96(, %s9)
|
||||||
|
; CHECK-NEXT: brgt.l 1, %s0, .LBB0_4
|
||||||
|
; CHECK-NEXT: # %bb.5:
|
||||||
|
; CHECK-NEXT: lea %s0, abort@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s0, abort@hi(, %s0)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s0)
|
||||||
|
; CHECK-NEXT: .LBB0_4:
|
||||||
|
; CHECK-NEXT: lea %s1, .LJTI0_0@lo
|
||||||
|
; CHECK-NEXT: and %s1, %s1, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s1, .LJTI0_0@hi(, %s1)
|
||||||
|
; CHECK-NEXT: sll %s0, %s0, 3
|
||||||
|
; CHECK-NEXT: ld %s0, (%s0, %s1)
|
||||||
|
; CHECK-NEXT: b.l.t (, %s0)
|
||||||
|
; CHECK-NEXT: .LBB0_6: # %handle
|
||||||
|
; CHECK-NEXT: .Ltmp2:
|
||||||
|
; CHECK-NEXT: ld %s0, -88(, %s9)
|
||||||
|
; CHECK-NEXT: ld %s0, -80(, %s9)
|
||||||
|
; CHECK-NEXT: lea %s0, _Unwind_SjLj_Unregister@lo
|
||||||
|
; CHECK-NEXT: and %s0, %s0, (32)0
|
||||||
|
; CHECK-NEXT: lea.sl %s12, _Unwind_SjLj_Unregister@hi(, %s0)
|
||||||
|
; CHECK-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; CHECK-NEXT: bsic %s10, (, %s12)
|
||||||
|
; CHECK-NEXT: or %s0, 1, (0)1
|
||||||
|
; CHECK-NEXT: br.l.t .LBB0_2
|
||||||
|
;
|
||||||
|
; PIC-LABEL: foo:
|
||||||
|
; PIC: # %bb.0: # %entry
|
||||||
|
; PIC-NEXT: st %s9, (, %s11)
|
||||||
|
; PIC-NEXT: st %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: st %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: st %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: or %s9, 0, %s11
|
||||||
|
; PIC-NEXT: lea %s11, -352(, %s11)
|
||||||
|
; PIC-NEXT: brge.l %s11, %s8, .LBB0_8
|
||||||
|
; PIC-NEXT: # %bb.7: # %entry
|
||||||
|
; PIC-NEXT: ld %s61, 24(, %s14)
|
||||||
|
; PIC-NEXT: or %s62, 0, %s0
|
||||||
|
; PIC-NEXT: lea %s63, 315
|
||||||
|
; PIC-NEXT: shm.l %s63, (%s61)
|
||||||
|
; PIC-NEXT: shm.l %s8, 8(%s61)
|
||||||
|
; PIC-NEXT: shm.l %s11, 16(%s61)
|
||||||
|
; PIC-NEXT: monc
|
||||||
|
; PIC-NEXT: or %s0, 0, %s62
|
||||||
|
; PIC-NEXT: .LBB0_8: # %entry
|
||||||
|
; PIC-NEXT: st %s18, 48(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s19, 56(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s20, 64(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s21, 72(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s22, 80(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s23, 88(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s24, 96(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s25, 104(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s26, 112(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s27, 120(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s28, 128(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s29, 136(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s30, 144(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s31, 152(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s32, 160(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: st %s33, 168(, %s9) # 8-byte Folded Spill
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: lea %s0, __gxx_personality_sj0@got_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, __gxx_personality_sj0@got_hi(, %s0)
|
||||||
|
; PIC-NEXT: ld %s0, (%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -56(, %s9)
|
||||||
|
; PIC-NEXT: lea %s0, GCC_except_table0@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, GCC_except_table0@gotoff_hi(%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -48(, %s9)
|
||||||
|
; PIC-NEXT: st %s9, -40(, %s9)
|
||||||
|
; PIC-NEXT: st %s11, -24(, %s9)
|
||||||
|
; PIC-NEXT: lea %s0, .LBB0_3@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s0, .LBB0_3@gotoff_hi(%s0, %s15)
|
||||||
|
; PIC-NEXT: st %s0, -32(, %s9)
|
||||||
|
; PIC-NEXT: or %s0, 1, (0)1
|
||||||
|
; PIC-NEXT: st %s0, -96(, %s9)
|
||||||
|
; PIC-NEXT: lea %s12, _Unwind_SjLj_Register@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, _Unwind_SjLj_Register@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: .Ltmp0:
|
||||||
|
; PIC-NEXT: lea %s12, errorbar@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, errorbar@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: .Ltmp1:
|
||||||
|
; PIC-NEXT: # %bb.1: # %exit
|
||||||
|
; PIC-NEXT: lea %s12, _Unwind_SjLj_Unregister@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, _Unwind_SjLj_Unregister@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: or %s0, 0, (0)1
|
||||||
|
; PIC-NEXT: .LBB0_2: # %exit
|
||||||
|
; PIC-NEXT: ld %s33, 168(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s32, 160(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s31, 152(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s30, 144(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s29, 136(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s28, 128(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s27, 120(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s26, 112(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s25, 104(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s24, 96(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s23, 88(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s22, 80(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s21, 72(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s20, 64(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s19, 56(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: ld %s18, 48(, %s9) # 8-byte Folded Reload
|
||||||
|
; PIC-NEXT: or %s11, 0, %s9
|
||||||
|
; PIC-NEXT: ld %s16, 32(, %s11)
|
||||||
|
; PIC-NEXT: ld %s15, 24(, %s11)
|
||||||
|
; PIC-NEXT: ld %s10, 8(, %s11)
|
||||||
|
; PIC-NEXT: ld %s9, (, %s11)
|
||||||
|
; PIC-NEXT: b.l.t (, %s10)
|
||||||
|
; PIC-NEXT: .LBB0_3:
|
||||||
|
; PIC-NEXT: ldl.zx %s0, -96(, %s9)
|
||||||
|
; PIC-NEXT: lea %s15, _GLOBAL_OFFSET_TABLE_@pc_lo(-24)
|
||||||
|
; PIC-NEXT: and %s15, %s15, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s15, _GLOBAL_OFFSET_TABLE_@pc_hi(%s16, %s15)
|
||||||
|
; PIC-NEXT: brgt.l 1, %s0, .LBB0_4
|
||||||
|
; PIC-NEXT: # %bb.5:
|
||||||
|
; PIC-NEXT: lea %s0, abort@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s0, %s0, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s0, abort@plt_hi(%s16, %s0)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s0)
|
||||||
|
; PIC-NEXT: .LBB0_4:
|
||||||
|
; PIC-NEXT: lea %s1, .LJTI0_0@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s1, %s1, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s1, .LJTI0_0@gotoff_hi(%s1, %s15)
|
||||||
|
; PIC-NEXT: sll %s0, %s0, 2
|
||||||
|
; PIC-NEXT: ldl.zx %s0, (%s0, %s1)
|
||||||
|
; PIC-NEXT: lea %s1, foo@gotoff_lo
|
||||||
|
; PIC-NEXT: and %s1, %s1, (32)0
|
||||||
|
; PIC-NEXT: lea.sl %s1, foo@gotoff_hi(%s1, %s15)
|
||||||
|
; PIC-NEXT: adds.l %s0, %s0, %s1
|
||||||
|
; PIC-NEXT: b.l.t (, %s0)
|
||||||
|
; PIC-NEXT: .LBB0_6: # %handle
|
||||||
|
; PIC-NEXT: .Ltmp2:
|
||||||
|
; PIC-NEXT: ld %s0, -88(, %s9)
|
||||||
|
; PIC-NEXT: ld %s0, -80(, %s9)
|
||||||
|
; PIC-NEXT: lea %s12, _Unwind_SjLj_Unregister@plt_lo(-24)
|
||||||
|
; PIC-NEXT: and %s12, %s12, (32)0
|
||||||
|
; PIC-NEXT: sic %s16
|
||||||
|
; PIC-NEXT: lea.sl %s12, _Unwind_SjLj_Unregister@plt_hi(%s16, %s12)
|
||||||
|
; PIC-NEXT: lea %s0, -104(, %s9)
|
||||||
|
; PIC-NEXT: bsic %s10, (, %s12)
|
||||||
|
; PIC-NEXT: or %s0, 1, (0)1
|
||||||
|
; PIC-NEXT: br.l.t .LBB0_2
|
||||||
|
; PIC-NEXT: .Lfunc_end0:
|
||||||
|
; PIC-NEXT: .size foo, .Lfunc_end0-foo
|
||||||
|
; PIC-NEXT: .section .rodata,"a",@progbits
|
||||||
|
; PIC-NEXT: .p2align 2
|
||||||
|
; PIC-NEXT: .LJTI0_0:
|
||||||
|
; PIC-NEXT: .4byte .LBB0_6-foo
|
||||||
|
; PIC-NEXT: .section .gcc_except_table,"a",@progbits
|
||||||
|
; PIC-NEXT: .p2align 2
|
||||||
|
; PIC-NEXT: GCC_except_table0:
|
||||||
|
; PIC-NEXT: .Lexception0:
|
||||||
|
; PIC-NEXT: .byte 255 # @LPStart Encoding = omit
|
||||||
|
; PIC-NEXT: .byte 0 # @TType Encoding = absptr
|
||||||
|
; PIC-NEXT: .uleb128 .Lttbase0-.Lttbaseref0
|
||||||
|
; PIC-NEXT: .Lttbaseref0:
|
||||||
|
; PIC-NEXT: .byte 3 # Call site Encoding = udata4
|
||||||
|
; PIC-NEXT: .uleb128 .Lcst_end0-.Lcst_begin0
|
||||||
|
; PIC-NEXT: .Lcst_begin0:
|
||||||
|
; PIC-NEXT: .byte 0 # >> Call Site 0 <<
|
||||||
|
; PIC-NEXT: # On exception at call site 0
|
||||||
|
; PIC-NEXT: .byte 1 # Action: 1
|
||||||
|
; PIC-NEXT: .Lcst_end0:
|
||||||
|
; PIC-NEXT: .byte 1 # >> Action Record 1 <<
|
||||||
|
; PIC-NEXT: # Catch TypeInfo 1
|
||||||
|
; PIC-NEXT: .byte 0 # No further actions
|
||||||
|
; PIC-NEXT: .p2align 2
|
||||||
|
; PIC-NEXT: # >> Catch TypeInfos <<
|
||||||
|
; PIC-NEXT: .8byte SomeGlobal # TypeInfo 1
|
||||||
|
; PIC-NEXT: .Lttbase0:
|
||||||
|
; PIC-NEXT: .p2align 2
|
||||||
|
; PIC-NEXT: # -- End function
|
||||||
|
entry:
|
||||||
|
invoke void @errorbar() to label %exit unwind label %handle
|
||||||
|
|
||||||
|
handle:
|
||||||
|
%error = landingpad { i8*, i32 } catch i8* @SomeGlobal
|
||||||
|
ret i32 1
|
||||||
|
|
||||||
|
exit:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare dso_local void @errorbar() local_unnamed_addr
|
||||||
|
|
||||||
|
declare dso_local i32 @__gxx_personality_sj0(...)
|
@ -1,32 +0,0 @@
|
|||||||
; RUN: llc -mtriple=x86_64-unknown-unknown --exception-model=sjlj --print-after=sjljehprepare < %s 2>&1 | FileCheck --check-prefix=CHECK-X86 %s
|
|
||||||
; RUN: (llc -mtriple=ve-unknown-unknown --exception-model=sjlj --print-after=sjljehprepare < %s || true) 2>&1 | FileCheck --check-prefix=CHECK-VE %s
|
|
||||||
|
|
||||||
@SomeGlobal = external dso_local global i8
|
|
||||||
|
|
||||||
define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
|
|
||||||
; CHECK-VE: *** IR Dump After SJLJ Exception Handling preparation ***
|
|
||||||
; CHECK-VE-NEXT: define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
|
|
||||||
; CHECK-VE-NEXT: entry:
|
|
||||||
; CHECK-VE-NEXT: %fn_context = alloca { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }, align 8
|
|
||||||
; CHECK-VE-NEXT: %arg.tmp = select i1 true, i32 %arg, i32 undef
|
|
||||||
; CHECK-VE-NEXT: %pers_fn_gep = getelementptr { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }, { i8*, i64, [4 x i64], i8*, i8*, [5 x i8*] }* %fn_context, i32 0, i32 3
|
|
||||||
; CHECK-X86: *** IR Dump After SJLJ Exception Handling preparation ***
|
|
||||||
; CHECK-X86-NEXT: define dso_local i32 @foo(i32 %arg) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
|
|
||||||
; CHECK-X86-NEXT: entry:
|
|
||||||
; CHECK-X86-NEXT: %fn_context = alloca { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }, align 8
|
|
||||||
; CHECK-X86-NEXT: %arg.tmp = select i1 true, i32 %arg, i32 undef
|
|
||||||
; CHECK-X86-NEXT: %pers_fn_gep = getelementptr { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }, { i8*, i32, [4 x i32], i8*, i8*, [5 x i8*] }* %fn_context, i32 0, i32 3
|
|
||||||
entry:
|
|
||||||
invoke void @errorbar() to label %exit unwind label %handle
|
|
||||||
|
|
||||||
handle:
|
|
||||||
%error = landingpad { i8*, i32 } catch i8* @SomeGlobal
|
|
||||||
ret i32 1
|
|
||||||
|
|
||||||
exit:
|
|
||||||
ret i32 0
|
|
||||||
}
|
|
||||||
|
|
||||||
declare dso_local void @errorbar() local_unnamed_addr
|
|
||||||
|
|
||||||
declare dso_local i32 @__gxx_personality_sj0(...)
|
|
Loading…
Reference in New Issue
Block a user