diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/InstSelectSimple.cpp | 30 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 30 |
2 files changed, 58 insertions, 2 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: diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index 03ae7d1d10..f754d11066 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.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: |