| Index: runtime/vm/assembler_arm64_test.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_arm64_test.cc (revision 36687)
|
| +++ runtime/vm/assembler_arm64_test.cc (working copy)
|
| @@ -2602,6 +2602,575 @@
|
| }
|
|
|
|
|
| +ASSEMBLER_TEST_GENERATE(Vceqs, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, -42.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vdups(V2, V0, 0);
|
| + __ vinss(V3, 0, V0, 0);
|
| + __ vinss(V3, 1, V1, 0);
|
| + __ vinss(V3, 2, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vceqs(V4, V2, V3);
|
| +
|
| + __ vmovrs(R1, V4, 0);
|
| + __ vmovrs(R2, V4, 1);
|
| + __ vmovrs(R3, V4, 2);
|
| + __ vmovrs(R4, V4, 3);
|
| +
|
| + __ addw(R0, R1, Operand(R2));
|
| + __ addw(R0, R0, Operand(R3));
|
| + __ addw(R0, R0, Operand(R4));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vceqs, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(0xfffffffe, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vceqd, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, -42.0, kNoPP);
|
| +
|
| + __ vdupd(V2, V0, 0);
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vceqd(V4, V2, V3);
|
| +
|
| + __ vmovrd(R1, V4, 0);
|
| + __ vmovrd(R2, V4, 1);
|
| +
|
| + __ add(R0, R1, Operand(R2));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vceqd, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vcgts, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, -42.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vdups(V2, V0, 0);
|
| + __ vinss(V3, 0, V0, 0);
|
| + __ vinss(V3, 1, V1, 0);
|
| + __ vinss(V3, 2, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vcgts(V4, V2, V3);
|
| +
|
| + __ vmovrs(R1, V4, 0);
|
| + __ vmovrs(R2, V4, 1);
|
| + __ vmovrs(R3, V4, 2);
|
| + __ vmovrs(R4, V4, 3);
|
| +
|
| + __ addw(R0, R1, Operand(R2));
|
| + __ addw(R0, R0, Operand(R3));
|
| + __ addw(R0, R0, Operand(R4));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vcgts, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(0xfffffffe, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vcgtd, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, -42.0, kNoPP);
|
| +
|
| + __ vdupd(V2, V0, 0);
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vcgtd(V4, V2, V3);
|
| +
|
| + __ vmovrd(R1, V4, 0);
|
| + __ vmovrd(R2, V4, 1);
|
| +
|
| + __ add(R0, R1, Operand(R2));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vcgtd, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vcges, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, 43.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vdups(V2, V0, 0);
|
| + __ vinss(V3, 0, V0, 0);
|
| + __ vinss(V3, 1, V1, 0);
|
| + __ vinss(V3, 2, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vcges(V4, V2, V3);
|
| +
|
| + __ vmovrs(R1, V4, 0);
|
| + __ vmovrs(R2, V4, 1);
|
| + __ vmovrs(R3, V4, 2);
|
| + __ vmovrs(R4, V4, 3);
|
| +
|
| + __ addw(R0, R1, Operand(R2));
|
| + __ addw(R0, R0, Operand(R3));
|
| + __ addw(R0, R0, Operand(R4));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vcges, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(0xfffffffe, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vcged, assembler) {
|
| + __ LoadDImmediate(V0, 42.0, kNoPP);
|
| + __ LoadDImmediate(V1, 43.0, kNoPP);
|
| +
|
| + __ vdupd(V2, V0, 0);
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vcged(V4, V2, V3);
|
| +
|
| + __ vmovrd(R1, V4, 0);
|
| + __ vmovrd(R2, V4, 1);
|
| +
|
| + __ add(R0, R1, Operand(R2));
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vcged, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(-1, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vmaxs, assembler) {
|
| + __ LoadDImmediate(V0, 10.5, kNoPP);
|
| + __ LoadDImmediate(V1, 10.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vdups(V2, V0, 0);
|
| + __ vinss(V3, 0, V0, 0);
|
| + __ vinss(V3, 1, V1, 0);
|
| + __ vinss(V3, 2, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vmaxs(V4, V2, V3);
|
| +
|
| + __ vinss(V0, 0, V4, 0);
|
| + __ vinss(V1, 0, V4, 1);
|
| + __ vinss(V2, 0, V4, 2);
|
| + __ vinss(V3, 0, V4, 3);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ fcvtds(V1, V1);
|
| + __ fcvtds(V2, V2);
|
| + __ fcvtds(V3, V3);
|
| +
|
| + __ faddd(V0, V0, V1);
|
| + __ faddd(V0, V0, V2);
|
| + __ faddd(V0, V0, V3);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vmaxs, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vmaxd, assembler) {
|
| + __ LoadDImmediate(V0, 21.0, kNoPP);
|
| + __ LoadDImmediate(V1, 20.5, kNoPP);
|
| +
|
| + __ vdupd(V2, V0, 0);
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vmaxd(V4, V2, V3);
|
| +
|
| + __ vinsd(V0, 0, V4, 0);
|
| + __ vinsd(V1, 0, V4, 1);
|
| +
|
| + __ faddd(V0, V0, V1);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vmaxd, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vmins, assembler) {
|
| + __ LoadDImmediate(V0, 10.5, kNoPP);
|
| + __ LoadDImmediate(V1, 11.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vdups(V2, V0, 0);
|
| + __ vinss(V3, 0, V0, 0);
|
| + __ vinss(V3, 1, V1, 0);
|
| + __ vinss(V3, 2, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vmins(V4, V2, V3);
|
| +
|
| + __ vinss(V0, 0, V4, 0);
|
| + __ vinss(V1, 0, V4, 1);
|
| + __ vinss(V2, 0, V4, 2);
|
| + __ vinss(V3, 0, V4, 3);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ fcvtds(V1, V1);
|
| + __ fcvtds(V2, V2);
|
| + __ fcvtds(V3, V3);
|
| +
|
| + __ faddd(V0, V0, V1);
|
| + __ faddd(V0, V0, V2);
|
| + __ faddd(V0, V0, V3);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vmins, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vmind, assembler) {
|
| + __ LoadDImmediate(V0, 21.0, kNoPP);
|
| + __ LoadDImmediate(V1, 21.5, kNoPP);
|
| +
|
| + __ vdupd(V2, V0, 0);
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vmind(V4, V2, V3);
|
| +
|
| + __ vinsd(V0, 0, V4, 0);
|
| + __ vinsd(V1, 0, V4, 1);
|
| +
|
| + __ faddd(V0, V0, V1);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vmind, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vsqrts, assembler) {
|
| + __ LoadDImmediate(V0, 64.0, kNoPP);
|
| + __ LoadDImmediate(V1, 49.0, kNoPP);
|
| +
|
| + __ fcvtsd(V0, V0);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ veor(V3, V3, V3);
|
| + __ vinss(V3, 1, V0, 0);
|
| + __ vinss(V3, 3, V1, 0);
|
| +
|
| + __ vsqrts(V4, V3);
|
| +
|
| + __ vinss(V5, 0, V4, 1);
|
| + __ vinss(V6, 0, V4, 3);
|
| +
|
| + __ fcvtds(V5, V5);
|
| + __ fcvtds(V6, V6);
|
| +
|
| + __ faddd(V0, V5, V6);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vsqrts, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(15.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vsqrtd, assembler) {
|
| + __ LoadDImmediate(V0, 64.0, kNoPP);
|
| + __ LoadDImmediate(V1, 49.0, kNoPP);
|
| +
|
| + __ vinsd(V3, 0, V0, 0);
|
| + __ vinsd(V3, 1, V1, 0);
|
| +
|
| + __ vsqrtd(V4, V3);
|
| +
|
| + __ vinsd(V5, 0, V4, 0);
|
| + __ vinsd(V6, 0, V4, 1);
|
| +
|
| + __ faddd(V0, V5, V6);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vsqrtd, test) {
|
| + typedef int (*SimpleCode)();
|
| + EXPECT_EQ(15.0, EXECUTE_TEST_CODE_DOUBLE(SimpleCode, test->entry()));
|
| +}
|
| +
|
| +
|
| +// This is the same function as in the Simulator.
|
| +static float arm_recip_estimate(float a) {
|
| + // From the ARM Architecture Reference Manual A2-85.
|
| + if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0;
|
| + else if (a == 0.0) return INFINITY;
|
| + else if (isnan(a)) return a;
|
| +
|
| + uint32_t a_bits = bit_cast<uint32_t, float>(a);
|
| + // scaled = '0011 1111 1110' : a<22:0> : Zeros(29)
|
| + uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) |
|
| + ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29);
|
| + // result_exp = 253 - UInt(a<30:23>)
|
| + int32_t result_exp = 253 - ((a_bits >> 23) & 0xff);
|
| + ASSERT((result_exp >= 1) && (result_exp <= 252));
|
| +
|
| + double scaled_d = bit_cast<double, uint64_t>(scaled);
|
| + ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0));
|
| +
|
| + // a in units of 1/512 rounded down.
|
| + int32_t q = static_cast<int32_t>(scaled_d * 512.0);
|
| + // reciprocal r.
|
| + double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
|
| + // r in units of 1/256 rounded to nearest.
|
| + int32_t s = static_cast<int32_t>(256.0 * r + 0.5);
|
| + double estimate = static_cast<double>(s) / 256.0;
|
| + ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0)));
|
| +
|
| + // result = sign : result_exp<7:0> : estimate<51:29>
|
| + int32_t result_bits =
|
| + (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) |
|
| + ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
|
| + return bit_cast<float, int32_t>(result_bits);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vrecpes, assembler) {
|
| + __ LoadDImmediate(V1, 147.0, kNoPP);
|
| + __ fcvtsd(V1, V1);
|
| + __ vinss(V2, 0, V1, 0);
|
| + __ vinss(V2, 1, V1, 0);
|
| + __ vinss(V2, 2, V1, 0);
|
| + __ vinss(V2, 3, V1, 0);
|
| + __ vrecpes(V0, V2);
|
| + __ fcvtds(V0, V0);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vrecpes, test) {
|
| + EXPECT(test != NULL);
|
| + typedef double (*Vrecpes)();
|
| + float res = EXECUTE_TEST_CODE_DOUBLE(Vrecpes, test->entry());
|
| + EXPECT_FLOAT_EQ(arm_recip_estimate(147.0), res, 0.0001);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vrecpss, assembler) {
|
| + __ LoadDImmediate(V1, 5.0, kNoPP);
|
| + __ LoadDImmediate(V2, 10.0, kNoPP);
|
| +
|
| + __ fcvtsd(V1, V1);
|
| + __ fcvtsd(V2, V2);
|
| +
|
| + __ vrecpss(V0, V1, V2);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vrecpss, test) {
|
| + EXPECT(test != NULL);
|
| + typedef double (*Vrecpss)();
|
| + double res = EXECUTE_TEST_CODE_DOUBLE(Vrecpss, test->entry());
|
| + EXPECT_FLOAT_EQ(2.0 - 10.0 * 5.0, res, 0.0001);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(VRecps, assembler) {
|
| + __ LoadDImmediate(V0, 1.0 / 10.5, kNoPP);
|
| + __ fcvtsd(V0, V0);
|
| +
|
| + __ vdups(V1, V0, 0);
|
| +
|
| + __ VRecps(V2, V1);
|
| +
|
| + __ vinss(V0, 0, V2, 0);
|
| + __ vinss(V1, 0, V2, 1);
|
| + __ vinss(V2, 0, V2, 2);
|
| + __ vinss(V3, 0, V2, 3);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ fcvtds(V1, V1);
|
| + __ fcvtds(V2, V2);
|
| + __ fcvtds(V3, V3);
|
| +
|
| + __ faddd(V0, V0, V1);
|
| + __ faddd(V0, V0, V2);
|
| + __ faddd(V0, V0, V3);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(VRecps, test) {
|
| + typedef double (*VRecps)();
|
| + double res = EXECUTE_TEST_CODE_DOUBLE(VRecps, test->entry());
|
| + EXPECT_FLOAT_EQ(42.0, res, 0.0001);
|
| +}
|
| +
|
| +
|
| +static float arm_reciprocal_sqrt_estimate(float a) {
|
| + // From the ARM Architecture Reference Manual A2-87.
|
| + if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0;
|
| + else if (a == 0.0) return INFINITY;
|
| + else if (isnan(a)) return a;
|
| +
|
| + uint32_t a_bits = bit_cast<uint32_t, float>(a);
|
| + uint64_t scaled;
|
| + if (((a_bits >> 23) & 1) != 0) {
|
| + // scaled = '0 01111111101' : operand<22:0> : Zeros(29)
|
| + scaled = (static_cast<uint64_t>(0x3fd) << 52) |
|
| + ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29);
|
| + } else {
|
| + // scaled = '0 01111111110' : operand<22:0> : Zeros(29)
|
| + scaled = (static_cast<uint64_t>(0x3fe) << 52) |
|
| + ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29);
|
| + }
|
| + // result_exp = (380 - UInt(operand<30:23>) DIV 2;
|
| + int32_t result_exp = (380 - ((a_bits >> 23) & 0xff)) / 2;
|
| +
|
| + double scaled_d = bit_cast<double, uint64_t>(scaled);
|
| + ASSERT((scaled_d >= 0.25) && (scaled_d < 1.0));
|
| +
|
| + double r;
|
| + if (scaled_d < 0.5) {
|
| + // range 0.25 <= a < 0.5
|
| +
|
| + // a in units of 1/512 rounded down.
|
| + int32_t q0 = static_cast<int32_t>(scaled_d * 512.0);
|
| + // reciprocal root r.
|
| + r = 1.0 / sqrt((static_cast<double>(q0) + 0.5) / 512.0);
|
| + } else {
|
| + // range 0.5 <= a < 1.0
|
| +
|
| + // a in units of 1/256 rounded down.
|
| + int32_t q1 = static_cast<int32_t>(scaled_d * 256.0);
|
| + // reciprocal root r.
|
| + r = 1.0 / sqrt((static_cast<double>(q1) + 0.5) / 256.0);
|
| + }
|
| + // r in units of 1/256 rounded to nearest.
|
| + int32_t s = static_cast<int>(256.0 * r + 0.5);
|
| + double estimate = static_cast<double>(s) / 256.0;
|
| + ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0)));
|
| +
|
| + // result = 0 : result_exp<7:0> : estimate<51:29>
|
| + int32_t result_bits = ((result_exp & 0xff) << 23) |
|
| + ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
|
| + return bit_cast<float, int32_t>(result_bits);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vrsqrtes, assembler) {
|
| + __ LoadDImmediate(V1, 147.0, kNoPP);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ vrsqrtes(V0, V1);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vrsqrtes, test) {
|
| + EXPECT(test != NULL);
|
| + typedef double (*Vrsqrtes)();
|
| + double res = EXECUTE_TEST_CODE_DOUBLE(Vrsqrtes, test->entry());
|
| + EXPECT_FLOAT_EQ(arm_reciprocal_sqrt_estimate(147.0), res, 0.0001);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(Vrsqrtss, assembler) {
|
| + __ LoadDImmediate(V1, 5.0, kNoPP);
|
| + __ LoadDImmediate(V2, 10.0, kNoPP);
|
| +
|
| + __ fcvtsd(V1, V1);
|
| + __ fcvtsd(V2, V2);
|
| +
|
| + __ vrsqrtss(V0, V1, V2);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(Vrsqrtss, test) {
|
| + EXPECT(test != NULL);
|
| + typedef double (*Vrsqrtss)();
|
| + double res = EXECUTE_TEST_CODE_DOUBLE(Vrsqrtss, test->entry());
|
| + EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0)/2.0, res, 0.0001);
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) {
|
| + __ LoadDImmediate(V1, 147000.0, kNoPP);
|
| + __ fcvtsd(V1, V1);
|
| +
|
| + __ VRSqrts(V0, V1);
|
| +
|
| + __ fcvtds(V0, V0);
|
| + __ ret();
|
| +}
|
| +
|
| +
|
| +ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) {
|
| + EXPECT(test != NULL);
|
| + typedef double (*ReciprocalSqrt)();
|
| + double res = EXECUTE_TEST_CODE_DOUBLE(ReciprocalSqrt, test->entry());
|
| + EXPECT_FLOAT_EQ(1.0/sqrt(147000.0), res, 0.0001);
|
| +}
|
| +
|
| +
|
| // Called from assembler_test.cc.
|
| // LR: return address.
|
| // R0: context.
|
|
|