llvm.org GIT mirror llvm / f32a6a3
add interpreter support for indirect goto / blockaddress. The interpreter now correctly runs clang's test/CodeGen/indirect-goto.c. The JIT will abort on it until someone feels compelled to implement this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85488 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 10 years ago
5 changed file(s) with 35 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
267267 ///
268268 virtual void *getPointerToFunction(Function *F) = 0;
269269
270 /// getPointerToBasicBlock - The different EE's represent basic blocks in
271 /// different ways. Return the representation for a blockaddress of the
272 /// specified block.
273 ///
274 virtual void *getPointerToBasicBlock(BasicBlock *BB) = 0;
275
270276 /// getPointerToFunctionOrStub - If the specified function has been
271277 /// code-gen'd, return a pointer to the function. If not, compile it, or use
272278 /// a stub to implement lazy compilation if available. See
759759 Result.PointerVal = 0;
760760 else if (const Function *F = dyn_cast(C))
761761 Result = PTOGV(getPointerToFunctionOrStub(const_cast(F)));
762 else if (const GlobalVariable* GV = dyn_cast(C))
762 else if (const GlobalVariable *GV = dyn_cast(C))
763763 Result = PTOGV(getOrEmitGlobalVariable(const_cast(GV)));
764 else if (const BlockAddress *BA = dyn_cast(C))
765 Result = PTOGV(getPointerToBasicBlock(const_cast(
766 BA->getBasicBlock())));
764767 else
765768 llvm_unreachable("Unknown constant pointer type!");
766769 break;
571571 // runAtExitHandlers() assumes there are no stack frames, but
572572 // if exit() was called, then it had a stack frame. Blow away
573573 // the stack before interpreting atexit handlers.
574 ECStack.clear ();
575 runAtExitHandlers ();
576 exit (GV.IntVal.zextOrTrunc(32).getZExtValue());
574 ECStack.clear();
575 runAtExitHandlers();
576 exit(GV.IntVal.zextOrTrunc(32).getZExtValue());
577577 }
578578
579579 /// Pop the last stack frame off of ECStack and then copy the result
584584 /// care of switching to the normal destination BB, if we are returning
585585 /// from an invoke.
586586 ///
587 void Interpreter::popStackAndReturnValueToCaller (const Type *RetTy,
588 GenericValue Result) {
587 void Interpreter::popStackAndReturnValueToCaller(const Type *RetTy,
588 GenericValue Result) {
589589 // Pop the current stack frame.
590590 ECStack.pop_back();
591591
628628 // Unwind stack
629629 Instruction *Inst;
630630 do {
631 ECStack.pop_back ();
632 if (ECStack.empty ())
631 ECStack.pop_back();
632 if (ECStack.empty())
633633 llvm_report_error("Empty stack during unwind!");
634 Inst = ECStack.back ().Caller.getInstruction ();
635 } while (!(Inst && isa (Inst)));
634 Inst = ECStack.back().Caller.getInstruction();
635 } while (!(Inst && isa(Inst)));
636636
637637 // Return from invoke
638 ExecutionContext &InvokingSF = ECStack.back ();
639 InvokingSF.Caller = CallSite ();
638 ExecutionContext &InvokingSF = ECStack.back();
639 InvokingSF.Caller = CallSite();
640640
641641 // Go to exceptional destination BB of invoke instruction
642642 SwitchToNewBasicBlock(cast(Inst)->getUnwindDest(), InvokingSF);
676676 if (!Dest) Dest = I.getDefaultDest(); // No cases matched: use default
677677 SwitchToNewBasicBlock(Dest, SF);
678678 }
679
680 void Interpreter::visitIndirectBrInst(IndirectBrInst &I) {
681 ExecutionContext &SF = ECStack.back();
682 void *Dest = GVTOP(getOperandValue(I.getAddress(), SF));
683 SwitchToNewBasicBlock((BasicBlock*)Dest, SF);
684 }
685
679686
680687 // SwitchToNewBasicBlock - This method is used to jump to a new basic block.
681688 // This function handles the actual updating of block and instruction iterators
826833
827834 // Check to see if this is an intrinsic function call...
828835 Function *F = CS.getCalledFunction();
829 if (F && F->isDeclaration ())
836 if (F && F->isDeclaration())
830837 switch (F->getIntrinsicID()) {
831838 case Intrinsic::not_intrinsic:
832839 break;
134134 void visitReturnInst(ReturnInst &I);
135135 void visitBranchInst(BranchInst &I);
136136 void visitSwitchInst(SwitchInst &I);
137 void visitIndirectBrInst(IndirectBrInst &I);
137138
138139 void visitBinaryOperator(BinaryOperator &I);
139140 void visitICmpInst(ICmpInst &I);
201202 void SwitchToNewBasicBlock(BasicBlock *Dest, ExecutionContext &SF);
202203
203204 void *getPointerToFunction(Function *F) { return (void*)F; }
205 void *getPointerToBasicBlock(BasicBlock *BB) { return (void*)BB; }
204206
205207 void initializeExecutionEngine() { }
206208 void initializeExternalFunctions();
127127 ///
128128 void *getPointerToFunction(Function *F);
129129
130 void *getPointerToBasicBlock(BasicBlock *BB) {
131 assert(0 && "JIT does not support address-of-label yet!");
132 }
133
130134 /// getOrEmitGlobalVariable - Return the address of the specified global
131135 /// variable, possibly emitting it to memory if needed. This is used by the
132136 /// Emitter.