Move X86 specific code out of the JIT into the X86 backend
[oota-llvm.git] / lib / ExecutionEngine / JIT / Callback.cpp
1 //===-- Callback.cpp - Trap handler for function resolution ---------------===//
2 //
3 // This file defines the handler which is invoked when a reference to a
4 // non-codegen'd function is found.  This file defines target specific code
5 // which is used by the JIT.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "VM.h"
10 #include "Support/Statistic.h"
11 #include "llvm/CodeGen/MachineCodeEmitter.h"
12 #include <iostream>
13
14 static VM *TheVM = 0;
15
16 // CompilationCallback - Invoked the first time that a call site is found,
17 // which causes lazy compilation of the target function.
18 // 
19 void VM::CompilationCallback() {
20 #if defined(i386) || defined(__i386__) || defined(__x86__)
21   unsigned *StackPtr = (unsigned*)__builtin_frame_address(0);
22   unsigned RetAddr = (unsigned)__builtin_return_address(0);
23
24   assert(StackPtr[1] == RetAddr &&
25          "Could not find return address on the stack!");
26   bool isStub = ((unsigned char*)RetAddr)[0] == 0xCD;  // Interrupt marker?
27
28   // The call instruction should have pushed the return value onto the stack...
29   RetAddr -= 4;  // Backtrack to the reference itself...
30
31   DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << RetAddr
32                   << " ESP=0x" << (unsigned)StackPtr << std::dec
33                   << ": Resolving call to function: "
34                   << TheVM->getFunctionReferencedName((void*)RetAddr) << "\n");
35
36   // Sanity check to make sure this really is a call instruction...
37   assert(((unsigned char*)RetAddr)[-1] == 0xE8 && "Not a call instr!");
38   
39   unsigned NewVal = (unsigned)TheVM->resolveFunctionReference((void*)RetAddr);
40
41   // Rewrite the call target... so that we don't fault every time we execute
42   // the call.
43   *(unsigned*)RetAddr = NewVal-RetAddr-4;    
44
45   if (isStub) {
46     // If this is a stub, rewrite the call into an unconditional branch
47     // instruction so that two return addresses are not pushed onto the stack
48     // when the requested function finally gets called.  This also makes the
49     // 0xCD byte (interrupt) dead, so the marker doesn't effect anything.
50     ((unsigned char*)RetAddr)[-1] = 0xE9;
51   }
52
53   // Change the return address to reexecute the call instruction...
54   StackPtr[1] -= 5;
55 #else
56   abort();
57 #endif
58 }
59
60 /// emitStubForFunction - This virtual method is used by the JIT when it needs
61 /// to emit the address of a function for a function whose code has not yet
62 /// been generated.  In order to do this, it generates a stub which jumps to
63 /// the lazy function compiler, which will eventually get fixed to call the
64 /// function directly.
65 ///
66 void *VM::emitStubForFunction(const Function &F) {
67 #if defined(i386) || defined(__i386__) || defined(__x86__)
68   MCE->startFunctionStub(F, 6);
69   MCE->emitByte(0xE8);   // Call with 32 bit pc-rel destination...
70   MCE->emitGlobalAddress((GlobalValue*)&F, true);
71   MCE->emitByte(0xCD);   // Interrupt - Just a marker identifying the stub!
72   return MCE->finishFunctionStub(F);
73 #else
74   abort();
75 #endif
76 }
77
78 void VM::registerCallback() {
79   TheVM = this;
80 }
81
82