diff options
| -rw-r--r-- | compiler/utils/x86/assembler_x86.h | 14 | ||||
| -rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 15 |
2 files changed, 28 insertions, 1 deletions
diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 2fe3b7bec5..ba928672df 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -814,12 +814,24 @@ class X86Assembler final : public Assembler { void LoadLongConstant(XmmRegister dst, int64_t value); void LoadDoubleConstant(XmmRegister dst, double value); + void LockCmpxchgb(const Address& address, Register reg) { + // For testing purpose + lock()->cmpxchgb(address, static_cast<ByteRegister>(reg)); + } + void LockCmpxchgb(const Address& address, ByteRegister reg) { lock()->cmpxchgb(address, reg); } void LockCmpxchgw(const Address& address, Register reg) { - lock()->cmpxchgw(address, reg); + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + // We make sure that the operand size override bytecode is emited before the lock bytecode. + // We test against clang which enforces this bytecode order. + EmitOperandSizeOverride(); + EmitUint8(0xF0); + EmitUint8(0x0F); + EmitUint8(0xB1); + EmitOperand(reg, address); } void LockCmpxchgl(const Address& address, Register reg) { diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index 5d34a51cb9..305f3c451e 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -114,6 +114,11 @@ class AssemblerX86Test : public AssemblerTest<x86::X86Assembler, tertiary_register_names_.emplace(x86::Register(x86::EBX), "bl"); tertiary_register_names_.emplace(x86::Register(x86::ECX), "cl"); tertiary_register_names_.emplace(x86::Register(x86::EDX), "dl"); + // FIXME: Refactor RepeatAw() to only use the tertiary for EAX, EBX, ECX, EDX + tertiary_register_names_.emplace(x86::Register(x86::EBP), "ch"); + tertiary_register_names_.emplace(x86::Register(x86::ESP), "ah"); + tertiary_register_names_.emplace(x86::Register(x86::ESI), "dh"); + tertiary_register_names_.emplace(x86::Register(x86::EDI), "bh"); } if (fp_registers_.size() == 0) { @@ -322,6 +327,16 @@ TEST_F(AssemblerX86Test, LoadLongConstant) { DriverStr(expected, "LoadLongConstant"); } +TEST_F(AssemblerX86Test, LockCmpxchgb) { + DriverStr(RepeatAw(&x86::X86Assembler::LockCmpxchgb, + "lock cmpxchgb %{reg}, {mem}"), "lock_cmpxchgb"); +} + +TEST_F(AssemblerX86Test, LockCmpxchgw) { + DriverStr(RepeatAr(&x86::X86Assembler::LockCmpxchgw, + "lock cmpxchgw %{reg}, {mem}"), "lock_cmpxchgw"); +} + TEST_F(AssemblerX86Test, LockCmpxchgl) { DriverStr(RepeatAR(&x86::X86Assembler::LockCmpxchgl, "lock cmpxchgl %{reg}, {mem}"), "lock_cmpxchgl"); |