| Index: test/cctest/test-assembler-x64.cc
|
| diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc
|
| index 3d305b650e807280961b334b502042911aad103c..23d0be64ae74f3e519ea7e1149848dd6e4caf08e 100644
|
| --- a/test/cctest/test-assembler-x64.cc
|
| +++ b/test/cctest/test-assembler-x64.cc
|
| @@ -736,4 +736,454 @@ TEST(AssemblerX64SSE) {
|
| F6 f = FUNCTION_CAST<F6>(code->entry());
|
| CHECK_EQ(2, f(1.0, 2.0));
|
| }
|
| +
|
| +
|
| +typedef int (*F7)(double x, double y, double z);
|
| +TEST(AssemblerX64FMA_sd) {
|
| + CcTest::InitializeVM();
|
| + if (!CpuFeatures::IsSupported(FMA3)) return;
|
| +
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
|
| + HandleScope scope(isolate);
|
| + v8::internal::byte buffer[1024];
|
| + MacroAssembler assm(isolate, buffer, sizeof buffer);
|
| + {
|
| + CpuFeatureScope fscope(&assm, FMA3);
|
| + Label exit;
|
| + // argument in xmm0, xmm1 and xmm2
|
| + // xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ addsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + __ subq(rsp, Immediate(kDoubleSize)); // For memory operand
|
| + // vfmadd132sd
|
| + __ movl(rax, Immediate(1)); // Test number
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfmadd132sd(xmm8, xmm2, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfmadd213sd(xmm8, xmm0, xmm2);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfmadd231sd(xmm8, xmm0, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmadd132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfmadd132sd(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movsd(Operand(rsp, 0), xmm2);
|
| + __ vfmadd213sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfmadd231sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ subsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfmsub132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfmsub132sd(xmm8, xmm2, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfmsub213sd(xmm8, xmm0, xmm2);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfmsub231sd(xmm8, xmm0, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmsub132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfmsub132sd(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movsd(Operand(rsp, 0), xmm2);
|
| + __ vfmsub213sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfmsub231sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + // - xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ Move(xmm4, (uint64_t)1 << 63);
|
| + __ xorpd(xmm3, xmm4);
|
| + __ addsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfnmadd132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfnmadd132sd(xmm8, xmm2, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfnmadd213sd(xmm8, xmm0, xmm2);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfnmadd231sd(xmm8, xmm0, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmadd132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfnmadd132sd(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movsd(Operand(rsp, 0), xmm2);
|
| + __ vfnmadd213sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfnmadd231sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + // - xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ Move(xmm4, (uint64_t)1 << 63);
|
| + __ xorpd(xmm3, xmm4);
|
| + __ subsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfnmsub132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfnmsub132sd(xmm8, xmm2, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfnmsub213sd(xmm8, xmm0, xmm2);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfnmsub231sd(xmm8, xmm0, xmm1);
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmsub132sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfnmsub132sd(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub213sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movsd(Operand(rsp, 0), xmm2);
|
| + __ vfnmsub213sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231sd
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movsd(Operand(rsp, 0), xmm1);
|
| + __ vfnmsub231sd(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomisd(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + __ xorl(rax, rax);
|
| + __ bind(&exit);
|
| + __ addq(rsp, Immediate(kDoubleSize));
|
| + __ ret(0);
|
| + }
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef OBJECT_PRINT
|
| + OFStream os(stdout);
|
| + code->Print(os);
|
| +#endif
|
| +
|
| + F7 f = FUNCTION_CAST<F7>(code->entry());
|
| + CHECK_EQ(0, f(0.000092662107262076, -2.460774966188315, -1.0958787393627414));
|
| +}
|
| +
|
| +
|
| +typedef int (*F8)(float x, float y, float z);
|
| +TEST(AssemblerX64FMA_ss) {
|
| + CcTest::InitializeVM();
|
| + if (!CpuFeatures::IsSupported(FMA3)) return;
|
| +
|
| + Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
|
| + HandleScope scope(isolate);
|
| + v8::internal::byte buffer[1024];
|
| + MacroAssembler assm(isolate, buffer, sizeof buffer);
|
| + {
|
| + CpuFeatureScope fscope(&assm, FMA3);
|
| + Label exit;
|
| + // arguments in xmm0, xmm1 and xmm2
|
| + // xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ addss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + __ subq(rsp, Immediate(kDoubleSize)); // For memory operand
|
| + // vfmadd132ss
|
| + __ movl(rax, Immediate(1)); // Test number
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfmadd132ss(xmm8, xmm2, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfmadd213ss(xmm8, xmm0, xmm2);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfmadd231ss(xmm8, xmm0, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmadd132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfmadd132ss(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movss(Operand(rsp, 0), xmm2);
|
| + __ vfmadd213ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfmadd231ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ subss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfmsub132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfmsub132ss(xmm8, xmm2, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfmsub213ss(xmm8, xmm0, xmm2);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfmsub231ss(xmm8, xmm0, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmsub132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfmsub132ss(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movss(Operand(rsp, 0), xmm2);
|
| + __ vfmsub213ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfmsub231ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + // - xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ Move(xmm4, (uint32_t)1 << 31);
|
| + __ xorps(xmm3, xmm4);
|
| + __ addss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfnmadd132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfnmadd132ss(xmm8, xmm2, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfnmadd213ss(xmm8, xmm0, xmm2);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfnmadd231ss(xmm8, xmm0, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmadd132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfnmadd132ss(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movss(Operand(rsp, 0), xmm2);
|
| + __ vfnmadd213ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfnmadd231ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + // - xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ Move(xmm4, (uint32_t)1 << 31);
|
| + __ xorps(xmm3, xmm4);
|
| + __ subss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfnmsub132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ vfnmsub132ss(xmm8, xmm2, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ vfnmsub213ss(xmm8, xmm0, xmm2);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ vfnmsub231ss(xmm8, xmm0, xmm1);
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmsub132ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm0);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfnmsub132ss(xmm8, xmm2, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub213ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm1);
|
| + __ movss(Operand(rsp, 0), xmm2);
|
| + __ vfnmsub213ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231ss
|
| + __ incq(rax);
|
| + __ movaps(xmm8, xmm2);
|
| + __ movss(Operand(rsp, 0), xmm1);
|
| + __ vfnmsub231ss(xmm8, xmm0, Operand(rsp, 0));
|
| + __ ucomiss(xmm8, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + __ xorl(rax, rax);
|
| + __ bind(&exit);
|
| + __ addq(rsp, Immediate(kDoubleSize));
|
| + __ ret(0);
|
| + }
|
| +
|
| + CodeDesc desc;
|
| + assm.GetCode(&desc);
|
| + Handle<Code> code = isolate->factory()->NewCode(
|
| + desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
| +#ifdef OBJECT_PRINT
|
| + OFStream os(stdout);
|
| + code->Print(os);
|
| +#endif
|
| +
|
| + F8 f = FUNCTION_CAST<F8>(code->entry());
|
| + CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f));
|
| +}
|
| #undef __
|
|
|