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

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

Issue 670263007: IR refactoring: consolidate all boxing and unboxing instructions. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.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" // 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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698