x86_64: Add LockXadd* helper function and tests for it.
A separate function is need for 16-bit variant `lock xaddw` because the
LOCK prefix should go after the operand size override prefix to match
the order of prefixes emitted by the reference implementation.
Bug: 65872996
Test: m test-art-host-gtest # new test cases for LOCK XADD
Change-Id: I29946c75c76966cb9c6425b2a22eae3664ce3c00
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index bed3d34..2eb018d 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -1011,6 +1011,30 @@
lock()->cmpxchgq(address, reg);
}
+ void LockXaddb(const Address& address, CpuRegister reg) {
+ lock()->xaddb(address, reg);
+ }
+
+ void LockXaddw(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(0xC1);
+ EmitOperand(reg.LowBits(), address);
+ }
+
+ void LockXaddl(const Address& address, CpuRegister reg) {
+ lock()->xaddl(address, reg);
+ }
+
+ void LockXaddq(const Address& address, CpuRegister reg) {
+ lock()->xaddq(address, reg);
+ }
+
//
// Misc. functionality
//