Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: runtime/vm/assembler_arm_test.cc

Issue 1043943002: A few fixes for ARMv5TE. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698