mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Add support for the unwind instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8408 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a6ce898dad
commit
36143fc444
@ -229,6 +229,7 @@ ret { RET_TOK(TermOpVal, Ret, RET); }
|
||||
br { RET_TOK(TermOpVal, Br, BR); }
|
||||
switch { RET_TOK(TermOpVal, Switch, SWITCH); }
|
||||
invoke { RET_TOK(TermOpVal, Invoke, INVOKE); }
|
||||
unwind { RET_TOK(TermOpVal, Unwind, UNWIND); }
|
||||
|
||||
|
||||
malloc { RET_TOK(MemOpVal, Malloc, MALLOC); }
|
||||
|
@ -701,7 +701,7 @@ Module *RunVMAsmParser(const std::string &Filename, FILE *F) {
|
||||
%token OPAQUE NOT EXTERNAL TARGET ENDIAN POINTERSIZE LITTLE BIG
|
||||
|
||||
// Basic Block Terminating Operators
|
||||
%token <TermOpVal> RET BR SWITCH
|
||||
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND
|
||||
|
||||
// Binary Operators
|
||||
%type <BinaryOpVal> BinaryOps // all the binary operators
|
||||
@ -714,7 +714,7 @@ Module *RunVMAsmParser(const std::string &Filename, FILE *F) {
|
||||
|
||||
// Other Operators
|
||||
%type <OtherOpVal> ShiftOps
|
||||
%token <OtherOpVal> PHI CALL INVOKE CAST SHL SHR VA_ARG
|
||||
%token <OtherOpVal> PHI CALL CAST SHL SHR VA_ARG
|
||||
|
||||
%start Module
|
||||
%%
|
||||
@ -1535,6 +1535,9 @@ BBTerminatorInst : RET ResolvedVal { // Return with a result...
|
||||
$$ = new InvokeInst(V, Normal, Except, *$5);
|
||||
}
|
||||
delete $5;
|
||||
}
|
||||
| UNWIND {
|
||||
$$ = new UnwindInst();
|
||||
};
|
||||
|
||||
|
||||
|
@ -421,6 +421,9 @@ bool BytecodeParser::ParseInstruction(const unsigned char *&Buf,
|
||||
Res = new StoreInst(getValue(ValTy, Raw.Arg1), Ptr, Raw.Opcode == 63);
|
||||
return false;
|
||||
}
|
||||
case Instruction::Unwind:
|
||||
if (Raw.NumOperands != 0) return true;
|
||||
return new UnwindInst();
|
||||
} // end switch(Raw.Opcode)
|
||||
|
||||
std::cerr << "Unrecognized instruction! " << Raw.Opcode
|
||||
|
@ -117,6 +117,7 @@ namespace {
|
||||
void visitBranchInst(BranchInst &I);
|
||||
void visitSwitchInst(SwitchInst &I);
|
||||
void visitInvokeInst(InvokeInst &I);
|
||||
void visitUnwindInst(UnwindInst &I);
|
||||
|
||||
void visitPHINode(PHINode &I);
|
||||
void visitBinaryOperator(Instruction &I);
|
||||
@ -980,6 +981,19 @@ void CWriter::visitInvokeInst(InvokeInst &II) {
|
||||
}
|
||||
|
||||
|
||||
void CWriter::visitUnwindInst(UnwindInst &I) {
|
||||
// The unwind instructions causes a control flow transfer out of the current
|
||||
// function, unwinding the stack until a caller who used the invoke
|
||||
// instruction is found. In this context, we code generated the invoke
|
||||
// instruction to add an entry to the top of the jmpbuf_list. Thus, here we
|
||||
// just have to longjmp to the specified handler.
|
||||
Out << " if (__llvm_jmpbuf_list == 0) { /* llvm.unwind */\n"
|
||||
<< " printf(\"throw found with no handler!\\n\"); abort();\n"
|
||||
<< " }\n"
|
||||
<< " longjmp(__llvm_jmpbuf_list->buf, 1);\n";
|
||||
emittedInvoke = true;
|
||||
}
|
||||
|
||||
static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) {
|
||||
// If PHI nodes need copies, we need the copy code...
|
||||
if (isa<PHINode>(To->front()) ||
|
||||
|
@ -117,6 +117,7 @@ namespace {
|
||||
void visitBranchInst(BranchInst &I);
|
||||
void visitSwitchInst(SwitchInst &I);
|
||||
void visitInvokeInst(InvokeInst &I);
|
||||
void visitUnwindInst(UnwindInst &I);
|
||||
|
||||
void visitPHINode(PHINode &I);
|
||||
void visitBinaryOperator(Instruction &I);
|
||||
@ -980,6 +981,19 @@ void CWriter::visitInvokeInst(InvokeInst &II) {
|
||||
}
|
||||
|
||||
|
||||
void CWriter::visitUnwindInst(UnwindInst &I) {
|
||||
// The unwind instructions causes a control flow transfer out of the current
|
||||
// function, unwinding the stack until a caller who used the invoke
|
||||
// instruction is found. In this context, we code generated the invoke
|
||||
// instruction to add an entry to the top of the jmpbuf_list. Thus, here we
|
||||
// just have to longjmp to the specified handler.
|
||||
Out << " if (__llvm_jmpbuf_list == 0) { /* llvm.unwind */\n"
|
||||
<< " printf(\"throw found with no handler!\\n\"); abort();\n"
|
||||
<< " }\n"
|
||||
<< " longjmp(__llvm_jmpbuf_list->buf, 1);\n";
|
||||
emittedInvoke = true;
|
||||
}
|
||||
|
||||
static bool isGotoCodeNeccessary(BasicBlock *From, BasicBlock *To) {
|
||||
// If PHI nodes need copies, we need the copy code...
|
||||
if (isa<PHINode>(To->front()) ||
|
||||
|
@ -132,6 +132,7 @@ namespace {
|
||||
const std::vector<ValueRecord> &Args);
|
||||
void visitCallInst(CallInst &I);
|
||||
void visitInvokeInst(InvokeInst &II);
|
||||
void visitUnwindInst(UnwindInst &UI);
|
||||
void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I);
|
||||
|
||||
// Arithmetic operators
|
||||
@ -1020,6 +1021,10 @@ void ISel::visitInvokeInst(InvokeInst &II) {
|
||||
BuildMI(BB, X86::JMP, 1).addPCDisp(II.getNormalDest());
|
||||
}
|
||||
|
||||
void ISel::visitUnwindInst(UnwindInst &UI) {
|
||||
// unwind is not supported yet! Just abort when the unwind inst is executed!
|
||||
BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
|
||||
}
|
||||
|
||||
void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
|
||||
unsigned TmpReg1, TmpReg2;
|
||||
|
@ -132,6 +132,7 @@ namespace {
|
||||
const std::vector<ValueRecord> &Args);
|
||||
void visitCallInst(CallInst &I);
|
||||
void visitInvokeInst(InvokeInst &II);
|
||||
void visitUnwindInst(UnwindInst &UI);
|
||||
void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I);
|
||||
|
||||
// Arithmetic operators
|
||||
@ -1020,6 +1021,10 @@ void ISel::visitInvokeInst(InvokeInst &II) {
|
||||
BuildMI(BB, X86::JMP, 1).addPCDisp(II.getNormalDest());
|
||||
}
|
||||
|
||||
void ISel::visitUnwindInst(UnwindInst &UI) {
|
||||
// unwind is not supported yet! Just abort when the unwind inst is executed!
|
||||
BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
|
||||
}
|
||||
|
||||
void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
|
||||
unsigned TmpReg1, TmpReg2;
|
||||
|
@ -352,6 +352,7 @@ void MutateStructTypes::transformFunction(Function *m) {
|
||||
}
|
||||
case Instruction::Switch:
|
||||
case Instruction::Invoke:
|
||||
case Instruction::Unwind:
|
||||
assert(0 && "Insn not implemented!");
|
||||
|
||||
// Binary Instructions
|
||||
|
@ -196,6 +196,7 @@ private:
|
||||
markOverdefined(&I);
|
||||
visitTerminatorInst(I);
|
||||
}
|
||||
void visitUnwindInst (TerminatorInst &I) { /*returns void*/ }
|
||||
void visitAllocationInst(Instruction &I) { markOverdefined(&I); }
|
||||
void visitVarArgInst (Instruction &I) { markOverdefined(&I); }
|
||||
void visitFreeInst (Instruction &I) { /*returns void*/ }
|
||||
|
Loading…
Reference in New Issue
Block a user