1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

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.

llvm-svn: 95866
This commit is contained in:
Chris Lattner 2010-02-11 08:41:21 +00:00
parent eb0dbdca22
commit c279bf31b7
2 changed files with 12 additions and 7 deletions

View File

@ -387,10 +387,14 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
// If no BaseReg, issue a RIP relative instruction only if the MCE can // 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 // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references. // 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. if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 && IndexReg.getReg() == 0 &&
// The SIB byte must be used if the base is ESP/RSP. // The SIB byte must be used if the base is ESP/RSP/R12, all of which
BaseReg != X86::ESP && BaseReg != X86::RSP && // 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 // 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). // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
(!Is64BitMode || BaseReg != 0)) { (!Is64BitMode || BaseReg != 0)) {
@ -401,7 +405,6 @@ void Emitter<CodeEmitter>::emitMemModRMByte(const MachineInstr &MI,
return; return;
} }
unsigned BaseRegNo = getX86RegNum(BaseReg);
// If the base is not EBP/ESP and there is no displacement, use simple // If the base is not EBP/ESP and there is no displacement, use simple
// indirect register encoding, this handles addresses like [EAX]. The // indirect register encoding, this handles addresses like [EAX]. The
// encoding for [EBP] with no displacement means [disp32] so we handle it // encoding for [EBP] with no displacement means [disp32] so we handle it

View File

@ -175,15 +175,19 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
const MCOperand &Scale = MI.getOperand(Op+1); const MCOperand &Scale = MI.getOperand(Op+1);
const MCOperand &IndexReg = MI.getOperand(Op+2); const MCOperand &IndexReg = MI.getOperand(Op+2);
unsigned BaseReg = Base.getReg(); unsigned BaseReg = Base.getReg();
unsigned BaseRegNo = BaseReg != 0 ? GetX86RegNum(Base) : -1U;
// Determine whether a SIB byte is needed. // Determine whether a SIB byte is needed.
// If no BaseReg, issue a RIP relative instruction only if the MCE can // 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 // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table
// 2-7) and absolute references. // 2-7) and absolute references.
if (// The SIB byte must be used if there is an index register. if (// The SIB byte must be used if there is an index register.
IndexReg.getReg() == 0 && IndexReg.getReg() == 0 &&
// The SIB byte must be used if the base is ESP/RSP. // The SIB byte must be used if the base is ESP/RSP/R12, all of which
BaseReg != X86::ESP && BaseReg != X86::RSP && // 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 // 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). // byte to emit an addr that is just 'disp32' (the non-RIP relative form).
(!Is64BitMode || BaseReg != 0)) { (!Is64BitMode || BaseReg != 0)) {
@ -195,8 +199,6 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
return; return;
} }
unsigned BaseRegNo = GetX86RegNum(Base);
// If the base is not EBP/ESP and there is no displacement, use simple // If the base is not EBP/ESP and there is no displacement, use simple
// indirect register encoding, this handles addresses like [EAX]. The // indirect register encoding, this handles addresses like [EAX]. The
// encoding for [EBP] with no displacement means [disp32] so we handle it // encoding for [EBP] with no displacement means [disp32] so we handle it