summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-08-28 21:23:43 +0000
committerChris Lattner <sabre@nondot.org>2003-08-28 21:23:43 +0000
commitaeb54b882c0ca460517b90c634d2846c5c2aaab3 (patch)
treed3d879208e18e89c70e361b016809b6307ae3aa3 /lib
parent81f0dbdc23235db3f056e7170c7cc1da1b3103f8 (diff)
downloadllvm-aeb54b882c0ca460517b90c634d2846c5c2aaab3.tar.gz
llvm-aeb54b882c0ca460517b90c634d2846c5c2aaab3.tar.bz2
llvm-aeb54b882c0ca460517b90c634d2846c5c2aaab3.tar.xz
Add support for the llvm.unwind intrinsic, which we codegen to just do an abort
until we implement unwinding. Add support for the invoke instruction, which codegens just like a call with a branch after it. The end effect of this change is that programs using the invoke instruction, but never unwinding, will work fine. Programs that unwind will abort until we get unwind support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8187 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp30
-rw-r--r--lib/Target/X86/X86ISelSimple.cpp30
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: