| 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" // 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |