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);
   }