[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:
parent
afb69f7438
commit
99230f8d0e
@ -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) {
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user