mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
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
This commit is contained in:
parent
b1e5edc27e
commit
c9f3cc3bda
@ -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
|
/// emitAlignment - Move the CurBufferPtr pointer up the the specified
|
||||||
/// alignment (saturated to BufferEnd of course).
|
/// alignment (saturated to BufferEnd of course).
|
||||||
void emitAlignment(unsigned Alignment) {
|
void emitAlignment(unsigned Alignment) {
|
||||||
|
@ -72,10 +72,10 @@ namespace {
|
|||||||
private:
|
private:
|
||||||
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
|
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
|
||||||
void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
|
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);
|
bool NeedStub = false, bool IsLazy = false);
|
||||||
void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
|
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);
|
intptr_t PCAdj = 0);
|
||||||
void emitJumpTableAddress(unsigned JTI, unsigned Reloc,
|
void emitJumpTableAddress(unsigned JTI, unsigned Reloc,
|
||||||
intptr_t PCAdj = 0);
|
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.
|
/// this is part of a "take the address of a global" instruction.
|
||||||
///
|
///
|
||||||
void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
|
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 NeedStub /* = false */,
|
||||||
bool isLazy /* = false */) {
|
bool isLazy /* = false */) {
|
||||||
intptr_t RelocCST = 0;
|
intptr_t RelocCST = 0;
|
||||||
@ -166,9 +167,11 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
|
|||||||
: MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
|
: MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
|
||||||
GV, RelocCST, NeedStub);
|
GV, RelocCST, NeedStub);
|
||||||
MCE.addRelocation(MR);
|
MCE.addRelocation(MR);
|
||||||
|
// The relocated value will be added to the displacement
|
||||||
if (Reloc == X86::reloc_absolute_dword)
|
if (Reloc == X86::reloc_absolute_dword)
|
||||||
MCE.emitWordLE(0);
|
MCE.emitDWordLE(Disp);
|
||||||
MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
|
else
|
||||||
|
MCE.emitWordLE((int32_t)Disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// emitExternalSymbolAddress - Arrange for the address of an external symbol to
|
/// 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(),
|
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
|
||||||
Reloc, ES, RelocCST));
|
Reloc, ES, RelocCST));
|
||||||
if (Reloc == X86::reloc_absolute_dword)
|
if (Reloc == X86::reloc_absolute_dword)
|
||||||
|
MCE.emitDWordLE(0);
|
||||||
|
else
|
||||||
MCE.emitWordLE(0);
|
MCE.emitWordLE(0);
|
||||||
MCE.emitWordLE(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// emitConstPoolAddress - Arrange for the address of an constant pool
|
/// 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
|
/// to be emitted to the current location in the function, and allow it to be PC
|
||||||
/// relative.
|
/// relative.
|
||||||
void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
|
void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
|
||||||
int Disp /* = 0 */,
|
intptr_t Disp /* = 0 */,
|
||||||
intptr_t PCAdj /* = 0 */) {
|
intptr_t PCAdj /* = 0 */) {
|
||||||
intptr_t RelocCST = 0;
|
intptr_t RelocCST = 0;
|
||||||
if (Reloc == X86::reloc_picrel_word)
|
if (Reloc == X86::reloc_picrel_word)
|
||||||
@ -196,9 +200,11 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
|
|||||||
RelocCST = PCAdj;
|
RelocCST = PCAdj;
|
||||||
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
|
||||||
Reloc, CPI, RelocCST));
|
Reloc, CPI, RelocCST));
|
||||||
|
// The relocated value will be added to the displacement
|
||||||
if (Reloc == X86::reloc_absolute_dword)
|
if (Reloc == X86::reloc_absolute_dword)
|
||||||
MCE.emitWordLE(0);
|
MCE.emitDWordLE(Disp);
|
||||||
MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
|
else
|
||||||
|
MCE.emitWordLE((int32_t)Disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// emitJumpTableAddress - Arrange for the address of a jump table to
|
/// emitJumpTableAddress - Arrange for the address of a jump table to
|
||||||
@ -213,9 +219,11 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
|
|||||||
RelocCST = PCAdj;
|
RelocCST = PCAdj;
|
||||||
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
|
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
|
||||||
Reloc, JTI, RelocCST));
|
Reloc, JTI, RelocCST));
|
||||||
|
// The relocated value will be added to the displacement
|
||||||
if (Reloc == X86::reloc_absolute_dword)
|
if (Reloc == X86::reloc_absolute_dword)
|
||||||
|
MCE.emitDWordLE(0);
|
||||||
|
else
|
||||||
MCE.emitWordLE(0);
|
MCE.emitWordLE(0);
|
||||||
MCE.emitWordLE(0); // The relocated value will be added to the displacement
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Emitter::getX86RegNum(unsigned RegNo) const {
|
unsigned Emitter::getX86RegNum(unsigned RegNo) const {
|
||||||
@ -554,7 +562,7 @@ void Emitter::emitInstruction(const MachineInstr &MI,
|
|||||||
TM.getSubtarget<X86Subtarget>().isTargetDarwin())) ||
|
TM.getSubtarget<X86Subtarget>().isTargetDarwin())) ||
|
||||||
Opcode == X86::TAILJMPd;
|
Opcode == X86::TAILJMPd;
|
||||||
emitGlobalAddress(MO.getGlobal(), X86::reloc_pcrel_word,
|
emitGlobalAddress(MO.getGlobal(), X86::reloc_pcrel_word,
|
||||||
0, 0, NeedStub);
|
MO.getOffset(), 0, NeedStub);
|
||||||
} else if (MO.isSymbol()) {
|
} else if (MO.isSymbol()) {
|
||||||
emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
|
emitExternalSymbolAddress(MO.getSymbolName(), X86::reloc_pcrel_word);
|
||||||
} else if (MO.isImm()) {
|
} else if (MO.isImm()) {
|
||||||
|
@ -18,6 +18,9 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace X86 {
|
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 {
|
enum RelocationType {
|
||||||
// reloc_pcrel_word - PC relative relocation, add the relocated value to
|
// 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.
|
// the value already in memory, after we adjust it for where the PC is.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user