diff options
| author | 2016-02-12 13:49:03 -0500 | |
|---|---|---|
| committer | 2016-02-12 14:45:35 -0500 | |
| commit | abdac47c3c471d034a5b81aec35bf4201ba86a88 (patch) | |
| tree | f55cb2462ed5e8f79871b96ed5ff0bc6f6d52da6 | |
| parent | b9adbf63f880f246d83b3af4ca03aca07711f857 (diff) | |
Add X86/X86_64 support for CMOV from memory.
Add support for the memory form of CMOV. Add tests.
Change-Id: Ib9f5dbd3031c7e235ee3f2afdb7db75eed46277a
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
| -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 // ///////////////// |