[x64] Fix code generation of testw and add tests

BUG=v8:5798
R=epertoso@chromium.org
LOG=N

Review-Url: https://codereview.chromium.org/2619263002
Cr-Commit-Position: refs/heads/master@{#42148}
This commit is contained in:
danno 2017-01-09 10:11:20 -08:00 committed by Commit bot
parent e6e968d0e6
commit 5c15115e8e
2 changed files with 166 additions and 4 deletions

View File

@ -2103,11 +2103,12 @@ void Assembler::testb(const Operand& op, Register reg) {
void Assembler::testw(Register dst, Register src) {
EnsureSpace ensure_space(this);
emit(0x66);
if (src.low_bits() == 4) {
emit_rex_32(src, dst);
if (!dst.is_byte_register() || !src.is_byte_register()) {
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
emit_rex_32(dst, src);
}
emit(0x85);
emit_modrm(src, dst);
emit_modrm(dst, src);
}
void Assembler::testw(Register reg, Immediate mask) {
@ -2118,7 +2119,7 @@ void Assembler::testw(Register reg, Immediate mask) {
emit(0xA9);
emitw(mask.value_);
} else {
if (reg.low_bits() == 4) {
if (!reg.is_byte_register()) {
emit_rex_32(reg);
}
emit(0xF7);

View File

@ -201,6 +201,167 @@ TEST(AssemblerX64ImulOperation) {
CHECK_EQ(-1, result);
}
TEST(AssemblerX64testbwOperation) {
CcTest::InitializeVM();
v8::HandleScope scope(CcTest::isolate());
// 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));
__ pushq(rbx);
__ pushq(rdi);
__ pushq(rsi);
__ pushq(r12);
__ pushq(r13);
__ pushq(r14);
__ pushq(r15);
// Assemble a simple function that tests testb and testw
Label bad;
Label done;
// Test immediate testb and testw
__ movq(rax, Immediate(2));
__ movq(rbx, Immediate(4));
__ movq(rcx, Immediate(8));
__ movq(rdx, Immediate(16));
__ movq(rsi, Immediate(32));
__ movq(rdi, Immediate(64));
__ movq(r10, Immediate(128));
__ movq(r11, Immediate(0));
__ movq(r12, Immediate(0));
__ movq(r13, Immediate(0));
__ testb(rax, Immediate(2));
__ j(zero, &bad);
__ testb(rbx, Immediate(4));
__ j(zero, &bad);
__ testb(rcx, Immediate(8));
__ j(zero, &bad);
__ testb(rdx, Immediate(16));
__ j(zero, &bad);
__ testb(rsi, Immediate(32));
__ j(zero, &bad);
__ testb(rdi, Immediate(64));
__ j(zero, &bad);
__ testb(r10, Immediate(128));
__ j(zero, &bad);
__ testw(rax, Immediate(2));
__ j(zero, &bad);
__ testw(rbx, Immediate(4));
__ j(zero, &bad);
__ testw(rcx, Immediate(8));
__ j(zero, &bad);
__ testw(rdx, Immediate(16));
__ j(zero, &bad);
__ testw(rsi, Immediate(32));
__ j(zero, &bad);
__ testw(rdi, Immediate(64));
__ j(zero, &bad);
__ testw(r10, Immediate(128));
__ j(zero, &bad);
// Test reg, reg testb and testw
__ movq(rax, Immediate(2));
__ movq(rbx, Immediate(2));
__ testb(rax, rbx);
__ j(zero, &bad);
__ movq(rbx, Immediate(4));
__ movq(rax, Immediate(4));
__ testb(rbx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(8));
__ testb(rcx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(16));
__ testb(rdx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(32));
__ testb(rsi, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(64));
__ testb(rdi, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(128));
__ testb(r10, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(2));
__ movq(rbx, Immediate(2));
__ testw(rax, rbx);
__ j(zero, &bad);
__ movq(rbx, Immediate(4));
__ movq(rax, Immediate(4));
__ testw(rbx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(8));
__ testw(rcx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(16));
__ testw(rdx, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(32));
__ testw(rsi, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(64));
__ testw(rdi, rax);
__ j(zero, &bad);
__ movq(rax, Immediate(128));
__ testw(r10, rax);
__ j(zero, &bad);
// Test diffrrent extended register coding combinations.
__ movq(rax, Immediate(5));
__ movq(r11, Immediate(5));
__ testb(r11, rax);
__ j(zero, &bad);
__ testb(rax, r11);
__ j(zero, &bad);
__ testw(r11, rax);
__ j(zero, &bad);
__ testw(rax, r11);
__ j(zero, &bad);
__ movq(r11, Immediate(3));
__ movq(r12, Immediate(3));
__ movq(rdi, Immediate(3));
__ testb(r12, rdi);
__ j(zero, &bad);
__ testb(rdi, r12);
__ j(zero, &bad);
__ testb(r12, r11);
__ j(zero, &bad);
__ testb(r11, r12);
__ j(zero, &bad);
__ testw(r12, r11);
__ j(zero, &bad);
__ testw(r11, r12);
__ j(zero, &bad);
// All tests passed
__ movq(rax, Immediate(1));
__ jmp(&done);
__ bind(&bad);
__ movq(rax, Immediate(0));
__ bind(&done);
__ popq(r15);
__ popq(r14);
__ popq(r13);
__ popq(r12);
__ popq(rsi);
__ popq(rdi);
__ popq(rbx);
__ ret(0);
CodeDesc desc;
assm.GetCode(&desc);
// Call the function from C++.
int result = FUNCTION_CAST<F2>(buffer)(0, 0);
CHECK_EQ(1, result);
}
TEST(AssemblerX64XchglOperations) {
CcTest::InitializeVM();