diff options
author | 2017-02-13 14:28:45 -0800 | |
---|---|---|
committer | 2017-02-13 14:28:45 -0800 | |
commit | 68555e952eea58023fa403951b1491496acf0f4b (patch) | |
tree | 304d10e4d1b11698d73e0b5fb3d9aa69daccca9d | |
parent | 5abcfe6254acce99bf25a151b19ffe5c9b50494f (diff) |
Added a few integral SIMD extensions for x86/x86_64 (SSE).
Rationale:
ART vectorizer needs SIMD for integer operations too.
Test: assembler_x86[_64]_test
Bug: 34083438
Change-Id: Id6fec558c617d38cb643839eafcd10e59dcd6e0a
-rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 142 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 16 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86_test.cc | 74 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.cc | 119 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64.h | 18 | ||||
-rw-r--r-- | compiler/utils/x86_64/assembler_x86_64_test.cc | 50 | ||||
-rw-r--r-- | disassembler/disassembler_x86.cc | 16 |
7 files changed, 416 insertions, 19 deletions
diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index a24d49e08d..5a466e1d5d 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -783,6 +783,79 @@ void X86Assembler::divpd(XmmRegister dst, XmmRegister src) { } +void X86Assembler::movdqa(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::movdqa(XmmRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitOperand(dst, src); +} + + +void X86Assembler::movdqu(XmmRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xF3); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitOperand(dst, src); +} + + +void X86Assembler::movdqa(const Address& dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x7F); + EmitOperand(src, dst); +} + + +void X86Assembler::movdqu(const Address& dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xF3); + EmitUint8(0x0F); + EmitUint8(0x7F); + EmitOperand(src, dst); +} + + +void X86Assembler::paddd(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xFE); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::psubd(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xFA); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::pmulld(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x38); + EmitUint8(0x40); + EmitXmmRegisterOperand(dst, src); +} + + void X86Assembler::cvtsi2ss(XmmRegister dst, Register src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xF3); @@ -990,10 +1063,27 @@ void X86Assembler::xorpd(XmmRegister dst, XmmRegister src) { } -void X86Assembler::andps(XmmRegister dst, XmmRegister src) { +void X86Assembler::xorps(XmmRegister dst, const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x0F); - EmitUint8(0x54); + EmitUint8(0x57); + EmitOperand(dst, src); +} + + +void X86Assembler::xorps(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x0F); + EmitUint8(0x57); + EmitXmmRegisterOperand(dst, src); +} + + +void X86Assembler::pxor(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0xEF); EmitXmmRegisterOperand(dst, src); } @@ -1007,53 +1097,63 @@ void X86Assembler::andpd(XmmRegister dst, XmmRegister src) { } -void X86Assembler::orpd(XmmRegister dst, XmmRegister src) { +void X86Assembler::andpd(XmmRegister dst, const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x66); EmitUint8(0x0F); - EmitUint8(0x56); + EmitUint8(0x54); + EmitOperand(dst, src); +} + + +void X86Assembler::andps(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x0F); + EmitUint8(0x54); EmitXmmRegisterOperand(dst, src); } -void X86Assembler::xorps(XmmRegister dst, const Address& src) { +void X86Assembler::andps(XmmRegister dst, const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x0F); - EmitUint8(0x57); + EmitUint8(0x54); EmitOperand(dst, src); } -void X86Assembler::orps(XmmRegister dst, XmmRegister src) { +void X86Assembler::pand(XmmRegister dst, XmmRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); EmitUint8(0x0F); - EmitUint8(0x56); + EmitUint8(0xDB); EmitXmmRegisterOperand(dst, src); } -void X86Assembler::xorps(XmmRegister dst, XmmRegister src) { +void X86Assembler::orpd(XmmRegister dst, XmmRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); EmitUint8(0x0F); - EmitUint8(0x57); + EmitUint8(0x56); EmitXmmRegisterOperand(dst, src); } -void X86Assembler::andps(XmmRegister dst, const Address& src) { +void X86Assembler::orps(XmmRegister dst, XmmRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x0F); - EmitUint8(0x54); - EmitOperand(dst, src); + EmitUint8(0x56); + EmitXmmRegisterOperand(dst, src); } -void X86Assembler::andpd(XmmRegister dst, const Address& src) { +void X86Assembler::por(XmmRegister dst, XmmRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x66); EmitUint8(0x0F); - EmitUint8(0x54); - EmitOperand(dst, src); + EmitUint8(0xEB); + EmitXmmRegisterOperand(dst, src); } @@ -1076,6 +1176,16 @@ void X86Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& imm } +void X86Assembler::pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitUint8(0x0F); + EmitUint8(0x70); + EmitXmmRegisterOperand(dst, src); + EmitUint8(imm.value()); +} + + void X86Assembler::fldl(const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xDD); diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 4056ca67fb..4343e2e734 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -430,6 +430,16 @@ class X86Assembler FINAL : public Assembler { void mulpd(XmmRegister dst, XmmRegister src); void divpd(XmmRegister dst, XmmRegister src); + void movdqa(XmmRegister dst, XmmRegister src); // move + void movdqa(XmmRegister dst, const Address& src); // load aligned + void movdqu(XmmRegister dst, const Address& src); // load unaligned + void movdqa(const Address& dst, XmmRegister src); // store aligned + void movdqu(const Address& dst, XmmRegister src); // store unaligned + + void paddd(XmmRegister dst, XmmRegister src); // no addr variant (for now) + void psubd(XmmRegister dst, XmmRegister src); + void pmulld(XmmRegister dst, XmmRegister src); + void cvtsi2ss(XmmRegister dst, Register src); void cvtsi2sd(XmmRegister dst, Register src); @@ -463,17 +473,21 @@ class X86Assembler FINAL : public Assembler { void xorpd(XmmRegister dst, XmmRegister src); void xorps(XmmRegister dst, const Address& src); void xorps(XmmRegister dst, XmmRegister src); + void pxor(XmmRegister dst, XmmRegister src); // no addr variant (for now) void andpd(XmmRegister dst, XmmRegister src); void andpd(XmmRegister dst, const Address& src); void andps(XmmRegister dst, XmmRegister src); void andps(XmmRegister dst, const Address& src); + void pand(XmmRegister dst, XmmRegister src); // no addr variant (for now) - void orpd(XmmRegister dst, XmmRegister src); + void orpd(XmmRegister dst, XmmRegister src); // no addr variant (for now) void orps(XmmRegister dst, XmmRegister src); + void por(XmmRegister dst, XmmRegister src); void shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm); void shufps(XmmRegister dst, XmmRegister src, const Immediate& imm); + void pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm); void flds(const Address& src); void fstps(const Address& dst); diff --git a/compiler/utils/x86/assembler_x86_test.cc b/compiler/utils/x86/assembler_x86_test.cc index 1768d8b715..c6ab893aea 100644 --- a/compiler/utils/x86/assembler_x86_test.cc +++ b/compiler/utils/x86/assembler_x86_test.cc @@ -467,6 +467,28 @@ TEST_F(AssemblerX86Test, MovupdAddr) { DriverStr(expected, "movupd_address"); } +TEST_F(AssemblerX86Test, Movdqa) { + DriverStr(RepeatFF(&x86::X86Assembler::movdqa, "movdqa %{reg2}, %{reg1}"), "movdqa"); +} + +TEST_F(AssemblerX86Test, MovdqaAddr) { + GetAssembler()->movdqa(x86::XmmRegister(x86::XMM0), x86::Address(x86::Register(x86::ESP), 4)); + GetAssembler()->movdqa(x86::Address(x86::Register(x86::ESP), 2), x86::XmmRegister(x86::XMM1)); + const char* expected = + "movdqa 0x4(%ESP), %xmm0\n" + "movdqa %xmm1, 0x2(%ESP)\n"; + DriverStr(expected, "movdqa_address"); +} + +TEST_F(AssemblerX86Test, MovdquAddr) { + GetAssembler()->movdqu(x86::XmmRegister(x86::XMM0), x86::Address(x86::Register(x86::ESP), 4)); + GetAssembler()->movdqu(x86::Address(x86::Register(x86::ESP), 2), x86::XmmRegister(x86::XMM1)); + const char* expected = + "movdqu 0x4(%ESP), %xmm0\n" + "movdqu %xmm1, 0x2(%ESP)\n"; + DriverStr(expected, "movdqu_address"); +} + TEST_F(AssemblerX86Test, AddPS) { DriverStr(RepeatFF(&x86::X86Assembler::addps, "addps %{reg2}, %{reg1}"), "addps"); } @@ -499,6 +521,54 @@ TEST_F(AssemblerX86Test, DivPD) { DriverStr(RepeatFF(&x86::X86Assembler::divpd, "divpd %{reg2}, %{reg1}"), "divpd"); } +TEST_F(AssemblerX86Test, PAddD) { + DriverStr(RepeatFF(&x86::X86Assembler::paddd, "paddd %{reg2}, %{reg1}"), "paddd"); +} + +TEST_F(AssemblerX86Test, PSubD) { + DriverStr(RepeatFF(&x86::X86Assembler::psubd, "psubd %{reg2}, %{reg1}"), "psubd"); +} + +TEST_F(AssemblerX86Test, PMullD) { + DriverStr(RepeatFF(&x86::X86Assembler::pmulld, "pmulld %{reg2}, %{reg1}"), "pmulld"); +} + +TEST_F(AssemblerX86Test, XorPD) { + DriverStr(RepeatFF(&x86::X86Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd"); +} + +TEST_F(AssemblerX86Test, XorPS) { + DriverStr(RepeatFF(&x86::X86Assembler::xorps, "xorps %{reg2}, %{reg1}"), "xorps"); +} + +TEST_F(AssemblerX86Test, PXor) { + DriverStr(RepeatFF(&x86::X86Assembler::pxor, "pxor %{reg2}, %{reg1}"), "pxor"); +} + +TEST_F(AssemblerX86Test, AndPD) { + DriverStr(RepeatFF(&x86::X86Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd"); +} + +TEST_F(AssemblerX86Test, AndPS) { + DriverStr(RepeatFF(&x86::X86Assembler::andps, "andps %{reg2}, %{reg1}"), "andps"); +} + +TEST_F(AssemblerX86Test, PAnd) { + DriverStr(RepeatFF(&x86::X86Assembler::pand, "pand %{reg2}, %{reg1}"), "pand"); +} + +TEST_F(AssemblerX86Test, OrPD) { + DriverStr(RepeatFF(&x86::X86Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd"); +} + +TEST_F(AssemblerX86Test, OrPS) { + DriverStr(RepeatFF(&x86::X86Assembler::orps, "orps %{reg2}, %{reg1}"), "orps"); +} + +TEST_F(AssemblerX86Test, POr) { + DriverStr(RepeatFF(&x86::X86Assembler::por, "por %{reg2}, %{reg1}"), "por"); +} + TEST_F(AssemblerX86Test, ShufPS) { DriverStr(RepeatFFI(&x86::X86Assembler::shufps, 1, "shufps ${imm}, %{reg2}, %{reg1}"), "shufps"); } @@ -507,6 +577,10 @@ TEST_F(AssemblerX86Test, ShufPD) { DriverStr(RepeatFFI(&x86::X86Assembler::shufpd, 1, "shufpd ${imm}, %{reg2}, %{reg1}"), "shufpd"); } +TEST_F(AssemblerX86Test, PShufD) { + DriverStr(RepeatFFI(&x86::X86Assembler::pshufd, 1, "pshufd ${imm}, %{reg2}, %{reg1}"), "pshufd"); +} + ///////////////// // Near labels // ///////////////// diff --git a/compiler/utils/x86_64/assembler_x86_64.cc b/compiler/utils/x86_64/assembler_x86_64.cc index c2c44ab58c..b41be80ae4 100644 --- a/compiler/utils/x86_64/assembler_x86_64.cc +++ b/compiler/utils/x86_64/assembler_x86_64.cc @@ -832,6 +832,87 @@ void X86_64Assembler::divpd(XmmRegister dst, XmmRegister src) { } +void X86_64Assembler::movdqa(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::movdqa(XmmRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::movdqu(XmmRegister dst, const Address& src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xF3); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0x6F); + EmitOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::movdqa(const Address& dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(src, dst); + EmitUint8(0x0F); + EmitUint8(0x7F); + EmitOperand(src.LowBits(), dst); +} + + +void X86_64Assembler::movdqu(const Address& dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0xF3); + EmitOptionalRex32(src, dst); + EmitUint8(0x0F); + EmitUint8(0x7F); + EmitOperand(src.LowBits(), dst); +} + + +void X86_64Assembler::paddd(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xFE); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::psubd(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xFA); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + +void X86_64Assembler::pmulld(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0x38); + EmitUint8(0x40); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + void X86_64Assembler::cvtsi2ss(XmmRegister dst, CpuRegister src) { cvtsi2ss(dst, src, false); } @@ -1170,6 +1251,16 @@ void X86_64Assembler::xorps(XmmRegister dst, XmmRegister src) { } +void X86_64Assembler::pxor(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xEF); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + + void X86_64Assembler::andpd(XmmRegister dst, const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x66); @@ -1196,6 +1287,15 @@ void X86_64Assembler::andps(XmmRegister dst, XmmRegister src) { EmitXmmRegisterOperand(dst.LowBits(), src); } +void X86_64Assembler::pand(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xDB); + EmitXmmRegisterOperand(dst.LowBits(), src); +} + void X86_64Assembler::orpd(XmmRegister dst, XmmRegister src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0x66); @@ -1213,6 +1313,14 @@ void X86_64Assembler::orps(XmmRegister dst, XmmRegister src) { EmitXmmRegisterOperand(dst.LowBits(), src); } +void X86_64Assembler::por(XmmRegister dst, XmmRegister src) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0xEB); + EmitXmmRegisterOperand(dst.LowBits(), src); +} void X86_64Assembler::shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); @@ -1235,6 +1343,17 @@ void X86_64Assembler::shufps(XmmRegister dst, XmmRegister src, const Immediate& } +void X86_64Assembler::pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm) { + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x66); + EmitOptionalRex32(dst, src); + EmitUint8(0x0F); + EmitUint8(0x70); + EmitXmmRegisterOperand(dst.LowBits(), src); + EmitUint8(imm.value()); +} + + void X86_64Assembler::fldl(const Address& src) { AssemblerBuffer::EnsureCapacity ensured(&buffer_); EmitUint8(0xDD); diff --git a/compiler/utils/x86_64/assembler_x86_64.h b/compiler/utils/x86_64/assembler_x86_64.h index e140b45a00..43ea12a4cb 100644 --- a/compiler/utils/x86_64/assembler_x86_64.h +++ b/compiler/utils/x86_64/assembler_x86_64.h @@ -446,6 +446,16 @@ class X86_64Assembler FINAL : public Assembler { void mulpd(XmmRegister dst, XmmRegister src); void divpd(XmmRegister dst, XmmRegister src); + void movdqa(XmmRegister dst, XmmRegister src); // move + void movdqa(XmmRegister dst, const Address& src); // load aligned + void movdqu(XmmRegister dst, const Address& src); // load unaligned + void movdqa(const Address& dst, XmmRegister src); // store aligned + void movdqu(const Address& dst, XmmRegister src); // store unaligned + + void paddd(XmmRegister dst, XmmRegister src); // no addr variant (for now) + void psubd(XmmRegister dst, XmmRegister src); + void pmulld(XmmRegister dst, XmmRegister src); + void cvtsi2ss(XmmRegister dst, CpuRegister src); // Note: this is the r/m32 version. void cvtsi2ss(XmmRegister dst, CpuRegister src, bool is64bit); void cvtsi2ss(XmmRegister dst, const Address& src, bool is64bit); @@ -487,16 +497,20 @@ class X86_64Assembler FINAL : public Assembler { void xorpd(XmmRegister dst, XmmRegister src); void xorps(XmmRegister dst, const Address& src); void xorps(XmmRegister dst, XmmRegister src); + void pxor(XmmRegister dst, XmmRegister src); // no addr variant (for now) void andpd(XmmRegister dst, const Address& src); void andpd(XmmRegister dst, XmmRegister src); - void andps(XmmRegister dst, XmmRegister src); + void andps(XmmRegister dst, XmmRegister src); // no addr variant (for now) + void pand(XmmRegister dst, XmmRegister src); - void orpd(XmmRegister dst, XmmRegister src); + void orpd(XmmRegister dst, XmmRegister src); // no addr variant (for now) void orps(XmmRegister dst, XmmRegister src); + void por(XmmRegister dst, XmmRegister src); void shufpd(XmmRegister dst, XmmRegister src, const Immediate& imm); void shufps(XmmRegister dst, XmmRegister src, const Immediate& imm); + void pshufd(XmmRegister dst, XmmRegister src, const Immediate& imm); void flds(const Address& src); void fstps(const Address& dst); diff --git a/compiler/utils/x86_64/assembler_x86_64_test.cc b/compiler/utils/x86_64/assembler_x86_64_test.cc index efa5cc97ea..aeb1911835 100644 --- a/compiler/utils/x86_64/assembler_x86_64_test.cc +++ b/compiler/utils/x86_64/assembler_x86_64_test.cc @@ -1034,6 +1034,28 @@ TEST_F(AssemblerX86_64Test, Movsd) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::movsd, "movsd %{reg2}, %{reg1}"), "movsd"); } +TEST_F(AssemblerX86_64Test, Movdqa) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::movdqa, "movdqa %{reg2}, %{reg1}"), "movapd"); +} + +TEST_F(AssemblerX86_64Test, MovdqaAddr) { + GetAssembler()->movdqa(x86_64::XmmRegister(x86_64::XMM0), x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4)); + GetAssembler()->movdqa(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 2), x86_64::XmmRegister(x86_64::XMM1)); + const char* expected = + "movdqa 0x4(%RSP), %xmm0\n" + "movdqa %xmm1, 0x2(%RSP)\n"; + DriverStr(expected, "movdqa_address"); +} + +TEST_F(AssemblerX86_64Test, MovdquAddr) { + GetAssembler()->movdqu(x86_64::XmmRegister(x86_64::XMM0), x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 4)); + GetAssembler()->movdqu(x86_64::Address(x86_64::CpuRegister(x86_64::RSP), 2), x86_64::XmmRegister(x86_64::XMM1)); + const char* expected = + "movdqu 0x4(%RSP), %xmm0\n" + "movdqu %xmm1, 0x2(%RSP)\n"; + DriverStr(expected, "movdqu_address"); +} + TEST_F(AssemblerX86_64Test, Movd1) { DriverStr(RepeatFR(&x86_64::X86_64Assembler::movd, "movd %{reg2}, %{reg1}"), "movd.1"); } @@ -1106,6 +1128,18 @@ TEST_F(AssemblerX86_64Test, Divpd) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::divpd, "divpd %{reg2}, %{reg1}"), "divpd"); } +TEST_F(AssemblerX86_64Test, Paddd) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::paddd, "paddd %{reg2}, %{reg1}"), "paddd"); +} + +TEST_F(AssemblerX86_64Test, Psubd) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::psubd, "psubd %{reg2}, %{reg1}"), "psubd"); +} + +TEST_F(AssemblerX86_64Test, Pmulld) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::pmulld, "pmulld %{reg2}, %{reg1}"), "pmulld"); +} + TEST_F(AssemblerX86_64Test, Cvtsi2ss) { DriverStr(RepeatFr(&x86_64::X86_64Assembler::cvtsi2ss, "cvtsi2ss %{reg2}, %{reg1}"), "cvtsi2ss"); } @@ -1187,6 +1221,10 @@ TEST_F(AssemblerX86_64Test, Xorpd) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::xorpd, "xorpd %{reg2}, %{reg1}"), "xorpd"); } +TEST_F(AssemblerX86_64Test, Pxor) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::pxor, "pxor %{reg2}, %{reg1}"), "pxor"); +} + TEST_F(AssemblerX86_64Test, Andps) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::andps, "andps %{reg2}, %{reg1}"), "andps"); } @@ -1195,6 +1233,10 @@ TEST_F(AssemblerX86_64Test, Andpd) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::andpd, "andpd %{reg2}, %{reg1}"), "andpd"); } +TEST_F(AssemblerX86_64Test, Pand) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::pand, "pand %{reg2}, %{reg1}"), "pand"); +} + TEST_F(AssemblerX86_64Test, Orps) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::orps, "orps %{reg2}, %{reg1}"), "orps"); } @@ -1203,6 +1245,10 @@ TEST_F(AssemblerX86_64Test, Orpd) { DriverStr(RepeatFF(&x86_64::X86_64Assembler::orpd, "orpd %{reg2}, %{reg1}"), "orpd"); } +TEST_F(AssemblerX86_64Test, Por) { + DriverStr(RepeatFF(&x86_64::X86_64Assembler::por, "por %{reg2}, %{reg1}"), "por"); +} + TEST_F(AssemblerX86_64Test, Shufps) { DriverStr(RepeatFFI(&x86_64::X86_64Assembler::shufps, 1, "shufps ${imm}, %{reg2}, %{reg1}"), "shufps"); } @@ -1211,6 +1257,10 @@ TEST_F(AssemblerX86_64Test, Shufpd) { DriverStr(RepeatFFI(&x86_64::X86_64Assembler::shufpd, 1, "shufpd ${imm}, %{reg2}, %{reg1}"), "shufpd"); } +TEST_F(AssemblerX86_64Test, PShufd) { + DriverStr(RepeatFFI(&x86_64::X86_64Assembler::pshufd, 1, "pshufd ${imm}, %{reg2}, %{reg1}"), "pshufd"); +} + TEST_F(AssemblerX86_64Test, UcomissAddress) { GetAssembler()->ucomiss(x86_64::XmmRegister(x86_64::XMM0), x86_64::Address( x86_64::CpuRegister(x86_64::RDI), x86_64::CpuRegister(x86_64::RBX), x86_64::TIMES_4, 12)); diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 9f49ec6f60..ff05733345 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -859,6 +859,22 @@ DISASSEMBLER_ENTRY(cmp, has_modrm = true; store = true; break; + case 0x7F: + if (prefix[2] == 0x66) { + src_reg_file = dst_reg_file = SSE; + opcode1 = "movdqa"; + prefix[2] = 0; // clear prefix now it's served its purpose as part of the opcode + } else if (prefix[0] == 0xF3) { + src_reg_file = dst_reg_file = SSE; + opcode1 = "movdqu"; + prefix[0] = 0; // clear prefix now it's served its purpose as part of the opcode + } else { + dst_reg_file = MMX; + opcode1 = "movq"; + } + store = true; + has_modrm = true; + break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8A: case 0x8B: case 0x8C: case 0x8D: case 0x8E: case 0x8F: opcode1 = "j"; |