diff options
-rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 8 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 1 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 15 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 13 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 1 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64_test.cc | 31 |
6 files changed, 69 insertions, 0 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 7138a46890..3efef70f77 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -326,6 +326,14 @@ void X86Assembler::cmovl(Condition condition, Register dst, Register src) { } +void X86Assembler::cmovl(Condition condition, Register dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x0F); + EmitUint8(0x40 + condition); + EmitOperand(dst, src); +} + + void X86Assembler::setb(Condition condition, Register dst) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x0F); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 759a41e80e..00ff7bdbbd 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -363,6 +363,7 @@ class X86Assembler FINAL : public Assembler { void leal(Register dst, const Address& src); void cmovl(Condition condition, Register dst, Register src); + void cmovl(Condition condition, Register dst, const Address& src); void setb(Condition condition, Register dst); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index 0fd098227a..d0d51473fe 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -332,6 +332,21 @@ TEST_F(AssemblerX86Test, UComisdAddr) { } +TEST_F(AssemblerX86Test, CmovlAddress) { + GetAssembler()->cmovl(x86::kEqual, x86::Register(x86::EAX), x86::Address( + x86::Register(x86::EDI), x86::Register(x86::EBX), x86::TIMES_4, 12)); + GetAssembler()->cmovl(x86::kNotEqual, x86::Register(x86::EDI), x86::Address( + x86::Register(x86::ESI), x86::Register(x86::EBX), x86::TIMES_4, 12)); + GetAssembler()->cmovl(x86::kEqual, x86::Register(x86::EDI), x86::Address( + x86::Register(x86::EDI), x86::Register(x86::EAX), x86::TIMES_4, 12)); + const char* expected = + "cmovzl 0xc(%EDI,%EBX,4), %eax\n" + "cmovnzl 0xc(%ESI,%EBX,4), %edi\n" + "cmovzl 0xc(%EDI,%EAX,4), %edi\n"; + + DriverStr(expected, "cmovl_address"); +} + ///////////////// // Near labels // ///////////////// diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index 10f5a005e1..d86ad1be5f 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -223,6 +223,19 @@ void X86_64Assembler::cmov(Condition c, CpuRegister dst, CpuRegister src, bool i } +void X86_64Assembler::cmov(Condition c, CpuRegister dst, const Address& src, bool is64bit) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + if (is64bit) { + EmitRex64(dst, src); + } else { + EmitOptionalRex32(dst, src); + } + EmitUint8(0x0F); + EmitUint8(0x40 + c); + EmitOperand(dst.LowBits(), src); +} + + void X86_64Assembler::movzxb(CpuRegister dst, CpuRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitOptionalByteRegNormalizingRex32(dst, src); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index 6f0847eb61..f00cb12413 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -366,6 +366,7 @@ class X86_64Assembler FINAL : public Assembler { void cmov(Condition c, CpuRegister dst, CpuRegister src); // This is the 64b version. void cmov(Condition c, CpuRegister dst, CpuRegister src, bool is64bit); + void cmov(Condition c, CpuRegister dst, const Address& src, bool is64bit); void movzxb(CpuRegister dst, CpuRegister src); void movzxb(CpuRegister dst, const Address& src); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index 8a87fca96a..4f65709810 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -1371,6 +1371,37 @@ TEST_F(AssemblerX86_64Test, PopcntqAddress) { DriverStr(expected, "popcntq_address"); } +TEST_F(AssemblerX86_64Test, CmovlAddress) { + GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::R10), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), false); + GetAssembler()->cmov(x86_64::kNotEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), false); + GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), false); + const char* expected = + "cmovzl 0xc(%RDI,%RBX,4), %R10d\n" + "cmovnzl 0xc(%R10,%RBX,4), %edi\n" + "cmovzl 0xc(%RDI,%R9,4), %edi\n"; + + DriverStr(expected, "cmovl_address"); +} + +TEST_F(AssemblerX86_64Test, CmovqAddress) { + GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::R10), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), true); + GetAssembler()->cmov(x86_64::kNotEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::R10), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12), true); + GetAssembler()->cmov(x86_64::kEqual, x86_64::CpuRegister(x86_64::RDI), x86_64::Address( + x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12), true); + const char* expected = + "cmovzq 0xc(%RDI,%RBX,4), %R10\n" + "cmovnzq 0xc(%R10,%RBX,4), %rdi\n" + "cmovzq 0xc(%RDI,%R9,4), %rdi\n"; + + DriverStr(expected, "cmovq_address"); +} + + ///////////////// // Near labels // ///////////////// |