From 5526b699014b0b58e08d7d43e28084589eda26f2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 11 Feb 2010 08:41:21 +0000 Subject: [PATCH] fix a really nasty bug I introduced in r95693: r12 (and r12d, r12b, etc) also encodes to a R/M value of 4, which is just as illegal as ESP/RSP for the non-sib version an address. This fixes x86-64 jit miscompilations of a bunch of programs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95866 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86CodeEmitter.cpp | 9 ++++++--- lib/Target/X86/X86MCCodeEmitter.cpp | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index f0bceb1483f..bcf3f15d423 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -387,10 +387,14 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI, // If no BaseReg, issue a RIP relative instruction only if the MCE can // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table // 2-7) and absolute references. + unsigned BaseRegNo = BaseReg != 0 ? getX86RegNum(BaseReg) : -1U; + if (// The SIB byte must be used if there is an index register. IndexReg.getReg() == 0 && - // The SIB byte must be used if the base is ESP/RSP. - BaseReg != X86::ESP && BaseReg != X86::RSP && + // The SIB byte must be used if the base is ESP/RSP/R12, all of which + // encode to an R/M value of 4, which indicates that a SIB byte is + // present. + BaseRegNo != N86::ESP && // If there is no base register and we're in 64-bit mode, we need a SIB // byte to emit an addr that is just 'disp32' (the non-RIP relative form). (!Is64BitMode || BaseReg != 0)) { @@ -401,7 +405,6 @@ void Emitter::emitMemModRMByte(const MachineInstr &MI, return; } - unsigned BaseRegNo = getX86RegNum(BaseReg); // If the base is not EBP/ESP and there is no displacement, use simple // indirect register encoding, this handles addresses like [EAX]. The // encoding for [EBP] with no displacement means [disp32] so we handle it diff --git a/lib/Target/X86/X86MCCodeEmitter.cpp b/lib/Target/X86/X86MCCodeEmitter.cpp index b13023cdbe3..ef1733f9939 100644 --- a/lib/Target/X86/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/X86MCCodeEmitter.cpp @@ -175,15 +175,19 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, const MCOperand &Scale = MI.getOperand(Op+1); const MCOperand &IndexReg = MI.getOperand(Op+2); unsigned BaseReg = Base.getReg(); + unsigned BaseRegNo = BaseReg != 0 ? GetX86RegNum(Base) : -1U; // Determine whether a SIB byte is needed. // If no BaseReg, issue a RIP relative instruction only if the MCE can // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table // 2-7) and absolute references. + if (// The SIB byte must be used if there is an index register. IndexReg.getReg() == 0 && - // The SIB byte must be used if the base is ESP/RSP. - BaseReg != X86::ESP && BaseReg != X86::RSP && + // The SIB byte must be used if the base is ESP/RSP/R12, all of which + // encode to an R/M value of 4, which indicates that a SIB byte is + // present. + BaseRegNo != N86::ESP && // If there is no base register and we're in 64-bit mode, we need a SIB // byte to emit an addr that is just 'disp32' (the non-RIP relative form). (!Is64BitMode || BaseReg != 0)) { @@ -195,8 +199,6 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op, return; } - unsigned BaseRegNo = GetX86RegNum(Base); - // If the base is not EBP/ESP and there is no displacement, use simple // indirect register encoding, this handles addresses like [EAX]. The // encoding for [EBP] with no displacement means [disp32] so we handle it