aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Korobeynikov <asl@math.spbu.ru>2008-09-08 21:12:47 +0000
committerAnton Korobeynikov <asl@math.spbu.ru>2008-09-08 21:12:47 +0000
commit1ec04ee1d8cfcb49b0693bae8f1d32c4aec4a69e (patch)
tree4eaaf387fc22ca03dd37fdeff67ed7c5081f8ee3
parent566f9d9315c544560b0251330d6271e1c51e9397 (diff)
downloadexternal_llvm-1ec04ee1d8cfcb49b0693bae8f1d32c4aec4a69e.zip
external_llvm-1ec04ee1d8cfcb49b0693bae8f1d32c4aec4a69e.tar.gz
external_llvm-1ec04ee1d8cfcb49b0693bae8f1d32c4aec4a69e.tar.bz2
Reapply 55899: First draft of EH support on x86/64-linux
Now with fix, which prevents subtle codegen bug to trigger on darwin. No fix for bug though, it's still there. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55955 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Intrinsics.td4
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp23
-rw-r--r--lib/Target/X86/X86Instr64bit.td11
-rw-r--r--lib/Target/X86/X86RegisterInfo.cpp58
4 files changed, 62 insertions, 34 deletions
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
index 5dd1d61..36d8337 100644
--- a/include/llvm/Intrinsics.td
+++ b/include/llvm/Intrinsics.td
@@ -255,8 +255,8 @@ def int_eh_selector_i64 : Intrinsic<[llvm_i64_ty, llvm_ptr_ty, llvm_ptr_ty,
def int_eh_typeid_for_i32 : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
def int_eh_typeid_for_i64 : Intrinsic<[llvm_i64_ty, llvm_ptr_ty]>;
-def int_eh_return : Intrinsic<[llvm_void_ty, llvm_i32_ty, llvm_ptr_ty]>,
- GCCBuiltin<"__builtin_eh_return">;
+def int_eh_return_i32 : Intrinsic<[llvm_void_ty, llvm_i32_ty, llvm_ptr_ty]>;
+def int_eh_return_i64 : Intrinsic<[llvm_void_ty, llvm_i64_ty, llvm_ptr_ty]>;
def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
GCCBuiltin<"__builtin_unwind_init">;
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 93ffb41..83b8b0c 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -316,7 +316,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
if (Subtarget->is64Bit()) {
- // FIXME: Verify
setExceptionPointerRegister(X86::RAX);
setExceptionSelectorRegister(X86::RDX);
} else {
@@ -5596,7 +5595,7 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI,
- DAG.getIntPtrConstant(!Subtarget->is64Bit() ? 4 : 8));
+ DAG.getIntPtrConstant(Subtarget->is64Bit() ? 8 : 4));
}
SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op,
@@ -5606,26 +5605,26 @@ SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op,
SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
{
- assert(!Subtarget->is64Bit() &&
- "Lowering of eh_return builtin is not supported yet on x86-64");
-
MachineFunction &MF = DAG.getMachineFunction();
SDValue Chain = Op.getOperand(0);
SDValue Offset = Op.getOperand(1);
SDValue Handler = Op.getOperand(2);
- SDValue Frame = DAG.getRegister(RegInfo->getFrameRegister(MF),
- getPointerTy());
+ SDValue Frame = DAG.getRegister(Subtarget->is64Bit() ? X86::RBP : X86::EBP,
+ getPointerTy());
+ unsigned StoreAddrReg = (Subtarget->is64Bit() ? X86::RCX : X86::ECX);
SDValue StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
- DAG.getIntPtrConstant(-4UL));
+ DAG.getIntPtrConstant(Subtarget->is64Bit() ?
+ -8ULL: -4ULL));
StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
- Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
- MF.getRegInfo().addLiveOut(X86::ECX);
+ Chain = DAG.getCopyToReg(Chain, StoreAddrReg, StoreAddr);
+ MF.getRegInfo().addLiveOut(StoreAddrReg);
- return DAG.getNode(X86ISD::EH_RETURN, MVT::Other,
- Chain, DAG.getRegister(X86::ECX, getPointerTy()));
+ return DAG.getNode(X86ISD::EH_RETURN,
+ MVT::Other,
+ Chain, DAG.getRegister(StoreAddrReg, getPointerTy()));
}
SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td
index 1bffac9..29066b5 100644
--- a/lib/Target/X86/X86Instr64bit.td
+++ b/lib/Target/X86/X86Instr64bit.td
@@ -130,6 +130,17 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
}
//===----------------------------------------------------------------------===//
+// EH Pseudo Instructions
+//
+let isTerminator = 1, isReturn = 1, isBarrier = 1,
+ hasCtrlDep = 1 in {
+def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
+ "ret\t#eh_return, addr: $addr",
+ [(X86ehret GR64:$addr)]>;
+
+}
+
+//===----------------------------------------------------------------------===//
// Miscellaneous Instructions...
//
let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, neverHasSideEffects = 1 in
diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp
index d7bf939..3a8209a 100644
--- a/lib/Target/X86/X86RegisterInfo.cpp
+++ b/lib/Target/X86/X86RegisterInfo.cpp
@@ -159,6 +159,14 @@ X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const {
const unsigned *
X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
+ bool callsEHReturn = false;
+
+ if (MF) {
+ const MachineFrameInfo *MFI = MF->getFrameInfo();
+ const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+ }
+
static const unsigned CalleeSavedRegs32Bit[] = {
X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0
};
@@ -171,6 +179,11 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
};
+ static const unsigned CalleeSavedRegs64EHRet[] = {
+ X86::RAX, X86::RDX, X86::RBX, X86::R12,
+ X86::R13, X86::R14, X86::R15, X86::RBP, 0
+ };
+
static const unsigned CalleeSavedRegsWin64[] = {
X86::RBX, X86::RBP, X86::RDI, X86::RSI,
X86::R12, X86::R13, X86::R14, X86::R15, 0
@@ -180,20 +193,22 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
if (IsWin64)
return CalleeSavedRegsWin64;
else
- return CalleeSavedRegs64Bit;
+ return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit);
} else {
- if (MF) {
- const MachineFrameInfo *MFI = MF->getFrameInfo();
- const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- if (MMI && MMI->callsEHReturn())
- return CalleeSavedRegs32EHRet;
- }
- return CalleeSavedRegs32Bit;
+ return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit);
}
}
const TargetRegisterClass* const*
X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
+ bool callsEHReturn = false;
+
+ if (MF) {
+ const MachineFrameInfo *MFI = MF->getFrameInfo();
+ const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
+ callsEHReturn = (MMI ? MMI->callsEHReturn() : false);
+ }
+
static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = {
&X86::GR32RegClass, &X86::GR32RegClass,
&X86::GR32RegClass, &X86::GR32RegClass, 0
@@ -208,6 +223,12 @@ X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
&X86::GR64RegClass, &X86::GR64RegClass,
&X86::GR64RegClass, &X86::GR64RegClass, 0
};
+ static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = {
+ &X86::GR64RegClass, &X86::GR64RegClass,
+ &X86::GR64RegClass, &X86::GR64RegClass,
+ &X86::GR64RegClass, &X86::GR64RegClass,
+ &X86::GR64RegClass, &X86::GR64RegClass, 0
+ };
static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = {
&X86::GR64RegClass, &X86::GR64RegClass,
&X86::GR64RegClass, &X86::GR64RegClass,
@@ -219,17 +240,12 @@ X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
if (IsWin64)
return CalleeSavedRegClassesWin64;
else
- return CalleeSavedRegClasses64Bit;
+ return (callsEHReturn ?
+ CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit);
} else {
- if (MF) {
- const MachineFrameInfo *MFI = MF->getFrameInfo();
- const MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
- if (MMI && MMI->callsEHReturn())
- return CalleeSavedRegClasses32EHRet;
- }
- return CalleeSavedRegClasses32Bit;
+ return (callsEHReturn ?
+ CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit);
}
-
}
BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
@@ -787,6 +803,7 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
case X86::TCRETURNri64:
case X86::TCRETURNdi64:
case X86::EH_RETURN:
+ case X86::EH_RETURN64:
case X86::TAILJMPd:
case X86::TAILJMPr:
case X86::TAILJMPm: break; // These are ok
@@ -860,12 +877,13 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
}
// We're returning from function via eh_return.
- if (RetOpcode == X86::EH_RETURN) {
+ if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) {
MBBI = prior(MBB.end());
MachineOperand &DestAddr = MBBI->getOperand(0);
assert(DestAddr.isRegister() && "Offset should be in register!");
- BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr).
- addReg(DestAddr.getReg());
+ BuildMI(MBB, MBBI,
+ TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
+ StackPtr).addReg(DestAddr.getReg());
// Tail call return: adjust the stack pointer and jump to callee
} else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi ||
RetOpcode== X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64) {