From c9f3cc3bdaf1ec134dec1f718e7f2e735b34b17b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 24 Oct 2008 01:57:54 +0000 Subject: [PATCH] Fix constant-offset emission for x86-64 absolute addresses. This 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 | 36 +++++++++++++++++++++++ lib/Target/X86/X86CodeEmitter.cpp | 30 ++++++++++++------- lib/Target/X86/X86Relocations.h | 3 ++ 3 files changed, 58 insertions(+), 11 deletions(-) diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 4ef230c81b1..822fced4cd9 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -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) { diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index e5bef574e93..729e4b663e2 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -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().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()) { diff --git a/lib/Target/X86/X86Relocations.h b/lib/Target/X86/X86Relocations.h index 709ef865eef..b225f480e4e 100644 --- a/lib/Target/X86/X86Relocations.h +++ b/lib/Target/X86/X86Relocations.h @@ -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.