summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
diff options
context:
space:
mode:
authorFrancis Visoiu Mistrih <francisvm@yahoo.com>2018-02-09 21:47:07 +0000
committerFrancis Visoiu Mistrih <francisvm@yahoo.com>2018-02-09 21:47:07 +0000
commite67ed4c039cb013fabbb7dccd2a0239f1d2fc3dc (patch)
tree2b09094abd3f19f6500d96ec7098e30ba40d0942 /llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
parent0dc2ac54e129cba9b672f5ed5e932bc16601e9eb (diff)
downloadbcm5719-llvm-e67ed4c039cb013fabbb7dccd2a0239f1d2fc3dc.tar.gz
bcm5719-llvm-e67ed4c039cb013fabbb7dccd2a0239f1d2fc3dc.zip
[X86][MC] Fix assembling rip-relative addressing + immediate displacements
In the rare case where the input contains rip-relative addressing with immediate displacements, *and* the instruction ends with an immediate, we encode the instruction in the wrong way: movl $12345678, 0x400(%rdi) // all good, no rip-relative addr movl %eax, 0x400(%rip) // all good, no immediate at the end of the instruction movl $12345678, 0x400(%rip) // fails, encodes address as 0x3fc(%rip) Offset is a label: movl $12345678, foo(%rip) we want to account for the size of the immediate (in this case, $12345678, 4 bytes). Offset is an immediate: movl $12345678, 0x400(%rip) we should not account for the size of the immediate, assuming the immediate offset is what the user wanted. Differential Revision: https://reviews.llvm.org/D43050 llvm-svn: 324772
Diffstat (limited to 'llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp')
-rw-r--r--llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp10
1 files changed, 7 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index a7059c6914d..4ddc1f0ba42 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -396,10 +396,14 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
// 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
- // the size of the immediate field. If we have this case, add it into the
+ // means that we need to bias the displacement field of the instruction with
+ // the size of the immediate field. If we have this case, add it into the
// expression to emit.
- int ImmSize = X86II::hasImm(TSFlags) ? X86II::getSizeOfImm(TSFlags) : 0;
+ // Note: rip-relative addressing using immediate displacement values should
+ // not be adjusted, assuming it was the user's intent.
+ int ImmSize = !Disp.isImm() && X86II::hasImm(TSFlags)
+ ? X86II::getSizeOfImm(TSFlags)
+ : 0;
EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind),
CurByte, OS, Fixups, -ImmSize);
OpenPOWER on IntegriCloud