diff options
author | Bill Wendling <isanbard@gmail.com> | 2010-04-21 00:34:04 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2010-04-21 00:34:04 +0000 |
commit | 658c45911acda231d89ff442f24aa754dcc5c196 (patch) | |
tree | cccbd9cf92b2a6dbce9ddc815bd058de4ae94abf | |
parent | b1bfff9b2abc4be11ac499f29e79a78e27e9ba25 (diff) | |
download | external_llvm-658c45911acda231d89ff442f24aa754dcc5c196.zip external_llvm-658c45911acda231d89ff442f24aa754dcc5c196.tar.gz external_llvm-658c45911acda231d89ff442f24aa754dcc5c196.tar.bz2 |
Handle a displacement location in 64-bit as an RIP-relative displacement. It
fixes a bug (<rdar://problem/7880900>) in the JIT. This code wouldn't work:
target triple = "x86_64-apple-darwin"
define double @func(double %a) {
%tmp1 = fmul double %a, 5.000000e-01 ; <double> [#uses=1]
ret double %tmp1
}
define i32 @main() nounwind {
%1 = call double @func(double 4.770000e-04) ; <i64> [#uses=0]
ret i32 0
}
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101965 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86CodeEmitter.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index cbc4ba3..8f02604 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -380,6 +380,16 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI, const MachineOperand &IndexReg = MI.getOperand(Op+2); unsigned BaseReg = Base.getReg(); + + // Handle %rip relative addressing. + if (BaseReg == X86::RIP || + (Is64BitMode && DispForReloc)) { // [disp32+RIP] in X86-64 mode + assert(IndexReg.getReg() == 0 && Is64BitMode && + "Invalid rip-relative address"); + MCE.emitByte(ModRMByte(0, RegOpcodeField, 5)); + emitDisplacementField(DispForReloc, DispVal, PCAdj, true); + return; + } // Indicate that the displacement will use an pcrel or absolute reference // by default. MCEs able to resolve addresses on-the-fly use pcrel by default @@ -447,7 +457,7 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI, // Emit the normal disp32 encoding. MCE.emitByte(ModRMByte(2, RegOpcodeField, 4)); ForceDisp32 = true; - } else if (DispVal == 0 && getX86RegNum(BaseReg) != N86::EBP) { + } else if (DispVal == 0 && BaseRegNo != N86::EBP) { // Emit no displacement ModR/M byte MCE.emitByte(ModRMByte(0, RegOpcodeField, 4)); } else if (isDisp8(DispVal)) { |