[x64] Fix testw with immediates.

Assembler::testw(Register, Immediate) and Assembler::testw(const Operand&, Immediate) were emitting only the first 8 bits of a 16-bit immediate, causing unexpected crashes.

This went unnoticed because before http://crrev.com/1948453002 no compiler was using them.

Review-Url: https://codereview.chromium.org/1962563003
Cr-Commit-Position: refs/heads/master@{#36110}
This commit is contained in:
epertoso 2016-05-09 06:54:37 -07:00 committed by Commit bot
parent afb69f7438
commit 99230f8d0e
2 changed files with 29 additions and 3 deletions

View File

@ -2095,14 +2095,14 @@ void Assembler::testw(Register reg, Immediate mask) {
emit(0x66);
if (reg.is(rax)) {
emit(0xA9);
emit(mask.value_);
emitw(mask.value_);
} else {
if (reg.low_bits() == 4) {
emit_rex_32(reg);
}
emit(0xF7);
emit_modrm(0x0, reg);
emit(mask.value_);
emitw(mask.value_);
}
}
@ -2113,7 +2113,7 @@ void Assembler::testw(const Operand& op, Immediate mask) {
emit_optional_rex_32(rax, op);
emit(0xF7);
emit_operand(rax, op);
emit(mask.value_);
emitw(mask.value_);
}
void Assembler::testw(const Operand& op, Register reg) {

View File

@ -328,6 +328,32 @@ TEST(AssemblerX64TestlOperations) {
CHECK_EQ(1u, result);
}
TEST(AssemblerX64TestwOperations) {
typedef uint16_t (*F)(uint16_t * x);
CcTest::InitializeVM();
// Allocate an executable page of memory.
size_t actual_size;
byte* buffer = static_cast<byte*>(v8::base::OS::Allocate(
Assembler::kMinimalBufferSize, &actual_size, true));
CHECK(buffer);
Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
// Set rax with the ZF flag of the testl instruction.
Label done;
__ movq(rax, Immediate(1));
__ testw(Operand(arg1, 0), Immediate(0xf0f0));
__ j(not_zero, &done, Label::kNear);
__ movq(rax, Immediate(0));
__ bind(&done);
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
// Call the function from C++.
uint16_t operand = 0x8000;
uint16_t result = FUNCTION_CAST<F>(buffer)(&operand);
CHECK_EQ(1u, result);
}
TEST(AssemblerX64XorlOperations) {
CcTest::InitializeVM();