X86 JIT PIC jumptable support.
authorEvan Cheng <evan.cheng@apple.com>
Sat, 5 Jan 2008 02:26:58 +0000 (02:26 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Sat, 5 Jan 2008 02:26:58 +0000 (02:26 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45616 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineCodeEmitter.h
include/llvm/Target/TargetJITInfo.h
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86JITInfo.cpp
lib/Target/X86/X86JITInfo.h

index ede40d13cfbab1519fc222a880f8ea9e73f3913e..2c207f22f8568f3232850dcac73546f756bcbbf8 100644 (file)
@@ -58,6 +58,7 @@ protected:
   /// all code emission requests will be ignored (this is the buffer overflow
   /// condition).
   unsigned char *CurBufferPtr;
+
 public:
   virtual ~MachineCodeEmitter() {}
 
index 3be6cb79ce9141cc9efb00914747ebdfcdb03515..1ad927b9b04d1220148d69abf472e6c1c4a4283d 100644 (file)
@@ -55,6 +55,13 @@ namespace llvm {
       return 0;
     }
 
+    /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
+    /// specific basic block.
+    virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase) {
+      assert(0 && "This target doesn't implement getPICJumpTableEntry!");
+      return 0;
+    }
+
     /// LazyResolverFn - This typedef is used to represent the function that
     /// unresolved call points should invoke.  This is a target specific
     /// function that knows how to walk the stack and find out which stub the
index aa572a408f8e1b4cdf71204f01a2064bfcb9dbad..049b3bc4a368061a5b4089e074fba9dea3e3e59f 100644 (file)
@@ -341,7 +341,7 @@ namespace {
     /// JumpTableBase - A pointer to the first entry in the jump table.
     ///
     void *JumpTableBase;
-    
+
     /// Resolver - This contains info about the currently resolved functions.
     JITResolver Resolver;
   public:
@@ -380,7 +380,7 @@ namespace {
 
     virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const;
     virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const;
-    
+
     virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
       assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 
              MBBLocations[MBB->getNumber()] && "MBB not emitted!");
@@ -616,8 +616,10 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
       // Store the offset of the basic block for this jump table slot in the
       // memory we allocated for the jump table in 'initJumpTableInfo'
       intptr_t Base = (intptr_t)SlotPtr;
-      for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi)
-        *SlotPtr++ = (intptr_t)getMachineBasicBlockAddress(MBBs[mi]) - Base;
+      for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
+        intptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]);
+        *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base);
+      }
     }
   } else {
     assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
index d531fd5f7b6b4f3b627b7452fa7a779663145698..bc2c007a6bce3fafa95d745f136565bd710771c1 100644 (file)
@@ -14,6 +14,7 @@
 
 #define DEBUG_TYPE "x86-emitter"
 #include "X86InstrInfo.h"
+#include "X86JITInfo.h"
 #include "X86Subtarget.h"
 #include "X86TargetMachine.h"
 #include "X86Relocations.h"
@@ -37,19 +38,19 @@ namespace {
     const TargetData    *TD;
     TargetMachine       &TM;
     MachineCodeEmitter  &MCE;
-    intptr_t PICBase;
+    intptr_t PICBaseOffset;
     bool Is64BitMode;
     bool IsPIC;
   public:
     static char ID;
     explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
       : MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm), 
-      MCE(mce), PICBase(0), Is64BitMode(false),
+      MCE(mce), PICBaseOffset(0), Is64BitMode(false),
       IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
     Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
             const X86InstrInfo &ii, const TargetData &td, bool is64)
       : MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm), 
-      MCE(mce), PICBase(0), Is64BitMode(is64),
+      MCE(mce), PICBaseOffset(0), Is64BitMode(is64),
       IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
 
     bool runOnMachineFunction(MachineFunction &MF);
@@ -148,7 +149,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
                                 bool isLazy /* = false */) {
   intptr_t RelocCST = 0;
   if (Reloc == X86::reloc_picrel_word)
-    RelocCST = PICBase;
+    RelocCST = PICBaseOffset;
   else if (Reloc == X86::reloc_pcrel_word)
     RelocCST = PCAdj;
   MachineRelocation MR = isLazy 
@@ -166,7 +167,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
 /// be emitted to the current location in the function, and allow it to be PC
 /// relative.
 void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
-  intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBase : 0;
+  intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBaseOffset : 0;
   MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
                                                  Reloc, ES, RelocCST));
   if (Reloc == X86::reloc_absolute_dword)
@@ -182,7 +183,7 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
                                    intptr_t PCAdj /* = 0 */) {
   intptr_t RelocCST = 0;
   if (Reloc == X86::reloc_picrel_word)
-    RelocCST = PICBase;
+    RelocCST = PICBaseOffset;
   else if (Reloc == X86::reloc_pcrel_word)
     RelocCST = PCAdj;
   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
@@ -199,7 +200,7 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
                                    intptr_t PCAdj /* = 0 */) {
   intptr_t RelocCST = 0;
   if (Reloc == X86::reloc_picrel_word)
-    RelocCST = PICBase;
+    RelocCST = PICBaseOffset;
   else if (Reloc == X86::reloc_pcrel_word)
     RelocCST = PCAdj;
   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
@@ -615,13 +616,17 @@ void Emitter::emitInstruction(const MachineInstr &MI,
     case X86::FP_REG_KILL:
       break;
 #endif
-    case X86::MOVPC32r:
+    case X86::MOVPC32r: {
       // This emits the "call" portion of this pseudo instruction.
       MCE.emitByte(BaseOpcode);
       emitConstant(0, sizeOfImm(Desc));
-      PICBase = MCE.getCurrentPCOffset();
+      // Remember PIC base.
+      PICBaseOffset = MCE.getCurrentPCOffset();
+      X86JITInfo *JTI = dynamic_cast<X86JITInfo*>(TM.getJITInfo());
+      JTI->setPICBase(MCE.getCurrentPCValue());
       break;
     }
+    }
     CurOp = NumOps;
     break;
 
index d5d3cda2dc6c3237348cea413d2d78dff4dc11c2..dd451176568ef15d14a183d82152962770a0f543 100644 (file)
@@ -440,6 +440,12 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
   return MCE.finishFunctionStub(0);
 }
 
+/// getPICJumpTableEntry - Returns the value of the jumptable entry for the
+/// specific basic block.
+intptr_t X86JITInfo::getPICJumpTableEntry(intptr_t BB, intptr_t Entry) {
+  return BB - PICBase;
+}
+
 /// relocate - Before the JIT can run a block of code that has been emitted,
 /// it must rewrite the code to contain the actual addresses of any
 /// referenced global symbols.
index f1639040c422550afc95c99e3474c4adbc3ea8c9..183e2f2bb81a448f6514bbcb87aaa33b8df33f21 100644 (file)
@@ -21,6 +21,7 @@ namespace llvm {
 
   class X86JITInfo : public TargetJITInfo {
     X86TargetMachine &TM;
+    intptr_t PICBase;
   public:
     X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
 
@@ -40,6 +41,10 @@ namespace llvm {
     /// address.
     virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
 
+    /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
+    /// specific basic block.
+    virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase);
+
     /// getLazyResolverFunction - Expose the lazy resolver to the JIT.
     virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
 
@@ -48,6 +53,11 @@ namespace llvm {
     /// referenced global symbols.
     virtual void relocate(void *Function, MachineRelocation *MR,
                           unsigned NumRelocs, unsigned char* GOTBase);
+
+    /// setPICBase / getPICBase - Getter / setter of PICBase, used to compute
+    /// PIC jumptable entry.
+    void setPICBase(intptr_t Base) { PICBase = Base; }
+    intptr_t getPICBase() const { return PICBase; }
   };
 }