x86_64: Add byte and word sized CMPXCHG variants and tests for them.
Bug: 65872996
Test: m test-art-host-gtest # new test cases for CMPXCHG
Change-Id: Id8f691d10e60dfd5b2d9ee3b387ff3062347cde1
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index 5bc6a3d..f385f22 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -909,6 +909,8 @@
void jmp(NearLabel* label);
X86_64Assembler* lock();
+ void cmpxchgb(const Address& address, CpuRegister reg);
+ void cmpxchgw(const Address& address, CpuRegister reg);
void cmpxchgl(const Address& address, CpuRegister reg);
void cmpxchgq(const Address& address, CpuRegister reg);
@@ -965,6 +967,22 @@
void LoadDoubleConstant(XmmRegister dst, double value);
+ void LockCmpxchgb(const Address& address, CpuRegister reg) {
+ lock()->cmpxchgb(address, reg);
+ }
+
+ void LockCmpxchgw(const Address& address, CpuRegister 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);
+ EmitOptionalRex32(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xB1);
+ EmitOperand(reg.LowBits(), address);
+ }
+
void LockCmpxchgl(const Address& address, CpuRegister reg) {
lock()->cmpxchgl(address, reg);
}