OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/os.h" | 10 #include "vm/os.h" |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), | 448 EXECUTE_TEST_CODE_INT32_D(DoubleToIntConversion, test->entry(), |
449 DBL_MAX)); | 449 DBL_MAX)); |
450 } else { | 450 } else { |
451 typedef int (*DoubleToIntConversion)() DART_UNUSED; | 451 typedef int (*DoubleToIntConversion)() DART_UNUSED; |
452 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleToIntConversion, test->entry())); | 452 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(DoubleToIntConversion, test->entry())); |
453 } | 453 } |
454 } | 454 } |
455 | 455 |
456 | 456 |
457 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { | 457 ASSEMBLER_TEST_GENERATE(FloatToDoubleConversion, assembler) { |
458 __ LoadSImmediate(S2, 12.8f); | 458 if (TargetCPUFeatures::vfp_supported()) { |
459 __ vcvtds(D0, S2); | 459 __ LoadSImmediate(S2, 12.8f); |
460 __ vcvtds(D0, S2); | |
461 } else { | |
462 __ LoadImmediate(R0, 0); | |
463 } | |
460 __ bx(LR); | 464 __ bx(LR); |
461 } | 465 } |
462 | 466 |
463 | 467 |
464 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { | 468 ASSEMBLER_TEST_RUN(FloatToDoubleConversion, test) { |
465 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; | 469 if (TargetCPUFeatures::vfp_supported()) { |
466 EXPECT(test != NULL); | 470 typedef double (*FloatToDoubleConversionCode)() DART_UNUSED; |
467 double res = EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, | 471 EXPECT(test != NULL); |
468 test->entry()); | 472 double res = EXECUTE_TEST_CODE_DOUBLE(FloatToDoubleConversionCode, |
469 EXPECT_FLOAT_EQ(12.8, res, 0.001); | 473 test->entry()); |
474 EXPECT_FLOAT_EQ(12.8, res, 0.001); | |
475 } else { | |
srdjan
2015/03/30 17:39:50
Maybe you just want to do nothing instead of runni
zra
2015/03/30 20:02:05
Changed here, and used the same pattern for all ne
| |
476 typedef int (*FloatToDoubleConversionCode)() DART_UNUSED; | |
477 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(FloatToDoubleConversionCode, | |
478 test->entry())); | |
479 } | |
470 } | 480 } |
471 | 481 |
472 | 482 |
473 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { | 483 ASSEMBLER_TEST_GENERATE(DoubleToFloatConversion, assembler) { |
474 if (TargetCPUFeatures::vfp_supported()) { | 484 if (TargetCPUFeatures::vfp_supported()) { |
475 __ LoadDImmediate(D1, 12.8, R0); | 485 __ LoadDImmediate(D1, 12.8, R0); |
476 __ vcvtsd(S0, D1); | 486 __ vcvtsd(S0, D1); |
477 } else { | 487 } else { |
478 __ LoadImmediate(R0, 0); | 488 __ LoadImmediate(R0, 0); |
479 } | 489 } |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
932 ASSEMBLER_TEST_RUN(Multiply64To64, test) { | 942 ASSEMBLER_TEST_RUN(Multiply64To64, test) { |
933 EXPECT(test != NULL); | 943 EXPECT(test != NULL); |
934 typedef int64_t (*Multiply64To64) | 944 typedef int64_t (*Multiply64To64) |
935 (int64_t operand0, int64_t operand1) DART_UNUSED; | 945 (int64_t operand0, int64_t operand1) DART_UNUSED; |
936 EXPECT_EQ(6, | 946 EXPECT_EQ(6, |
937 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); | 947 EXECUTE_TEST_CODE_INT64_LL(Multiply64To64, test->entry(), -3, -2)); |
938 } | 948 } |
939 | 949 |
940 | 950 |
941 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { | 951 ASSEMBLER_TEST_GENERATE(Multiply32To64, assembler) { |
942 #if defined(USING_SIMULATOR) | 952 __ smull(R0, R1, R0, R2); |
943 const ARMVersion version = TargetCPUFeatures::arm_version(); | |
944 HostCPUFeatures::set_arm_version(ARMv7); | |
945 #endif | |
946 if (TargetCPUFeatures::arm_version() == ARMv7) { | |
947 __ smull(R0, R1, R0, R2); | |
948 } else { | |
949 __ LoadImmediate(R0, 6); | |
950 __ LoadImmediate(R1, 0); | |
951 } | |
952 __ bx(LR); | 953 __ bx(LR); |
953 #if defined(USING_SIMULATOR) | |
954 HostCPUFeatures::set_arm_version(version); | |
955 #endif | |
956 } | 954 } |
957 | 955 |
958 | 956 |
959 ASSEMBLER_TEST_RUN(Multiply32To64, test) { | 957 ASSEMBLER_TEST_RUN(Multiply32To64, test) { |
960 EXPECT(test != NULL); | 958 EXPECT(test != NULL); |
961 typedef int64_t (*Multiply32To64) | 959 typedef int64_t (*Multiply32To64) |
962 (int64_t operand0, int64_t operand1) DART_UNUSED; | 960 (int64_t operand0, int64_t operand1) DART_UNUSED; |
963 EXPECT_EQ(6, | 961 EXPECT_EQ(6, |
964 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); | 962 EXECUTE_TEST_CODE_INT64_LL(Multiply32To64, test->entry(), -3, -2)); |
965 } | 963 } |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1267 | 1265 |
1268 ASSEMBLER_TEST_RUN(Ldrh1, test) { | 1266 ASSEMBLER_TEST_RUN(Ldrh1, test) { |
1269 EXPECT(test != NULL); | 1267 EXPECT(test != NULL); |
1270 typedef int (*Tst)() DART_UNUSED; | 1268 typedef int (*Tst)() DART_UNUSED; |
1271 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1269 EXPECT_EQ(0xff, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1272 } | 1270 } |
1273 | 1271 |
1274 | 1272 |
1275 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { | 1273 ASSEMBLER_TEST_GENERATE(Ldrd, assembler) { |
1276 __ mov(IP, Operand(SP)); | 1274 __ mov(IP, Operand(SP)); |
1277 __ strd(R2, Address(SP, (-kWordSize * 30), Address::PreIndex)); | 1275 __ sub(SP, SP, Operand(kWordSize*30)); |
1278 __ strd(R0, Address(IP, (-kWordSize * 28))); | 1276 __ strd(R2, SP, 0); |
1279 __ ldrd(R2, Address(IP, (-kWordSize * 28))); | 1277 __ strd(R0, IP, (-kWordSize*28)); |
1280 __ ldrd(R0, Address(SP, (kWordSize * 30), Address::PostIndex)); | 1278 __ ldrd(R2, IP, (-kWordSize*28)); |
1279 __ ldrd(R0, SP, 0); | |
1280 __ add(SP, SP, Operand(kWordSize*30)); | |
1281 __ sub(R0, R0, Operand(R2)); | 1281 __ sub(R0, R0, Operand(R2)); |
1282 __ add(R1, R1, Operand(R3)); | 1282 __ add(R1, R1, Operand(R3)); |
1283 __ bx(LR); | 1283 __ bx(LR); |
1284 } | 1284 } |
1285 | 1285 |
1286 | 1286 |
1287 ASSEMBLER_TEST_RUN(Ldrd, test) { | 1287 ASSEMBLER_TEST_RUN(Ldrd, test) { |
1288 EXPECT(test != NULL); | 1288 EXPECT(test != NULL); |
1289 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; | 1289 typedef int64_t (*Tst)(int64_t r0r1, int64_t r2r3) DART_UNUSED; |
1290 EXPECT_EQ(0x0000444400002222LL, EXECUTE_TEST_CODE_INT64_LL( | 1290 EXPECT_EQ(0x0000444400002222LL, EXECUTE_TEST_CODE_INT64_LL( |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1902 ASSEMBLER_TEST_GENERATE(IntDiv_supported, assembler) { | 1902 ASSEMBLER_TEST_GENERATE(IntDiv_supported, assembler) { |
1903 #if defined(USING_SIMULATOR) | 1903 #if defined(USING_SIMULATOR) |
1904 bool orig = TargetCPUFeatures::integer_division_supported(); | 1904 bool orig = TargetCPUFeatures::integer_division_supported(); |
1905 HostCPUFeatures::set_integer_division_supported(true); | 1905 HostCPUFeatures::set_integer_division_supported(true); |
1906 __ mov(R0, Operand(27)); | 1906 __ mov(R0, Operand(27)); |
1907 __ mov(R1, Operand(9)); | 1907 __ mov(R1, Operand(9)); |
1908 __ IntegerDivide(R0, R0, R1, D0, D1); | 1908 __ IntegerDivide(R0, R0, R1, D0, D1); |
1909 HostCPUFeatures::set_integer_division_supported(orig); | 1909 HostCPUFeatures::set_integer_division_supported(orig); |
1910 __ bx(LR); | 1910 __ bx(LR); |
1911 #else | 1911 #else |
1912 __ mov(R0, Operand(27)); | 1912 if (TargetCPUFeatures::can_divide()) { |
1913 __ mov(R1, Operand(9)); | 1913 __ mov(R0, Operand(27)); |
1914 __ IntegerDivide(R0, R0, R1, D0, D1); | 1914 __ mov(R1, Operand(9)); |
1915 __ IntegerDivide(R0, R0, R1, D0, D1); | |
1916 } else { | |
1917 __ LoadImmediate(R0, 3); | |
srdjan
2015/03/30 17:39:50
ditto
zra
2015/03/30 20:02:05
Done.
| |
1918 } | |
1915 __ bx(LR); | 1919 __ bx(LR); |
1916 #endif | 1920 #endif |
1917 } | 1921 } |
1918 | 1922 |
1919 | 1923 |
1920 ASSEMBLER_TEST_RUN(IntDiv_supported, test) { | 1924 ASSEMBLER_TEST_RUN(IntDiv_supported, test) { |
1921 EXPECT(test != NULL); | 1925 EXPECT(test != NULL); |
1922 typedef int (*Tst)() DART_UNUSED; | 1926 typedef int (*Tst)() DART_UNUSED; |
1923 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1927 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1924 } | 1928 } |
1925 | 1929 |
1926 | 1930 |
1927 ASSEMBLER_TEST_GENERATE(IntDiv_unsupported, assembler) { | 1931 ASSEMBLER_TEST_GENERATE(IntDiv_unsupported, assembler) { |
1928 #if defined(USING_SIMULATOR) | 1932 #if defined(USING_SIMULATOR) |
1929 bool orig = TargetCPUFeatures::integer_division_supported(); | 1933 bool orig = TargetCPUFeatures::integer_division_supported(); |
1930 HostCPUFeatures::set_integer_division_supported(false); | 1934 HostCPUFeatures::set_integer_division_supported(false); |
1931 __ mov(R0, Operand(27)); | 1935 __ mov(R0, Operand(27)); |
1932 __ mov(R1, Operand(9)); | 1936 __ mov(R1, Operand(9)); |
1933 __ IntegerDivide(R0, R0, R1, D0, D1); | 1937 __ IntegerDivide(R0, R0, R1, D0, D1); |
1934 HostCPUFeatures::set_integer_division_supported(orig); | 1938 HostCPUFeatures::set_integer_division_supported(orig); |
1935 __ bx(LR); | 1939 __ bx(LR); |
1936 #else | 1940 #else |
1937 __ mov(R0, Operand(27)); | 1941 if (TargetCPUFeatures::can_divide()) { |
1938 __ mov(R1, Operand(9)); | 1942 __ mov(R0, Operand(27)); |
1939 __ IntegerDivide(R0, R0, R1, D0, D1); | 1943 __ mov(R1, Operand(9)); |
1944 __ IntegerDivide(R0, R0, R1, D0, D1); | |
1945 } else { | |
1946 __ LoadImmediate(R0, 3); | |
srdjan
2015/03/30 17:39:50
ditto
zra
2015/03/30 20:02:05
Done.
| |
1947 } | |
1940 __ bx(LR); | 1948 __ bx(LR); |
1941 #endif | 1949 #endif |
1942 } | 1950 } |
1943 | 1951 |
1944 | 1952 |
1945 ASSEMBLER_TEST_RUN(IntDiv_unsupported, test) { | 1953 ASSEMBLER_TEST_RUN(IntDiv_unsupported, test) { |
1946 EXPECT(test != NULL); | 1954 EXPECT(test != NULL); |
1947 typedef int (*Tst)() DART_UNUSED; | 1955 typedef int (*Tst)() DART_UNUSED; |
1948 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 1956 EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
1949 } | 1957 } |
(...skipping 1263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3213 | 3221 |
3214 | 3222 |
3215 ASSEMBLER_TEST_RUN(Vdupw, test) { | 3223 ASSEMBLER_TEST_RUN(Vdupw, test) { |
3216 EXPECT(test != NULL); | 3224 EXPECT(test != NULL); |
3217 typedef int (*Tst)() DART_UNUSED; | 3225 typedef int (*Tst)() DART_UNUSED; |
3218 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | 3226 EXPECT_EQ(-4, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); |
3219 } | 3227 } |
3220 | 3228 |
3221 | 3229 |
3222 ASSEMBLER_TEST_GENERATE(Vzipqw, assembler) { | 3230 ASSEMBLER_TEST_GENERATE(Vzipqw, assembler) { |
3223 if (TargetCPUFeatures::neon_supported()) { | 3231 if (TargetCPUFeatures::vfp_supported() && |
3232 TargetCPUFeatures::neon_supported()) { | |
3224 __ LoadSImmediate(S0, 0.0); | 3233 __ LoadSImmediate(S0, 0.0); |
3225 __ LoadSImmediate(S1, 1.0); | 3234 __ LoadSImmediate(S1, 1.0); |
3226 __ LoadSImmediate(S2, 2.0); | 3235 __ LoadSImmediate(S2, 2.0); |
3227 __ LoadSImmediate(S3, 3.0); | 3236 __ LoadSImmediate(S3, 3.0); |
3228 __ LoadSImmediate(S4, 4.0); | 3237 __ LoadSImmediate(S4, 4.0); |
3229 __ LoadSImmediate(S5, 5.0); | 3238 __ LoadSImmediate(S5, 5.0); |
3230 __ LoadSImmediate(S6, 6.0); | 3239 __ LoadSImmediate(S6, 6.0); |
3231 __ LoadSImmediate(S7, 7.0); | 3240 __ LoadSImmediate(S7, 7.0); |
3232 | 3241 |
3233 __ vzipqw(Q0, Q1); | 3242 __ vzipqw(Q0, Q1); |
3234 | 3243 |
3235 __ vsubqs(Q0, Q1, Q0); | 3244 __ vsubqs(Q0, Q1, Q0); |
3236 | 3245 |
3237 __ vadds(S0, S0, S1); | 3246 __ vadds(S0, S0, S1); |
3238 __ vadds(S0, S0, S2); | 3247 __ vadds(S0, S0, S2); |
3239 __ vadds(S0, S0, S3); | 3248 __ vadds(S0, S0, S3); |
3240 __ bx(LR); | 3249 } else if (TargetCPUFeatures::vfp_supported()) { |
3250 __ LoadSImmediate(S0, 8.0); | |
3241 } else { | 3251 } else { |
3242 __ LoadSImmediate(S0, 8.0); | 3252 __ LoadImmediate(R0, 0); |
3243 __ bx(LR); | |
3244 } | 3253 } |
3254 __ bx(LR); | |
3245 } | 3255 } |
3246 | 3256 |
3247 | 3257 |
3248 ASSEMBLER_TEST_RUN(Vzipqw, test) { | 3258 ASSEMBLER_TEST_RUN(Vzipqw, test) { |
3249 EXPECT(test != NULL); | 3259 EXPECT(test != NULL); |
3250 typedef float (*Vzipqw)() DART_UNUSED; | 3260 if (TargetCPUFeatures::vfp_supported()) { |
3251 float res = EXECUTE_TEST_CODE_FLOAT(Vzipqw, test->entry()); | 3261 typedef float (*Vzipqw)() DART_UNUSED; |
3252 EXPECT_FLOAT_EQ(8.0, res, 0.0001f); | 3262 float res = EXECUTE_TEST_CODE_FLOAT(Vzipqw, test->entry()); |
3263 EXPECT_FLOAT_EQ(8.0, res, 0.0001f); | |
srdjan
2015/03/30 17:39:50
ditto
zra
2015/03/30 20:02:05
Done.
| |
3264 } else { | |
3265 typedef int (*Vzipqw)() DART_UNUSED; | |
3266 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vzipqw, test->entry())); | |
3267 } | |
3253 } | 3268 } |
3254 | 3269 |
3255 | 3270 |
3256 ASSEMBLER_TEST_GENERATE(Vceqqi32, assembler) { | 3271 ASSEMBLER_TEST_GENERATE(Vceqqi32, assembler) { |
3257 if (TargetCPUFeatures::neon_supported()) { | 3272 if (TargetCPUFeatures::neon_supported()) { |
3258 __ mov(R0, Operand(1)); | 3273 __ mov(R0, Operand(1)); |
3259 __ vmovsr(S0, R0); | 3274 __ vmovsr(S0, R0); |
3260 __ mov(R0, Operand(2)); | 3275 __ mov(R0, Operand(2)); |
3261 __ vmovsr(S1, R0); | 3276 __ vmovsr(S1, R0); |
3262 __ mov(R0, Operand(3)); | 3277 __ mov(R0, Operand(3)); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3680 | 3695 |
3681 // result = sign : result_exp<7:0> : estimate<51:29> | 3696 // result = sign : result_exp<7:0> : estimate<51:29> |
3682 int32_t result_bits = | 3697 int32_t result_bits = |
3683 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | | 3698 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | |
3684 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3699 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3685 return bit_cast<float, int32_t>(result_bits); | 3700 return bit_cast<float, int32_t>(result_bits); |
3686 } | 3701 } |
3687 | 3702 |
3688 | 3703 |
3689 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { | 3704 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) { |
3690 if (TargetCPUFeatures::neon_supported()) { | 3705 if (TargetCPUFeatures::vfp_supported() && |
3706 TargetCPUFeatures::neon_supported()) { | |
3691 __ LoadSImmediate(S4, 147.0); | 3707 __ LoadSImmediate(S4, 147.0); |
3692 __ vmovs(S5, S4); | 3708 __ vmovs(S5, S4); |
3693 __ vmovs(S6, S4); | 3709 __ vmovs(S6, S4); |
3694 __ vmovs(S7, S4); | 3710 __ vmovs(S7, S4); |
3695 | |
3696 __ vrecpeqs(Q0, Q1); | 3711 __ vrecpeqs(Q0, Q1); |
3697 | 3712 } else if (TargetCPUFeatures::vfp_supported()) { |
3698 __ bx(LR); | 3713 __ LoadSImmediate(S0, arm_recip_estimate(147.0)); |
3699 } else { | 3714 } else { |
3700 __ LoadSImmediate(S0, arm_recip_estimate(147.0)); | 3715 __ LoadImmediate(R0, 0); |
3701 __ bx(LR); | |
3702 } | 3716 } |
3717 __ bx(LR); | |
3703 } | 3718 } |
3704 | 3719 |
3705 | 3720 |
3706 ASSEMBLER_TEST_RUN(Vrecpeqs, test) { | 3721 ASSEMBLER_TEST_RUN(Vrecpeqs, test) { |
3707 EXPECT(test != NULL); | 3722 EXPECT(test != NULL); |
3708 typedef float (*Vrecpeqs)() DART_UNUSED; | 3723 if (TargetCPUFeatures::vfp_supported()) { |
3709 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpeqs, test->entry()); | 3724 typedef float (*Vrecpeqs)() DART_UNUSED; |
3710 EXPECT_FLOAT_EQ(arm_recip_estimate(147.0), res, 0.0001f); | 3725 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpeqs, test->entry()); |
3726 EXPECT_FLOAT_EQ(arm_recip_estimate(147.0), res, 0.0001f); | |
3727 } else { | |
3728 typedef int (*Vrecpeqs)() DART_UNUSED; | |
3729 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vrecpeqs, test->entry())); | |
3730 } | |
3711 } | 3731 } |
3712 | 3732 |
3713 | 3733 |
3714 ASSEMBLER_TEST_GENERATE(Vrecpsqs, assembler) { | 3734 ASSEMBLER_TEST_GENERATE(Vrecpsqs, assembler) { |
3715 if (TargetCPUFeatures::neon_supported()) { | 3735 if (TargetCPUFeatures::vfp_supported() && |
3736 TargetCPUFeatures::neon_supported()) { | |
3716 __ LoadSImmediate(S4, 5.0); | 3737 __ LoadSImmediate(S4, 5.0); |
3717 __ LoadSImmediate(S5, 2.0); | 3738 __ LoadSImmediate(S5, 2.0); |
3718 __ LoadSImmediate(S6, 3.0); | 3739 __ LoadSImmediate(S6, 3.0); |
3719 __ LoadSImmediate(S7, 4.0); | 3740 __ LoadSImmediate(S7, 4.0); |
3720 | 3741 |
3721 __ LoadSImmediate(S8, 10.0); | 3742 __ LoadSImmediate(S8, 10.0); |
3722 __ LoadSImmediate(S9, 1.0); | 3743 __ LoadSImmediate(S9, 1.0); |
3723 __ LoadSImmediate(S10, 6.0); | 3744 __ LoadSImmediate(S10, 6.0); |
3724 __ LoadSImmediate(S11, 3.0); | 3745 __ LoadSImmediate(S11, 3.0); |
3725 | 3746 |
3726 __ vrecpsqs(Q0, Q1, Q2); | 3747 __ vrecpsqs(Q0, Q1, Q2); |
3727 | 3748 } else if (TargetCPUFeatures::vfp_supported()) { |
3728 __ bx(LR); | 3749 __ LoadSImmediate(S0, 2.0 - 10.0 * 5.0); |
3729 } else { | 3750 } else { |
3730 __ LoadSImmediate(S0, 2.0 - 10.0 * 5.0); | 3751 __ LoadImmediate(R0, 0); |
3731 __ bx(LR); | |
3732 } | 3752 } |
3753 __ bx(LR); | |
3733 } | 3754 } |
3734 | 3755 |
3735 | 3756 |
3736 ASSEMBLER_TEST_RUN(Vrecpsqs, test) { | 3757 ASSEMBLER_TEST_RUN(Vrecpsqs, test) { |
3737 EXPECT(test != NULL); | 3758 EXPECT(test != NULL); |
3738 typedef float (*Vrecpsqs)() DART_UNUSED; | 3759 if (TargetCPUFeatures::vfp_supported()) { |
3739 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpsqs, test->entry()); | 3760 typedef float (*Vrecpsqs)() DART_UNUSED; |
3740 EXPECT_FLOAT_EQ(2.0 - 10.0 * 5.0, res, 0.0001f); | 3761 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpsqs, test->entry()); |
3762 EXPECT_FLOAT_EQ(2.0 - 10.0 * 5.0, res, 0.0001f); | |
3763 } else { | |
3764 typedef int (*Vrecpsqs)() DART_UNUSED; | |
3765 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vrecpsqs, test->entry())); | |
3766 } | |
3741 } | 3767 } |
3742 | 3768 |
3743 | 3769 |
3744 ASSEMBLER_TEST_GENERATE(Reciprocal, assembler) { | 3770 ASSEMBLER_TEST_GENERATE(Reciprocal, assembler) { |
3745 if (TargetCPUFeatures::neon_supported()) { | 3771 if (TargetCPUFeatures::vfp_supported() && |
3772 TargetCPUFeatures::neon_supported()) { | |
3746 __ LoadSImmediate(S4, 147000.0); | 3773 __ LoadSImmediate(S4, 147000.0); |
3747 __ vmovs(S5, S4); | 3774 __ vmovs(S5, S4); |
3748 __ vmovs(S6, S4); | 3775 __ vmovs(S6, S4); |
3749 __ vmovs(S7, S4); | 3776 __ vmovs(S7, S4); |
3750 | 3777 |
3751 // Reciprocal estimate. | 3778 // Reciprocal estimate. |
3752 __ vrecpeqs(Q0, Q1); | 3779 __ vrecpeqs(Q0, Q1); |
3753 // 2 Newton-Raphson steps. | 3780 // 2 Newton-Raphson steps. |
3754 __ vrecpsqs(Q2, Q1, Q0); | 3781 __ vrecpsqs(Q2, Q1, Q0); |
3755 __ vmulqs(Q0, Q0, Q2); | 3782 __ vmulqs(Q0, Q0, Q2); |
3756 __ vrecpsqs(Q2, Q1, Q0); | 3783 __ vrecpsqs(Q2, Q1, Q0); |
3757 __ vmulqs(Q0, Q0, Q2); | 3784 __ vmulqs(Q0, Q0, Q2); |
3758 | 3785 } else if (TargetCPUFeatures::vfp_supported()) { |
3759 __ bx(LR); | 3786 __ LoadSImmediate(S0, 1.0/147000.0); |
3760 } else { | 3787 } else { |
3761 __ LoadSImmediate(S0, 1.0/147000.0); | 3788 __ LoadImmediate(R0, 0); |
3762 __ bx(LR); | |
3763 } | 3789 } |
3790 __ bx(LR); | |
3764 } | 3791 } |
3765 | 3792 |
3766 | 3793 |
3767 ASSEMBLER_TEST_RUN(Reciprocal, test) { | 3794 ASSEMBLER_TEST_RUN(Reciprocal, test) { |
3768 EXPECT(test != NULL); | 3795 EXPECT(test != NULL); |
3769 typedef float (*Reciprocal)() DART_UNUSED; | 3796 if (TargetCPUFeatures::vfp_supported()) { |
3770 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); | 3797 typedef float (*Reciprocal)() DART_UNUSED; |
3771 EXPECT_FLOAT_EQ(1.0/147000.0, res, 0.0001f); | 3798 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry()); |
3799 EXPECT_FLOAT_EQ(1.0/147000.0, res, 0.0001f); | |
3800 } else { | |
3801 typedef int (*Reciprocal)() DART_UNUSED; | |
3802 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Reciprocal, test->entry())); | |
3803 } | |
3772 } | 3804 } |
3773 | 3805 |
3774 | 3806 |
3775 static float arm_reciprocal_sqrt_estimate(float a) { | 3807 static float arm_reciprocal_sqrt_estimate(float a) { |
3776 // From the ARM Architecture Reference Manual A2-87. | 3808 // From the ARM Architecture Reference Manual A2-87. |
3777 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; | 3809 if (isinf(a) || (fabs(a) >= exp2f(126))) return 0.0; |
3778 else if (a == 0.0) return kPosInfinity; | 3810 else if (a == 0.0) return kPosInfinity; |
3779 else if (isnan(a)) return a; | 3811 else if (isnan(a)) return a; |
3780 | 3812 |
3781 uint32_t a_bits = bit_cast<uint32_t, float>(a); | 3813 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3817 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); | 3849 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); |
3818 | 3850 |
3819 // result = 0 : result_exp<7:0> : estimate<51:29> | 3851 // result = 0 : result_exp<7:0> : estimate<51:29> |
3820 int32_t result_bits = ((result_exp & 0xff) << 23) | | 3852 int32_t result_bits = ((result_exp & 0xff) << 23) | |
3821 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); | 3853 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
3822 return bit_cast<float, int32_t>(result_bits); | 3854 return bit_cast<float, int32_t>(result_bits); |
3823 } | 3855 } |
3824 | 3856 |
3825 | 3857 |
3826 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { | 3858 ASSEMBLER_TEST_GENERATE(Vrsqrteqs, assembler) { |
3827 if (TargetCPUFeatures::neon_supported()) { | 3859 if (TargetCPUFeatures::vfp_supported() && |
3860 TargetCPUFeatures::neon_supported()) { | |
3828 __ LoadSImmediate(S4, 147.0); | 3861 __ LoadSImmediate(S4, 147.0); |
3829 __ vmovs(S5, S4); | 3862 __ vmovs(S5, S4); |
3830 __ vmovs(S6, S4); | 3863 __ vmovs(S6, S4); |
3831 __ vmovs(S7, S4); | 3864 __ vmovs(S7, S4); |
3832 | 3865 |
3833 __ vrsqrteqs(Q0, Q1); | 3866 __ vrsqrteqs(Q0, Q1); |
3834 | 3867 } else if (TargetCPUFeatures::vfp_supported()) { |
3835 __ bx(LR); | 3868 __ LoadSImmediate(S0, arm_reciprocal_sqrt_estimate(147.0)); |
3836 } else { | 3869 } else { |
3837 __ LoadSImmediate(S0, arm_reciprocal_sqrt_estimate(147.0)); | 3870 __ LoadImmediate(R0, 0); |
3838 __ bx(LR); | |
3839 } | 3871 } |
3872 __ bx(LR); | |
3840 } | 3873 } |
3841 | 3874 |
3842 | 3875 |
3843 ASSEMBLER_TEST_RUN(Vrsqrteqs, test) { | 3876 ASSEMBLER_TEST_RUN(Vrsqrteqs, test) { |
3844 EXPECT(test != NULL); | 3877 EXPECT(test != NULL); |
3845 typedef float (*Vrsqrteqs)() DART_UNUSED; | 3878 if (TargetCPUFeatures::vfp_supported()) { |
3846 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrteqs, test->entry()); | 3879 typedef float (*Vrsqrteqs)() DART_UNUSED; |
3847 EXPECT_FLOAT_EQ(arm_reciprocal_sqrt_estimate(147.0), res, 0.0001f); | 3880 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrteqs, test->entry()); |
3881 EXPECT_FLOAT_EQ(arm_reciprocal_sqrt_estimate(147.0), res, 0.0001f); | |
3882 } else { | |
3883 typedef int (*Vrsqrteqs)() DART_UNUSED; | |
3884 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vrsqrteqs, test->entry())); | |
3885 } | |
3848 } | 3886 } |
3849 | 3887 |
3850 | 3888 |
3851 ASSEMBLER_TEST_GENERATE(Vrsqrtsqs, assembler) { | 3889 ASSEMBLER_TEST_GENERATE(Vrsqrtsqs, assembler) { |
3852 if (TargetCPUFeatures::neon_supported()) { | 3890 if (TargetCPUFeatures::vfp_supported() && |
3891 TargetCPUFeatures::neon_supported()) { | |
3853 __ LoadSImmediate(S4, 5.0); | 3892 __ LoadSImmediate(S4, 5.0); |
3854 __ LoadSImmediate(S5, 2.0); | 3893 __ LoadSImmediate(S5, 2.0); |
3855 __ LoadSImmediate(S6, 3.0); | 3894 __ LoadSImmediate(S6, 3.0); |
3856 __ LoadSImmediate(S7, 4.0); | 3895 __ LoadSImmediate(S7, 4.0); |
3857 | 3896 |
3858 __ LoadSImmediate(S8, 10.0); | 3897 __ LoadSImmediate(S8, 10.0); |
3859 __ LoadSImmediate(S9, 1.0); | 3898 __ LoadSImmediate(S9, 1.0); |
3860 __ LoadSImmediate(S10, 6.0); | 3899 __ LoadSImmediate(S10, 6.0); |
3861 __ LoadSImmediate(S11, 3.0); | 3900 __ LoadSImmediate(S11, 3.0); |
3862 | 3901 |
3863 __ vrsqrtsqs(Q0, Q1, Q2); | 3902 __ vrsqrtsqs(Q0, Q1, Q2); |
3864 | 3903 } else if (TargetCPUFeatures::vfp_supported()) { |
3865 __ bx(LR); | 3904 __ LoadSImmediate(S0, (3.0 - 10.0 * 5.0) / 2.0); |
3866 } else { | 3905 } else { |
3867 __ LoadSImmediate(S0, (3.0 - 10.0 * 5.0) / 2.0); | 3906 __ LoadImmediate(R0, 0); |
3868 __ bx(LR); | |
3869 } | 3907 } |
3908 __ bx(LR); | |
3870 } | 3909 } |
3871 | 3910 |
3872 | 3911 |
3873 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { | 3912 ASSEMBLER_TEST_RUN(Vrsqrtsqs, test) { |
3874 EXPECT(test != NULL); | 3913 EXPECT(test != NULL); |
3875 typedef float (*Vrsqrtsqs)() DART_UNUSED; | 3914 if (TargetCPUFeatures::vfp_supported()) { |
3876 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); | 3915 typedef float (*Vrsqrtsqs)() DART_UNUSED; |
3877 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0)/2.0, res, 0.0001f); | 3916 float res = EXECUTE_TEST_CODE_FLOAT(Vrsqrtsqs, test->entry()); |
3917 EXPECT_FLOAT_EQ((3.0 - 10.0 * 5.0)/2.0, res, 0.0001f); | |
3918 } else { | |
3919 typedef int (*Vrsqrtsqs)() DART_UNUSED; | |
3920 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vrsqrtsqs, test->entry())); | |
3921 } | |
3878 } | 3922 } |
3879 | 3923 |
3880 | 3924 |
3881 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { | 3925 ASSEMBLER_TEST_GENERATE(ReciprocalSqrt, assembler) { |
3882 if (TargetCPUFeatures::neon_supported()) { | 3926 if (TargetCPUFeatures::vfp_supported() && |
3927 TargetCPUFeatures::neon_supported()) { | |
3883 __ LoadSImmediate(S4, 147000.0); | 3928 __ LoadSImmediate(S4, 147000.0); |
3884 __ vmovs(S5, S4); | 3929 __ vmovs(S5, S4); |
3885 __ vmovs(S6, S4); | 3930 __ vmovs(S6, S4); |
3886 __ vmovs(S7, S4); | 3931 __ vmovs(S7, S4); |
3887 | 3932 |
3888 // Reciprocal square root estimate. | 3933 // Reciprocal square root estimate. |
3889 __ vrsqrteqs(Q0, Q1); | 3934 __ vrsqrteqs(Q0, Q1); |
3890 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3935 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
3891 // First step. | 3936 // First step. |
3892 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3937 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
3893 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3938 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
3894 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3939 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
3895 // Second step. | 3940 // Second step. |
3896 __ vmulqs(Q2, Q0, Q0); | 3941 __ vmulqs(Q2, Q0, Q0); |
3897 __ vrsqrtsqs(Q2, Q1, Q2); | 3942 __ vrsqrtsqs(Q2, Q1, Q2); |
3898 __ vmulqs(Q0, Q0, Q2); | 3943 __ vmulqs(Q0, Q0, Q2); |
3899 | 3944 } else if (TargetCPUFeatures::vfp_supported()) { |
3900 __ bx(LR); | 3945 __ LoadSImmediate(S0, 1.0/sqrt(147000.0)); |
3901 } else { | 3946 } else { |
3902 __ LoadSImmediate(S0, 1.0/sqrt(147000.0)); | 3947 __ LoadImmediate(R0, 0); |
3903 __ bx(LR); | |
3904 } | 3948 } |
3949 __ bx(LR); | |
3905 } | 3950 } |
3906 | 3951 |
3907 | 3952 |
3908 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { | 3953 ASSEMBLER_TEST_RUN(ReciprocalSqrt, test) { |
3909 EXPECT(test != NULL); | 3954 EXPECT(test != NULL); |
3910 typedef float (*ReciprocalSqrt)() DART_UNUSED; | 3955 if (TargetCPUFeatures::vfp_supported()) { |
3911 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); | 3956 typedef float (*ReciprocalSqrt)() DART_UNUSED; |
3912 EXPECT_FLOAT_EQ(1.0/sqrt(147000.0), res, 0.0001f); | 3957 float res = EXECUTE_TEST_CODE_FLOAT(ReciprocalSqrt, test->entry()); |
3958 EXPECT_FLOAT_EQ(1.0/sqrt(147000.0), res, 0.0001f); | |
3959 } else { | |
3960 typedef int (*ReciprocalSqrt)() DART_UNUSED; | |
3961 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(ReciprocalSqrt, test->entry())); | |
3962 } | |
3913 } | 3963 } |
3914 | 3964 |
3915 | 3965 |
3916 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { | 3966 ASSEMBLER_TEST_GENERATE(SIMDSqrt, assembler) { |
3917 if (TargetCPUFeatures::neon_supported()) { | 3967 if (TargetCPUFeatures::vfp_supported() && |
3968 TargetCPUFeatures::neon_supported()) { | |
3918 __ LoadSImmediate(S4, 147000.0); | 3969 __ LoadSImmediate(S4, 147000.0); |
3919 __ vmovs(S5, S4); | 3970 __ vmovs(S5, S4); |
3920 __ vmovs(S6, S4); | 3971 __ vmovs(S6, S4); |
3921 __ vmovs(S7, S4); | 3972 __ vmovs(S7, S4); |
3922 | 3973 |
3923 // Reciprocal square root estimate. | 3974 // Reciprocal square root estimate. |
3924 __ vrsqrteqs(Q0, Q1); | 3975 __ vrsqrteqs(Q0, Q1); |
3925 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 3976 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
3926 // First step. | 3977 // First step. |
3927 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 3978 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
3928 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. | 3979 __ vrsqrtsqs(Q2, Q1, Q2); // Q2 <- (3 - Q1*Q2) / 2. |
3929 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 | 3980 __ vmulqs(Q0, Q0, Q2); // xn+1 <- xn * Q2 |
3930 // Second step. | 3981 // Second step. |
3931 __ vmulqs(Q2, Q0, Q0); | 3982 __ vmulqs(Q2, Q0, Q0); |
3932 __ vrsqrtsqs(Q2, Q1, Q2); | 3983 __ vrsqrtsqs(Q2, Q1, Q2); |
3933 __ vmulqs(Q0, Q0, Q2); | 3984 __ vmulqs(Q0, Q0, Q2); |
3934 | 3985 |
3935 // Reciprocal. | 3986 // Reciprocal. |
3936 __ vmovq(Q1, Q0); | 3987 __ vmovq(Q1, Q0); |
3937 // Reciprocal estimate. | 3988 // Reciprocal estimate. |
3938 __ vrecpeqs(Q0, Q1); | 3989 __ vrecpeqs(Q0, Q1); |
3939 // 2 Newton-Raphson steps. | 3990 // 2 Newton-Raphson steps. |
3940 __ vrecpsqs(Q2, Q1, Q0); | 3991 __ vrecpsqs(Q2, Q1, Q0); |
3941 __ vmulqs(Q0, Q0, Q2); | 3992 __ vmulqs(Q0, Q0, Q2); |
3942 __ vrecpsqs(Q2, Q1, Q0); | 3993 __ vrecpsqs(Q2, Q1, Q0); |
3943 __ vmulqs(Q0, Q0, Q2); | 3994 __ vmulqs(Q0, Q0, Q2); |
3944 | 3995 } else if (TargetCPUFeatures::vfp_supported()) { |
3945 __ bx(LR); | 3996 __ LoadSImmediate(S0, sqrt(147000.0)); |
3946 } else { | 3997 } else { |
3947 __ LoadSImmediate(S0, sqrt(147000.0)); | 3998 __ LoadImmediate(R0, 0); |
3948 __ bx(LR); | |
3949 } | 3999 } |
4000 __ bx(LR); | |
3950 } | 4001 } |
3951 | 4002 |
3952 | 4003 |
3953 ASSEMBLER_TEST_RUN(SIMDSqrt, test) { | 4004 ASSEMBLER_TEST_RUN(SIMDSqrt, test) { |
3954 EXPECT(test != NULL); | 4005 EXPECT(test != NULL); |
3955 typedef float (*SIMDSqrt)() DART_UNUSED; | 4006 if (TargetCPUFeatures::vfp_supported()) { |
3956 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt, test->entry()); | 4007 typedef float (*SIMDSqrt)() DART_UNUSED; |
3957 EXPECT_FLOAT_EQ(sqrt(147000.0), res, 0.0001f); | 4008 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt, test->entry()); |
4009 EXPECT_FLOAT_EQ(sqrt(147000.0), res, 0.0001f); | |
4010 } else { | |
4011 typedef int (*SIMDSqrt)() DART_UNUSED; | |
4012 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SIMDSqrt, test->entry())); | |
4013 } | |
3958 } | 4014 } |
3959 | 4015 |
3960 | 4016 |
3961 ASSEMBLER_TEST_GENERATE(SIMDSqrt2, assembler) { | 4017 ASSEMBLER_TEST_GENERATE(SIMDSqrt2, assembler) { |
3962 if (TargetCPUFeatures::neon_supported()) { | 4018 if (TargetCPUFeatures::vfp_supported() && |
4019 TargetCPUFeatures::neon_supported()) { | |
3963 __ LoadSImmediate(S4, 1.0); | 4020 __ LoadSImmediate(S4, 1.0); |
3964 __ LoadSImmediate(S5, 4.0); | 4021 __ LoadSImmediate(S5, 4.0); |
3965 __ LoadSImmediate(S6, 9.0); | 4022 __ LoadSImmediate(S6, 9.0); |
3966 __ LoadSImmediate(S7, 16.0); | 4023 __ LoadSImmediate(S7, 16.0); |
3967 | 4024 |
3968 // Reciprocal square root estimate. | 4025 // Reciprocal square root estimate. |
3969 __ vrsqrteqs(Q0, Q1); | 4026 __ vrsqrteqs(Q0, Q1); |
3970 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. | 4027 // 2 Newton-Raphson steps. xn+1 = xn * (3 - Q1*xn^2) / 2. |
3971 // First step. | 4028 // First step. |
3972 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 | 4029 __ vmulqs(Q2, Q0, Q0); // Q2 <- xn^2 |
(...skipping 10 matching lines...) Expand all Loading... | |
3983 __ vrecpeqs(Q0, Q1); | 4040 __ vrecpeqs(Q0, Q1); |
3984 // 2 Newton-Raphson steps. | 4041 // 2 Newton-Raphson steps. |
3985 __ vrecpsqs(Q2, Q1, Q0); | 4042 __ vrecpsqs(Q2, Q1, Q0); |
3986 __ vmulqs(Q0, Q0, Q2); | 4043 __ vmulqs(Q0, Q0, Q2); |
3987 __ vrecpsqs(Q2, Q1, Q0); | 4044 __ vrecpsqs(Q2, Q1, Q0); |
3988 __ vmulqs(Q0, Q0, Q2); | 4045 __ vmulqs(Q0, Q0, Q2); |
3989 | 4046 |
3990 __ vadds(S0, S0, S1); | 4047 __ vadds(S0, S0, S1); |
3991 __ vadds(S0, S0, S2); | 4048 __ vadds(S0, S0, S2); |
3992 __ vadds(S0, S0, S3); | 4049 __ vadds(S0, S0, S3); |
3993 | 4050 } else if (TargetCPUFeatures::vfp_supported()) { |
3994 __ bx(LR); | 4051 __ LoadSImmediate(S0, 10.0); |
3995 } else { | 4052 } else { |
3996 __ LoadSImmediate(S0, 10.0); | 4053 __ LoadImmediate(R0, 0); |
3997 __ bx(LR); | |
3998 } | 4054 } |
4055 __ bx(LR); | |
3999 } | 4056 } |
4000 | 4057 |
4001 | 4058 |
4002 ASSEMBLER_TEST_RUN(SIMDSqrt2, test) { | 4059 ASSEMBLER_TEST_RUN(SIMDSqrt2, test) { |
4003 EXPECT(test != NULL); | 4060 EXPECT(test != NULL); |
4004 typedef float (*SIMDSqrt2)() DART_UNUSED; | 4061 if (TargetCPUFeatures::vfp_supported()) { |
4005 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt2, test->entry()); | 4062 typedef float (*SIMDSqrt2)() DART_UNUSED; |
4006 EXPECT_FLOAT_EQ(10.0, res, 0.0001f); | 4063 float res = EXECUTE_TEST_CODE_FLOAT(SIMDSqrt2, test->entry()); |
4064 EXPECT_FLOAT_EQ(10.0, res, 0.0001f); | |
4065 } else { | |
4066 typedef int (*SIMDSqrt2)() DART_UNUSED; | |
4067 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SIMDSqrt2, test->entry())); | |
4068 } | |
4007 } | 4069 } |
4008 | 4070 |
4009 | 4071 |
4010 ASSEMBLER_TEST_GENERATE(SIMDDiv, assembler) { | 4072 ASSEMBLER_TEST_GENERATE(SIMDDiv, assembler) { |
4011 if (TargetCPUFeatures::neon_supported()) { | 4073 if (TargetCPUFeatures::vfp_supported() && |
4074 TargetCPUFeatures::neon_supported()) { | |
4012 __ LoadSImmediate(S4, 1.0); | 4075 __ LoadSImmediate(S4, 1.0); |
4013 __ LoadSImmediate(S5, 4.0); | 4076 __ LoadSImmediate(S5, 4.0); |
4014 __ LoadSImmediate(S6, 9.0); | 4077 __ LoadSImmediate(S6, 9.0); |
4015 __ LoadSImmediate(S7, 16.0); | 4078 __ LoadSImmediate(S7, 16.0); |
4016 | 4079 |
4017 __ LoadSImmediate(S12, 4.0); | 4080 __ LoadSImmediate(S12, 4.0); |
4018 __ LoadSImmediate(S13, 16.0); | 4081 __ LoadSImmediate(S13, 16.0); |
4019 __ LoadSImmediate(S14, 36.0); | 4082 __ LoadSImmediate(S14, 36.0); |
4020 __ LoadSImmediate(S15, 64.0); | 4083 __ LoadSImmediate(S15, 64.0); |
4021 | 4084 |
4022 // Reciprocal estimate. | 4085 // Reciprocal estimate. |
4023 __ vrecpeqs(Q0, Q1); | 4086 __ vrecpeqs(Q0, Q1); |
4024 // 2 Newton-Raphson steps. | 4087 // 2 Newton-Raphson steps. |
4025 __ vrecpsqs(Q2, Q1, Q0); | 4088 __ vrecpsqs(Q2, Q1, Q0); |
4026 __ vmulqs(Q0, Q0, Q2); | 4089 __ vmulqs(Q0, Q0, Q2); |
4027 __ vrecpsqs(Q2, Q1, Q0); | 4090 __ vrecpsqs(Q2, Q1, Q0); |
4028 __ vmulqs(Q0, Q0, Q2); | 4091 __ vmulqs(Q0, Q0, Q2); |
4029 | 4092 |
4030 __ vmulqs(Q0, Q3, Q0); | 4093 __ vmulqs(Q0, Q3, Q0); |
4031 __ vadds(S0, S0, S1); | 4094 __ vadds(S0, S0, S1); |
4032 __ vadds(S0, S0, S2); | 4095 __ vadds(S0, S0, S2); |
4033 __ vadds(S0, S0, S3); | 4096 __ vadds(S0, S0, S3); |
4034 | 4097 } else if (TargetCPUFeatures::vfp_supported()) { |
4035 __ bx(LR); | 4098 __ LoadSImmediate(S0, 16.0); |
4036 } else { | 4099 } else { |
4037 __ LoadSImmediate(S0, 16.0); | 4100 __ LoadImmediate(R0, 0); |
4038 __ bx(LR); | |
4039 } | 4101 } |
4102 __ bx(LR); | |
4040 } | 4103 } |
4041 | 4104 |
4042 | 4105 |
4043 ASSEMBLER_TEST_RUN(SIMDDiv, test) { | 4106 ASSEMBLER_TEST_RUN(SIMDDiv, test) { |
4044 EXPECT(test != NULL); | 4107 EXPECT(test != NULL); |
4045 typedef float (*SIMDDiv)() DART_UNUSED; | 4108 if (TargetCPUFeatures::vfp_supported()) { |
4046 float res = EXECUTE_TEST_CODE_FLOAT(SIMDDiv, test->entry()); | 4109 typedef float (*SIMDDiv)() DART_UNUSED; |
4047 EXPECT_FLOAT_EQ(16.0, res, 0.0001f); | 4110 float res = EXECUTE_TEST_CODE_FLOAT(SIMDDiv, test->entry()); |
4111 EXPECT_FLOAT_EQ(16.0, res, 0.0001f); | |
4112 } else { | |
4113 typedef int (*SIMDDiv)() DART_UNUSED; | |
4114 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SIMDDiv, test->entry())); | |
4115 } | |
4048 } | 4116 } |
4049 | 4117 |
4050 | 4118 |
4051 ASSEMBLER_TEST_GENERATE(Vabsqs, assembler) { | 4119 ASSEMBLER_TEST_GENERATE(Vabsqs, assembler) { |
4052 if (TargetCPUFeatures::neon_supported()) { | 4120 if (TargetCPUFeatures::vfp_supported() && |
4121 TargetCPUFeatures::neon_supported()) { | |
4053 __ LoadSImmediate(S4, 1.0); | 4122 __ LoadSImmediate(S4, 1.0); |
4054 __ LoadSImmediate(S5, -1.0); | 4123 __ LoadSImmediate(S5, -1.0); |
4055 __ LoadSImmediate(S6, 1.0); | 4124 __ LoadSImmediate(S6, 1.0); |
4056 __ LoadSImmediate(S7, -1.0); | 4125 __ LoadSImmediate(S7, -1.0); |
4057 | 4126 |
4058 __ vabsqs(Q0, Q1); | 4127 __ vabsqs(Q0, Q1); |
4059 | 4128 |
4060 __ vadds(S0, S0, S1); | 4129 __ vadds(S0, S0, S1); |
4061 __ vadds(S0, S0, S2); | 4130 __ vadds(S0, S0, S2); |
4062 __ vadds(S0, S0, S3); | 4131 __ vadds(S0, S0, S3); |
4063 | 4132 } else if (TargetCPUFeatures::vfp_supported()) { |
4064 __ bx(LR); | 4133 __ LoadSImmediate(S0, 4.0); |
4065 } else { | 4134 } else { |
4066 __ LoadSImmediate(S0, 4.0); | 4135 __ LoadImmediate(R0, 0); |
4067 __ bx(LR); | |
4068 } | 4136 } |
4137 __ bx(LR); | |
4069 } | 4138 } |
4070 | 4139 |
4071 | 4140 |
4072 ASSEMBLER_TEST_RUN(Vabsqs, test) { | 4141 ASSEMBLER_TEST_RUN(Vabsqs, test) { |
4073 EXPECT(test != NULL); | 4142 EXPECT(test != NULL); |
4074 typedef float (*Vabsqs)() DART_UNUSED; | 4143 if (TargetCPUFeatures::vfp_supported()) { |
4075 float res = EXECUTE_TEST_CODE_FLOAT(Vabsqs, test->entry()); | 4144 typedef float (*Vabsqs)() DART_UNUSED; |
4076 EXPECT_FLOAT_EQ(4.0, res, 0.0001f); | 4145 float res = EXECUTE_TEST_CODE_FLOAT(Vabsqs, test->entry()); |
4146 EXPECT_FLOAT_EQ(4.0, res, 0.0001f); | |
4147 } else { | |
4148 typedef int (*SIMDDiv)() DART_UNUSED; | |
4149 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SIMDDiv, test->entry())); | |
4150 } | |
4077 } | 4151 } |
4078 | 4152 |
4079 | 4153 |
4080 ASSEMBLER_TEST_GENERATE(Vnegqs, assembler) { | 4154 ASSEMBLER_TEST_GENERATE(Vnegqs, assembler) { |
4081 if (TargetCPUFeatures::neon_supported()) { | 4155 if (TargetCPUFeatures::vfp_supported() && |
4156 TargetCPUFeatures::neon_supported()) { | |
4082 __ LoadSImmediate(S4, 1.0); | 4157 __ LoadSImmediate(S4, 1.0); |
4083 __ LoadSImmediate(S5, -2.0); | 4158 __ LoadSImmediate(S5, -2.0); |
4084 __ LoadSImmediate(S6, 1.0); | 4159 __ LoadSImmediate(S6, 1.0); |
4085 __ LoadSImmediate(S7, -2.0); | 4160 __ LoadSImmediate(S7, -2.0); |
4086 | 4161 |
4087 __ vnegqs(Q0, Q1); | 4162 __ vnegqs(Q0, Q1); |
4088 | 4163 |
4089 __ vadds(S0, S0, S1); | 4164 __ vadds(S0, S0, S1); |
4090 __ vadds(S0, S0, S2); | 4165 __ vadds(S0, S0, S2); |
4091 __ vadds(S0, S0, S3); | 4166 __ vadds(S0, S0, S3); |
4092 | 4167 } else if (TargetCPUFeatures::vfp_supported()) { |
4093 __ bx(LR); | 4168 __ LoadSImmediate(S0, 2.0); |
4094 } else { | 4169 } else { |
4095 __ LoadSImmediate(S0, 2.0); | 4170 __ LoadImmediate(R0, 0); |
4096 __ bx(LR); | |
4097 } | 4171 } |
4172 __ bx(LR); | |
4098 } | 4173 } |
4099 | 4174 |
4100 | 4175 |
4101 ASSEMBLER_TEST_RUN(Vnegqs, test) { | 4176 ASSEMBLER_TEST_RUN(Vnegqs, test) { |
4102 EXPECT(test != NULL); | 4177 EXPECT(test != NULL); |
4103 typedef float (*Vnegqs)() DART_UNUSED; | 4178 if (TargetCPUFeatures::vfp_supported()) { |
4104 float res = EXECUTE_TEST_CODE_FLOAT(Vnegqs, test->entry()); | 4179 typedef float (*Vnegqs)() DART_UNUSED; |
4105 EXPECT_FLOAT_EQ(2.0, res, 0.0001f); | 4180 float res = EXECUTE_TEST_CODE_FLOAT(Vnegqs, test->entry()); |
4106 } | 4181 EXPECT_FLOAT_EQ(2.0, res, 0.0001f); |
4107 | 4182 } else { |
4108 | 4183 typedef int (*Vnegqs)() DART_UNUSED; |
4109 ASSEMBLER_TEST_GENERATE(MultCheckOverflow, assembler) { | 4184 EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(Vnegqs, test->entry())); |
4110 // Both positive, no overflow | 4185 } |
4111 Label overflow1, test1; | |
4112 __ LoadImmediate(R0, 42); | |
4113 __ LoadImmediate(R1, 0xff); | |
4114 __ LoadImmediate(R2, 0xf0); | |
4115 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &overflow1); | |
4116 __ b(&test1); | |
4117 __ Bind(&overflow1); | |
4118 __ LoadImmediate(R0, 1); | |
4119 __ Ret(); | |
4120 | |
4121 | |
4122 // Left negative no overflow. | |
4123 __ Bind(&test1); | |
4124 Label overflow2, test2; | |
4125 __ LoadImmediate(R1, -0xff); | |
4126 __ LoadImmediate(R2, 0xf0); | |
4127 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &overflow2); | |
4128 __ b(&test2); | |
4129 __ Bind(&overflow2); | |
4130 __ LoadImmediate(R0, 2); | |
4131 __ Ret(); | |
4132 | |
4133 // Right negative no overflow | |
4134 Label overflow3, test3; | |
4135 __ Bind(&test2); | |
4136 __ LoadImmediate(R1, 0xff); | |
4137 __ LoadImmediate(R2, -0xf0); | |
4138 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &overflow3); | |
4139 __ b(&test3); | |
4140 __ Bind(&overflow3); | |
4141 __ LoadImmediate(R0, 3); | |
4142 __ Ret(); | |
4143 | |
4144 // Both negative no overflow. | |
4145 Label overflow4, test4; | |
4146 __ Bind(&test3); | |
4147 __ LoadImmediate(R1, -0xff); | |
4148 __ LoadImmediate(R2, -0xf0); | |
4149 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &overflow4); | |
4150 __ b(&test4); | |
4151 __ Bind(&overflow4); | |
4152 __ LoadImmediate(R0, 4); | |
4153 __ Ret(); | |
4154 | |
4155 // Both positive with overflow. | |
4156 Label test5; | |
4157 __ Bind(&test4); | |
4158 __ LoadImmediate(R1, 0x0fffffff); | |
4159 __ LoadImmediate(R2, 0xffff); | |
4160 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &test5); | |
4161 __ LoadImmediate(R0, 5); | |
4162 __ Ret(); | |
4163 | |
4164 // left negative with overflow. | |
4165 Label test6; | |
4166 __ Bind(&test5); | |
4167 __ LoadImmediate(R1, -0x0fffffff); | |
4168 __ LoadImmediate(R2, 0xffff); | |
4169 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &test6); | |
4170 __ LoadImmediate(R0, 6); | |
4171 __ Ret(); | |
4172 | |
4173 // right negative with overflow. | |
4174 Label test7; | |
4175 __ Bind(&test6); | |
4176 __ LoadImmediate(R1, 0x0fffffff); | |
4177 __ LoadImmediate(R2, -0xffff); | |
4178 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &test7); | |
4179 __ LoadImmediate(R0, 7); | |
4180 __ Ret(); | |
4181 | |
4182 // both negative with overflow. | |
4183 Label test8; | |
4184 __ Bind(&test7); | |
4185 __ LoadImmediate(R1, -0x0fffffff); | |
4186 __ LoadImmediate(R2, -0xffff); | |
4187 __ CheckMultSignedOverflow(R1, R2, R3, D0, D1, &test8); | |
4188 __ LoadImmediate(R0, 8); | |
4189 __ Ret(); | |
4190 | |
4191 __ Bind(&test8); | |
4192 __ Ret(); | |
4193 } | |
4194 | |
4195 | |
4196 ASSEMBLER_TEST_RUN(MultCheckOverflow, test) { | |
4197 EXPECT(test != NULL); | |
4198 typedef int (*Tst)() DART_UNUSED; | |
4199 EXPECT_EQ(42, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); | |
4200 } | 4186 } |
4201 | 4187 |
4202 | 4188 |
4203 // Called from assembler_test.cc. | 4189 // Called from assembler_test.cc. |
4204 // LR: return address. | 4190 // LR: return address. |
4205 // R0: context. | 4191 // R0: context. |
4206 // R1: value. | 4192 // R1: value. |
4207 // R2: growable array. | 4193 // R2: growable array. |
4208 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { | 4194 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { |
4209 __ PushList((1 << CTX) | (1 << LR)); | 4195 __ PushList((1 << CTX) | (1 << LR)); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4260 EXPECT_EQ(ICData::kInt64RangeBit, | 4246 EXPECT_EQ(ICData::kInt64RangeBit, |
4261 RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1))); | 4247 RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1))); |
4262 EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64))); | 4248 EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64))); |
4263 EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64))); | 4249 EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64))); |
4264 | 4250 |
4265 EXPECT_EQ(-1, RANGE_OF(Bool::True().raw())); | 4251 EXPECT_EQ(-1, RANGE_OF(Bool::True().raw())); |
4266 | 4252 |
4267 #undef RANGE_OF | 4253 #undef RANGE_OF |
4268 } | 4254 } |
4269 | 4255 |
4270 | |
4271 } // namespace dart | 4256 } // namespace dart |
4272 | 4257 |
4273 #endif // defined TARGET_ARCH_ARM | 4258 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |