| 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 3059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3070 } else if (right_cid == kSmiCid) { | 3070 } else if (right_cid == kSmiCid) { |
| 3071 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); | 3071 __ andi(CMPRES1, left, Immediate(kSmiTagMask)); |
| 3072 } else { | 3072 } else { |
| 3073 __ or_(TMP, left, right); | 3073 __ or_(TMP, left, right); |
| 3074 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); | 3074 __ andi(CMPRES1, TMP, Immediate(kSmiTagMask)); |
| 3075 } | 3075 } |
| 3076 __ beq(CMPRES1, ZR, deopt); | 3076 __ beq(CMPRES1, ZR, deopt); |
| 3077 } | 3077 } |
| 3078 | 3078 |
| 3079 | 3079 |
| 3080 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3080 LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate, |
| 3081 bool opt) const { | 3081 bool opt) const { |
| 3082 const intptr_t kNumInputs = 1; | 3082 const intptr_t kNumInputs = 1; |
| 3083 const intptr_t kNumTemps = 1; | 3083 const intptr_t kNumTemps = 1; |
| 3084 LocationSummary* summary = new(isolate) LocationSummary( | 3084 LocationSummary* summary = new(isolate) LocationSummary( |
| 3085 isolate, kNumInputs, | 3085 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3086 kNumTemps, | |
| 3087 LocationSummary::kCallOnSlowPath); | |
| 3088 summary->set_in(0, Location::RequiresFpuRegister()); | 3086 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3089 summary->set_temp(0, Location::RequiresRegister()); | 3087 summary->set_temp(0, Location::RequiresRegister()); |
| 3090 summary->set_out(0, Location::RequiresRegister()); | 3088 summary->set_out(0, Location::RequiresRegister()); |
| 3091 return summary; | 3089 return summary; |
| 3092 } | 3090 } |
| 3093 | 3091 |
| 3094 | 3092 |
| 3095 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3093 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3094 ASSERT(from_representation() == kUnboxedDouble); |
| 3095 |
| 3096 Register out_reg = locs()->out(0).reg(); | 3096 Register out_reg = locs()->out(0).reg(); |
| 3097 DRegister value = locs()->in(0).fpu_reg(); | 3097 DRegister value = locs()->in(0).fpu_reg(); |
| 3098 | 3098 |
| 3099 BoxAllocationSlowPath::Allocate( | 3099 BoxAllocationSlowPath::Allocate( |
| 3100 compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg()); | 3100 compiler, this, compiler->double_class(), out_reg, locs()->temp(0).reg()); |
| 3101 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); | 3101 __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag); |
| 3102 } | 3102 } |
| 3103 | 3103 |
| 3104 | 3104 |
| 3105 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, | 3105 LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate, |
| 3106 bool opt) const { | 3106 bool opt) const { |
| 3107 const intptr_t kNumInputs = 1; | 3107 const intptr_t kNumInputs = 1; |
| 3108 const intptr_t kNumTemps = 0; | 3108 const intptr_t kNumTemps = 0; |
| 3109 LocationSummary* summary = new(isolate) LocationSummary( | 3109 LocationSummary* summary = new(isolate) LocationSummary( |
| 3110 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3110 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3111 summary->set_in(0, Location::RequiresRegister()); | 3111 summary->set_in(0, Location::RequiresRegister()); |
| 3112 summary->set_out(0, Location::RequiresFpuRegister()); | 3112 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3113 return summary; | 3113 return summary; |
| 3114 } | 3114 } |
| 3115 | 3115 |
| 3116 | 3116 |
| 3117 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3117 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) { |
| 3118 CompileType* value_type = value()->Type(); | 3118 const Register box = locs()->in(0).reg(); |
| 3119 const intptr_t value_cid = value_type->ToCid(); | 3119 |
| 3120 const Register value = locs()->in(0).reg(); | 3120 switch (representation()) { |
| 3121 const DRegister result = locs()->out(0).fpu_reg(); | 3121 case kUnboxedMint: { |
| 3122 | 3122 UNIMPLEMENTED(); |
| 3123 if (value_cid == kDoubleCid) { | 3123 break; |
| 3124 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); | 3124 } |
| 3125 } else if (value_cid == kSmiCid) { | 3125 |
| 3126 __ SmiUntag(TMP, value); | 3126 case kUnboxedDouble: { |
| 3127 __ mtc1(TMP, STMP1); | 3127 const DRegister result = locs()->out(0).fpu_reg(); |
| 3128 __ cvtdw(result, STMP1); | 3128 __ LoadDFromOffset(result, box, Double::value_offset() - kHeapObjectTag); |
| 3129 break; |
| 3130 } |
| 3131 |
| 3132 case kUnboxedFloat32x4: |
| 3133 case kUnboxedFloat64x2: |
| 3134 case kUnboxedInt32x4: { |
| 3135 UNIMPLEMENTED(); |
| 3136 break; |
| 3137 } |
| 3138 |
| 3139 default: |
| 3140 UNREACHABLE(); |
| 3141 break; |
| 3142 } |
| 3143 } |
| 3144 |
| 3145 |
| 3146 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) { |
| 3147 const Register box = locs()->in(0).reg(); |
| 3148 |
| 3149 switch (representation()) { |
| 3150 case kUnboxedMint: { |
| 3151 UNIMPLEMENTED(); |
| 3152 break; |
| 3153 } |
| 3154 |
| 3155 case kUnboxedDouble: { |
| 3156 const DRegister result = locs()->out(0).fpu_reg(); |
| 3157 __ SmiUntag(TMP, box); |
| 3158 __ mtc1(TMP, STMP1); |
| 3159 __ cvtdw(result, STMP1); |
| 3160 break; |
| 3161 } |
| 3162 |
| 3163 default: |
| 3164 UNREACHABLE(); |
| 3165 break; |
| 3166 } |
| 3167 } |
| 3168 |
| 3169 |
| 3170 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3171 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3172 const intptr_t box_cid = BoxCid(); |
| 3173 |
| 3174 if (value_cid == box_cid) { |
| 3175 EmitLoadFromBox(compiler); |
| 3176 } else if (CanConvertSmi() && (value_cid == kSmiCid)) { |
| 3177 EmitSmiConversion(compiler); |
| 3129 } else { | 3178 } else { |
| 3179 const Register box = locs()->in(0).reg(); |
| 3130 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), | 3180 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), |
| 3131 ICData::kDeoptBinaryDoubleOp); | 3181 ICData::kDeoptCheckClass); |
| 3132 if (value_type->is_nullable() && | 3182 Label is_smi; |
| 3133 (value_type->ToNullableCid() == kDoubleCid)) { | 3183 |
| 3134 __ BranchEqual(value, Object::null_object(), deopt); | 3184 if ((value()->Type()->ToNullableCid() == box_cid) && |
| 3135 // It must be double now. | 3185 value()->Type()->is_nullable()) { |
| 3136 __ LoadDFromOffset(result, value, | 3186 __ BranchEqual(box, Object::null_object(), deopt); |
| 3137 Double::value_offset() - kHeapObjectTag); | |
| 3138 } else { | 3187 } else { |
| 3139 Label is_smi, done; | 3188 __ andi(CMPRES1, box, Immediate(kSmiTagMask)); |
| 3140 | 3189 __ beq(CMPRES1, ZR, CanConvertSmi() ? &is_smi : deopt); |
| 3141 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | 3190 __ LoadClassId(CMPRES1, box); |
| 3142 __ beq(CMPRES1, ZR, &is_smi); | 3191 __ BranchNotEqual(CMPRES1, Immediate(box_cid), deopt); |
| 3143 __ LoadClassId(CMPRES1, value); | 3192 } |
| 3144 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), deopt); | 3193 |
| 3145 __ LoadDFromOffset(result, value, | 3194 EmitLoadFromBox(compiler); |
| 3146 Double::value_offset() - kHeapObjectTag); | 3195 |
| 3196 if (is_smi.IsLinked()) { |
| 3197 Label done; |
| 3147 __ b(&done); | 3198 __ b(&done); |
| 3148 __ Bind(&is_smi); | 3199 __ Bind(&is_smi); |
| 3149 __ SmiUntag(TMP, value); | 3200 EmitSmiConversion(compiler); |
| 3150 __ mtc1(TMP, STMP1); | |
| 3151 __ cvtdw(result, STMP1); | |
| 3152 __ Bind(&done); | 3201 __ Bind(&done); |
| 3153 } | 3202 } |
| 3154 } | 3203 } |
| 3155 } | 3204 } |
| 3156 | 3205 |
| 3157 | 3206 |
| 3158 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3207 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate, |
| 3159 bool opt) const { | 3208 bool opt) const { |
| 3160 UNIMPLEMENTED(); | 3209 ASSERT((from_representation() == kUnboxedInt32) || |
| 3161 return NULL; | 3210 (from_representation() == kUnboxedUint32)); |
| 3162 } | 3211 const intptr_t kNumInputs = 1; |
| 3163 | 3212 const intptr_t kNumTemps = 1; |
| 3164 | 3213 LocationSummary* summary = new(isolate) LocationSummary( |
| 3165 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3214 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); |
| 3166 UNIMPLEMENTED(); | 3215 summary->set_in(0, Location::RequiresRegister()); |
| 3167 } | 3216 summary->set_temp(0, Location::RequiresRegister()); |
| 3168 | 3217 summary->set_out(0, Location::RequiresRegister()); |
| 3169 | 3218 return summary; |
| 3170 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, | 3219 } |
| 3220 |
| 3221 |
| 3222 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3223 Register value = locs()->in(0).reg(); |
| 3224 Register out = locs()->out(0).reg(); |
| 3225 ASSERT(value != out); |
| 3226 |
| 3227 Label done; |
| 3228 __ SmiTag(out, value); |
| 3229 if (!ValueFitsSmi()) { |
| 3230 Register temp = locs()->temp(0).reg(); |
| 3231 if (from_representation() == kUnboxedInt32) { |
| 3232 __ SmiUntag(CMPRES1, out); |
| 3233 __ BranchEqual(CMPRES1, value, &done); |
| 3234 } else { |
| 3235 ASSERT(from_representation() == kUnboxedUint32); |
| 3236 __ AndImmediate(CMPRES1, value, 0xC0000000); |
| 3237 __ BranchEqual(CMPRES1, ZR, &done); |
| 3238 } |
| 3239 BoxAllocationSlowPath::Allocate( |
| 3240 compiler, |
| 3241 this, |
| 3242 compiler->mint_class(), |
| 3243 out, |
| 3244 temp); |
| 3245 Register hi; |
| 3246 if (from_representation() == kUnboxedInt32) { |
| 3247 hi = temp; |
| 3248 __ sra(hi, value, kBitsPerWord - 1); |
| 3249 } else { |
| 3250 ASSERT(from_representation() == kUnboxedUint32); |
| 3251 hi = ZR; |
| 3252 } |
| 3253 __ StoreToOffset(value, |
| 3254 out, |
| 3255 Mint::value_offset() - kHeapObjectTag); |
| 3256 __ StoreToOffset(hi, |
| 3257 out, |
| 3258 Mint::value_offset() - kHeapObjectTag + kWordSize); |
| 3259 __ Bind(&done); |
| 3260 } |
| 3261 } |
| 3262 |
| 3263 |
| 3264 DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt64Instr); |
| 3265 |
| 3266 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate, |
| 3171 bool opt) const { | 3267 bool opt) const { |
| 3172 UNIMPLEMENTED(); | 3268 ASSERT((representation() == kUnboxedInt32) || |
| 3173 return NULL; | 3269 (representation() == kUnboxedUint32)); |
| 3174 } | 3270 const intptr_t kNumInputs = 1; |
| 3175 | 3271 const intptr_t kNumTemps = 0; |
| 3176 | 3272 LocationSummary* summary = new(isolate) LocationSummary( |
| 3177 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3273 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3178 UNIMPLEMENTED(); | 3274 summary->set_in(0, Location::RequiresRegister()); |
| 3179 } | 3275 summary->set_out(0, Location::RequiresRegister()); |
| 3180 | 3276 return summary; |
| 3181 | 3277 } |
| 3182 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | 3278 |
| 3183 bool opt) const { | 3279 |
| 3184 UNIMPLEMENTED(); | 3280 static void LoadInt32FromMint(FlowGraphCompiler* compiler, |
| 3185 return NULL; | 3281 Register mint, |
| 3186 } | 3282 Register result, |
| 3187 | 3283 Label* deopt) { |
| 3188 | 3284 __ LoadFromOffset(result, |
| 3189 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3285 mint, |
| 3190 UNIMPLEMENTED(); | 3286 Mint::value_offset() - kHeapObjectTag); |
| 3191 } | 3287 if (deopt != NULL) { |
| 3192 | 3288 __ LoadFromOffset(CMPRES1, |
| 3193 | 3289 mint, |
| 3194 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, | 3290 Mint::value_offset() - kHeapObjectTag + kWordSize); |
| 3195 bool opt) const { | 3291 __ sra(CMPRES2, result, kBitsPerWord - 1); |
| 3196 UNIMPLEMENTED(); | 3292 __ BranchNotEqual(CMPRES1, CMPRES2, deopt); |
| 3197 return NULL; | 3293 } |
| 3198 } | 3294 } |
| 3199 | 3295 |
| 3200 | 3296 |
| 3201 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3297 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 3202 UNIMPLEMENTED(); | 3298 const intptr_t value_cid = value()->Type()->ToCid(); |
| 3203 } | 3299 const Register value = locs()->in(0).reg(); |
| 3204 | 3300 const Register out = locs()->out(0).reg(); |
| 3205 | 3301 Label* deopt = CanDeoptimize() ? |
| 3206 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3302 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; |
| 3207 bool opt) const { | 3303 Label* out_of_range = !is_truncating() ? deopt : NULL; |
| 3208 UNIMPLEMENTED(); | 3304 ASSERT(value != out); |
| 3209 return NULL; | 3305 |
| 3210 } | 3306 if (value_cid == kSmiCid) { |
| 3211 | 3307 __ SmiUntag(out, value); |
| 3212 | 3308 } else if (value_cid == kMintCid) { |
| 3213 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3309 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 3214 UNIMPLEMENTED(); | 3310 } else { |
| 3215 } | 3311 Label done; |
| 3216 | 3312 __ SmiUntag(out, value); |
| 3217 | 3313 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); |
| 3218 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate, | 3314 __ beq(CMPRES1, ZR, &done); |
| 3219 bool opt) const { | 3315 __ LoadClassId(CMPRES1, value); |
| 3220 UNIMPLEMENTED(); | 3316 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt); |
| 3221 return NULL; | 3317 LoadInt32FromMint(compiler, value, out, out_of_range); |
| 3222 } | 3318 __ Bind(&done); |
| 3223 | 3319 } |
| 3224 | 3320 } |
| 3225 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3321 |
| 3226 UNIMPLEMENTED(); | 3322 |
| 3227 } | |
| 3228 | |
| 3229 | |
| 3230 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, | 3323 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, |
| 3231 bool opt) const { | 3324 bool opt) const { |
| 3232 const intptr_t kNumInputs = 2; | 3325 const intptr_t kNumInputs = 2; |
| 3233 const intptr_t kNumTemps = 0; | 3326 const intptr_t kNumTemps = 0; |
| 3234 LocationSummary* summary = new(isolate) LocationSummary( | 3327 LocationSummary* summary = new(isolate) LocationSummary( |
| 3235 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3328 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3236 summary->set_in(0, Location::RequiresFpuRegister()); | 3329 summary->set_in(0, Location::RequiresFpuRegister()); |
| 3237 summary->set_in(1, Location::RequiresFpuRegister()); | 3330 summary->set_in(1, Location::RequiresFpuRegister()); |
| 3238 summary->set_out(0, Location::RequiresFpuRegister()); | 3331 summary->set_out(0, Location::RequiresFpuRegister()); |
| 3239 return summary; | 3332 return summary; |
| (...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4483 __ BranchUnsignedGreaterEqual( | 4576 __ BranchUnsignedGreaterEqual( |
| 4484 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); | 4577 index, Immediate(reinterpret_cast<int32_t>(length.raw())), deopt); |
| 4485 } | 4578 } |
| 4486 } else { | 4579 } else { |
| 4487 Register length = length_loc.reg(); | 4580 Register length = length_loc.reg(); |
| 4488 Register index = index_loc.reg(); | 4581 Register index = index_loc.reg(); |
| 4489 __ BranchUnsignedGreaterEqual(index, length, deopt); | 4582 __ BranchUnsignedGreaterEqual(index, length, deopt); |
| 4490 } | 4583 } |
| 4491 } | 4584 } |
| 4492 | 4585 |
| 4493 | 4586 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryMintOpInstr); |
| 4494 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 4495 bool opt) const { | |
| 4496 UNIMPLEMENTED(); | |
| 4497 return NULL; | |
| 4498 } | |
| 4499 | |
| 4500 | |
| 4501 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4502 UNIMPLEMENTED(); | |
| 4503 } | |
| 4504 | |
| 4505 | |
| 4506 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate, | |
| 4507 bool opt) const { | |
| 4508 UNIMPLEMENTED(); | |
| 4509 return NULL; | |
| 4510 } | |
| 4511 | |
| 4512 | |
| 4513 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4514 UNIMPLEMENTED(); | |
| 4515 } | |
| 4516 | |
| 4517 | |
| 4518 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | |
| 4519 bool opt) const { | |
| 4520 UNIMPLEMENTED(); | |
| 4521 return NULL; | |
| 4522 } | |
| 4523 | |
| 4524 | |
| 4525 void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4526 UNIMPLEMENTED(); | |
| 4527 } | |
| 4528 | |
| 4529 | 4587 |
| 4530 bool ShiftMintOpInstr::has_shift_count_check() const { | 4588 bool ShiftMintOpInstr::has_shift_count_check() const { |
| 4531 UNREACHABLE(); | 4589 UNREACHABLE(); |
| 4532 return false; | 4590 return false; |
| 4533 } | 4591 } |
| 4534 | 4592 |
| 4535 | 4593 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftMintOpInstr); |
| 4536 LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate, | 4594 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryMintOpInstr); |
| 4537 bool opt) const { | |
| 4538 UNIMPLEMENTED(); | |
| 4539 return NULL; | |
| 4540 } | |
| 4541 | |
| 4542 | |
| 4543 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4544 UNIMPLEMENTED(); | |
| 4545 } | |
| 4546 | |
| 4547 | |
| 4548 LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate, | |
| 4549 bool opt) const { | |
| 4550 UNIMPLEMENTED(); | |
| 4551 return NULL; | |
| 4552 } | |
| 4553 | |
| 4554 | |
| 4555 void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4556 UNIMPLEMENTED(); | |
| 4557 } | |
| 4558 | |
| 4559 | 4595 |
| 4560 CompileType BinaryUint32OpInstr::ComputeType() const { | 4596 CompileType BinaryUint32OpInstr::ComputeType() const { |
| 4561 return CompileType::Int(); | 4597 return CompileType::Int(); |
| 4562 } | 4598 } |
| 4563 | 4599 |
| 4564 | 4600 |
| 4565 CompileType ShiftUint32OpInstr::ComputeType() const { | 4601 CompileType ShiftUint32OpInstr::ComputeType() const { |
| 4566 return CompileType::Int(); | 4602 return CompileType::Int(); |
| 4567 } | 4603 } |
| 4568 | 4604 |
| 4569 | 4605 |
| 4570 CompileType UnaryUint32OpInstr::ComputeType() const { | 4606 CompileType UnaryUint32OpInstr::ComputeType() const { |
| 4571 return CompileType::Int(); | 4607 return CompileType::Int(); |
| 4572 } | 4608 } |
| 4573 | 4609 |
| 4574 | 4610 |
| 4575 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) | 4611 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryUint32OpInstr) |
| 4576 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) | 4612 DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftUint32OpInstr) |
| 4577 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) | 4613 DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryUint32OpInstr) |
| 4578 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) | 4614 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) |
| 4579 | 4615 |
| 4580 | 4616 |
| 4581 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 4582 bool opt) const { | |
| 4583 ASSERT((from_representation() == kUnboxedInt32) || | |
| 4584 (from_representation() == kUnboxedUint32)); | |
| 4585 const intptr_t kNumInputs = 1; | |
| 4586 const intptr_t kNumTemps = 1; | |
| 4587 LocationSummary* summary = new(isolate) LocationSummary( | |
| 4588 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath); | |
| 4589 summary->set_in(0, Location::RequiresRegister()); | |
| 4590 summary->set_temp(0, Location::RequiresRegister()); | |
| 4591 summary->set_out(0, Location::RequiresRegister()); | |
| 4592 return summary; | |
| 4593 } | |
| 4594 | |
| 4595 | |
| 4596 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4597 Register value = locs()->in(0).reg(); | |
| 4598 Register out = locs()->out(0).reg(); | |
| 4599 ASSERT(value != out); | |
| 4600 | |
| 4601 Label done; | |
| 4602 __ SmiTag(out, value); | |
| 4603 if (!ValueFitsSmi()) { | |
| 4604 Register temp = locs()->temp(0).reg(); | |
| 4605 if (from_representation() == kUnboxedInt32) { | |
| 4606 __ SmiUntag(CMPRES1, out); | |
| 4607 __ BranchEqual(CMPRES1, value, &done); | |
| 4608 } else { | |
| 4609 ASSERT(from_representation() == kUnboxedUint32); | |
| 4610 __ AndImmediate(CMPRES1, value, 0xC0000000); | |
| 4611 __ BranchEqual(CMPRES1, ZR, &done); | |
| 4612 } | |
| 4613 BoxAllocationSlowPath::Allocate( | |
| 4614 compiler, | |
| 4615 this, | |
| 4616 compiler->mint_class(), | |
| 4617 out, | |
| 4618 temp); | |
| 4619 Register hi; | |
| 4620 if (from_representation() == kUnboxedInt32) { | |
| 4621 hi = temp; | |
| 4622 __ sra(hi, value, kBitsPerWord - 1); | |
| 4623 } else { | |
| 4624 ASSERT(from_representation() == kUnboxedUint32); | |
| 4625 hi = ZR; | |
| 4626 } | |
| 4627 __ StoreToOffset(value, | |
| 4628 out, | |
| 4629 Mint::value_offset() - kHeapObjectTag); | |
| 4630 __ StoreToOffset(hi, | |
| 4631 out, | |
| 4632 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 4633 __ Bind(&done); | |
| 4634 } | |
| 4635 } | |
| 4636 | |
| 4637 | |
| 4638 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, | |
| 4639 bool opt) const { | |
| 4640 ASSERT((representation() == kUnboxedInt32) || | |
| 4641 (representation() == kUnboxedUint32)); | |
| 4642 const intptr_t kNumInputs = 1; | |
| 4643 const intptr_t kNumTemps = 0; | |
| 4644 LocationSummary* summary = new(isolate) LocationSummary( | |
| 4645 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
| 4646 summary->set_in(0, Location::RequiresRegister()); | |
| 4647 summary->set_out(0, Location::RequiresRegister()); | |
| 4648 return summary; | |
| 4649 } | |
| 4650 | |
| 4651 | |
| 4652 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | |
| 4653 Register mint, | |
| 4654 Register result, | |
| 4655 Label* deopt) { | |
| 4656 __ LoadFromOffset(result, | |
| 4657 mint, | |
| 4658 Mint::value_offset() - kHeapObjectTag); | |
| 4659 if (deopt != NULL) { | |
| 4660 __ LoadFromOffset(CMPRES1, | |
| 4661 mint, | |
| 4662 Mint::value_offset() - kHeapObjectTag + kWordSize); | |
| 4663 __ sra(CMPRES2, result, kBitsPerWord - 1); | |
| 4664 __ BranchNotEqual(CMPRES1, CMPRES2, deopt); | |
| 4665 } | |
| 4666 } | |
| 4667 | |
| 4668 | |
| 4669 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 4670 const intptr_t value_cid = value()->Type()->ToCid(); | |
| 4671 const Register value = locs()->in(0).reg(); | |
| 4672 const Register out = locs()->out(0).reg(); | |
| 4673 Label* deopt = CanDeoptimize() ? | |
| 4674 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL; | |
| 4675 Label* out_of_range = !is_truncating() ? deopt : NULL; | |
| 4676 ASSERT(value != out); | |
| 4677 | |
| 4678 if (value_cid == kSmiCid) { | |
| 4679 __ SmiUntag(out, value); | |
| 4680 } else if (value_cid == kMintCid) { | |
| 4681 LoadInt32FromMint(compiler, value, out, out_of_range); | |
| 4682 } else { | |
| 4683 Label done; | |
| 4684 __ SmiUntag(out, value); | |
| 4685 __ andi(CMPRES1, value, Immediate(kSmiTagMask)); | |
| 4686 __ beq(CMPRES1, ZR, &done); | |
| 4687 __ LoadClassId(CMPRES1, value); | |
| 4688 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt); | |
| 4689 LoadInt32FromMint(compiler, value, out, out_of_range); | |
| 4690 __ Bind(&done); | |
| 4691 } | |
| 4692 } | |
| 4693 | |
| 4694 | |
| 4695 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 4617 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
| 4696 bool opt) const { | 4618 bool opt) const { |
| 4697 const intptr_t kNumInputs = 1; | 4619 const intptr_t kNumInputs = 1; |
| 4698 const intptr_t kNumTemps = 0; | 4620 const intptr_t kNumTemps = 0; |
| 4699 LocationSummary* summary = new(isolate) LocationSummary( | 4621 LocationSummary* summary = new(isolate) LocationSummary( |
| 4700 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4622 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 4701 if (from() == kUnboxedMint) { | 4623 if (from() == kUnboxedMint) { |
| 4702 UNREACHABLE(); | 4624 UNREACHABLE(); |
| 4703 } else if (to() == kUnboxedMint) { | 4625 } else if (to() == kUnboxedMint) { |
| 4704 UNREACHABLE(); | 4626 UNREACHABLE(); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4944 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 4866 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
| 4945 #if defined(DEBUG) | 4867 #if defined(DEBUG) |
| 4946 __ LoadImmediate(S4, kInvalidObjectPointer); | 4868 __ LoadImmediate(S4, kInvalidObjectPointer); |
| 4947 __ LoadImmediate(S5, kInvalidObjectPointer); | 4869 __ LoadImmediate(S5, kInvalidObjectPointer); |
| 4948 #endif | 4870 #endif |
| 4949 } | 4871 } |
| 4950 | 4872 |
| 4951 } // namespace dart | 4873 } // namespace dart |
| 4952 | 4874 |
| 4953 #endif // defined TARGET_ARCH_MIPS | 4875 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |