Index: src/x64/assembler-x64.cc |
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc |
index 9a0d18e9c2fba4c71648b999eb560165927ddbf9..d202aadf7a141b167cf6a1bc608e2bc841b948f8 100644 |
--- a/src/x64/assembler-x64.cc |
+++ b/src/x64/assembler-x64.cc |
@@ -79,6 +79,7 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
if (cross_compile) return; |
if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1; |
+ if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3; |
if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3; |
// SAHF is not generally available in long mode. |
if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF; |
@@ -105,13 +106,15 @@ void CpuFeatures::ProbeImpl(bool cross_compile) { |
void CpuFeatures::PrintTarget() { } |
void CpuFeatures::PrintFeatures() { |
printf( |
- "SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d " |
+ "SSE3=%d SSSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d " |
+ "LZCNT=%d " |
"POPCNT=%d ATOM=%d\n", |
- CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1), |
- CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX), |
- CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(BMI1), |
- CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT), |
- CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM)); |
+ CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3), |
+ CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(SAHF), |
+ CpuFeatures::IsSupported(AVX), CpuFeatures::IsSupported(FMA3), |
+ CpuFeatures::IsSupported(BMI1), CpuFeatures::IsSupported(BMI2), |
+ CpuFeatures::IsSupported(LZCNT), CpuFeatures::IsSupported(POPCNT), |
+ CpuFeatures::IsSupported(ATOM)); |
} |
// ----------------------------------------------------------------------------- |
@@ -2834,6 +2837,77 @@ void Assembler::extractps(Register dst, XMMRegister src, byte imm8) { |
emit(imm8); |
} |
+void Assembler::pextrb(Register dst, XMMRegister src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(src, dst); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x14); |
+ emit_sse_operand(src, dst); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pextrb(const Operand& dst, XMMRegister src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(src, dst); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x14); |
+ emit_sse_operand(src, dst); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pinsrw(XMMRegister dst, Register src, int8_t imm8) { |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(dst, src); |
+ emit(0x0F); |
+ emit(0xC4); |
+ emit_sse_operand(dst, src); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pinsrw(XMMRegister dst, const Operand& src, int8_t imm8) { |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(dst, src); |
+ emit(0x0F); |
+ emit(0xC4); |
+ emit_sse_operand(dst, src); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pextrw(Register dst, XMMRegister src, int8_t imm8) { |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(src, dst); |
+ emit(0x0F); |
+ emit(0xC5); |
+ emit_sse_operand(src, dst); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pextrw(const Operand& dst, XMMRegister src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ DCHECK(is_uint8(imm8)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(src, dst); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x15); |
+ emit_sse_operand(src, dst); |
+ emit(imm8); |
+} |
void Assembler::pextrd(Register dst, XMMRegister src, int8_t imm8) { |
DCHECK(IsEnabled(SSE4_1)); |
@@ -2847,6 +2921,17 @@ void Assembler::pextrd(Register dst, XMMRegister src, int8_t imm8) { |
emit(imm8); |
} |
+void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(src, dst); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x16); |
+ emit_sse_operand(src, dst); |
+ emit(imm8); |
+} |
void Assembler::pinsrd(XMMRegister dst, Register src, int8_t imm8) { |
DCHECK(IsEnabled(SSE4_1)); |
@@ -2873,6 +2958,30 @@ void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) { |
emit(imm8); |
} |
+void Assembler::pinsrb(XMMRegister dst, Register src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(dst, src); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x20); |
+ emit_sse_operand(dst, src); |
+ emit(imm8); |
+} |
+ |
+void Assembler::pinsrb(XMMRegister dst, const Operand& src, int8_t imm8) { |
+ DCHECK(IsEnabled(SSE4_1)); |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(dst, src); |
+ emit(0x0F); |
+ emit(0x3A); |
+ emit(0x20); |
+ emit_sse_operand(dst, src); |
+ emit(imm8); |
+} |
+ |
void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) { |
DCHECK(CpuFeatures::IsSupported(SSE4_1)); |
DCHECK(is_uint8(imm8)); |
@@ -3202,6 +3311,15 @@ void Assembler::psrlq(XMMRegister reg, byte imm8) { |
emit(imm8); |
} |
+void Assembler::psllw(XMMRegister reg, byte imm8) { |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(reg); |
+ emit(0x0F); |
+ emit(0x71); |
+ emit_sse_operand(rsi, reg); // rsi == 6 |
+ emit(imm8); |
+} |
void Assembler::pslld(XMMRegister reg, byte imm8) { |
EnsureSpace ensure_space(this); |
@@ -3213,6 +3331,15 @@ void Assembler::pslld(XMMRegister reg, byte imm8) { |
emit(imm8); |
} |
+void Assembler::psrlw(XMMRegister reg, byte imm8) { |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(reg); |
+ emit(0x0F); |
+ emit(0x71); |
+ emit_sse_operand(rdx, reg); // rdx == 2 |
+ emit(imm8); |
+} |
void Assembler::psrld(XMMRegister reg, byte imm8) { |
EnsureSpace ensure_space(this); |
@@ -3224,6 +3351,26 @@ void Assembler::psrld(XMMRegister reg, byte imm8) { |
emit(imm8); |
} |
+void Assembler::psraw(XMMRegister reg, byte imm8) { |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(reg); |
+ emit(0x0F); |
+ emit(0x71); |
+ emit_sse_operand(rsp, reg); // rsp == 4 |
+ emit(imm8); |
+} |
+ |
+void Assembler::psrad(XMMRegister reg, byte imm8) { |
+ EnsureSpace ensure_space(this); |
+ emit(0x66); |
+ emit_optional_rex_32(reg); |
+ emit(0x0F); |
+ emit(0x72); |
+ emit_sse_operand(rsp, reg); // rsp == 4 |
+ emit(imm8); |
+} |
+ |
void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) { |
EnsureSpace ensure_space(this); |
emit_optional_rex_32(dst, src); |
@@ -3789,17 +3936,6 @@ void Assembler::movmskps(Register dst, XMMRegister src) { |
} |
-void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) { |
- DCHECK(!IsEnabled(AVX)); |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0x76); |
- emit_sse_operand(dst, src); |
-} |
- |
- |
void Assembler::punpckldq(XMMRegister dst, XMMRegister src) { |
EnsureSpace ensure_space(this); |
emit(0x66); |
@@ -3926,9 +4062,9 @@ void Assembler::vmovq(Register dst, XMMRegister src) { |
emit_sse_operand(src, dst); |
} |
- |
-void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, |
- XMMRegister src2, SIMDPrefix pp, LeadingOpcode m, VexW w) { |
+void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, |
+ XMMRegister src2, SIMDPrefix pp, LeadingOpcode m, |
+ VexW w) { |
DCHECK(IsEnabled(AVX)); |
EnsureSpace ensure_space(this); |
emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w); |
@@ -3936,10 +4072,9 @@ void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, |
emit_sse_operand(dst, src2); |
} |
- |
-void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, |
- const Operand& src2, SIMDPrefix pp, LeadingOpcode m, |
- VexW w) { |
+void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, |
+ const Operand& src2, SIMDPrefix pp, LeadingOpcode m, |
+ VexW w) { |
DCHECK(IsEnabled(AVX)); |
EnsureSpace ensure_space(this); |
emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w); |
@@ -4409,78 +4544,81 @@ void Assembler::movups(const Operand& dst, XMMRegister src) { |
emit_sse_operand(src, dst); |
} |
-void Assembler::paddd(XMMRegister dst, XMMRegister src) { |
+void Assembler::sse2_instr(XMMRegister dst, XMMRegister src, byte prefix, |
+ byte escape, byte opcode) { |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0xFE); |
+ emit(escape); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::paddd(XMMRegister dst, const Operand& src) { |
+void Assembler::sse2_instr(XMMRegister dst, const Operand& src, byte prefix, |
+ byte escape, byte opcode) { |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0xFE); |
+ emit(escape); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::psubd(XMMRegister dst, XMMRegister src) { |
+void Assembler::ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix, |
+ byte escape1, byte escape2, byte opcode) { |
+ DCHECK(IsEnabled(SSSE3)); |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0xFA); |
+ emit(escape1); |
+ emit(escape2); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::psubd(XMMRegister dst, const Operand& src) { |
+void Assembler::ssse3_instr(XMMRegister dst, const Operand& src, byte prefix, |
+ byte escape1, byte escape2, byte opcode) { |
+ DCHECK(IsEnabled(SSSE3)); |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0xFA); |
+ emit(escape1); |
+ emit(escape2); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::pmulld(XMMRegister dst, XMMRegister src) { |
+void Assembler::sse4_instr(XMMRegister dst, XMMRegister src, byte prefix, |
+ byte escape1, byte escape2, byte opcode) { |
DCHECK(IsEnabled(SSE4_1)); |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0x38); |
- emit(0x40); |
- emit_sse_operand(dst, src); |
-} |
- |
-void Assembler::pmulld(XMMRegister dst, const Operand& src) { |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0x38); |
- emit(0x40); |
+ emit(escape1); |
+ emit(escape2); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::pmuludq(XMMRegister dst, XMMRegister src) { |
+void Assembler::sse4_instr(XMMRegister dst, const Operand& src, byte prefix, |
+ byte escape1, byte escape2, byte opcode) { |
+ DCHECK(IsEnabled(SSE4_1)); |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(prefix); |
emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0xF4); |
+ emit(escape1); |
+ emit(escape2); |
+ emit(opcode); |
emit_sse_operand(dst, src); |
} |
-void Assembler::pmuludq(XMMRegister dst, const Operand& src) { |
+void Assembler::lddqu(XMMRegister dst, const Operand& src) { |
+ DCHECK(IsEnabled(SSE3)); |
EnsureSpace ensure_space(this); |
- emit(0x66); |
+ emit(0xF2); |
emit_optional_rex_32(dst, src); |
emit(0x0F); |
- emit(0xF4); |
+ emit(0xF0); |
emit_sse_operand(dst, src); |
} |
@@ -4494,25 +4632,17 @@ void Assembler::psrldq(XMMRegister dst, uint8_t shift) { |
emit(shift); |
} |
-void Assembler::cvtps2dq(XMMRegister dst, XMMRegister src) { |
- EnsureSpace ensure_space(this); |
- emit(0x66); |
- emit_optional_rex_32(dst, src); |
- emit(0x0F); |
- emit(0x5B); |
- emit_sse_operand(dst, src); |
-} |
- |
-void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) { |
+void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) { |
EnsureSpace ensure_space(this); |
emit(0x66); |
emit_optional_rex_32(dst, src); |
emit(0x0F); |
- emit(0x5B); |
+ emit(0x70); |
emit_sse_operand(dst, src); |
+ emit(shuffle); |
} |
-void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) { |
+void Assembler::pshufd(XMMRegister dst, const Operand& src, uint8_t shuffle) { |
EnsureSpace ensure_space(this); |
emit(0x66); |
emit_optional_rex_32(dst, src); |