Commit a1f7da8f authored by Deepti Gandluri's avatar Deepti Gandluri Committed by Commit Bot

[x64] Add assembly/disassembly for left-over SIMD ops

Change-Id: I55d15fd15cc714732139e4bf12bd75f21f922048
Reviewed-on: https://chromium-review.googlesource.com/1174013Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55174}
parent c07c93f3
...@@ -75,6 +75,10 @@ void Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) { ...@@ -75,6 +75,10 @@ void Assembler::emit_rex_64(Register reg, XMMRegister rm_reg) {
emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3); emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
} }
void Assembler::emit_rex_64(XMMRegister reg, XMMRegister rm_reg) {
emit(0x48 | (reg.code() & 0x8) >> 1 | rm_reg.code() >> 3);
}
void Assembler::emit_rex_64(Register reg, Operand op) { void Assembler::emit_rex_64(Register reg, Operand op) {
emit(0x48 | reg.high_bit() << 2 | op.data().rex); emit(0x48 | reg.high_bit() << 2 | op.data().rex);
} }
......
...@@ -1020,7 +1020,7 @@ void Assembler::pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle) { ...@@ -1020,7 +1020,7 @@ void Assembler::pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
emit_optional_rex_32(dst, src); emit_optional_rex_32(dst, src);
emit(0x0F); emit(0x0F);
emit(0x70); emit(0x70);
emit(0xC0 | (dst.low_bits() << 3) | src.low_bits()); emit_sse_operand(dst, src);
emit(shuffle); emit(shuffle);
} }
...@@ -1033,6 +1033,26 @@ void Assembler::pshufw(XMMRegister dst, Operand src, uint8_t shuffle) { ...@@ -1033,6 +1033,26 @@ void Assembler::pshufw(XMMRegister dst, Operand src, uint8_t shuffle) {
emit(shuffle); emit(shuffle);
} }
void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t mask) {
sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
emit(mask);
}
void Assembler::pblendw(XMMRegister dst, XMMRegister src, uint8_t mask) {
sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
emit(mask);
}
void Assembler::palignr(XMMRegister dst, Operand src, uint8_t mask) {
ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
emit(mask);
}
void Assembler::palignr(XMMRegister dst, XMMRegister src, uint8_t mask) {
ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
emit(mask);
}
void Assembler::call(Label* L) { void Assembler::call(Label* L) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
// 1110 1000 #32-bit disp. // 1110 1000 #32-bit disp.
...@@ -3749,6 +3769,24 @@ void Assembler::cvttsd2siq(Register dst, Operand src) { ...@@ -3749,6 +3769,24 @@ void Assembler::cvttsd2siq(Register dst, Operand src) {
emit_sse_operand(dst, src); emit_sse_operand(dst, src);
} }
void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
EnsureSpace ensure_space(this);
emit(0xF3);
emit_rex_64(dst, src);
emit(0x0F);
emit(0x5B);
emit_sse_operand(dst, src);
}
void Assembler::cvttps2dq(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0xF3);
emit_rex_64(dst, src);
emit(0x0F);
emit(0x5B);
emit_sse_operand(dst, src);
}
void Assembler::cvtlsi2sd(XMMRegister dst, Operand src) { void Assembler::cvtlsi2sd(XMMRegister dst, Operand src) {
DCHECK(!IsEnabled(AVX)); DCHECK(!IsEnabled(AVX));
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
...@@ -4191,34 +4229,6 @@ void Assembler::movmskps(Register dst, XMMRegister src) { ...@@ -4191,34 +4229,6 @@ void Assembler::movmskps(Register dst, XMMRegister src) {
} }
void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x62);
emit_sse_operand(dst, src);
}
void Assembler::punpckldq(XMMRegister dst, Operand src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x62);
emit_sse_operand(dst, src);
}
void Assembler::punpckhdq(XMMRegister dst, XMMRegister src) {
EnsureSpace ensure_space(this);
emit(0x66);
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0x6A);
emit_sse_operand(dst, src);
}
// AVX instructions // AVX instructions
void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1, void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
XMMRegister src2) { XMMRegister src2) {
......
...@@ -931,6 +931,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -931,6 +931,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle); void pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle);
void pshufw(XMMRegister dst, Operand src, uint8_t shuffle); void pshufw(XMMRegister dst, Operand src, uint8_t shuffle);
void pblendw(XMMRegister dst, Operand src, uint8_t mask);
void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask);
void palignr(XMMRegister dst, Operand src, uint8_t mask);
void palignr(XMMRegister dst, XMMRegister src, uint8_t mask);
// Label operations & relative jumps (PPUM Appendix D) // Label operations & relative jumps (PPUM Appendix D)
// //
...@@ -1242,6 +1246,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -1242,6 +1246,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void cvttss2siq(Register dst, Operand src); void cvttss2siq(Register dst, Operand src);
void cvttsd2siq(Register dst, XMMRegister src); void cvttsd2siq(Register dst, XMMRegister src);
void cvttsd2siq(Register dst, Operand src); void cvttsd2siq(Register dst, Operand src);
void cvttps2dq(XMMRegister dst, Operand src);
void cvttps2dq(XMMRegister dst, XMMRegister src);
void cvtlsi2sd(XMMRegister dst, Operand src); void cvtlsi2sd(XMMRegister dst, Operand src);
void cvtlsi2sd(XMMRegister dst, Register src); void cvtlsi2sd(XMMRegister dst, Register src);
...@@ -1293,10 +1299,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -1293,10 +1299,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void movmskpd(Register dst, XMMRegister src); void movmskpd(Register dst, XMMRegister src);
void punpckldq(XMMRegister dst, XMMRegister src);
void punpckldq(XMMRegister dst, Operand src);
void punpckhdq(XMMRegister dst, XMMRegister src);
// SSE 4.1 instruction // SSE 4.1 instruction
void insertps(XMMRegister dst, XMMRegister src, byte imm8); void insertps(XMMRegister dst, XMMRegister src, byte imm8);
void extractps(Register dst, XMMRegister src, byte imm8); void extractps(Register dst, XMMRegister src, byte imm8);
...@@ -2044,6 +2046,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase { ...@@ -2044,6 +2046,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
inline void emit_rex_64(XMMRegister reg, Register rm_reg); inline void emit_rex_64(XMMRegister reg, Register rm_reg);
inline void emit_rex_64(Register reg, XMMRegister rm_reg); inline void emit_rex_64(Register reg, XMMRegister rm_reg);
inline void emit_rex_64(Register reg, Register rm_reg); inline void emit_rex_64(Register reg, Register rm_reg);
inline void emit_rex_64(XMMRegister reg, XMMRegister rm_reg);
// Emits a REX prefix that encodes a 64-bit operand size and // Emits a REX prefix that encodes a 64-bit operand size and
// the top bit of the destination, index, and base register codes. // the top bit of the destination, index, and base register codes.
......
...@@ -1682,6 +1682,18 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1682,6 +1682,18 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
AppendToBuffer(",0x%x", (*current) & 3); AppendToBuffer(",0x%x", (*current) & 3);
current += 1; current += 1;
} else if (third_byte == 0x0E) {
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("pblendw %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(data);
AppendToBuffer(",0x%x", (*current) & 3);
current += 1;
} else if (third_byte == 0x0F) {
get_modrm(*data, &mod, &regop, &rm);
AppendToBuffer("palignr %s,", NameOfXMMRegister(regop));
current += PrintRightXMMOperand(data);
AppendToBuffer(",0x%x", (*current) & 3);
current += 1;
} else if (third_byte == 0x14) { } else if (third_byte == 0x14) {
get_modrm(*current, &mod, &regop, &rm); get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("pextrb "); // reg/m32, xmm, imm8 AppendToBuffer("pextrb "); // reg/m32, xmm, imm8
...@@ -1813,32 +1825,44 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1813,32 +1825,44 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
mnemonic = "xorpd"; mnemonic = "xorpd";
} else if (opcode == 0x5B) { } else if (opcode == 0x5B) {
mnemonic = "cvtps2dq"; mnemonic = "cvtps2dq";
} else if (opcode == 0x2E) { } else if (opcode == 0x60) {
mnemonic = "ucomisd"; mnemonic = "punpcklbw";
} else if (opcode == 0x2F) { } else if (opcode == 0x61) {
mnemonic = "comisd"; mnemonic = "punpcklwd";
} else if (opcode == 0x62) {
mnemonic = "punpckldq";
} else if (opcode == 0x63) {
mnemonic = "packsswb";
} else if (opcode == 0x64) { } else if (opcode == 0x64) {
mnemonic = "pcmpgtb"; mnemonic = "pcmpgtb";
} else if (opcode == 0x65) { } else if (opcode == 0x65) {
mnemonic = "pcmpgtw"; mnemonic = "pcmpgtw";
} else if (opcode == 0x66) { } else if (opcode == 0x66) {
mnemonic = "pcmpgtd"; mnemonic = "pcmpgtd";
} else if (opcode == 0x74) {
mnemonic = "pcmpeqb";
} else if (opcode == 0x75) {
mnemonic = "pcmpeqw";
} else if (opcode == 0x76) {
mnemonic = "pcmpeqd";
} else if (opcode == 0x62) {
mnemonic = "punpckldq";
} else if (opcode == 0x63) {
mnemonic = "packsswb";
} else if (opcode == 0x67) { } else if (opcode == 0x67) {
mnemonic = "packuswb"; mnemonic = "packuswb";
} else if (opcode == 0x68) {
mnemonic = "punpckhbw";
} else if (opcode == 0x69) {
mnemonic = "punpckhwd";
} else if (opcode == 0x6A) { } else if (opcode == 0x6A) {
mnemonic = "punpckhdq"; mnemonic = "punpckhdq";
} else if (opcode == 0x6B) { } else if (opcode == 0x6B) {
mnemonic = "packssdw"; mnemonic = "packssdw";
} else if (opcode == 0x6C) {
mnemonic = "punpcklqdq";
} else if (opcode == 0x6D) {
mnemonic = "punpckhqdq";
} else if (opcode == 0x2E) {
mnemonic = "ucomisd";
} else if (opcode == 0x2F) {
mnemonic = "comisd";
} else if (opcode == 0x74) {
mnemonic = "pcmpeqb";
} else if (opcode == 0x75) {
mnemonic = "pcmpeqw";
} else if (opcode == 0x76) {
mnemonic = "pcmpeqd";
} else if (opcode == 0xD1) { } else if (opcode == 0xD1) {
mnemonic = "psrlw"; mnemonic = "psrlw";
} else if (opcode == 0xD2) { } else if (opcode == 0xD2) {
...@@ -1950,6 +1974,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) { ...@@ -1950,6 +1974,14 @@ int DisassemblerX64::TwoByteOpcodeInstruction(byte* data) {
AppendToBuffer("cvtsd2si%c %s,", AppendToBuffer("cvtsd2si%c %s,",
operand_size_code(), NameOfCPURegister(regop)); operand_size_code(), NameOfCPURegister(regop));
current += PrintRightXMMOperand(current); current += PrintRightXMMOperand(current);
} else if (opcode == 0x5B) {
// CVTTPS2DQ: Convert packed single-precision FP values to packed signed
// doubleword integer values
int mod, regop, rm;
get_modrm(*current, &mod, &regop, &rm);
AppendToBuffer("cvttps2dq%c %s,", operand_size_code(),
NameOfCPURegister(regop));
current += PrintRightXMMOperand(current);
} else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) { } else if ((opcode & 0xF8) == 0x58 || opcode == 0x51) {
// XMM arithmetic. Mnemonic was retrieved at the start of this function. // XMM arithmetic. Mnemonic was retrieved at the start of this function.
int mod, regop, rm; int mod, regop, rm;
......
...@@ -6,9 +6,18 @@ ...@@ -6,9 +6,18 @@
#define V8_X64_SSE_INSTR_H_ #define V8_X64_SSE_INSTR_H_
#define SSE2_INSTRUCTION_LIST(V) \ #define SSE2_INSTRUCTION_LIST(V) \
V(cvtps2dq, 66, 0F, 5B) \
V(punpcklbw, 66, 0F, 60) \
V(punpcklwd, 66, 0F, 61) \
V(punpckldq, 66, 0F, 62) \
V(packsswb, 66, 0F, 63) \ V(packsswb, 66, 0F, 63) \
V(packssdw, 66, 0F, 6B) \
V(packuswb, 66, 0F, 67) \ V(packuswb, 66, 0F, 67) \
V(punpckhbw, 66, 0F, 68) \
V(punpckhwd, 66, 0F, 69) \
V(punpckhdq, 66, 0F, 6A) \
V(packssdw, 66, 0F, 6B) \
V(punpcklqdq, 66, 0F, 6C) \
V(punpckhqdq, 66, 0F, 6D) \
V(paddb, 66, 0F, FC) \ V(paddb, 66, 0F, FC) \
V(paddw, 66, 0F, FD) \ V(paddw, 66, 0F, FD) \
V(paddd, 66, 0F, FE) \ V(paddd, 66, 0F, FE) \
...@@ -43,8 +52,7 @@ ...@@ -43,8 +52,7 @@
V(psubusw, 66, 0F, D9) \ V(psubusw, 66, 0F, D9) \
V(pand, 66, 0F, DB) \ V(pand, 66, 0F, DB) \
V(por, 66, 0F, EB) \ V(por, 66, 0F, EB) \
V(pxor, 66, 0F, EF) \ V(pxor, 66, 0F, EF)
V(cvtps2dq, 66, 0F, 5B)
#define SSSE3_INSTRUCTION_LIST(V) \ #define SSSE3_INSTRUCTION_LIST(V) \
V(pabsb, 66, 0F, 38, 1C) \ V(pabsb, 66, 0F, 38, 1C) \
...@@ -58,7 +66,12 @@ ...@@ -58,7 +66,12 @@
V(psignd, 66, 0F, 38, 0A) V(psignd, 66, 0F, 38, 0A)
#define SSE4_INSTRUCTION_LIST(V) \ #define SSE4_INSTRUCTION_LIST(V) \
V(ptest, 66, 0F, 38, 17) \
V(pmovsxbw, 66, 0F, 38, 20) \
V(pmovsxwd, 66, 0F, 38, 23) \
V(packusdw, 66, 0F, 38, 2B) \ V(packusdw, 66, 0F, 38, 2B) \
V(pmovzxbw, 66, 0F, 38, 30) \
V(pmovzxwd, 66, 0F, 38, 33) \
V(pminsb, 66, 0F, 38, 38) \ V(pminsb, 66, 0F, 38, 38) \
V(pminsd, 66, 0F, 38, 39) \ V(pminsd, 66, 0F, 38, 39) \
V(pminuw, 66, 0F, 38, 3A) \ V(pminuw, 66, 0F, 38, 3A) \
...@@ -67,7 +80,6 @@ ...@@ -67,7 +80,6 @@
V(pmaxsd, 66, 0F, 38, 3D) \ V(pmaxsd, 66, 0F, 38, 3D) \
V(pmaxuw, 66, 0F, 38, 3E) \ V(pmaxuw, 66, 0F, 38, 3E) \
V(pmaxud, 66, 0F, 38, 3F) \ V(pmaxud, 66, 0F, 38, 3F) \
V(pmulld, 66, 0F, 38, 40) \ V(pmulld, 66, 0F, 38, 40)
V(ptest, 66, 0F, 38, 17)
#endif // V8_X64_SSE_INSTR_H_ #endif // V8_X64_SSE_INSTR_H_
...@@ -386,6 +386,8 @@ TEST(DisasmX64) { ...@@ -386,6 +386,8 @@ TEST(DisasmX64) {
__ cvttss2si(rdx, xmm1); __ cvttss2si(rdx, xmm1);
__ cvtsd2ss(xmm0, xmm1); __ cvtsd2ss(xmm0, xmm1);
__ cvtsd2ss(xmm0, Operand(rbx, rcx, times_4, 10000)); __ cvtsd2ss(xmm0, Operand(rbx, rcx, times_4, 10000));
__ cvttps2dq(xmm0, xmm1);
__ cvttps2dq(xmm0, Operand(rbx, rcx, times_4, 10000));
__ movaps(xmm0, xmm1); __ movaps(xmm0, xmm1);
__ movdqa(xmm0, Operand(rsp, 12)); __ movdqa(xmm0, Operand(rsp, 12));
__ movdqa(Operand(rsp, 12), xmm0); __ movdqa(Operand(rsp, 12), xmm0);
...@@ -526,6 +528,8 @@ TEST(DisasmX64) { ...@@ -526,6 +528,8 @@ TEST(DisasmX64) {
{ {
if (CpuFeatures::IsSupported(SSSE3)) { if (CpuFeatures::IsSupported(SSSE3)) {
CpuFeatureScope scope(&assm, SSSE3); CpuFeatureScope scope(&assm, SSSE3);
__ palignr(xmm5, xmm1, 5);
__ palignr(xmm5, Operand(rdx, 4), 5);
SSSE3_INSTRUCTION_LIST(EMIT_SSE34_INSTR) SSSE3_INSTRUCTION_LIST(EMIT_SSE34_INSTR)
} }
} }
...@@ -541,6 +545,8 @@ TEST(DisasmX64) { ...@@ -541,6 +545,8 @@ TEST(DisasmX64) {
__ pextrd(r12, xmm0, 1); __ pextrd(r12, xmm0, 1);
__ pinsrd(xmm9, r9, 0); __ pinsrd(xmm9, r9, 0);
__ pinsrd(xmm5, Operand(rax, 4), 1); __ pinsrd(xmm5, Operand(rax, 4), 1);
__ pblendw(xmm5, xmm1, 1);
__ pblendw(xmm9, Operand(rax, 4), 1);
__ cmpps(xmm5, xmm1, 1); __ cmpps(xmm5, xmm1, 1);
__ cmpps(xmm5, Operand(rbx, rcx, times_4, 10000), 1); __ cmpps(xmm5, Operand(rbx, rcx, times_4, 10000), 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment