summaryrefslogtreecommitdiffstats
path: root/compiler/utils
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-04-08 16:07:41 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-08 16:07:41 +0000
commit9d0ab6f0a2f08c3fa9a59e0b8742cf366d7d0feb (patch)
tree5b05ed14a1aa514a1887dd4268f61209087716e1 /compiler/utils
parentcde8e5da3e774a2494b051043130c0495eca09ef (diff)
parent58d25fd052e999a24734b0cf856a1563e3d1b2d0 (diff)
downloadandroid_art-9d0ab6f0a2f08c3fa9a59e0b8742cf366d7d0feb.tar.gz
android_art-9d0ab6f0a2f08c3fa9a59e0b8742cf366d7d0feb.tar.bz2
android_art-9d0ab6f0a2f08c3fa9a59e0b8742cf366d7d0feb.zip
Merge "[optimizing] Implement more x86/x86_64 intrinsics"
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/x86/assembler_x86.cc9
-rw-r--r--compiler/utils/x86/assembler_x86.h5
-rw-r--r--compiler/utils/x86/assembler_x86_test.cc45
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.cc11
-rw-r--r--compiler/utils/x86_64/assembler_x86_64.h5
-rw-r--r--compiler/utils/x86_64/assembler_x86_64_test.cc50
6 files changed, 125 insertions, 0 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc
index 4b71412193..4cca529258 100644
--- a/compiler/utils/x86/assembler_x86.cc
+++ b/compiler/utils/x86/assembler_x86.cc
@@ -1466,6 +1466,15 @@ void X86Assembler::cmpxchgl(const Address& address, Register reg) {
EmitOperand(reg, address);
}
+
+void X86Assembler::cmpxchg8b(const Address& address) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitUint8(0x0F);
+ EmitUint8(0xC7);
+ EmitOperand(1, address);
+}
+
+
void X86Assembler::mfence() {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x0F);
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h
index 046df02b94..f3675aeceb 100644
--- a/compiler/utils/x86/assembler_x86.h
+++ b/compiler/utils/x86/assembler_x86.h
@@ -457,6 +457,7 @@ class X86Assembler FINAL : public Assembler {
X86Assembler* lock();
void cmpxchgl(const Address& address, Register reg);
+ void cmpxchg8b(const Address& address);
void mfence();
@@ -476,6 +477,10 @@ class X86Assembler FINAL : public Assembler {
lock()->cmpxchgl(address, reg);
}
+ void LockCmpxchg8b(const Address& address) {
+ lock()->cmpxchg8b(address);
+ }
+
//
// Misc. functionality
//
diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc
index fccb510afb..dba3b6ba67 100644
--- a/compiler/utils/x86/assembler_x86_test.cc
+++ b/compiler/utils/x86/assembler_x86_test.cc
@@ -127,4 +127,49 @@ TEST_F(AssemblerX86Test, LoadLongConstant) {
DriverStr(expected, "LoadLongConstant");
}
+TEST_F(AssemblerX86Test, LockCmpxchgl) {
+ GetAssembler()->LockCmpxchgl(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::EBX), x86::TIMES_4, 12),
+ x86::Register(x86::ESI));
+ GetAssembler()->LockCmpxchgl(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::ESI), x86::TIMES_4, 12),
+ x86::Register(x86::ESI));
+ GetAssembler()->LockCmpxchgl(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::ESI), x86::TIMES_4, 12),
+ x86::Register(x86::EDI));
+ GetAssembler()->LockCmpxchgl(x86::Address(
+ x86::Register(x86::EBP), 0), x86::Register(x86::ESI));
+ GetAssembler()->LockCmpxchgl(x86::Address(
+ x86::Register(x86::EBP), x86::Register(x86::ESI), x86::TIMES_1, 0),
+ x86::Register(x86::ESI));
+ const char* expected =
+ "lock cmpxchgl %ESI, 0xc(%EDI,%EBX,4)\n"
+ "lock cmpxchgl %ESI, 0xc(%EDI,%ESI,4)\n"
+ "lock cmpxchgl %EDI, 0xc(%EDI,%ESI,4)\n"
+ "lock cmpxchgl %ESI, (%EBP)\n"
+ "lock cmpxchgl %ESI, (%EBP,%ESI,1)\n";
+
+ DriverStr(expected, "lock_cmpxchgl");
+}
+
+TEST_F(AssemblerX86Test, LockCmpxchg8b) {
+ GetAssembler()->LockCmpxchg8b(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::EBX), x86::TIMES_4, 12));
+ GetAssembler()->LockCmpxchg8b(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::ESI), x86::TIMES_4, 12));
+ GetAssembler()->LockCmpxchg8b(x86::Address(
+ x86::Register(x86::EDI), x86::Register(x86::ESI), x86::TIMES_4, 12));
+ GetAssembler()->LockCmpxchg8b(x86::Address(x86::Register(x86::EBP), 0));
+ GetAssembler()->LockCmpxchg8b(x86::Address(
+ x86::Register(x86::EBP), x86::Register(x86::ESI), x86::TIMES_1, 0));
+ const char* expected =
+ "lock cmpxchg8b 0xc(%EDI,%EBX,4)\n"
+ "lock cmpxchg8b 0xc(%EDI,%ESI,4)\n"
+ "lock cmpxchg8b 0xc(%EDI,%ESI,4)\n"
+ "lock cmpxchg8b (%EBP)\n"
+ "lock cmpxchg8b (%EBP,%ESI,1)\n";
+
+ DriverStr(expected, "lock_cmpxchg8b");
+}
+
} // namespace art
diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc
index 25d24fb468..2e0d9e1840 100644
--- a/compiler/utils/x86_64/assembler_x86_64.cc
+++ b/compiler/utils/x86_64/assembler_x86_64.cc
@@ -1853,11 +1853,22 @@ X86_64Assembler* X86_64Assembler::lock() {
void X86_64Assembler::cmpxchgl(const Address& address, CpuRegister reg) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOptionalRex32(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xB1);
+ EmitOperand(reg.LowBits(), address);
+}
+
+
+void X86_64Assembler::cmpxchgq(const Address& address, CpuRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitRex64(reg, address);
EmitUint8(0x0F);
EmitUint8(0xB1);
EmitOperand(reg.LowBits(), address);
}
+
void X86_64Assembler::mfence() {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
EmitUint8(0x0F);
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index bcc8e62a67..a786a6cbff 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -517,6 +517,7 @@ class X86_64Assembler FINAL : public Assembler {
X86_64Assembler* lock();
void cmpxchgl(const Address& address, CpuRegister reg);
+ void cmpxchgq(const Address& address, CpuRegister reg);
void mfence();
@@ -539,6 +540,10 @@ class X86_64Assembler FINAL : public Assembler {
lock()->cmpxchgl(address, reg);
}
+ void LockCmpxchgq(const Address& address, CpuRegister reg) {
+ lock()->cmpxchgq(address, reg);
+ }
+
//
// Misc. functionality
//
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index 4402dfcb37..a79bd09687 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -539,6 +539,56 @@ TEST_F(AssemblerX86_64Test, Xchgl) {
// DriverStr(Repeatrr(&x86_64::X86_64Assembler::xchgl, "xchgl %{reg2}, %{reg1}"), "xchgl");
}
+TEST_F(AssemblerX86_64Test, LockCmpxchgl) {
+ GetAssembler()->LockCmpxchgl(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgl(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgl(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::R8));
+ GetAssembler()->LockCmpxchgl(x86_64::Address(
+ x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgl(x86_64::Address(
+ x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
+ x86_64::CpuRegister(x86_64::RSI));
+ const char* expected =
+ "lock cmpxchgl %ESI, 0xc(%RDI,%RBX,4)\n"
+ "lock cmpxchgl %ESI, 0xc(%RDI,%R9,4)\n"
+ "lock cmpxchgl %R8d, 0xc(%RDI,%R9,4)\n"
+ "lock cmpxchgl %ESI, (%R13)\n"
+ "lock cmpxchgl %ESI, (%R13,%R9,1)\n";
+
+ DriverStr(expected, "lock_cmpxchgl");
+}
+
+TEST_F(AssemblerX86_64Test, LockCmpxchgq) {
+ GetAssembler()->LockCmpxchgq(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgq(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgq(x86_64::Address(
+ x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_4, 12),
+ x86_64::CpuRegister(x86_64::R8));
+ GetAssembler()->LockCmpxchgq(x86_64::Address(
+ x86_64::CpuRegister(x86_64::R13), 0), x86_64::CpuRegister(x86_64::RSI));
+ GetAssembler()->LockCmpxchgq(x86_64::Address(
+ x86_64::CpuRegister(x86_64::R13), x86_64::CpuRegister(x86_64::R9), x86_64::TIMES_1, 0),
+ x86_64::CpuRegister(x86_64::RSI));
+ const char* expected =
+ "lock cmpxchg %RSI, 0xc(%RDI,%RBX,4)\n"
+ "lock cmpxchg %RSI, 0xc(%RDI,%R9,4)\n"
+ "lock cmpxchg %R8, 0xc(%RDI,%R9,4)\n"
+ "lock cmpxchg %RSI, (%R13)\n"
+ "lock cmpxchg %RSI, (%R13,%R9,1)\n";
+
+ DriverStr(expected, "lock_cmpxchg");
+}
+
TEST_F(AssemblerX86_64Test, Movl) {
GetAssembler()->movl(x86_64::CpuRegister(x86_64::RAX), x86_64::Address(
x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12));