summaryrefslogtreecommitdiff
path: root/lib/Target/X86/InstSelectSimple.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/InstSelectSimple.cpp')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp30
1 files changed, 29 insertions, 1 deletions
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 03ae7d1d10..f754d11066 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -131,6 +131,7 @@ namespace {
void doCall(const ValueRecord &Ret, MachineInstr *CallMI,
const std::vector<ValueRecord> &Args);
void visitCallInst(CallInst &I);
+ void visitInvokeInst(InvokeInst &II);
void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I);
// Arithmetic operators
@@ -994,6 +995,32 @@ void ISel::visitCallInst(CallInst &CI) {
doCall(ValueRecord(DestReg, CI.getType()), TheCall, Args);
}
+
+// visitInvokeInst - For now, we don't support the llvm.unwind intrinsic, so
+// invoke's are just calls with an unconditional branch after them!
+void ISel::visitInvokeInst(InvokeInst &II) {
+ MachineInstr *TheCall;
+ if (Function *F = II.getCalledFunction()) {
+ // Emit a CALL instruction with PC-relative displacement.
+ TheCall = BuildMI(X86::CALLpcrel32, 1).addGlobalAddress(F, true);
+ } else { // Emit an indirect call...
+ unsigned Reg = getReg(II.getCalledValue());
+ TheCall = BuildMI(X86::CALLr32, 1).addReg(Reg);
+ }
+
+ std::vector<ValueRecord> Args;
+ for (unsigned i = 3, e = II.getNumOperands(); i != e; ++i)
+ Args.push_back(ValueRecord(II.getOperand(i)));
+
+ unsigned DestReg = II.getType() != Type::VoidTy ? getReg(II) : 0;
+ doCall(ValueRecord(DestReg, II.getType()), TheCall, Args);
+
+ // If the normal destination is not the next basic block, emit a 'jmp'.
+ if (II.getNormalDest() != getBlockAfter(II.getParent()))
+ BuildMI(BB, X86::JMP, 1).addPCDisp(II.getNormalDest());
+}
+
+
void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
unsigned TmpReg1, TmpReg2;
switch (ID) {
@@ -1012,9 +1039,10 @@ void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1);
return;
+ case LLVMIntrinsic::unwind: // llvm.unwind is not supported yet!
case LLVMIntrinsic::longjmp:
case LLVMIntrinsic::siglongjmp:
- BuildMI(X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
+ BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
return;
case LLVMIntrinsic::setjmp: