From 7ae54d2b82a283d06c0b60a1268fcf5136da6eca Mon Sep 17 00:00:00 2001 From: alph Date: Thu, 22 Oct 2015 23:47:13 -0700 Subject: [PATCH] [x64] Implement vsqrtsd AVX instruction. BUG=v8:4406 LOG=N Review URL: https://codereview.chromium.org/1420543003 Cr-Commit-Position: refs/heads/master@{#31490} --- src/crankshaft/x64/lithium-codegen-x64.cc | 6 +++--- src/x64/assembler-x64.cc | 2 ++ src/x64/assembler-x64.h | 1 + src/x64/code-stubs-x64.cc | 4 ++-- src/x64/codegen-x64.cc | 2 +- src/x64/disasm-x64.cc | 5 +++++ src/x64/macro-assembler-x64.cc | 20 ++++++++++++++++++++ src/x64/macro-assembler-x64.h | 3 +++ test/cctest/test-assembler-x64.cc | 15 +++++++++++++++ test/cctest/test-disasm-x64.cc | 2 ++ 10 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/crankshaft/x64/lithium-codegen-x64.cc b/src/crankshaft/x64/lithium-codegen-x64.cc index da86d31712..c7d68d8a8d 100644 --- a/src/crankshaft/x64/lithium-codegen-x64.cc +++ b/src/crankshaft/x64/lithium-codegen-x64.cc @@ -3712,10 +3712,10 @@ void LCodeGen::DoMathSqrt(LMathSqrt* instr) { XMMRegister output = ToDoubleRegister(instr->result()); if (instr->value()->IsDoubleRegister()) { XMMRegister input = ToDoubleRegister(instr->value()); - __ sqrtsd(output, input); + __ Sqrtsd(output, input); } else { Operand input = ToOperand(instr->value()); - __ sqrtsd(output, input); + __ Sqrtsd(output, input); } } @@ -3747,7 +3747,7 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { __ bind(&sqrt); __ Xorpd(xmm_scratch, xmm_scratch); __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. - __ sqrtsd(input_reg, input_reg); + __ Sqrtsd(input_reg, input_reg); __ bind(&done); } diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index 25c9e55657..f34ca85d59 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -3365,6 +3365,7 @@ void Assembler::xorpd(XMMRegister dst, XMMRegister src) { void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { + DCHECK(!IsEnabled(AVX)); EnsureSpace ensure_space(this); emit(0xF2); emit_optional_rex_32(dst, src); @@ -3375,6 +3376,7 @@ void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) { void Assembler::sqrtsd(XMMRegister dst, const Operand& src) { + DCHECK(!IsEnabled(AVX)); EnsureSpace ensure_space(this); emit(0xF2); emit_optional_rex_32(dst, src); diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index 900c058e5a..af27b36965 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -1318,6 +1318,7 @@ class Assembler : public AssemblerBase { impl(opcode, dst, src1, src2); \ } + AVX_SP_3(vsqrt, 0x51); AVX_SP_3(vadd, 0x58); AVX_SP_3(vsub, 0x5c); AVX_SP_3(vmul, 0x59); diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 481e100c77..7740ae3ac3 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -363,7 +363,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { // sqrtsd returns -0 when input is -0. ECMA spec requires +0. __ Xorpd(double_scratch, double_scratch); __ addsd(double_scratch, double_base); // Convert -0 to 0. - __ sqrtsd(double_result, double_scratch); + __ Sqrtsd(double_result, double_scratch); __ jmp(&done); // Test for -0.5. @@ -394,7 +394,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { // sqrtsd returns -0 when input is -0. ECMA spec requires +0. __ Xorpd(double_exponent, double_exponent); __ addsd(double_exponent, double_base); // Convert -0 to +0. - __ sqrtsd(double_exponent, double_exponent); + __ Sqrtsd(double_exponent, double_exponent); __ divsd(double_result, double_exponent); __ jmp(&done); } diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 1b20983831..b857abf715 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -74,7 +74,7 @@ UnaryMathFunction CreateSqrtFunction() { MacroAssembler masm(NULL, buffer, static_cast(actual_size)); // xmm0: raw double input. // Move double input into registers. - __ sqrtsd(xmm0, xmm0); + __ Sqrtsd(xmm0, xmm0); __ Ret(); CodeDesc desc; diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc index 3d3b57e00b..301affe9e9 100644 --- a/src/x64/disasm-x64.cc +++ b/src/x64/disasm-x64.cc @@ -1038,6 +1038,11 @@ int DisassemblerX64::AVXInstruction(byte* data) { NameOfCPURegister(regop)); current += PrintRightXMMOperand(current); break; + case 0x51: + AppendToBuffer("vsqrtsd %s,%s,", NameOfXMMRegister(regop), + NameOfXMMRegister(vvvv)); + current += PrintRightXMMOperand(current); + break; case 0x58: AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop), NameOfXMMRegister(vvvv)); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index df010e04fd..599e403409 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -2669,6 +2669,26 @@ void MacroAssembler::Movmskpd(Register dst, XMMRegister src) { } +void MacroAssembler::Sqrtsd(XMMRegister dst, XMMRegister src) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vsqrtsd(dst, dst, src); + } else { + sqrtsd(dst, src); + } +} + + +void MacroAssembler::Sqrtsd(XMMRegister dst, const Operand& src) { + if (CpuFeatures::IsSupported(AVX)) { + CpuFeatureScope scope(this, AVX); + vsqrtsd(dst, dst, src); + } else { + sqrtsd(dst, src); + } +} + + void MacroAssembler::Ucomiss(XMMRegister src1, XMMRegister src2) { if (CpuFeatures::IsSupported(AVX)) { CpuFeatureScope scope(this, AVX); diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index 08a183486c..9771ad79eb 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -921,6 +921,9 @@ class MacroAssembler: public Assembler { void Movapd(XMMRegister dst, XMMRegister src); void Movmskpd(Register dst, XMMRegister src); + void Sqrtsd(XMMRegister dst, XMMRegister src); + void Sqrtsd(XMMRegister dst, const Operand& src); + void Ucomiss(XMMRegister src1, XMMRegister src2); void Ucomiss(XMMRegister src1, const Operand& src2); void Ucomisd(XMMRegister src1, XMMRegister src2); diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc index c3ec40a146..f7249baf01 100644 --- a/test/cctest/test-assembler-x64.cc +++ b/test/cctest/test-assembler-x64.cc @@ -1469,6 +1469,21 @@ TEST(AssemblerX64AVX_sd) { __ cmpl(rdx, Immediate(0x0ff00ff0)); __ j(not_equal, &exit); + // Test vsqrtsd + __ movl(rax, Immediate(15)); + __ movq(rdx, V8_UINT64_C(0x4004000000000000)); // 2.5 + __ vmovq(xmm4, rdx); + __ vmulsd(xmm5, xmm4, xmm4); + __ vmovsd(Operand(rsp, 0), xmm5); + __ vsqrtsd(xmm6, xmm5, xmm5); + __ vmovq(rcx, xmm6); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ vsqrtsd(xmm7, xmm7, Operand(rsp, 0)); + __ vmovq(rcx, xmm7); + __ cmpq(rcx, rdx); + __ j(not_equal, &exit); + __ movl(rdx, Immediate(6)); __ vcvtlsi2sd(xmm6, xmm6, rdx); __ movl(Operand(rsp, 0), Immediate(5)); diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc index 77b9816b4c..467e16b9dc 100644 --- a/test/cctest/test-disasm-x64.cc +++ b/test/cctest/test-disasm-x64.cc @@ -540,6 +540,8 @@ TEST(DisasmX64) { __ vminsd(xmm9, xmm1, Operand(rbx, rcx, times_8, 10000)); __ vmaxsd(xmm8, xmm1, xmm2); __ vmaxsd(xmm9, xmm1, Operand(rbx, rcx, times_1, 10000)); + __ vsqrtsd(xmm8, xmm1, xmm2); + __ vsqrtsd(xmm9, xmm1, Operand(rbx, rcx, times_1, 10000)); __ vucomisd(xmm9, xmm1); __ vucomisd(xmm8, Operand(rbx, rdx, times_2, 10981));