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

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

Issue 19978004: Implements Float32x4 and Uint32x4 instructions for ARM. (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') | tests/lib/lib.status » ('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" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 2916 matching lines...) Expand 10 before | Expand all | Expand 10 after
2927 2927
2928 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2928 void BinaryFloat32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2929 QRegister left = locs()->in(0).fpu_reg(); 2929 QRegister left = locs()->in(0).fpu_reg();
2930 QRegister right = locs()->in(1).fpu_reg(); 2930 QRegister right = locs()->in(1).fpu_reg();
2931 QRegister result = locs()->out().fpu_reg(); 2931 QRegister result = locs()->out().fpu_reg();
2932 2932
2933 switch (op_kind()) { 2933 switch (op_kind()) {
2934 case Token::kADD: __ vaddqs(result, left, right); break; 2934 case Token::kADD: __ vaddqs(result, left, right); break;
2935 case Token::kSUB: __ vsubqs(result, left, right); break; 2935 case Token::kSUB: __ vsubqs(result, left, right); break;
2936 case Token::kMUL: __ vmulqs(result, left, right); break; 2936 case Token::kMUL: __ vmulqs(result, left, right); break;
2937 // TODO(zra): Two options for division. Either use vdiv piecewise, or do 2937 case Token::kDIV: __ Vdivqs(result, left, right); break;
2938 // vrecpeqs followed by vmulqs.
2939 case Token::kDIV: UNIMPLEMENTED(); break;
2940 default: UNREACHABLE(); 2938 default: UNREACHABLE();
2941 } 2939 }
2942 } 2940 }
2943 2941
2944 2942
2945 LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const { 2943 LocationSummary* Float32x4ShuffleInstr::MakeLocationSummary() const {
2946 const intptr_t kNumInputs = 1; 2944 const intptr_t kNumInputs = 1;
2947 const intptr_t kNumTemps = 0; 2945 const intptr_t kNumTemps = 0;
2948 LocationSummary* summary = 2946 LocationSummary* summary =
2949 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 2947 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
2950 // Low (< Q7) Q registers are needed for the vcvtds instruction. 2948 // Low (< Q7) Q registers are needed for the vcvtds and vmovs instructions.
2951 summary->set_in(0, Location::FpuRegisterLocation(Q5)); 2949 summary->set_in(0, Location::FpuRegisterLocation(Q5));
2952 summary->set_out(Location::FpuRegisterLocation(Q6)); 2950 summary->set_out(Location::FpuRegisterLocation(Q6));
2953 return summary; 2951 return summary;
2954 } 2952 }
2955 2953
2956 2954
2957 void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2955 void Float32x4ShuffleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2958 QRegister value = locs()->in(0).fpu_reg(); 2956 QRegister value = locs()->in(0).fpu_reg();
2959 QRegister result = locs()->out().fpu_reg(); 2957 QRegister result = locs()->out().fpu_reg();
2960 DRegister dresult0 = EvenDRegisterOf(result); 2958 DRegister dresult0 = EvenDRegisterOf(result);
2959 DRegister dresult1 = OddDRegisterOf(result);
2961 SRegister sresult0 = EvenSRegisterOf(dresult0); 2960 SRegister sresult0 = EvenSRegisterOf(dresult0);
2961 SRegister sresult1 = OddSRegisterOf(dresult0);
2962 SRegister sresult2 = EvenSRegisterOf(dresult1);
2963 SRegister sresult3 = OddSRegisterOf(dresult1);
2962 2964
2963 DRegister dvalue0 = EvenDRegisterOf(value); 2965 DRegister dvalue0 = EvenDRegisterOf(value);
2964 DRegister dvalue1 = OddDRegisterOf(value); 2966 DRegister dvalue1 = OddDRegisterOf(value);
2965 2967
2966 // For these cases the vdup instruction requires fewer 2968 DRegister dtemp0 = DTMP;
2967 // instructions. For arbitrary shuffles, vtbl will be needed. 2969 DRegister dtemp1 = OddDRegisterOf(QTMP);
2970
2971 // For some cases the vdup instruction requires fewer
2972 // instructions. For arbitrary shuffles, use vtbl.
2968 switch (op_kind()) { 2973 switch (op_kind()) {
2969 case MethodRecognizer::kFloat32x4ShuffleX: 2974 case MethodRecognizer::kFloat32x4ShuffleX:
2970 __ vdup(kWord, result, dvalue0, 0); 2975 __ vdup(kWord, result, dvalue0, 0);
2971 __ vcvtds(dresult0, sresult0); 2976 __ vcvtds(dresult0, sresult0);
2972 break; 2977 break;
2973 case MethodRecognizer::kFloat32x4ShuffleY: 2978 case MethodRecognizer::kFloat32x4ShuffleY:
2974 __ vdup(kWord, result, dvalue0, 1); 2979 __ vdup(kWord, result, dvalue0, 1);
2975 __ vcvtds(dresult0, sresult0); 2980 __ vcvtds(dresult0, sresult0);
2976 break; 2981 break;
2977 case MethodRecognizer::kFloat32x4ShuffleZ: 2982 case MethodRecognizer::kFloat32x4ShuffleZ:
2978 __ vdup(kWord, result, dvalue1, 0); 2983 __ vdup(kWord, result, dvalue1, 0);
2979 __ vcvtds(dresult0, sresult0); 2984 __ vcvtds(dresult0, sresult0);
2980 break; 2985 break;
2981 case MethodRecognizer::kFloat32x4ShuffleW: 2986 case MethodRecognizer::kFloat32x4ShuffleW:
2982 __ vdup(kWord, result, dvalue1, 1); 2987 __ vdup(kWord, result, dvalue1, 1);
2983 __ vcvtds(dresult0, sresult0); 2988 __ vcvtds(dresult0, sresult0);
2984 break; 2989 break;
2985 case MethodRecognizer::kFloat32x4Shuffle: 2990 case MethodRecognizer::kFloat32x4Shuffle:
2986 if (mask_ == 0x00) { 2991 if (mask_ == 0x00) {
2987 __ vdup(kWord, result, dvalue0, 0); 2992 __ vdup(kWord, result, dvalue0, 0);
2988 } else if (mask_ == 0x55) { 2993 } else if (mask_ == 0x55) {
2989 __ vdup(kWord, result, dvalue0, 1); 2994 __ vdup(kWord, result, dvalue0, 1);
2990 } else if (mask_ == 0xAA) { 2995 } else if (mask_ == 0xAA) {
2991 __ vdup(kWord, result, dvalue1, 0); 2996 __ vdup(kWord, result, dvalue1, 0);
2992 } else if (mask_ == 0xFF) { 2997 } else if (mask_ == 0xFF) {
2993 __ vdup(kWord, result, dvalue1, 1); 2998 __ vdup(kWord, result, dvalue1, 1);
2994 } else { 2999 } else {
2995 // TODO(zra): Implement other shuffles. 3000 SRegister svalues[4];
2996 UNIMPLEMENTED(); 3001
3002 svalues[0] = EvenSRegisterOf(dtemp0);
3003 svalues[1] = OddSRegisterOf(dtemp0);
3004 svalues[2] = EvenSRegisterOf(dtemp1);
3005 svalues[3] = OddSRegisterOf(dtemp1);
3006
3007 __ vmovq(QTMP, value);
3008 __ vmovs(sresult0, svalues[mask_ & 0x3]);
3009 __ vmovs(sresult1, svalues[(mask_ >> 2) & 0x3]);
3010 __ vmovs(sresult2, svalues[(mask_ >> 4) & 0x3]);
3011 __ vmovs(sresult3, svalues[(mask_ >> 6) & 0x3]);
2997 } 3012 }
2998 break; 3013 break;
2999 default: UNREACHABLE(); 3014 default: UNREACHABLE();
3000 } 3015 }
3001 } 3016 }
3002 3017
3003 3018
3004 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const { 3019 LocationSummary* Float32x4ConstructorInstr::MakeLocationSummary() const {
3005 const intptr_t kNumInputs = 4; 3020 const intptr_t kNumInputs = 4;
3006 const intptr_t kNumTemps = 0; 3021 const intptr_t kNumTemps = 0;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3113 case MethodRecognizer::kFloat32x4LessThanOrEqual: 3128 case MethodRecognizer::kFloat32x4LessThanOrEqual:
3114 __ vcgeqs(result, right, left); 3129 __ vcgeqs(result, right, left);
3115 break; 3130 break;
3116 3131
3117 default: UNREACHABLE(); 3132 default: UNREACHABLE();
3118 } 3133 }
3119 } 3134 }
3120 3135
3121 3136
3122 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const { 3137 LocationSummary* Float32x4MinMaxInstr::MakeLocationSummary() const {
3123 UNIMPLEMENTED(); 3138 const intptr_t kNumInputs = 2;
3124 return NULL; 3139 const intptr_t kNumTemps = 0;
3140 LocationSummary* summary =
3141 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3142 summary->set_in(0, Location::RequiresFpuRegister());
3143 summary->set_in(1, Location::RequiresFpuRegister());
3144 summary->set_out(Location::RequiresFpuRegister());
3145 return summary;
3125 } 3146 }
3126 3147
3127 3148
3128 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3149 void Float32x4MinMaxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3129 UNIMPLEMENTED(); 3150 QRegister left = locs()->in(0).fpu_reg();
3151 QRegister right = locs()->in(1).fpu_reg();
3152 QRegister result = locs()->out().fpu_reg();
3153
3154 switch (op_kind()) {
3155 case MethodRecognizer::kFloat32x4Min:
3156 __ vminqs(result, left, right);
3157 break;
3158 case MethodRecognizer::kFloat32x4Max:
3159 __ vmaxqs(result, left, right);
3160 break;
3161 default: UNREACHABLE();
3162 }
3130 } 3163 }
3131 3164
3132 3165
3133 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const { 3166 LocationSummary* Float32x4SqrtInstr::MakeLocationSummary() const {
3134 UNIMPLEMENTED(); 3167 const intptr_t kNumInputs = 1;
3135 return NULL; 3168 const intptr_t kNumTemps = 1;
3169 LocationSummary* summary =
3170 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3171 summary->set_in(0, Location::RequiresFpuRegister());
3172 summary->set_out(Location::RequiresFpuRegister());
3173 summary->set_temp(0, Location::RequiresFpuRegister());
3174 return summary;
3136 } 3175 }
3137 3176
3138 3177
3139 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3178 void Float32x4SqrtInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3140 UNIMPLEMENTED(); 3179 QRegister left = locs()->in(0).fpu_reg();
3180 QRegister result = locs()->out().fpu_reg();
3181
3182 switch (op_kind()) {
3183 case MethodRecognizer::kFloat32x4Sqrt:
3184 __ Vsqrtqs(result, left);
3185 break;
3186 case MethodRecognizer::kFloat32x4Reciprocal:
3187 __ Vreciprocalqs(result, left);
3188 break;
3189 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
3190 __ VreciprocalSqrtqs(result, left);
3191 break;
3192 default: UNREACHABLE();
3193 }
3141 } 3194 }
3142 3195
3143 3196
3144 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const { 3197 LocationSummary* Float32x4ScaleInstr::MakeLocationSummary() const {
3145 UNIMPLEMENTED(); 3198 const intptr_t kNumInputs = 2;
3146 return NULL; 3199 const intptr_t kNumTemps = 0;
3200 LocationSummary* summary =
3201 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3202 summary->set_in(0, Location::RequiresFpuRegister());
3203 summary->set_in(1, Location::RequiresFpuRegister());
3204 summary->set_out(Location::RequiresFpuRegister());
3205 return summary;
3147 } 3206 }
3148 3207
3149 3208
3150 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3209 void Float32x4ScaleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3151 UNIMPLEMENTED(); 3210 QRegister left = locs()->in(0).fpu_reg();
3211 QRegister right = locs()->in(1).fpu_reg();
3212 QRegister result = locs()->out().fpu_reg();
3213
3214 switch (op_kind()) {
3215 case MethodRecognizer::kFloat32x4Scale:
3216 __ vcvtsd(STMP, EvenDRegisterOf(left));
3217 __ vdup(kWord, result, DTMP, 0);
3218 __ vmulqs(result, result, right);
3219 break;
3220 default: UNREACHABLE();
3221 }
3152 } 3222 }
3153 3223
3154 3224
3155 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const { 3225 LocationSummary* Float32x4ZeroArgInstr::MakeLocationSummary() const {
3156 UNIMPLEMENTED(); 3226 const intptr_t kNumInputs = 1;
3157 return NULL; 3227 const intptr_t kNumTemps = 0;
3228 LocationSummary* summary =
3229 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3230 summary->set_in(0, Location::RequiresFpuRegister());
3231 summary->set_out(Location::RequiresFpuRegister());
3232 return summary;
3158 } 3233 }
3159 3234
3160 3235
3161 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3236 void Float32x4ZeroArgInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3162 UNIMPLEMENTED(); 3237 QRegister left = locs()->in(0).fpu_reg();
3238 QRegister result = locs()->out().fpu_reg();
3239
3240 switch (op_kind()) {
3241 case MethodRecognizer::kFloat32x4Negate:
3242 __ vnegqs(result, left);
3243 break;
3244 case MethodRecognizer::kFloat32x4Absolute:
3245 __ vabsqs(result, left);
3246 break;
3247 default: UNREACHABLE();
3248 }
3163 } 3249 }
3164 3250
3165 3251
3166 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const { 3252 LocationSummary* Float32x4ClampInstr::MakeLocationSummary() const {
3167 UNIMPLEMENTED(); 3253 const intptr_t kNumInputs = 3;
3168 return NULL; 3254 const intptr_t kNumTemps = 0;
3255 LocationSummary* summary =
3256 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3257 summary->set_in(0, Location::RequiresFpuRegister());
3258 summary->set_in(1, Location::RequiresFpuRegister());
3259 summary->set_in(2, Location::RequiresFpuRegister());
3260 summary->set_out(Location::RequiresFpuRegister());
3261 return summary;
3169 } 3262 }
3170 3263
3171 3264
3172 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3265 void Float32x4ClampInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3173 UNIMPLEMENTED(); 3266 QRegister left = locs()->in(0).fpu_reg();
3267 QRegister lower = locs()->in(1).fpu_reg();
3268 QRegister upper = locs()->in(2).fpu_reg();
3269 QRegister result = locs()->out().fpu_reg();
3270 __ vminqs(result, left, upper);
3271 __ vmaxqs(result, result, lower);
3174 } 3272 }
3175 3273
3176 3274
3177 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const { 3275 LocationSummary* Float32x4WithInstr::MakeLocationSummary() const {
3178 const intptr_t kNumInputs = 2; 3276 const intptr_t kNumInputs = 2;
3179 const intptr_t kNumTemps = 0; 3277 const intptr_t kNumTemps = 0;
3180 LocationSummary* summary = 3278 LocationSummary* summary =
3181 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3279 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3182 summary->set_in(0, Location::RequiresFpuRegister()); 3280 summary->set_in(0, Location::RequiresFpuRegister());
3183 summary->set_in(1, Location::RequiresFpuRegister()); 3281 summary->set_in(1, Location::RequiresFpuRegister());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3216 break; 3314 break;
3217 case MethodRecognizer::kFloat32x4WithW: 3315 case MethodRecognizer::kFloat32x4WithW:
3218 __ vmovs(sresult3, STMP); 3316 __ vmovs(sresult3, STMP);
3219 break; 3317 break;
3220 default: UNREACHABLE(); 3318 default: UNREACHABLE();
3221 } 3319 }
3222 } 3320 }
3223 3321
3224 3322
3225 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const { 3323 LocationSummary* Float32x4ToUint32x4Instr::MakeLocationSummary() const {
3226 UNIMPLEMENTED(); 3324 const intptr_t kNumInputs = 1;
3227 return NULL; 3325 const intptr_t kNumTemps = 0;
3326 LocationSummary* summary =
3327 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3328 summary->set_in(0, Location::RequiresFpuRegister());
3329 summary->set_out(Location::RequiresFpuRegister());
3330 return summary;
3228 } 3331 }
3229 3332
3230 3333
3231 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3334 void Float32x4ToUint32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3232 UNIMPLEMENTED(); 3335 QRegister value = locs()->in(0).fpu_reg();
3336 QRegister result = locs()->out().fpu_reg();
3337
3338 if (value != result) {
3339 __ vmovq(result, value);
3340 }
3233 } 3341 }
3234 3342
3235 3343
3236 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const { 3344 LocationSummary* Uint32x4BoolConstructorInstr::MakeLocationSummary() const {
3237 UNIMPLEMENTED(); 3345 const intptr_t kNumInputs = 4;
3238 return NULL; 3346 const intptr_t kNumTemps = 1;
3347 LocationSummary* summary =
3348 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3349 summary->set_in(0, Location::RequiresRegister());
3350 summary->set_in(1, Location::RequiresRegister());
3351 summary->set_in(2, Location::RequiresRegister());
3352 summary->set_in(3, Location::RequiresRegister());
3353 summary->set_temp(0, Location::RequiresRegister());
3354 // Low (< 7) Q register needed for the vmovsr instruction.
3355 summary->set_out(Location::FpuRegisterLocation(Q6));
3356 return summary;
3239 } 3357 }
3240 3358
3241 3359
3242 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3360 void Uint32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3243 UNIMPLEMENTED(); 3361 Register v0 = locs()->in(0).reg();
3362 Register v1 = locs()->in(1).reg();
3363 Register v2 = locs()->in(2).reg();
3364 Register v3 = locs()->in(3).reg();
3365 Register temp = locs()->temp(0).reg();
3366 QRegister result = locs()->out().fpu_reg();
3367 DRegister dresult0 = EvenDRegisterOf(result);
3368 DRegister dresult1 = OddDRegisterOf(result);
3369 SRegister sresult0 = EvenSRegisterOf(dresult0);
3370 SRegister sresult1 = OddSRegisterOf(dresult0);
3371 SRegister sresult2 = EvenSRegisterOf(dresult1);
3372 SRegister sresult3 = OddSRegisterOf(dresult1);
3373
3374 __ veorq(result, result, result);
3375 __ LoadImmediate(temp, 0xffffffff);
3376
3377 __ CompareObject(v0, Bool::True());
3378 __ vmovsr(sresult0, temp, EQ);
3379
3380 __ CompareObject(v1, Bool::True());
3381 __ vmovsr(sresult1, temp, EQ);
3382
3383 __ CompareObject(v2, Bool::True());
3384 __ vmovsr(sresult2, temp, EQ);
3385
3386 __ CompareObject(v3, Bool::True());
3387 __ vmovsr(sresult3, temp, EQ);
3244 } 3388 }
3245 3389
3246 3390
3247 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const { 3391 LocationSummary* Uint32x4GetFlagInstr::MakeLocationSummary() const {
3248 const intptr_t kNumInputs = 1; 3392 const intptr_t kNumInputs = 1;
3249 const intptr_t kNumTemps = 0; 3393 const intptr_t kNumTemps = 0;
3250 LocationSummary* summary = 3394 LocationSummary* summary =
3251 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3395 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3252 // Low (< 7) Q registers are needed for the vmovrs instruction. 3396 // Low (< 7) Q registers are needed for the vmovrs instruction.
3253 summary->set_in(0, Location::FpuRegisterLocation(Q6)); 3397 summary->set_in(0, Location::FpuRegisterLocation(Q6));
(...skipping 29 matching lines...) Expand all
3283 default: UNREACHABLE(); 3427 default: UNREACHABLE();
3284 } 3428 }
3285 3429
3286 __ tst(result, ShifterOperand(result)); 3430 __ tst(result, ShifterOperand(result));
3287 __ LoadObject(result, Bool::True(), NE); 3431 __ LoadObject(result, Bool::True(), NE);
3288 __ LoadObject(result, Bool::False(), EQ); 3432 __ LoadObject(result, Bool::False(), EQ);
3289 } 3433 }
3290 3434
3291 3435
3292 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const { 3436 LocationSummary* Uint32x4SelectInstr::MakeLocationSummary() const {
3293 UNIMPLEMENTED(); 3437 const intptr_t kNumInputs = 3;
3294 return NULL; 3438 const intptr_t kNumTemps = 1;
3439 LocationSummary* summary =
3440 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3441 summary->set_in(0, Location::RequiresFpuRegister());
3442 summary->set_in(1, Location::RequiresFpuRegister());
3443 summary->set_in(2, Location::RequiresFpuRegister());
3444 summary->set_temp(0, Location::RequiresFpuRegister());
3445 summary->set_out(Location::RequiresFpuRegister());
3446 return summary;
3295 } 3447 }
3296 3448
3297 3449
3298 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3450 void Uint32x4SelectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3299 UNIMPLEMENTED(); 3451 QRegister mask = locs()->in(0).fpu_reg();
3452 QRegister trueValue = locs()->in(1).fpu_reg();
3453 QRegister falseValue = locs()->in(2).fpu_reg();
3454 QRegister out = locs()->out().fpu_reg();
3455 QRegister temp = locs()->temp(0).fpu_reg();
3456
3457 // Copy mask.
3458 __ vmovq(temp, mask);
3459 // Invert it.
3460 __ veorq(QTMP, QTMP, QTMP); // QTMP <- 0.
3461 __ vornq(temp, QTMP, temp); // temp <- ~temp.
3462 // mask = mask & trueValue.
3463 __ vandq(mask, mask, trueValue);
3464 // temp = temp & falseValue.
3465 __ vandq(temp, temp, falseValue);
3466 // out = mask | temp.
3467 __ vorrq(out, mask, temp);
3300 } 3468 }
3301 3469
3302 3470
3303 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const { 3471 LocationSummary* Uint32x4SetFlagInstr::MakeLocationSummary() const {
3304 UNIMPLEMENTED(); 3472 const intptr_t kNumInputs = 2;
3305 return NULL; 3473 const intptr_t kNumTemps = 0;
3474 LocationSummary* summary =
3475 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3476 summary->set_in(0, Location::RequiresFpuRegister());
3477 summary->set_in(1, Location::RequiresRegister());
3478 // Low (< 7) Q register needed for the vmovsr instruction.
3479 summary->set_out(Location::FpuRegisterLocation(Q6));
3480 return summary;
3306 } 3481 }
3307 3482
3308 3483
3309 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3484 void Uint32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3310 UNIMPLEMENTED(); 3485 QRegister mask = locs()->in(0).fpu_reg();
3486 Register flag = locs()->in(1).reg();
3487 QRegister result = locs()->out().fpu_reg();
3488
3489 DRegister dresult0 = EvenDRegisterOf(result);
3490 DRegister dresult1 = OddDRegisterOf(result);
3491 SRegister sresult0 = EvenSRegisterOf(dresult0);
3492 SRegister sresult1 = OddSRegisterOf(dresult0);
3493 SRegister sresult2 = EvenSRegisterOf(dresult1);
3494 SRegister sresult3 = OddSRegisterOf(dresult1);
3495
3496 if (result != mask) {
3497 __ vmovq(result, mask);
3498 }
3499
3500 __ CompareObject(flag, Bool::True());
3501 __ LoadImmediate(TMP, 0xffffffff, EQ);
3502 __ LoadImmediate(TMP, 0, NE);
3503 switch (op_kind()) {
3504 case MethodRecognizer::kUint32x4WithFlagX:
3505 __ vmovsr(sresult0, TMP);
3506 break;
3507 case MethodRecognizer::kUint32x4WithFlagY:
3508 __ vmovsr(sresult1, TMP);
3509 break;
3510 case MethodRecognizer::kUint32x4WithFlagZ:
3511 __ vmovsr(sresult2, TMP);
3512 break;
3513 case MethodRecognizer::kUint32x4WithFlagW:
3514 __ vmovsr(sresult3, TMP);
3515 break;
3516 default: UNREACHABLE();
3517 }
3311 } 3518 }
3312 3519
3313 3520
3314 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const { 3521 LocationSummary* Uint32x4ToFloat32x4Instr::MakeLocationSummary() const {
3315 UNIMPLEMENTED(); 3522 const intptr_t kNumInputs = 1;
3316 return NULL; 3523 const intptr_t kNumTemps = 0;
3524 LocationSummary* summary =
3525 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3526 summary->set_in(0, Location::RequiresFpuRegister());
3527 summary->set_out(Location::RequiresFpuRegister());
3528 return summary;
3317 } 3529 }
3318 3530
3319 3531
3320 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3532 void Uint32x4ToFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3321 UNIMPLEMENTED(); 3533 QRegister value = locs()->in(0).fpu_reg();
3534 QRegister result = locs()->out().fpu_reg();
3535
3536 if (value != result) {
3537 __ vmovq(result, value);
3538 }
3322 } 3539 }
3323 3540
3324 3541
3325 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const { 3542 LocationSummary* BinaryUint32x4OpInstr::MakeLocationSummary() const {
3326 UNIMPLEMENTED(); 3543 const intptr_t kNumInputs = 2;
3327 return NULL; 3544 const intptr_t kNumTemps = 0;
3545 LocationSummary* summary =
3546 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3547 summary->set_in(0, Location::RequiresFpuRegister());
3548 summary->set_in(1, Location::RequiresFpuRegister());
3549 summary->set_out(Location::RequiresFpuRegister());
3550 return summary;
3328 } 3551 }
3329 3552
3330 3553
3331 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3554 void BinaryUint32x4OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3332 UNIMPLEMENTED(); 3555 QRegister left = locs()->in(0).fpu_reg();
3556 QRegister right = locs()->in(1).fpu_reg();
3557 QRegister result = locs()->out().fpu_reg();
3558 switch (op_kind()) {
3559 case Token::kBIT_AND: {
3560 __ vandq(result, left, right);
3561 break;
3562 }
3563 case Token::kBIT_OR: {
3564 __ vorrq(result, left, right);
3565 break;
3566 }
3567 case Token::kBIT_XOR: {
3568 __ veorq(result, left, right);
3569 break;
3570 }
3571 default: UNREACHABLE();
3572 }
3333 } 3573 }
3334 3574
3335 3575
3336 LocationSummary* MathSqrtInstr::MakeLocationSummary() const { 3576 LocationSummary* MathSqrtInstr::MakeLocationSummary() const {
3337 const intptr_t kNumInputs = 1; 3577 const intptr_t kNumInputs = 1;
3338 const intptr_t kNumTemps = 0; 3578 const intptr_t kNumTemps = 0;
3339 LocationSummary* summary = 3579 LocationSummary* summary =
3340 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 3580 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
3341 summary->set_in(0, Location::RequiresFpuRegister()); 3581 summary->set_in(0, Location::RequiresFpuRegister());
3342 summary->set_out(Location::RequiresFpuRegister()); 3582 summary->set_out(Location::RequiresFpuRegister());
(...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after
4112 compiler->GenerateCall(token_pos(), 4352 compiler->GenerateCall(token_pos(),
4113 &label, 4353 &label,
4114 PcDescriptors::kOther, 4354 PcDescriptors::kOther,
4115 locs()); 4355 locs());
4116 __ Drop(2); // Discard type arguments and receiver. 4356 __ Drop(2); // Discard type arguments and receiver.
4117 } 4357 }
4118 4358
4119 } // namespace dart 4359 } // namespace dart
4120 4360
4121 #endif // defined TARGET_ARCH_ARM 4361 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/assembler_arm.cc ('k') | tests/lib/lib.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698