diff options
author | Mark Mendell <mark.p.mendell@intel.com> | 2015-04-03 14:52:31 -0400 |
---|---|---|
committer | Mark Mendell <mark.p.mendell@intel.com> | 2015-04-06 23:05:13 -0400 |
commit | 58d25fd052e999a24734b0cf856a1563e3d1b2d0 (patch) | |
tree | b1dbeae13a24e3f7ec325698a3724b5d90df2ef9 /compiler/utils | |
parent | 1b8e8cac2c96f6d2af8e7217f997a30e11c098b5 (diff) | |
download | art-58d25fd052e999a24734b0cf856a1563e3d1b2d0.zip art-58d25fd052e999a24734b0cf856a1563e3d1b2d0.tar.gz art-58d25fd052e999a24734b0cf856a1563e3d1b2d0.tar.bz2 |
[optimizing] Implement more x86/x86_64 intrinsics
Implement CAS and bit reverse and byte reverse intrinsics that were
missing from x86 and x86_64 implementations.
Add assembler tests and compareAndSwapLong test.
Change-Id: Iabb2ff46036645df0a91f640288ef06090a64ee3
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
Diffstat (limited to 'compiler/utils')
-rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 9 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 5 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 45 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 11 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 5 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64_test.cc | 50 |
6 files changed, 125 insertions, 0 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index b3a1376..4ecb1d8 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -1467,6 +1467,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 bdf8843..46630e3 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 fccb510..dba3b6b 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 e82d90c..627d94e 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -1854,11 +1854,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 39f781c..3b4fbb5 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 4402dfc..a79bd09 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)); |