mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-13 09:33:50 +00:00
Fix setjmp on models with non-Small code model nor non-Static relocation model
- MBB address is only valid as an immediate value in Small & Static code/relocation models. On other models, LEA is needed to load IP address of the restore MBB. - A minor fix of MBB in MC lowering is added as well to enable target relocation flag being propagated into MC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166084 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d7ea7d5cd7
commit
281ae5abf5
@ -459,7 +459,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
|||||||
setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
|
setOperationAction(ISD::EH_RETURN , MVT::Other, Custom);
|
||||||
// NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intened to support
|
// NOTE: EH_SJLJ_SETJMP/_LONGJMP supported here is NOT intened to support
|
||||||
// SjLj exception handling but a light-weight setjmp/longjmp replacement to
|
// SjLj exception handling but a light-weight setjmp/longjmp replacement to
|
||||||
// support continuation, user-level threading, and etc.. As a result, not
|
// support continuation, user-level threading, and etc.. As a result, no
|
||||||
// other SjLj exception interfaces are implemented and please don't build
|
// other SjLj exception interfaces are implemented and please don't build
|
||||||
// your own exception handling based on them.
|
// your own exception handling based on them.
|
||||||
// LLVM/Clang supports zero-cost DWARF exception handling.
|
// LLVM/Clang supports zero-cost DWARF exception handling.
|
||||||
@ -13312,7 +13312,7 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
// For v = setjmp(buf), we generate
|
// For v = setjmp(buf), we generate
|
||||||
//
|
//
|
||||||
// thisMBB:
|
// thisMBB:
|
||||||
// buf[Label_Offset] = ljMBB
|
// buf[LabelOffset] = restoreMBB
|
||||||
// SjLjSetup restoreMBB
|
// SjLjSetup restoreMBB
|
||||||
//
|
//
|
||||||
// mainMBB:
|
// mainMBB:
|
||||||
@ -13340,18 +13340,48 @@ X86TargetLowering::emitEHSjLjSetJmp(MachineInstr *MI,
|
|||||||
sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
|
sinkMBB->transferSuccessorsAndUpdatePHIs(MBB);
|
||||||
|
|
||||||
// thisMBB:
|
// thisMBB:
|
||||||
unsigned PtrImmStoreOpc = (PVT == MVT::i64) ? X86::MOV64mi32 : X86::MOV32mi;
|
unsigned PtrStoreOpc = 0;
|
||||||
const int64_t Label_Offset = 1 * PVT.getStoreSize();
|
unsigned LabelReg = 0;
|
||||||
|
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
||||||
|
Reloc::Model RM = getTargetMachine().getRelocationModel();
|
||||||
|
bool UseImmLabel = (getTargetMachine().getCodeModel() == CodeModel::Small) &&
|
||||||
|
(RM == Reloc::Static || RM == Reloc::DynamicNoPIC);
|
||||||
|
|
||||||
|
// Prepare IP either in reg or imm.
|
||||||
|
if (!UseImmLabel) {
|
||||||
|
PtrStoreOpc = (PVT == MVT::i64) ? X86::MOV64mr : X86::MOV32mr;
|
||||||
|
const TargetRegisterClass *PtrRC = getRegClassFor(PVT);
|
||||||
|
LabelReg = MRI.createVirtualRegister(PtrRC);
|
||||||
|
if (Subtarget->is64Bit()) {
|
||||||
|
MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::LEA64r), LabelReg)
|
||||||
|
.addReg(X86::RIP)
|
||||||
|
.addImm(0)
|
||||||
|
.addReg(0)
|
||||||
|
.addMBB(restoreMBB)
|
||||||
|
.addReg(0);
|
||||||
|
} else {
|
||||||
|
const X86InstrInfo *XII = static_cast<const X86InstrInfo*>(TII);
|
||||||
|
MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::LEA32r), LabelReg)
|
||||||
|
.addReg(XII->getGlobalBaseReg(MF))
|
||||||
|
.addImm(0)
|
||||||
|
.addReg(0)
|
||||||
|
.addMBB(restoreMBB, Subtarget->ClassifyBlockAddressReference())
|
||||||
|
.addReg(0);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
PtrStoreOpc = (PVT == MVT::i64) ? X86::MOV64mi32 : X86::MOV32mi;
|
||||||
// Store IP
|
// Store IP
|
||||||
MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrImmStoreOpc));
|
MIB = BuildMI(*thisMBB, MI, DL, TII->get(PtrStoreOpc));
|
||||||
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
||||||
if (i == X86::AddrDisp)
|
if (i == X86::AddrDisp)
|
||||||
MIB.addDisp(MI->getOperand(MemOpndSlot + i), Label_Offset);
|
MIB.addDisp(MI->getOperand(MemOpndSlot + i), LabelOffset);
|
||||||
else
|
else
|
||||||
MIB.addOperand(MI->getOperand(MemOpndSlot + i));
|
MIB.addOperand(MI->getOperand(MemOpndSlot + i));
|
||||||
}
|
}
|
||||||
MIB.addMBB(restoreMBB);
|
if (!UseImmLabel)
|
||||||
|
MIB.addReg(LabelReg);
|
||||||
|
else
|
||||||
|
MIB.addMBB(restoreMBB);
|
||||||
MIB.setMemRefs(MMOBegin, MMOEnd);
|
MIB.setMemRefs(MMOBegin, MMOEnd);
|
||||||
// Setup
|
// Setup
|
||||||
MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::EH_SjLj_Setup))
|
MIB = BuildMI(*thisMBB, MI, DL, TII->get(X86::EH_SjLj_Setup))
|
||||||
@ -13406,8 +13436,8 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
|
|||||||
|
|
||||||
MachineInstrBuilder MIB;
|
MachineInstrBuilder MIB;
|
||||||
|
|
||||||
const int64_t Label_Offset = 1 * PVT.getStoreSize();
|
const int64_t LabelOffset = 1 * PVT.getStoreSize();
|
||||||
const int64_t SP_Offset = 2 * PVT.getStoreSize();
|
const int64_t SPOffset = 2 * PVT.getStoreSize();
|
||||||
|
|
||||||
unsigned PtrLoadOpc = (PVT == MVT::i64) ? X86::MOV64rm : X86::MOV32rm;
|
unsigned PtrLoadOpc = (PVT == MVT::i64) ? X86::MOV64rm : X86::MOV32rm;
|
||||||
unsigned IJmpOpc = (PVT == MVT::i64) ? X86::JMP64r : X86::JMP32r;
|
unsigned IJmpOpc = (PVT == MVT::i64) ? X86::JMP64r : X86::JMP32r;
|
||||||
@ -13421,7 +13451,7 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
|
|||||||
MIB = BuildMI(*MBB, MI, DL, TII->get(PtrLoadOpc), Tmp);
|
MIB = BuildMI(*MBB, MI, DL, TII->get(PtrLoadOpc), Tmp);
|
||||||
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
||||||
if (i == X86::AddrDisp)
|
if (i == X86::AddrDisp)
|
||||||
MIB.addDisp(MI->getOperand(i), Label_Offset);
|
MIB.addDisp(MI->getOperand(i), LabelOffset);
|
||||||
else
|
else
|
||||||
MIB.addOperand(MI->getOperand(i));
|
MIB.addOperand(MI->getOperand(i));
|
||||||
}
|
}
|
||||||
@ -13430,7 +13460,7 @@ X86TargetLowering::emitEHSjLjLongJmp(MachineInstr *MI,
|
|||||||
MIB = BuildMI(*MBB, MI, DL, TII->get(PtrLoadOpc), SP);
|
MIB = BuildMI(*MBB, MI, DL, TII->get(PtrLoadOpc), SP);
|
||||||
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
for (unsigned i = 0; i < X86::AddrNumOperands; ++i) {
|
||||||
if (i == X86::AddrDisp)
|
if (i == X86::AddrDisp)
|
||||||
MIB.addDisp(MI->getOperand(i), SP_Offset);
|
MIB.addDisp(MI->getOperand(i), SPOffset);
|
||||||
else
|
else
|
||||||
MIB.addOperand(MI->getOperand(i));
|
MIB.addOperand(MI->getOperand(i));
|
||||||
}
|
}
|
||||||
|
@ -67,15 +67,11 @@ MachineModuleInfoMachO &X86MCInstLower::getMachOMMI() const {
|
|||||||
/// operand to an MCSymbol.
|
/// operand to an MCSymbol.
|
||||||
MCSymbol *X86MCInstLower::
|
MCSymbol *X86MCInstLower::
|
||||||
GetSymbolFromOperand(const MachineOperand &MO) const {
|
GetSymbolFromOperand(const MachineOperand &MO) const {
|
||||||
assert((MO.isGlobal() || MO.isSymbol()) && "Isn't a symbol reference");
|
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) && "Isn't a symbol reference");
|
||||||
|
|
||||||
SmallString<128> Name;
|
SmallString<128> Name;
|
||||||
|
|
||||||
if (!MO.isGlobal()) {
|
if (MO.isGlobal()) {
|
||||||
assert(MO.isSymbol());
|
|
||||||
Name += MAI.getGlobalPrefix();
|
|
||||||
Name += MO.getSymbolName();
|
|
||||||
} else {
|
|
||||||
const GlobalValue *GV = MO.getGlobal();
|
const GlobalValue *GV = MO.getGlobal();
|
||||||
bool isImplicitlyPrivate = false;
|
bool isImplicitlyPrivate = false;
|
||||||
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
|
if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB ||
|
||||||
@ -85,6 +81,11 @@ GetSymbolFromOperand(const MachineOperand &MO) const {
|
|||||||
isImplicitlyPrivate = true;
|
isImplicitlyPrivate = true;
|
||||||
|
|
||||||
Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
|
Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate);
|
||||||
|
} else if (MO.isSymbol()) {
|
||||||
|
Name += MAI.getGlobalPrefix();
|
||||||
|
Name += MO.getSymbolName();
|
||||||
|
} else if (MO.isMBB()) {
|
||||||
|
Name += MO.getMBB()->getSymbol()->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the target flags on the operand changes the name of the symbol, do that
|
// If the target flags on the operand changes the name of the symbol, do that
|
||||||
@ -215,7 +216,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
|
|||||||
if (Expr == 0)
|
if (Expr == 0)
|
||||||
Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
|
Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);
|
||||||
|
|
||||||
if (!MO.isJTI() && MO.getOffset())
|
if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
|
||||||
Expr = MCBinaryExpr::CreateAdd(Expr,
|
Expr = MCBinaryExpr::CreateAdd(Expr,
|
||||||
MCConstantExpr::Create(MO.getOffset(), Ctx),
|
MCConstantExpr::Create(MO.getOffset(), Ctx),
|
||||||
Ctx);
|
Ctx);
|
||||||
@ -348,9 +349,6 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
|||||||
MCOp = MCOperand::CreateImm(MO.getImm());
|
MCOp = MCOperand::CreateImm(MO.getImm());
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_MachineBasicBlock:
|
case MachineOperand::MO_MachineBasicBlock:
|
||||||
MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
|
||||||
MO.getMBB()->getSymbol(), Ctx));
|
|
||||||
break;
|
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
case MachineOperand::MO_ExternalSymbol:
|
case MachineOperand::MO_ExternalSymbol:
|
||||||
MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
|
MCOp = LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
; RUN: llc < %s -mtriple=i386-pc-linux -mcpu=corei7 -relocation-model=static | FileCheck --check-prefix=X86 %s
|
; RUN: llc < %s -mtriple=i386-pc-linux -mcpu=corei7 -relocation-model=static | FileCheck --check-prefix=X86 %s
|
||||||
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7 | FileCheck --check-prefix=X64 %s
|
; RUN: llc < %s -mtriple=i386-pc-linux -mcpu=corei7 -relocation-model=pic | FileCheck --check-prefix=PIC86 %s
|
||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7 -relocation-model=static | FileCheck --check-prefix=X64 %s
|
||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=corei7 -relocation-model=pic | FileCheck --check-prefix=PIC64 %s
|
||||||
|
|
||||||
@buf = internal global [5 x i8*] zeroinitializer
|
@buf = internal global [5 x i8*] zeroinitializer
|
||||||
|
|
||||||
@ -20,14 +22,26 @@ define i32 @sj0() nounwind {
|
|||||||
ret i32 %r
|
ret i32 %r
|
||||||
; X86: sj0
|
; X86: sj0
|
||||||
; x86: movl %ebp, buf
|
; x86: movl %ebp, buf
|
||||||
; x86: movl ${{.*LBB.*}}, buf+4
|
|
||||||
; X86: movl %esp, buf+8
|
; X86: movl %esp, buf+8
|
||||||
|
; x86: movl ${{.*LBB.*}}, buf+4
|
||||||
; X86: ret
|
; X86: ret
|
||||||
|
; PIC86: sj0
|
||||||
|
; PIC86: movl %ebp, buf@GOTOFF(%[[GOT:.*]])
|
||||||
|
; PIC86: movl %esp, buf@GOTOFF+8(%[[GOT]])
|
||||||
|
; PIC86: leal {{.*LBB.*}}@GOTOFF(%[[GOT]]), %[[LREG:.*]]
|
||||||
|
; PIC86: movl %[[LREG]], buf@GOTOFF+4
|
||||||
|
; PIC86: ret
|
||||||
; X64: sj0
|
; X64: sj0
|
||||||
; x64: movq %rbp, buf(%rip)
|
; x64: movq %rbp, buf(%rip)
|
||||||
; x64: movq ${{.*LBB.*}}, buf+8(%rip)
|
; x64: movq ${{.*LBB.*}}, buf+8(%rip)
|
||||||
; X64: movq %rsp, buf+16(%rip)
|
; X64: movq %rsp, buf+16(%rip)
|
||||||
; X64: ret
|
; X64: ret
|
||||||
|
; PIC64: sj0
|
||||||
|
; PIC64: movq %rbp, buf(%rip)
|
||||||
|
; PIC64: movq %rsp, buf+16(%rip)
|
||||||
|
; PIC64: leaq {{.*LBB.*}}(%rip), %[[LREG:.*]]
|
||||||
|
; PIC64: movq %[[LREG]], buf+8(%rip)
|
||||||
|
; PIC64: ret
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @lj0() nounwind {
|
define void @lj0() nounwind {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user