| Index: test/cctest/test-assembler-ia32.cc
|
| diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc
|
| index d943297393b2b1be4d6ff4a1cb8898dc9712159b..f59c3c4aa1878e8cf6141fddc2169d7525ae2db8 100644
|
| --- a/test/cctest/test-assembler-ia32.cc
|
| +++ b/test/cctest/test-assembler-ia32.cc
|
| @@ -589,4 +589,458 @@ TEST(AssemblerIa32SSE) {
|
| }
|
|
|
|
|
| +typedef int (*F9)(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;
|
| + __ movsd(xmm0, Operand(esp, 1 * kPointerSize));
|
| + __ movsd(xmm1, Operand(esp, 3 * kPointerSize));
|
| + __ movsd(xmm2, Operand(esp, 5 * kPointerSize));
|
| + // argument in xmm0, xmm1 and xmm2
|
| + // xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ addsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + __ sub(esp, Immediate(kDoubleSize)); // For memory operand
|
| + // vfmadd132sd
|
| + __ mov(eax, Immediate(1)); // Test number
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfmadd132sd(xmm4, xmm2, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfmadd213sd(xmm4, xmm0, xmm2);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfmadd231sd(xmm4, xmm0, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmadd132sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfmadd132sd(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movsd(Operand(esp, 0), xmm2);
|
| + __ vfmadd213sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfmadd231sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulsd(xmm3, xmm1);
|
| + __ subsd(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfmsub132sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfmsub132sd(xmm4, xmm2, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfmsub213sd(xmm4, xmm0, xmm2);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfmsub231sd(xmm4, xmm0, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmsub132sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfmsub132sd(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movsd(Operand(esp, 0), xmm2);
|
| + __ vfmsub213sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfmsub231sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, 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
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfnmadd132sd(xmm4, xmm2, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfnmadd213sd(xmm4, xmm0, xmm2);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfnmadd231sd(xmm4, xmm0, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmadd132sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfnmadd132sd(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movsd(Operand(esp, 0), xmm2);
|
| + __ vfnmadd213sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfnmadd231sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, 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
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfnmsub132sd(xmm4, xmm2, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfnmsub213sd(xmm4, xmm0, xmm2);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfnmsub231sd(xmm4, xmm0, xmm1);
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmsub132sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfnmsub132sd(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub213sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movsd(Operand(esp, 0), xmm2);
|
| + __ vfnmsub213sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231sd
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movsd(Operand(esp, 0), xmm1);
|
| + __ vfnmsub231sd(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomisd(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + __ xor_(eax, eax);
|
| + __ bind(&exit);
|
| + __ add(esp, 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
|
| +
|
| + F9 f = FUNCTION_CAST<F9>(code->entry());
|
| + CHECK_EQ(0, f(0.000092662107262076, -2.460774966188315, -1.0958787393627414));
|
| +}
|
| +
|
| +
|
| +typedef int (*F10)(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;
|
| + __ movss(xmm0, Operand(esp, 1 * kPointerSize));
|
| + __ movss(xmm1, Operand(esp, 2 * kPointerSize));
|
| + __ movss(xmm2, Operand(esp, 3 * kPointerSize));
|
| + // arguments in xmm0, xmm1 and xmm2
|
| + // xmm0 * xmm1 + xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ addss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + __ sub(esp, Immediate(kDoubleSize)); // For memory operand
|
| + // vfmadd132ss
|
| + __ mov(eax, Immediate(1)); // Test number
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfmadd132ss(xmm4, xmm2, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfmadd213ss(xmm4, xmm0, xmm2);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfmadd231ss(xmm4, xmm0, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmadd132ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfmadd132ss(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movss(Operand(esp, 0), xmm2);
|
| + __ vfmadd213ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfmadd231ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // xmm0 * xmm1 - xmm2
|
| + __ movaps(xmm3, xmm0);
|
| + __ mulss(xmm3, xmm1);
|
| + __ subss(xmm3, xmm2); // Expected result in xmm3
|
| +
|
| + // vfmsub132ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfmsub132ss(xmm4, xmm2, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfmsub213ss(xmm4, xmm0, xmm2);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfmsub231ss(xmm4, xmm0, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfmsub132ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfmsub132ss(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movss(Operand(esp, 0), xmm2);
|
| + __ vfmsub213ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfmsub231ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, 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
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfnmadd132ss(xmm4, xmm2, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmadd213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfnmadd213ss(xmm4, xmm0, xmm2);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfnmadd231ss(xmm4, xmm0, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmadd132ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfnmadd132ss(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movss(Operand(esp, 0), xmm2);
|
| + __ vfnmadd213ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmadd231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfnmadd231ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, 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
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ vfnmsub132ss(xmm4, xmm2, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfmsub213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ vfnmsub213ss(xmm4, xmm0, xmm2);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ vfnmsub231ss(xmm4, xmm0, xmm1);
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| + // vfnmsub132ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm0);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfnmsub132ss(xmm4, xmm2, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub213ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm1);
|
| + __ movss(Operand(esp, 0), xmm2);
|
| + __ vfnmsub213ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| + // vfnmsub231ss
|
| + __ inc(eax);
|
| + __ movaps(xmm4, xmm2);
|
| + __ movss(Operand(esp, 0), xmm1);
|
| + __ vfnmsub231ss(xmm4, xmm0, Operand(esp, 0));
|
| + __ ucomiss(xmm4, xmm3);
|
| + __ j(not_equal, &exit);
|
| +
|
| +
|
| + __ xor_(eax, eax);
|
| + __ bind(&exit);
|
| + __ add(esp, 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
|
| +
|
| + F10 f = FUNCTION_CAST<F10>(code->entry());
|
| + CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f));
|
| +}
|
| #undef __
|
|
|