summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/utils/x86/assembler_x86.cc8
-rw-r--r--compiler/utils/x86/assembler_x86.h1
-rw-r--r--compiler/utils/x86/assembler_x86_test.cc15
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.cc13
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h1
-rw-r--r--compiler/utils/x86_64/assembler_x86_64_test.cc31
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 //
/////////////////