x86_64: Add XADD instruction and tests for it.
Bug: 65872996
Test: m test-art-host-gtest # new test cases for XADD
Change-Id: Idaa5f40dab106e7f48bfd8adeee629bcdaa8e33a
diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc
index 52cedf0..0f90ec8 100644
--- a/compiler/utils/x86_64/assembler_x86_64.cc
+++ b/compiler/utils/x86_64/assembler_x86_64.cc
@@ -3914,6 +3914,80 @@
}
+void X86_64Assembler::xaddb(CpuRegister dst, CpuRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOptionalByteRegNormalizingRex32(src, dst, /*normalize_both=*/ true);
+ EmitUint8(0x0F);
+ EmitUint8(0xC0);
+ EmitRegisterOperand(src.LowBits(), dst.LowBits());
+}
+
+
+void X86_64Assembler::xaddb(const Address& address, CpuRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOptionalByteRegNormalizingRex32(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xC0);
+ EmitOperand(reg.LowBits(), address);
+}
+
+
+void X86_64Assembler::xaddw(CpuRegister dst, CpuRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandSizeOverride();
+ EmitOptionalRex32(src, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitRegisterOperand(src.LowBits(), dst.LowBits());
+}
+
+
+void X86_64Assembler::xaddw(const Address& address, CpuRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOperandSizeOverride();
+ EmitOptionalRex32(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitOperand(reg.LowBits(), address);
+}
+
+
+void X86_64Assembler::xaddl(CpuRegister dst, CpuRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOptionalRex32(src, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitRegisterOperand(src.LowBits(), dst.LowBits());
+}
+
+
+void X86_64Assembler::xaddl(const Address& address, CpuRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitOptionalRex32(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitOperand(reg.LowBits(), address);
+}
+
+
+void X86_64Assembler::xaddq(CpuRegister dst, CpuRegister src) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitRex64(src, dst);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitRegisterOperand(src.LowBits(), dst.LowBits());
+}
+
+
+void X86_64Assembler::xaddq(const Address& address, CpuRegister reg) {
+ AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+ EmitRex64(reg, address);
+ EmitUint8(0x0F);
+ EmitUint8(0xC1);
+ EmitOperand(reg.LowBits(), address);
+}
+
+
void X86_64Assembler::cmpb(const Address& address, const Immediate& imm) {
AssemblerBuffer::EnsureCapacity ensured(&buffer_);
CHECK(imm.is_int32());
diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h
index 8ef8931..bed3d34 100644
--- a/compiler/utils/x86_64/assembler_x86_64.h
+++ b/compiler/utils/x86_64/assembler_x86_64.h
@@ -787,6 +787,18 @@
void xchgq(CpuRegister dst, CpuRegister src);
void xchgq(CpuRegister reg, const Address& address);
+ void xaddb(CpuRegister dst, CpuRegister src);
+ void xaddb(const Address& address, CpuRegister reg);
+
+ void xaddw(CpuRegister dst, CpuRegister src);
+ void xaddw(const Address& address, CpuRegister reg);
+
+ void xaddl(CpuRegister dst, CpuRegister src);
+ void xaddl(const Address& address, CpuRegister reg);
+
+ void xaddq(CpuRegister dst, CpuRegister src);
+ void xaddq(const Address& address, CpuRegister reg);
+
void cmpb(const Address& address, const Immediate& imm);
void cmpw(const Address& address, const Immediate& imm);
diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc
index feee577..2911d96 100644
--- a/compiler/utils/x86_64/assembler_x86_64_test.cc
+++ b/compiler/utils/x86_64/assembler_x86_64_test.cc
@@ -988,6 +988,38 @@
DriverStr(RepeatbA(&x86_64::X86_64Assembler::xchgb, "xchgb %{reg}, {mem}"), "xchgb");
}
+TEST_F(AssemblerX86_64Test, XaddqReg) {
+ DriverStr(RepeatRR(&x86_64::X86_64Assembler::xaddq, "xaddq %{reg2}, %{reg1}"), "xaddq");
+}
+
+TEST_F(AssemblerX86_64Test, XaddqMem) {
+ DriverStr(RepeatAR(&x86_64::X86_64Assembler::xaddq, "xaddq %{reg}, {mem}"), "xaddq");
+}
+
+TEST_F(AssemblerX86_64Test, XaddlReg) {
+ DriverStr(Repeatrr(&x86_64::X86_64Assembler::xaddl, "xaddl %{reg2}, %{reg1}"), "xaddl");
+}
+
+TEST_F(AssemblerX86_64Test, XaddlMem) {
+ DriverStr(RepeatAr(&x86_64::X86_64Assembler::xaddl, "xaddl %{reg}, {mem}"), "xaddl");
+}
+
+TEST_F(AssemblerX86_64Test, XaddwReg) {
+ DriverStr(Repeatww(&x86_64::X86_64Assembler::xaddw, "xaddw %{reg2}, %{reg1}"), "xaddw");
+}
+
+TEST_F(AssemblerX86_64Test, XaddwMem) {
+ DriverStr(RepeatAw(&x86_64::X86_64Assembler::xaddw, "xaddw %{reg}, {mem}"), "xaddw");
+}
+
+TEST_F(AssemblerX86_64Test, XaddbReg) {
+ DriverStr(Repeatbb(&x86_64::X86_64Assembler::xaddb, "xaddb %{reg2}, %{reg1}"), "xaddb");
+}
+
+TEST_F(AssemblerX86_64Test, XaddbMem) {
+ DriverStr(RepeatAb(&x86_64::X86_64Assembler::xaddb, "xaddb %{reg}, {mem}"), "xaddb");
+}
+
TEST_F(AssemblerX86_64Test, Cmpxchgb) {
DriverStr(RepeatAb(&x86_64::X86_64Assembler::cmpxchgb, "cmpxchgb %{reg}, {mem}"), "cmpxchgb");
}