[PATCH] D93159: [X86] Add REX prefix for GOTTPOFF/TLSDESC relocs in x32 mode
Harald van Dijk via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 12 04:36:44 PST 2020
hvdijk created this revision.
hvdijk added reviewers: craig.topper, RKSimon.
Herald added subscribers: pengfei, hiraditya.
hvdijk requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
The REX prefix is needed to allow linker relaxations: even if the
instruction we emit may not need it, the linker may change it to a
different instruction which does need it.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D93159
Files:
llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
llvm/test/MC/X86/tlsdesc-x32.s
Index: llvm/test/MC/X86/tlsdesc-x32.s
===================================================================
--- /dev/null
+++ llvm/test/MC/X86/tlsdesc-x32.s
@@ -0,0 +1,20 @@
+# RUN: llvm-mc -triple x86_64-pc-linux-gnux32 %s | FileCheck --check-prefix=PRINT %s
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnux32 %s -o %t
+# RUN: llvm-readelf -s %t | FileCheck --check-prefix=SYM %s
+# RUN: llvm-objdump -d -r %t | FileCheck --match-full-lines %s
+
+# PRINT: leal a at tlsdesc(%rip), %eax
+# PRINT-NEXT: callq *a at tlscall(%eax)
+
+# SYM: TLS GLOBAL DEFAULT UND a
+
+# CHECK: 0: 40 8d 05 00 00 00 00 leal (%rip), %eax # 7 <{{.*}}>
+# CHECK-NEXT: 00000003: R_X86_64_GOTPC32_TLSDESC a-0x4
+# CHECK-NEXT: 7: 67 ff 10 callq *(%eax)
+# CHECK-NEXT: 00000007: R_X86_64_TLSDESC_CALL a
+# CHECK-NEXT: a: 8d 05 34 12 00 00 leal 4660(%rip), %eax # {{.*}}
+
+lea a at tlsdesc(%rip), %eax
+call *a at tlscall(%eax)
+lea 0x1234(%rip), %eax
Index: llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -93,7 +93,8 @@
bool emitOpcodePrefix(int MemOperand, const MCInst &MI,
const MCSubtargetInfo &STI, raw_ostream &OS) const;
- bool emitREXPrefix(int MemOperand, const MCInst &MI, raw_ostream &OS) const;
+ bool emitREXPrefix(int MemOperand, const MCInst &MI,
+ const MCSubtargetInfo &STI, raw_ostream &OS) const;
};
} // end anonymous namespace
@@ -1201,6 +1202,7 @@
///
/// \returns true if REX prefix is used, otherwise returns false.
bool X86MCCodeEmitter::emitREXPrefix(int MemOperand, const MCInst &MI,
+ const MCSubtargetInfo &STI,
raw_ostream &OS) const {
uint8_t REX = [&, MemOperand]() {
uint8_t REX = 0;
@@ -1221,15 +1223,27 @@
// If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
for (unsigned i = CurOp; i != NumOps; ++i) {
const MCOperand &MO = MI.getOperand(i);
- if (!MO.isReg())
- continue;
- unsigned Reg = MO.getReg();
- if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
- UsesHighByteReg = true;
- if (X86II::isX86_64NonExtLowByteReg(Reg))
- // FIXME: The caller of determineREXPrefix slaps this prefix onto
- // anything that returns non-zero.
- REX |= 0x40; // REX fixed encoding prefix
+ if (MO.isReg()) {
+ unsigned Reg = MO.getReg();
+ if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
+ UsesHighByteReg = true;
+ if (X86II::isX86_64NonExtLowByteReg(Reg))
+ // FIXME: The caller of determineREXPrefix slaps this prefix onto
+ // anything that returns non-zero.
+ REX |= 0x40; // REX fixed encoding prefix
+ } else if (MO.isExpr() &&
+ STI.getTargetTriple().getEnvironment() == Triple::GNUX32) {
+ // GOTTPOFF and TLSDESC relocations require a REX prefix to allow
+ // linker optimizations: even if the instructions we see may not require
+ // any prefix, they may be replaced by instructions that do. This is
+ // handled as a special case here so that it also works for hand-written
+ // assembly without the user needing to write REX, as with GNU as.
+ const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(MO.getExpr());
+ if (Ref && (Ref->getKind() == MCSymbolRefExpr::VK_GOTTPOFF ||
+ Ref->getKind() == MCSymbolRefExpr::VK_TLSDESC)) {
+ REX |= 0x40; // REX fixed encoding prefix
+ }
+ }
}
switch (TSFlags & X86II::FormMask) {
@@ -1352,7 +1366,7 @@
assert((STI.hasFeature(X86::Mode64Bit) || !(TSFlags & X86II::REX_W)) &&
"REX.W requires 64bit mode.");
bool HasREX = STI.hasFeature(X86::Mode64Bit)
- ? emitREXPrefix(MemOperand, MI, OS)
+ ? emitREXPrefix(MemOperand, MI, STI, OS)
: false;
// 0x0F escape code must be emitted just before the opcode.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D93159.311378.patch
Type: text/x-patch
Size: 4227 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201212/854f1f0d/attachment.bin>
More information about the llvm-commits
mailing list