Commit 588e15c0 authored by epertoso's avatar epertoso Committed by Commit bot

[ia32] Fixes a bug in cmpw.

The opcodes for 'cmpw r/m16, r16' and 'cmpw r16, r/m16' were swapped, causing a few issues when less than/greater than comparison were performed.

Adds a regression test.

BUG=621926

Committed: https://crrev.com/efa7095e3e360fbadbe909d831ac11b268ca26b0
Review-Url: https://codereview.chromium.org/2103713003
Cr-Original-Commit-Position: refs/heads/master@{#37339}
Cr-Commit-Position: refs/heads/master@{#37345}
parent 05638b9d
...@@ -852,14 +852,14 @@ void Assembler::cmpw(const Operand& op, Immediate imm16) { ...@@ -852,14 +852,14 @@ void Assembler::cmpw(const Operand& op, Immediate imm16) {
void Assembler::cmpw(Register reg, const Operand& op) { void Assembler::cmpw(Register reg, const Operand& op) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
EMIT(0x66); EMIT(0x66);
EMIT(0x39); EMIT(0x3B);
emit_operand(reg, op); emit_operand(reg, op);
} }
void Assembler::cmpw(const Operand& op, Register reg) { void Assembler::cmpw(const Operand& op, Register reg) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
EMIT(0x66); EMIT(0x66);
EMIT(0x3B); EMIT(0x39);
emit_operand(reg, op); emit_operand(reg, op);
} }
......
...@@ -1622,11 +1622,19 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1622,11 +1622,19 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
while (*data == 0x66) data++; while (*data == 0x66) data++;
if (*data == 0xf && data[1] == 0x1f) { if (*data == 0xf && data[1] == 0x1f) {
AppendToBuffer("nop"); // 0x66 prefix AppendToBuffer("nop"); // 0x66 prefix
} else if (*data == 0x90) { } else if (*data == 0x39) {
AppendToBuffer("nop"); // 0x66 prefix
} else if (*data == 0x8B) {
data++; data++;
data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data); data += PrintOperands("cmpw", OPER_REG_OP_ORDER, data);
} else if (*data == 0x3B) {
data++;
data += PrintOperands("cmpw", REG_OPER_OP_ORDER, data);
} else if (*data == 0x81) {
data++;
AppendToBuffer("cmpw ");
data += PrintRightOperand(data);
int imm = *reinterpret_cast<int16_t*>(data);
AppendToBuffer(",0x%x", imm);
data += 2;
} else if (*data == 0x87) { } else if (*data == 0x87) {
data++; data++;
int mod, regop, rm; int mod, regop, rm;
...@@ -1640,6 +1648,11 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1640,6 +1648,11 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
AppendToBuffer("mov_w "); AppendToBuffer("mov_w ");
data += PrintRightOperand(data); data += PrintRightOperand(data);
AppendToBuffer(",%s", NameOfCPURegister(regop)); AppendToBuffer(",%s", NameOfCPURegister(regop));
} else if (*data == 0x8B) {
data++;
data += PrintOperands("mov_w", REG_OPER_OP_ORDER, data);
} else if (*data == 0x90) {
AppendToBuffer("nop"); // 0x66 prefix
} else if (*data == 0xC7) { } else if (*data == 0xC7) {
data++; data++;
AppendToBuffer("%s ", "mov_w"); AppendToBuffer("%s ", "mov_w");
......
...@@ -1497,4 +1497,45 @@ TEST(AssemblerIa32JumpTables2) { ...@@ -1497,4 +1497,45 @@ TEST(AssemblerIa32JumpTables2) {
} }
} }
TEST(Regress621926) {
// Bug description:
// The opcodes for cmpw r/m16, r16 and cmpw r16, r/m16 were swapped.
// This was causing non-commutative comparisons to produce the wrong result.
CcTest::InitializeVM();
Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
HandleScope scope(isolate);
Assembler assm(isolate, nullptr, 0);
int16_t a = 42;
Label fail;
__ push(ebx);
__ mov(ebx, Immediate(reinterpret_cast<intptr_t>(&a)));
__ mov(eax, Immediate(41));
__ cmpw(eax, Operand(ebx));
__ j(above_equal, &fail);
__ cmpw(Operand(ebx), eax);
__ j(below_equal, &fail);
__ mov(eax, 1);
__ pop(ebx);
__ ret(0);
__ bind(&fail);
__ mov(eax, 0);
__ pop(ebx);
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
OFStream os(stdout);
code->Print(os);
#endif
F0 f = FUNCTION_CAST<F0>(code->entry());
CHECK_EQ(f(), 1);
}
#undef __ #undef __
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment