diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/X86FixupKinds.h | 3 | ||||
-rw-r--r-- | lib/Target/X86/X86MCCodeEmitter.cpp | 15 |
2 files changed, 14 insertions, 4 deletions
diff --git a/lib/Target/X86/X86FixupKinds.h b/lib/Target/X86/X86FixupKinds.h index c8dac3ce45..a8117d47bf 100644 --- a/lib/Target/X86/X86FixupKinds.h +++ b/lib/Target/X86/X86FixupKinds.h @@ -17,7 +17,8 @@ namespace X86 { enum Fixups { reloc_pcrel_4byte = FirstTargetFixupKind, // 32-bit pcrel, e.g. a branch. reloc_pcrel_1byte, // 8-bit pcrel, e.g. branch_1 - reloc_riprel_4byte // 32-bit rip-relative + reloc_riprel_4byte, // 32-bit rip-relative + reloc_riprel_4byte_movq_load // 32-bit rip-relative in movq }; } } diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index 3f18696d85..4547a3a331 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -38,14 +38,15 @@ public: ~X86MCCodeEmitter() {} unsigned getNumFixupKinds() const { - return 3; + return 4; } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[] = { { "reloc_pcrel_4byte", 0, 4 * 8 }, { "reloc_pcrel_1byte", 0, 1 * 8 }, - { "reloc_riprel_4byte", 0, 4 * 8 } + { "reloc_riprel_4byte", 0, 4 * 8 }, + { "reloc_riprel_4byte_movq_load", 0, 4 * 8 } }; if (Kind < FirstTargetFixupKind) @@ -197,6 +198,14 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, "Invalid rip-relative address"); EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS); + unsigned FixupKind = X86::reloc_riprel_4byte; + + // movq loads are handled with a special relocation form which allows the + // linker to eliminate some loads for GOT references which end up in the + // same linkage unit. + if (MI.getOpcode() == X86::MOV64rm_TC) + FixupKind = X86::reloc_riprel_4byte_movq_load; + // rip-relative addressing is actually relative to the *next* instruction. // Since an immediate can follow the mod/rm byte for an instruction, this // means that we need to bias the immediate field of the instruction with @@ -204,7 +213,7 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, // expression to emit. int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0; - EmitImmediate(Disp, 4, MCFixupKind(X86::reloc_riprel_4byte), + EmitImmediate(Disp, 4, MCFixupKind(FixupKind), CurByte, OS, Fixups, -ImmSize); return; } |