[llvm-commits] [llvm] r78129 - in /llvm/trunk: include/llvm/CodeGen/JITCodeEmitter.h include/llvm/CodeGen/MachineCodeEmitter.h include/llvm/CodeGen/ObjectCodeEmitter.h lib/Target/X86/X86CodeEmitter.cpp lib/Target/X86/X86JITInfo.cpp lib/Target/X86/X86Relocations.h

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Tue Aug 4 17:11:22 PDT 2009


Author: bruno
Date: Tue Aug  4 19:11:21 2009
New Revision: 78129

URL: http://llvm.org/viewvc/llvm-project?rev=78129&view=rev
Log:
1) Proper emit displacements for x86, using absolute relocations where necessary
for ELF to work.  
2) RIP addressing: Use SIB bytes for absolute relocations where RegBase=0, 
IndexReg=0.
3) The JIT can get the real address of cstpools and jmptables during
code emission, fix that for object code emission

Modified:
    llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h
    llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
    llvm/trunk/include/llvm/CodeGen/ObjectCodeEmitter.h
    llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
    llvm/trunk/lib/Target/X86/X86JITInfo.cpp
    llvm/trunk/lib/Target/X86/X86Relocations.h

Modified: llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/JITCodeEmitter.h Tue Aug  4 19:11:21 2009
@@ -289,6 +289,13 @@
     return CurBufferPtr-BufferBegin;
   }
 
+  /// earlyResolveAddresses - True if the code emitter can use symbol addresses 
+  /// during code emission time. The JIT is capable of doing this because it
+  /// creates jump tables or constant pools in memory on the fly while the
+  /// object code emitters rely on a linker to have real addresses and should
+  /// use relocations instead.
+  bool earlyResolveAddresses() const { return true; }
+
   /// addRelocation - Whenever a relocatable address is needed, it should be
   /// noted with this interface.
   virtual void addRelocation(const MachineRelocation &MR) = 0;

Modified: llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineCodeEmitter.h Tue Aug  4 19:11:21 2009
@@ -280,6 +280,13 @@
     return CurBufferPtr-BufferBegin;
   }
 
+  /// earlyResolveAddresses - True if the code emitter can use symbol addresses 
+  /// during code emission time. The JIT is capable of doing this because it
+  /// creates jump tables or constant pools in memory on the fly while the
+  /// object code emitters rely on a linker to have real addresses and should
+  /// use relocations instead.
+  virtual bool earlyResolveAddresses() const = 0;
+
   /// addRelocation - Whenever a relocatable address is needed, it should be
   /// noted with this interface.
   virtual void addRelocation(const MachineRelocation &MR) = 0;

Modified: llvm/trunk/include/llvm/CodeGen/ObjectCodeEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ObjectCodeEmitter.h?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ObjectCodeEmitter.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ObjectCodeEmitter.h Tue Aug  4 19:11:21 2009
@@ -109,6 +109,13 @@
   /// noted with this interface.
   void addRelocation(const MachineRelocation& relocation);
 
+  /// earlyResolveAddresses - True if the code emitter can use symbol addresses 
+  /// during code emission time. The JIT is capable of doing this because it
+  /// creates jump tables or constant pools in memory on the fly while the
+  /// object code emitters rely on a linker to have real addresses and should
+  /// use relocations instead.
+  bool earlyResolveAddresses() const { return false; }
+
   /// startFunction - This callback is invoked when the specified function is
   /// about to be code generated.  This initializes the BufferBegin/End/Ptr
   /// fields.

Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Tue Aug  4 19:11:21 2009
@@ -87,7 +87,7 @@
                               intptr_t PCAdj = 0);
 
     void emitDisplacementField(const MachineOperand *RelocOp, int DispVal,
-                               intptr_t PCAdj = 0);
+                               intptr_t Adj = 0, bool IsPCRel = true);
 
     void emitRegModRMByte(unsigned ModRMReg, unsigned RegOpcodeField);
     void emitRegModRMByte(unsigned RegOpcodeField);
@@ -175,7 +175,7 @@
                                 intptr_t PCAdj /* = 0 */,
                                 bool NeedStub /* = false */,
                                 bool Indirect /* = false */) {
-  intptr_t RelocCST = 0;
+  intptr_t RelocCST = Disp;
   if (Reloc == X86::reloc_picrel_word)
     RelocCST = PICBaseOffset;
   else if (Reloc == X86::reloc_pcrel_word)
@@ -309,34 +309,42 @@
 
 template<class CodeEmitter>
 void Emitter<CodeEmitter>::emitDisplacementField(const MachineOperand *RelocOp,
-                                                 int DispVal, intptr_t PCAdj) {
+                                                 int DispVal,
+                                                 intptr_t Adj /* = 0 */,
+                                                 bool IsPCRel /* = true */) {
   // If this is a simple integer displacement that doesn't require a relocation,
   // emit it now.
   if (!RelocOp) {
     emitConstant(DispVal, 4);
     return;
   }
-  
+
   // Otherwise, this is something that requires a relocation.  Emit it as such
   // now.
   if (RelocOp->isGlobal()) {
     // In 64-bit static small code model, we could potentially emit absolute.
-    // But it's probably not beneficial.
+    // But it's probably not beneficial. If the MCE supports using RIP directly
+    // do it, otherwise fallback to absolute (this is determined by IsPCRel). 
     //  89 05 00 00 00 00     mov    %eax,0(%rip)  # PC-relative
     //  89 04 25 00 00 00 00  mov    %eax,0x0      # Absolute
-    unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
+    unsigned rt = Is64BitMode ?
+      (IsPCRel ? X86::reloc_pcrel_word : X86::reloc_absolute_word_sext)
       : (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
     bool NeedStub = isa<Function>(RelocOp->getGlobal());
     bool Indirect = gvNeedsNonLazyPtr(*RelocOp, TM);
     emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
-                      PCAdj, NeedStub, Indirect);
+                      Adj, NeedStub, Indirect);
   } else if (RelocOp->isCPI()) {
-    unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
+    unsigned rt = Is64BitMode ?
+      (IsPCRel ? X86::reloc_pcrel_word : X86::reloc_absolute_word_sext)
+      : (IsPCRel ? X86::reloc_picrel_word : X86::reloc_absolute_word);
     emitConstPoolAddress(RelocOp->getIndex(), rt,
-                         RelocOp->getOffset(), PCAdj);
+                         RelocOp->getOffset(), Adj);
   } else if (RelocOp->isJTI()) {
-    unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
-    emitJumpTableAddress(RelocOp->getIndex(), rt, PCAdj);
+    unsigned rt = Is64BitMode ?
+      (IsPCRel ? X86::reloc_pcrel_word : X86::reloc_absolute_word_sext)
+      : (IsPCRel ? X86::reloc_picrel_word : X86::reloc_absolute_word);
+    emitJumpTableAddress(RelocOp->getIndex(), rt, Adj);
   } else {
     llvm_unreachable("Unknown value to relocate!");
   }
@@ -354,14 +362,14 @@
   if (Op3.isGlobal()) {
     DispForReloc = &Op3;
   } else if (Op3.isCPI()) {
-    if (Is64BitMode || IsPIC) {
+    if (!MCE.earlyResolveAddresses() || Is64BitMode || IsPIC) {
       DispForReloc = &Op3;
     } else {
       DispVal += MCE.getConstantPoolEntryAddress(Op3.getIndex());
       DispVal += Op3.getOffset();
     }
   } else if (Op3.isJTI()) {
-    if (Is64BitMode || IsPIC) {
+    if (!MCE.earlyResolveAddresses() || Is64BitMode || IsPIC) {
       DispForReloc = &Op3;
     } else {
       DispVal += MCE.getJumpTableEntryAddress(Op3.getIndex());
@@ -376,17 +384,23 @@
 
   unsigned BaseReg = Base.getReg();
 
+  // Indicate that the displacement will use an pcrel or absolute reference
+  // by default. MCEs able to resolve addresses on-the-fly use pcrel by default
+  // while others, unless explicit asked to use RIP, use absolute references.
+  bool IsPCRel = MCE.earlyResolveAddresses() ? true : false;
+
   // Is a SIB byte needed?
+  // If no BaseReg, issue a RIP relative instruction only if the MCE can 
+  // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
+  // 2-7) and absolute references.
   if ((!Is64BitMode || DispForReloc || BaseReg != 0) &&
-      IndexReg.getReg() == 0 &&
-      (BaseReg == 0 || BaseReg == X86::RIP ||
-       getX86RegNum(BaseReg) != N86::ESP)) {
-    if (BaseReg == 0 ||
-        BaseReg == X86::RIP) {  // Just a displacement?
+      IndexReg.getReg() == 0 && 
+      ((BaseReg == 0 && MCE.earlyResolveAddresses()) || BaseReg == X86::RIP || 
+       (BaseReg != 0 && getX86RegNum(BaseReg) != N86::ESP))) {
+    if (BaseReg == 0 || BaseReg == X86::RIP) {  // Just a displacement?
       // Emit special case [disp32] encoding
       MCE.emitByte(ModRMByte(0, RegOpcodeField, 5));
-      
-      emitDisplacementField(DispForReloc, DispVal, PCAdj);
+      emitDisplacementField(DispForReloc, DispVal, PCAdj, true);
     } else {
       unsigned BaseRegNo = getX86RegNum(BaseReg);
       if (!DispForReloc && DispVal == 0 && BaseRegNo != N86::EBP) {
@@ -399,7 +413,7 @@
       } else {
         // Emit the most general non-SIB encoding: [REG+disp32]
         MCE.emitByte(ModRMByte(2, RegOpcodeField, BaseRegNo));
-        emitDisplacementField(DispForReloc, DispVal, PCAdj);
+        emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
       }
     }
 
@@ -435,13 +449,13 @@
     unsigned SS = SSTable[Scale.getImm()];
 
     if (BaseReg == 0) {
-      // Handle the SIB byte for the case where there is no base.  The
-      // displacement has already been output.
+      // Handle the SIB byte for the case where there is no base, see Intel 
+      // Manual 2A, table 2-7. The displacement has already been output.
       unsigned IndexRegNo;
       if (IndexReg.getReg())
         IndexRegNo = getX86RegNum(IndexReg.getReg());
-      else
-        IndexRegNo = 4;   // For example [ESP+1*<noreg>+4]
+      else // Examples: [ESP+1*<noreg>+4] or [scaled idx]+disp32 (MOD=0,BASE=5)
+        IndexRegNo = 4;
       emitSIBByte(SS, IndexRegNo, 5);
     } else {
       unsigned BaseRegNo = getX86RegNum(BaseReg);
@@ -457,7 +471,7 @@
     if (ForceDisp8) {
       emitConstant(DispVal, 1);
     } else if (DispVal != 0 || ForceDisp32) {
-      emitDisplacementField(DispForReloc, DispVal, PCAdj);
+      emitDisplacementField(DispForReloc, DispVal, PCAdj, IsPCRel);
     }
   }
 }

Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.cpp?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.cpp Tue Aug  4 19:11:21 2009
@@ -538,6 +538,7 @@
       break;
     }
     case X86::reloc_absolute_word:
+    case X86::reloc_absolute_word_sext:
       // Absolute relocation, just add the relocated value to the value already
       // in memory.
       *((unsigned*)RelocPos) += (unsigned)ResultPtr;

Modified: llvm/trunk/lib/Target/X86/X86Relocations.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Relocations.h?rev=78129&r1=78128&r2=78129&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86Relocations.h (original)
+++ llvm/trunk/lib/Target/X86/X86Relocations.h Tue Aug  4 19:11:21 2009
@@ -20,7 +20,9 @@
   namespace X86 {
     /// RelocationType - An enum for the x86 relocation codes. Note that
     /// the terminology here doesn't follow x86 convention - word means
-    /// 32-bit and dword means 64-bit.
+    /// 32-bit and dword means 64-bit. The relocations will be treated
+    /// by JIT or ObjectCode emitters, this is transparent to the x86 code 
+    /// emitter but JIT and ObjectCode will treat them differently
     enum RelocationType {
       /// reloc_pcrel_word - PC relative relocation, add the relocated value to
       /// the value already in memory, after we adjust it for where the PC is.
@@ -30,11 +32,19 @@
       /// value to the value already in memory, after we adjust it for where the
       /// PIC base is.
       reloc_picrel_word = 1,
-      
-      /// reloc_absolute_word, reloc_absolute_dword - Absolute relocation, just
-      /// add the relocated value to the value already in memory.
+
+      /// reloc_absolute_word - absolute relocation, just add the relocated
+      /// value to the value already in memory.
       reloc_absolute_word = 2,
-      reloc_absolute_dword = 3
+
+      /// reloc_absolute_word_sext - absolute relocation, just add the relocated
+      /// value to the value already in memory. In object files, it represents a
+      /// value which must be sign-extended when resolving the relocation.
+      reloc_absolute_word_sext = 3,
+
+      /// reloc_absolute_dword - absolute relocation, just add the relocated
+      /// value to the value already in memory.
+      reloc_absolute_dword = 4
     };
   }
 }





More information about the llvm-commits mailing list