[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:
parent
e6e968d0e6
commit
5c15115e8e
@ -2103,11 +2103,12 @@ void Assembler::testb(const Operand& op, Register reg) {
|
|||||||
void Assembler::testw(Register dst, Register src) {
|
void Assembler::testw(Register dst, Register src) {
|
||||||
EnsureSpace ensure_space(this);
|
EnsureSpace ensure_space(this);
|
||||||
emit(0x66);
|
emit(0x66);
|
||||||
if (src.low_bits() == 4) {
|
if (!dst.is_byte_register() || !src.is_byte_register()) {
|
||||||
emit_rex_32(src, dst);
|
// Register is not one of al, bl, cl, dl. Its encoding needs REX.
|
||||||
|
emit_rex_32(dst, src);
|
||||||
}
|
}
|
||||||
emit(0x85);
|
emit(0x85);
|
||||||
emit_modrm(src, dst);
|
emit_modrm(dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::testw(Register reg, Immediate mask) {
|
void Assembler::testw(Register reg, Immediate mask) {
|
||||||
@ -2118,7 +2119,7 @@ void Assembler::testw(Register reg, Immediate mask) {
|
|||||||
emit(0xA9);
|
emit(0xA9);
|
||||||
emitw(mask.value_);
|
emitw(mask.value_);
|
||||||
} else {
|
} else {
|
||||||
if (reg.low_bits() == 4) {
|
if (!reg.is_byte_register()) {
|
||||||
emit_rex_32(reg);
|
emit_rex_32(reg);
|
||||||
}
|
}
|
||||||
emit(0xF7);
|
emit(0xF7);
|
||||||
|
@ -201,6 +201,167 @@ TEST(AssemblerX64ImulOperation) {
|
|||||||
CHECK_EQ(-1, result);
|
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) {
|
TEST(AssemblerX64XchglOperations) {
|
||||||
CcTest::InitializeVM();
|
CcTest::InitializeVM();
|
||||||
|
Loading…
Reference in New Issue
Block a user