Fix constant-offset emission for x86-64 absolute addresses. This
authorDan Gohman <gohman@apple.com>
Fri, 24 Oct 2008 01:57:54 +0000 (01:57 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 24 Oct 2008 01:57:54 +0000 (01:57 +0000)
fixes a bunch of test-suite JIT failures on x86-64 in
-relocation-model=static mode.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58066 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/MachineCodeEmitter.h
lib/Target/X86/X86CodeEmitter.cpp
lib/Target/X86/X86Relocations.h

index 4ef230c81b1487b2db5b554f762e3c32d4e583c2..822fced4cd9e752e7c68ec765fdcf5b170be63dc 100644 (file)
@@ -125,6 +125,42 @@ public:
     }
   }
 
+  /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in little-endian format.
+  ///
+  void emitDWordLE(uint64_t W) {
+    if (CurBufferPtr+8 <= BufferEnd) {
+      *CurBufferPtr++ = (unsigned char)(W >>  0);
+      *CurBufferPtr++ = (unsigned char)(W >>  8);
+      *CurBufferPtr++ = (unsigned char)(W >> 16);
+      *CurBufferPtr++ = (unsigned char)(W >> 24);
+      *CurBufferPtr++ = (unsigned char)(W >> 32);
+      *CurBufferPtr++ = (unsigned char)(W >> 40);
+      *CurBufferPtr++ = (unsigned char)(W >> 48);
+      *CurBufferPtr++ = (unsigned char)(W >> 56);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+  
+  /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
+  /// written to the output stream in big-endian format.
+  ///
+  void emitDWordBE(uint64_t W) {
+    if (CurBufferPtr+8 <= BufferEnd) {
+      *CurBufferPtr++ = (unsigned char)(W >> 56);
+      *CurBufferPtr++ = (unsigned char)(W >> 48);
+      *CurBufferPtr++ = (unsigned char)(W >> 40);
+      *CurBufferPtr++ = (unsigned char)(W >> 32);
+      *CurBufferPtr++ = (unsigned char)(W >> 24);
+      *CurBufferPtr++ = (unsigned char)(W >> 16);
+      *CurBufferPtr++ = (unsigned char)(W >>  8);
+      *CurBufferPtr++ = (unsigned char)(W >>  0);
+    } else {
+      CurBufferPtr = BufferEnd;
+    }
+  }
+
   /// emitAlignment - Move the CurBufferPtr pointer up the the specified
   /// alignment (saturated to BufferEnd of course).
   void emitAlignment(unsigned Alignment) {
index e5bef574e934543303e0d8a03f279083ff9f9b6e..729e4b663e2c7d04e2851ab1b6b19439862826cd 100644 (file)
@@ -72,10 +72,10 @@ namespace {
   private:
     void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
     void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
-                           int Disp = 0, intptr_t PCAdj = 0,
+                           intptr_t Disp = 0, intptr_t PCAdj = 0,
                            bool NeedStub = false, bool IsLazy = false);
     void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
-    void emitConstPoolAddress(unsigned CPI, unsigned Reloc, int Disp = 0,
+    void emitConstPoolAddress(unsigned CPI, unsigned Reloc, intptr_t Disp = 0,
                               intptr_t PCAdj = 0);
     void emitJumpTableAddress(unsigned JTI, unsigned Reloc,
                               intptr_t PCAdj = 0);
@@ -152,7 +152,8 @@ void Emitter::emitPCRelativeBlockAddress(MachineBasicBlock *MBB) {
 /// this is part of a "take the address of a global" instruction.
 ///
 void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
-                                int Disp /* = 0 */, intptr_t PCAdj /* = 0 */,
+                                intptr_t Disp /* = 0 */,
+                                intptr_t PCAdj /* = 0 */,
                                 bool NeedStub /* = false */,
                                 bool isLazy /* = false */) {
   intptr_t RelocCST = 0;
@@ -166,9 +167,11 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
     : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
                                GV, RelocCST, NeedStub);
   MCE.addRelocation(MR);
+  // The relocated value will be added to the displacement
   if (Reloc == X86::reloc_absolute_dword)
-    MCE.emitWordLE(0);
-  MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
+    MCE.emitDWordLE(Disp);
+  else
+    MCE.emitWordLE((int32_t)Disp);
 }
 
 /// emitExternalSymbolAddress - Arrange for the address of an external symbol to
@@ -179,15 +182,16 @@ void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
   MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
                                                  Reloc, ES, RelocCST));
   if (Reloc == X86::reloc_absolute_dword)
+    MCE.emitDWordLE(0);
+  else
     MCE.emitWordLE(0);
-  MCE.emitWordLE(0);
 }
 
 /// emitConstPoolAddress - Arrange for the address of an constant pool
 /// to be emitted to the current location in the function, and allow it to be PC
 /// relative.
 void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
-                                   int Disp /* = 0 */,
+                                   intptr_t Disp /* = 0 */,
                                    intptr_t PCAdj /* = 0 */) {
   intptr_t RelocCST = 0;
   if (Reloc == X86::reloc_picrel_word)
@@ -196,9 +200,11 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
     RelocCST = PCAdj;
   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
                                                     Reloc, CPI, RelocCST));
+  // The relocated value will be added to the displacement
   if (Reloc == X86::reloc_absolute_dword)
-    MCE.emitWordLE(0);
-  MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
+    MCE.emitDWordLE(Disp);
+  else
+    MCE.emitWordLE((int32_t)Disp);
 }
 
 /// emitJumpTableAddress - Arrange for the address of a jump table to
@@ -213,9 +219,11 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
     RelocCST = PCAdj;
   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
                                                     Reloc, JTI, RelocCST));
+  // The relocated value will be added to the displacement
   if (Reloc == X86::reloc_absolute_dword)
+    MCE.emitDWordLE(0);
+  else
     MCE.emitWordLE(0);
-  MCE.emitWordLE(0); // The relocated value will be added to the displacement
 }
 
 unsigned Emitter::getX86RegNum(unsigned RegNo) const {
@@ -554,7 +562,7 @@ void Emitter::emitInstruction(const MachineInstr &MI,
                TM.getSubtarget<X86Subtarget>().isTargetDarwin())) ||
           Opcode == X86::TAILJMPd;
         emitGlobalAddress(MO.getGlobal(), X86::reloc_pcrel_word,
-                          0, 0, NeedStub);
+                          MO.getOffset(), 0, NeedStub);
       } else if (MO.isSymbol()) {
         emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
       } else if (MO.isImm()) {
index 709ef865eef42f07597b796fd9d25768bbefc18f..b225f480e4ed9a7be46e179452d4bdddabd4b323 100644 (file)
@@ -18,6 +18,9 @@
 
 namespace llvm {
   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.
     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.