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