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

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

Issue 19773017: Adds ARM SIMD instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/disassembler_arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/os.h" 9 #include "vm/os.h"
10 #include "vm/unit_test.h" 10 #include "vm/unit_test.h"
(...skipping 2906 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 } 2917 }
2918 2918
2919 2919
2920 ASSEMBLER_TEST_RUN(Vcgtqs, test) { 2920 ASSEMBLER_TEST_RUN(Vcgtqs, test) {
2921 EXPECT(test != NULL); 2921 EXPECT(test != NULL);
2922 typedef int (*Tst)(); 2922 typedef int (*Tst)();
2923 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry())); 2923 EXPECT_EQ(-2, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2924 } 2924 }
2925 2925
2926 2926
2927 ASSEMBLER_TEST_GENERATE(Vminqs, assembler) {
2928 if (CPUFeatures::neon_supported()) {
2929 __ LoadSImmediate(S0, 1.0);
2930 __ LoadSImmediate(S1, 2.0);
2931 __ LoadSImmediate(S2, 3.0);
2932 __ LoadSImmediate(S3, 4.0);
2933
2934 __ LoadSImmediate(S4, 2.0);
2935 __ LoadSImmediate(S5, 1.0);
2936 __ LoadSImmediate(S6, 6.0);
2937 __ LoadSImmediate(S7, 3.0);
2938
2939 __ vminqs(Q2, Q1, Q0);
2940
2941 __ vadds(S8, S8, S9);
2942 __ vadds(S8, S8, S10);
2943 __ vadds(S8, S8, S11);
2944
2945 __ vcvtis(S0, S8);
2946 __ vmovrs(R0, S0);
2947 __ bx(LR);
2948 } else {
2949 __ LoadImmediate(R0, 8);
2950 __ bx(LR);
2951 }
2952 }
2953
2954
2955 ASSEMBLER_TEST_RUN(Vminqs, test) {
2956 EXPECT(test != NULL);
2957 typedef int (*Tst)();
2958 EXPECT_EQ(8, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2959 }
2960
2961
2962 ASSEMBLER_TEST_GENERATE(Vmaxqs, assembler) {
2963 if (CPUFeatures::neon_supported()) {
2964 __ LoadSImmediate(S0, 1.0);
2965 __ LoadSImmediate(S1, 2.0);
2966 __ LoadSImmediate(S2, 3.0);
2967 __ LoadSImmediate(S3, 4.0);
2968
2969 __ LoadSImmediate(S4, 2.0);
2970 __ LoadSImmediate(S5, 1.0);
2971 __ LoadSImmediate(S6, 6.0);
2972 __ LoadSImmediate(S7, 3.0);
2973
2974 __ vmaxqs(Q2, Q1, Q0);
2975
2976 __ vadds(S8, S8, S9);
2977 __ vadds(S8, S8, S10);
2978 __ vadds(S8, S8, S11);
2979
2980 __ vcvtis(S0, S8);
2981 __ vmovrs(R0, S0);
2982 __ bx(LR);
2983 } else {
2984 __ LoadImmediate(R0, 14);
2985 __ bx(LR);
2986 }
2987 }
2988
2989
2990 ASSEMBLER_TEST_RUN(Vmaxqs, test) {
2991 EXPECT(test != NULL);
2992 typedef int (*Tst)();
2993 EXPECT_EQ(14, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
2994 }
2995
2996
2997 // This is the same function as in the Simulator.
2998 static float arm_recip_estimate(float a) {
2999 // From the ARM Architecture Reference Manual A2-85.
3000 if (isinf(a) || (abs(a) >= exp2f(126))) return 0.0;
3001 else if (a == 0.0) return INFINITY;
3002 else if (isnan(a)) return a;
3003
3004 uint32_t a_bits = bit_cast<uint32_t, float>(a);
3005 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29)
3006 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) |
3007 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29);
3008 // result_exp = 253 - UInt(a<30:23>)
3009 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff);
3010 ASSERT((result_exp >= 1) && (result_exp <= 252));
3011
3012 double scaled_d = bit_cast<double, uint64_t>(scaled);
3013 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0));
3014
3015 // a in units of 1/512 rounded down.
3016 int32_t q = static_cast<int32_t>(scaled_d * 512.0);
3017 // reciprocal r.
3018 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0);
3019 // r in units of 1/256 rounded to nearest.
3020 int32_t s = static_cast<int32_t>(256.0 * r + 0.5);
3021 double estimate = static_cast<double>(s) / 256.0;
3022 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0)));
3023
3024 // result = sign : result_exp<7:0> : estimate<51:29>
3025 int32_t result_bits =
3026 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) |
3027 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff);
3028 return bit_cast<float, int32_t>(result_bits);
3029 }
3030
3031
3032 ASSEMBLER_TEST_GENERATE(Vrecpeqs, assembler) {
3033 if (CPUFeatures::neon_supported()) {
3034 __ LoadSImmediate(S4, 147.0);
3035 __ vmovs(S5, S4);
3036 __ vmovs(S6, S4);
3037 __ vmovs(S7, S4);
3038
3039 __ vrecpeqs(Q0, Q1);
3040
3041 __ bx(LR);
3042 } else {
3043 __ LoadSImmediate(S0, arm_recip_estimate(147.0));
3044 __ bx(LR);
3045 }
3046 }
3047
3048
3049 ASSEMBLER_TEST_RUN(Vrecpeqs, test) {
3050 EXPECT(test != NULL);
3051 typedef float (*Vrecpeqs)();
3052 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpeqs, test->entry());
3053 EXPECT_FLOAT_EQ(arm_recip_estimate(147.0), res, 0.0001f);
3054 }
3055
3056
3057 ASSEMBLER_TEST_GENERATE(Vrecpsqs, assembler) {
3058 if (CPUFeatures::neon_supported()) {
3059 __ LoadSImmediate(S4, 5.0);
3060 __ LoadSImmediate(S5, 2.0);
3061 __ LoadSImmediate(S6, 3.0);
3062 __ LoadSImmediate(S7, 4.0);
3063
3064 __ LoadSImmediate(S8, 10.0);
3065 __ LoadSImmediate(S9, 1.0);
3066 __ LoadSImmediate(S10, 6.0);
3067 __ LoadSImmediate(S11, 3.0);
3068
3069 __ vrecpsqs(Q0, Q1, Q2);
3070
3071 __ bx(LR);
3072 } else {
3073 __ bx(LR);
3074 }
3075 }
3076
3077
3078 ASSEMBLER_TEST_RUN(Vrecpsqs, test) {
3079 EXPECT(test != NULL);
3080 typedef float (*Vrecpsqs)();
3081 float res = EXECUTE_TEST_CODE_FLOAT(Vrecpsqs, test->entry());
3082 EXPECT_FLOAT_EQ(2 - 10.0 * 5.0, res, 0.0001f);
3083 }
3084
3085
3086 ASSEMBLER_TEST_GENERATE(Reciprocal, assembler) {
3087 if (CPUFeatures::neon_supported()) {
3088 __ LoadSImmediate(S4, 147000.0);
3089 __ vmovs(S5, S4);
3090 __ vmovs(S6, S4);
3091 __ vmovs(S7, S4);
3092
3093 // Reciprocal estimate.
3094 __ vrecpeqs(Q0, Q1);
3095 // 2 Newton-Raphson steps.
3096 __ vrecpsqs(Q2, Q1, Q0);
3097 __ vmulqs(Q0, Q0, Q2);
3098 __ vrecpsqs(Q2, Q1, Q0);
3099 __ vmulqs(Q0, Q0, Q2);
3100
3101 __ bx(LR);
3102 } else {
3103 __ LoadSImmediate(S0, 1.0/147000.0);
3104 __ bx(LR);
3105 }
3106 }
3107
3108
3109 ASSEMBLER_TEST_RUN(Reciprocal, test) {
3110 EXPECT(test != NULL);
3111 typedef float (*Reciprocal)();
3112 float res = EXECUTE_TEST_CODE_FLOAT(Reciprocal, test->entry());
3113 EXPECT_FLOAT_EQ(1.0/147000.0, res, 0.0001f);
3114 }
3115
3116
2927 // Called from assembler_test.cc. 3117 // Called from assembler_test.cc.
2928 // LR: return address. 3118 // LR: return address.
2929 // R0: context. 3119 // R0: context.
2930 // R1: value. 3120 // R1: value.
2931 // R2: growable array. 3121 // R2: growable array.
2932 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) { 3122 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
2933 __ PushList((1 << CTX) | (1 << LR)); 3123 __ PushList((1 << CTX) | (1 << LR));
2934 __ mov(CTX, ShifterOperand(R0)); 3124 __ mov(CTX, ShifterOperand(R0));
2935 __ StoreIntoObject(R2, 3125 __ StoreIntoObject(R2,
2936 FieldAddress(R2, GrowableObjectArray::data_offset()), 3126 FieldAddress(R2, GrowableObjectArray::data_offset()),
2937 R1); 3127 R1);
2938 __ PopList((1 << CTX) | (1 << LR)); 3128 __ PopList((1 << CTX) | (1 << LR));
2939 __ Ret(); 3129 __ Ret();
2940 } 3130 }
2941 3131
2942 } // namespace dart 3132 } // namespace dart
2943 3133
2944 #endif // defined TARGET_ARCH_ARM 3134 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | runtime/vm/disassembler_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698