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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_mips.cc ('k') | runtime/vm/intrinsifier.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 3176 matching lines...) Expand 10 before | Expand all | Expand 10 after
3187 } else { 3187 } else {
3188 Register temp = locs()->temp(0).reg(); 3188 Register temp = locs()->temp(0).reg();
3189 __ movq(temp, left); 3189 __ movq(temp, left);
3190 __ orq(temp, right); 3190 __ orq(temp, right);
3191 __ testq(temp, Immediate(kSmiTagMask)); 3191 __ testq(temp, Immediate(kSmiTagMask));
3192 } 3192 }
3193 __ j(ZERO, deopt); 3193 __ j(ZERO, deopt);
3194 } 3194 }
3195 3195
3196 3196
3197 LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3197 LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
3198 bool opt) const { 3198 bool opt) const {
3199 const intptr_t kNumInputs = 1; 3199 const intptr_t kNumInputs = 1;
3200 const intptr_t kNumTemps = 0; 3200 const intptr_t kNumTemps = 0;
3201 LocationSummary* summary = new(isolate) LocationSummary( 3201 LocationSummary* summary = new(isolate) LocationSummary(
3202 isolate, kNumInputs, 3202 isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
3203 kNumTemps,
3204 LocationSummary::kCallOnSlowPath);
3205 summary->set_in(0, Location::RequiresFpuRegister()); 3203 summary->set_in(0, Location::RequiresFpuRegister());
3206 summary->set_out(0, Location::RequiresRegister()); 3204 summary->set_out(0, Location::RequiresRegister());
3207 return summary; 3205 return summary;
3208 } 3206 }
3209 3207
3210 3208
3211 void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3209 void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3212 Register out_reg = locs()->out(0).reg(); 3210 Register out_reg = locs()->out(0).reg();
3213 XmmRegister value = locs()->in(0).fpu_reg(); 3211 XmmRegister value = locs()->in(0).fpu_reg();
3214 3212
3215 BoxAllocationSlowPath::Allocate( 3213 BoxAllocationSlowPath::Allocate(
3216 compiler, this, compiler->double_class(), out_reg); 3214 compiler, this, compiler->BoxClassFor(from_representation()), out_reg);
3217 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); 3215 __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
3218 } 3216 switch (from_representation()) {
3219 3217 case kUnboxedDouble:
3220 3218 __ movsd(FieldAddress(out_reg, ValueOffset()), value);
3221 LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate, 3219 break;
3222 bool opt) const { 3220 case kUnboxedFloat32x4:
3223 const intptr_t kNumInputs = 1; 3221 case kUnboxedFloat64x2:
3224 const intptr_t kNumTemps = 0; 3222 case kUnboxedInt32x4:
3223 __ movups(FieldAddress(out_reg, ValueOffset()), value);
3224 break;
3225 default:
3226 UNREACHABLE();
3227 break;
3228 }
3229 }
3230
3231
3232 LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
3233 bool opt) const {
3234 const intptr_t kNumInputs = 1;
3235 const intptr_t kNumTemps = 0;
3236 const bool needs_writable_input =
3237 (representation() != kUnboxedMint) &&
3238 (value()->Type()->ToNullableCid() != BoxCid());
3225 LocationSummary* summary = new(isolate) LocationSummary( 3239 LocationSummary* summary = new(isolate) LocationSummary(
3226 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3240 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3227 const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid); 3241 summary->set_in(0, needs_writable_input ? Location::WritableRegister()
3228 summary->set_in(0, needs_writable_input 3242 : Location::RequiresRegister());
3229 ? Location::WritableRegister() 3243 if (representation() == kUnboxedMint) {
3230 : Location::RequiresRegister()); 3244 summary->set_out(0, Location::SameAsFirstInput());
3231 summary->set_out(0, Location::RequiresFpuRegister()); 3245 } else {
3232 return summary; 3246 summary->set_out(0, Location::RequiresFpuRegister());
3233 } 3247 }
3234 3248 return summary;
3235 3249 }
3236 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3250
3237 CompileType* value_type = value()->Type(); 3251
3238 const intptr_t value_cid = value_type->ToCid(); 3252 void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
3239 const Register value = locs()->in(0).reg(); 3253 const Register box = locs()->in(0).reg();
3240 const XmmRegister result = locs()->out(0).fpu_reg(); 3254
3241 3255 switch (representation()) {
3242 if (value_cid == kDoubleCid) { 3256 case kUnboxedMint: {
3243 __ movsd(result, FieldAddress(value, Double::value_offset())); 3257 const Register result = locs()->out(0).reg();
3244 } else if (value_cid == kSmiCid) { 3258 __ movq(result, FieldAddress(box, ValueOffset()));
3245 __ SmiUntag(value); // Untag input before conversion. 3259 break;
3246 __ cvtsi2sdq(result, value); 3260 }
3247 } else { 3261
3262 case kUnboxedDouble: {
3263 const FpuRegister result = locs()->out(0).fpu_reg();
3264 __ movsd(result, FieldAddress(box, ValueOffset()));
3265 break;
3266 }
3267
3268 case kUnboxedFloat32x4:
3269 case kUnboxedFloat64x2:
3270 case kUnboxedInt32x4: {
3271 const FpuRegister result = locs()->out(0).fpu_reg();
3272 __ movups(result, FieldAddress(box, ValueOffset()));
3273 break;
3274 }
3275
3276 default:
3277 UNREACHABLE();
3278 break;
3279 }
3280 }
3281
3282
3283 void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
3284 const Register box = locs()->in(0).reg();
3285
3286 switch (representation()) {
3287 case kUnboxedMint: {
3288 const Register result = locs()->out(0).reg();
3289 ASSERT(result == box);
3290 __ SmiUntag(box);
3291 break;
3292 }
3293
3294 case kUnboxedDouble: {
3295 const FpuRegister result = locs()->out(0).fpu_reg();
3296 __ SmiUntag(box);
3297 __ cvtsi2sdq(result, box);
3298 break;
3299 }
3300
3301 default:
3302 UNREACHABLE();
3303 break;
3304 }
3305 }
3306
3307
3308 void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3309 const intptr_t value_cid = value()->Type()->ToCid();
3310 const intptr_t box_cid = BoxCid();
3311
3312 if (value_cid == box_cid) {
3313 EmitLoadFromBox(compiler);
3314 } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
3315 EmitSmiConversion(compiler);
3316 } else {
3317 const Register box = locs()->in(0).reg();
3248 Label* deopt = compiler->AddDeoptStub(GetDeoptId(), 3318 Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
3249 ICData::kDeoptBinaryDoubleOp); 3319 ICData::kDeoptCheckClass);
3250 if (value_type->is_nullable() && 3320 Label is_smi;
3251 (value_type->ToNullableCid() == kDoubleCid)) { 3321
3322 if ((value()->Type()->ToNullableCid() == box_cid) &&
3323 value()->Type()->is_nullable()) {
3252 const Immediate& raw_null = 3324 const Immediate& raw_null =
3253 Immediate(reinterpret_cast<intptr_t>(Object::null())); 3325 Immediate(reinterpret_cast<intptr_t>(Object::null()));
3254 __ cmpq(value, raw_null); 3326 __ cmpq(box, raw_null);
3255 __ j(EQUAL, deopt); 3327 __ j(EQUAL, deopt);
3256 // It must be double now.
3257 __ movsd(result, FieldAddress(value, Double::value_offset()));
3258 } else { 3328 } else {
3259 Label is_smi, done; 3329 __ testq(box, Immediate(kSmiTagMask));
3260 __ testq(value, Immediate(kSmiTagMask)); 3330 __ j(ZERO, CanConvertSmi() ? &is_smi : deopt);
3261 __ j(ZERO, &is_smi); 3331 __ CompareClassId(box, box_cid);
3262 __ CompareClassId(value, kDoubleCid);
3263 __ j(NOT_EQUAL, deopt); 3332 __ j(NOT_EQUAL, deopt);
3264 __ movsd(result, FieldAddress(value, Double::value_offset())); 3333 }
3334
3335 EmitLoadFromBox(compiler);
3336
3337 if (is_smi.IsLinked()) {
3338 Label done;
3265 __ jmp(&done); 3339 __ jmp(&done);
3266 __ Bind(&is_smi); 3340 __ Bind(&is_smi);
3267 __ SmiUntag(value); 3341 EmitSmiConversion(compiler);
3268 __ cvtsi2sdq(result, value);
3269 __ Bind(&done); 3342 __ Bind(&done);
3270 } 3343 }
3271 } 3344 }
3272 } 3345 }
3273 3346
3274 3347
3275 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3348 LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
3276 bool opt) const {
3277 const intptr_t kNumInputs = 1;
3278 const intptr_t kNumTemps = 0;
3279 LocationSummary* summary = new(isolate) LocationSummary(
3280 isolate, kNumInputs,
3281 kNumTemps,
3282 LocationSummary::kCallOnSlowPath);
3283 summary->set_in(0, Location::RequiresFpuRegister());
3284 summary->set_out(0, Location::RequiresRegister());
3285 return summary;
3286 }
3287
3288
3289 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3290 Register out_reg = locs()->out(0).reg();
3291 XmmRegister value = locs()->in(0).fpu_reg();
3292
3293 BoxAllocationSlowPath::Allocate(
3294 compiler, this, compiler->float32x4_class(), out_reg);
3295 __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
3296 }
3297
3298
3299 LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
3300 bool opt) const { 3349 bool opt) const {
3301 const intptr_t kNumInputs = 1; 3350 const intptr_t kNumInputs = 1;
3302 return LocationSummary::Make(isolate, 3351 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
3303 kNumInputs, 3352 LocationSummary* summary = new(isolate) LocationSummary(
3304 Location::RequiresFpuRegister(), 3353 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3305 LocationSummary::kNoCall); 3354 summary->set_in(0, Location::RequiresRegister());
3306 } 3355 summary->set_out(0, Location::SameAsFirstInput());
3307 3356 if (kNumTemps > 0) {
3308 3357 summary->set_temp(0, Location::RequiresRegister());
3309 void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3358 }
3359 return summary;
3360 }
3361
3362
3363 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3310 const intptr_t value_cid = value()->Type()->ToCid(); 3364 const intptr_t value_cid = value()->Type()->ToCid();
3311 const Register value = locs()->in(0).reg(); 3365 const Register value = locs()->in(0).reg();
3312 const XmmRegister result = locs()->out(0).fpu_reg(); 3366 Label* deopt = CanDeoptimize() ?
3313 3367 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
3314 if (value_cid != kFloat32x4Cid) { 3368 ASSERT(value == locs()->out(0).reg());
3315 Label* deopt = 3369
3316 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass); 3370 if (value_cid == kSmiCid) {
3317 __ testq(value, Immediate(kSmiTagMask)); 3371 __ SmiUntag(value);
3318 __ j(ZERO, deopt); 3372 } else if (value_cid == kMintCid) {
3319 __ CompareClassId(value, kFloat32x4Cid); 3373 __ movq(value, FieldAddress(value, Mint::value_offset()));
3374 } else {
3375 Label done;
3376 // Optimistically untag value.
3377 __ SmiUntagOrCheckClass(value, kMintCid, &done);
3320 __ j(NOT_EQUAL, deopt); 3378 __ j(NOT_EQUAL, deopt);
3321 } 3379 // Undo untagging by multiplying value with 2.
3322 __ movups(result, FieldAddress(value, Float32x4::value_offset())); 3380 __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
3323 } 3381 __ Bind(&done);
3324 3382 }
3325 3383
3326 LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, 3384 // TODO(vegorov): as it is implemented right now truncating unboxing would
3327 bool opt) const { 3385 // leave "garbage" in the higher word.
3328 const intptr_t kNumInputs = 1; 3386 if (!is_truncating() && (deopt != NULL)) {
3329 const intptr_t kNumTemps = 0; 3387 ASSERT(representation() == kUnboxedInt32);
3330 LocationSummary* summary = new(isolate) LocationSummary( 3388 Register temp = locs()->temp(0).reg();
3331 isolate, kNumInputs, 3389 __ movsxd(temp, value);
3332 kNumTemps, 3390 __ cmpq(temp, value);
3333 LocationSummary::kCallOnSlowPath); 3391 __ j(NOT_EQUAL, deopt);
3334 summary->set_in(0, Location::RequiresFpuRegister()); 3392 }
3393 }
3394
3395
3396 LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
3397 bool opt) const {
3398 ASSERT((from_representation() == kUnboxedInt32) ||
3399 (from_representation() == kUnboxedUint32));
3400 const intptr_t kNumInputs = 1;
3401 const intptr_t kNumTemps = 0;
3402 LocationSummary* summary = new(isolate) LocationSummary(
3403 isolate,
3404 kNumInputs,
3405 kNumTemps,
3406 LocationSummary::kNoCall);
3407 summary->set_in(0, Location::RequiresRegister());
3335 summary->set_out(0, Location::RequiresRegister()); 3408 summary->set_out(0, Location::RequiresRegister());
3336 return summary; 3409 return summary;
3337 } 3410 }
3338 3411
3339 3412
3340 void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3413 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3341 Register out_reg = locs()->out(0).reg(); 3414 const Register value = locs()->in(0).reg();
3342 XmmRegister value = locs()->in(0).fpu_reg(); 3415 const Register out = locs()->out(0).reg();
3343 3416 ASSERT(value != out);
3344 BoxAllocationSlowPath::Allocate( 3417
3345 compiler, this, compiler->float64x2_class(), out_reg); 3418 ASSERT(kSmiTagSize == 1);
3346 __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value); 3419 if (from_representation() == kUnboxedInt32) {
3347 } 3420 __ movsxd(out, value);
3348 3421 } else {
3349 3422 ASSERT(from_representation() == kUnboxedUint32);
3350 LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate, 3423 __ movl(out, value);
3351 bool opt) const { 3424 }
3352 const intptr_t value_cid = value()->Type()->ToCid(); 3425 __ SmiTag(out);
3353 const intptr_t kNumInputs = 1; 3426 }
3354 const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1; 3427
3355 LocationSummary* summary = new(isolate) LocationSummary( 3428
3356 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3429 LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate,
3430 bool opt) const {
3431 const intptr_t kNumInputs = 1;
3432 const intptr_t kNumTemps = 0;
3433 LocationSummary* summary = new(isolate) LocationSummary(
3434 isolate,
3435 kNumInputs,
3436 kNumTemps,
3437 ValueFitsSmi() ? LocationSummary::kNoCall
3438 : LocationSummary::kCallOnSlowPath);
3357 summary->set_in(0, Location::RequiresRegister()); 3439 summary->set_in(0, Location::RequiresRegister());
3358 summary->set_out(0, Location::RequiresFpuRegister()); 3440 summary->set_out(0, Location::RequiresRegister());
3359 return summary; 3441 return summary;
3360 } 3442 }
3361 3443
3362 3444
3363 void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) { 3445 void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3364 const intptr_t value_cid = value()->Type()->ToCid(); 3446 const Register out = locs()->out(0).reg();
3365 const Register value = locs()->in(0).reg(); 3447 const Register value = locs()->in(0).reg();
3366 const XmmRegister result = locs()->out(0).fpu_reg(); 3448 __ MoveRegister(out, value);
3367 3449 __ SmiTag(out);
3368 if (value_cid != kFloat64x2Cid) { 3450 if (!ValueFitsSmi()) {
3369 Label* deopt = 3451 Label done;
3370 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass); 3452 __ j(NO_OVERFLOW, &done);
3371 __ testq(value, Immediate(kSmiTagMask)); 3453 BoxAllocationSlowPath::Allocate(
3372 __ j(ZERO, deopt); 3454 compiler, this, compiler->mint_class(), out);
3373 __ CompareClassId(value, kFloat64x2Cid); 3455 __ movq(FieldAddress(out, Mint::value_offset()), value);
3374 __ j(NOT_EQUAL, deopt); 3456 __ Bind(&done);
3375 } 3457 }
3376 __ movups(result, FieldAddress(value, Float64x2::value_offset())); 3458 }
3377 } 3459
3378 3460
3379
3380 LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
3381 bool opt) const {
3382 const intptr_t kNumInputs = 1;
3383 const intptr_t kNumTemps = 0;
3384 LocationSummary* summary = new(isolate) LocationSummary(
3385 isolate, kNumInputs,
3386 kNumTemps,
3387 LocationSummary::kCallOnSlowPath);
3388 summary->set_in(0, Location::RequiresFpuRegister());
3389 summary->set_out(0, Location::RequiresRegister());
3390 return summary;
3391 }
3392
3393
3394 void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3395 Register out_reg = locs()->out(0).reg();
3396 XmmRegister value = locs()->in(0).fpu_reg();
3397
3398 BoxAllocationSlowPath::Allocate(
3399 compiler, this, compiler->int32x4_class(), out_reg);
3400 __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
3401 }
3402
3403
3404 LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
3405 bool opt) const {
3406 const intptr_t kNumInputs = 1;
3407 const intptr_t kNumTemps = 0;
3408 LocationSummary* summary = new(isolate) LocationSummary(
3409 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3410 summary->set_in(0, Location::RequiresRegister());
3411 summary->set_out(0, Location::RequiresFpuRegister());
3412 return summary;
3413 }
3414
3415
3416 void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
3417 const intptr_t value_cid = value()->Type()->ToCid();
3418 const Register value = locs()->in(0).reg();
3419 const XmmRegister result = locs()->out(0).fpu_reg();
3420
3421 if (value_cid != kInt32x4Cid) {
3422 Label* deopt =
3423 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
3424 __ testq(value, Immediate(kSmiTagMask));
3425 __ j(ZERO, deopt);
3426 __ CompareClassId(value, kInt32x4Cid);
3427 __ j(NOT_EQUAL, deopt);
3428 }
3429 __ movups(result, FieldAddress(value, Int32x4::value_offset()));
3430 }
3431
3432
3433 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate, 3461 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate,
3434 bool opt) const { 3462 bool opt) const {
3435 const intptr_t kNumInputs = 2; 3463 const intptr_t kNumInputs = 2;
3436 const intptr_t kNumTemps = 0; 3464 const intptr_t kNumTemps = 0;
3437 LocationSummary* summary = new(isolate) LocationSummary( 3465 LocationSummary* summary = new(isolate) LocationSummary(
3438 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 3466 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
3439 summary->set_in(0, Location::RequiresFpuRegister()); 3467 summary->set_in(0, Location::RequiresFpuRegister());
3440 summary->set_in(1, Location::RequiresFpuRegister()); 3468 summary->set_in(1, Location::RequiresFpuRegister());
3441 summary->set_out(0, Location::SameAsFirstInput()); 3469 summary->set_out(0, Location::SameAsFirstInput());
3442 return summary; 3470 return summary;
(...skipping 2082 matching lines...) Expand 10 before | Expand all | Expand 10 after
5525 } 5553 }
5526 } else { 5554 } else {
5527 Register length = length_loc.reg(); 5555 Register length = length_loc.reg();
5528 Register index = index_loc.reg(); 5556 Register index = index_loc.reg();
5529 __ cmpq(index, length); 5557 __ cmpq(index, length);
5530 __ j(ABOVE_EQUAL, deopt); 5558 __ j(ABOVE_EQUAL, deopt);
5531 } 5559 }
5532 } 5560 }
5533 5561
5534 5562
5535 LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5536 bool opt) const {
5537 const intptr_t kNumInputs = 1;
5538 const intptr_t kNumTemps = 0;
5539 LocationSummary* locs = new(isolate) LocationSummary(
5540 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5541 locs->set_in(0, Location::RequiresRegister());
5542 locs->set_out(0, Location::SameAsFirstInput());
5543 return locs;
5544 }
5545
5546
5547 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5548 const intptr_t value_cid = value()->Type()->ToCid();
5549 const Register value = locs()->in(0).reg();
5550 const Register result = locs()->out(0).reg();
5551 ASSERT(value == result);
5552
5553 if (value_cid == kMintCid) {
5554 __ movq(result, FieldAddress(value, Mint::value_offset()));
5555 } else if (value_cid == kSmiCid) {
5556 __ SmiUntag(result);
5557 } else {
5558 Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
5559 ICData::kDeoptUnboxInteger);
5560 Label done;
5561 __ SmiUntagOrCheckClass(value, kMintCid, &done);
5562 __ j(NOT_EQUAL, deopt);
5563 // Undo untagging by multiplying value with 2.
5564 __ movq(result, Address(value, TIMES_2, Mint::value_offset()));
5565 __ Bind(&done);
5566 }
5567 }
5568
5569
5570 LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
5571 bool opt) const {
5572 const intptr_t kNumInputs = 1;
5573 const intptr_t kNumTemps = 0;
5574 LocationSummary* summary = new(isolate) LocationSummary(
5575 isolate, kNumInputs, kNumTemps, is_smi()
5576 ? LocationSummary::kNoCall
5577 : LocationSummary::kCallOnSlowPath);
5578 summary->set_in(0, Location::RequiresRegister());
5579 summary->set_out(0, Location::RequiresRegister());
5580 return summary;
5581 }
5582
5583
5584 void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5585 const Register out = locs()->out(0).reg();
5586 const Register value = locs()->in(0).reg();
5587
5588 if (is_smi()) {
5589 __ movq(out, value);
5590 __ SmiTag(out);
5591 return;
5592 }
5593
5594 Label is_smi;
5595 Label done;
5596 __ movq(out, value);
5597 __ SmiTag(out); // shlq sets OF := SF ^ CF on 1 bit shifts
5598 __ j(NO_OVERFLOW, &done);
5599 BoxAllocationSlowPath::Allocate(
5600 compiler, this, compiler->mint_class(), out);
5601 __ movq(FieldAddress(out, Mint::value_offset()), value);
5602 __ Bind(&done);
5603 }
5604
5605
5606 template<typename OperandType> 5563 template<typename OperandType>
5607 static void EmitInt64Arithmetic(FlowGraphCompiler* compiler, 5564 static void EmitInt64Arithmetic(FlowGraphCompiler* compiler,
5608 Token::Kind op_kind, 5565 Token::Kind op_kind,
5609 Register left, 5566 Register left,
5610 const OperandType& right, 5567 const OperandType& right,
5611 Label* deopt) { 5568 Label* deopt) {
5612 switch (op_kind) { 5569 switch (op_kind) {
5613 case Token::kADD: 5570 case Token::kADD:
5614 __ addq(left, right); 5571 __ addq(left, right);
5615 break; 5572 break;
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
5980 5937
5981 ASSERT(op_kind() == Token::kBIT_NOT); 5938 ASSERT(op_kind() == Token::kBIT_NOT);
5982 5939
5983 __ notl(out); 5940 __ notl(out);
5984 } 5941 }
5985 5942
5986 5943
5987 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr) 5944 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
5988 5945
5989 5946
5990 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
5991 bool opt) const {
5992 const intptr_t kNumInputs = 1;
5993 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
5994 LocationSummary* summary = new(isolate) LocationSummary(
5995 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5996 summary->set_in(0, Location::RequiresRegister());
5997 summary->set_out(0, Location::SameAsFirstInput());
5998 if (kNumTemps > 0) {
5999 summary->set_temp(0, Location::RequiresRegister());
6000 }
6001 return summary;
6002 }
6003
6004
6005 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6006 const intptr_t value_cid = value()->Type()->ToCid();
6007 const Register value = locs()->in(0).reg();
6008 Label* deopt = CanDeoptimize() ?
6009 compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
6010 ASSERT(value == locs()->out(0).reg());
6011
6012 if (value_cid == kSmiCid) {
6013 __ SmiUntag(value);
6014 } else if (value_cid == kMintCid) {
6015 __ movq(value, FieldAddress(value, Mint::value_offset()));
6016 } else {
6017 Label done;
6018 // Optimistically untag value.
6019 __ SmiUntagOrCheckClass(value, kMintCid, &done);
6020 __ j(NOT_EQUAL, deopt);
6021 // Undo untagging by multiplying value with 2.
6022 __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
6023 __ Bind(&done);
6024 }
6025
6026 // TODO(vegorov): as it is implemented right now truncating unboxing would
6027 // leave "garbage" in the higher word.
6028 if (!is_truncating() && (deopt != NULL)) {
6029 ASSERT(representation() == kUnboxedInt32);
6030 Register temp = locs()->temp(0).reg();
6031 __ movsxd(temp, value);
6032 __ cmpq(temp, value);
6033 __ j(NOT_EQUAL, deopt);
6034 }
6035 }
6036
6037
6038 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
6039 bool opt) const {
6040 ASSERT((from_representation() == kUnboxedInt32) ||
6041 (from_representation() == kUnboxedUint32));
6042 const intptr_t kNumInputs = 1;
6043 const intptr_t kNumTemps = 0;
6044 LocationSummary* summary = new(isolate) LocationSummary(
6045 isolate,
6046 kNumInputs,
6047 kNumTemps,
6048 LocationSummary::kNoCall);
6049 summary->set_in(0, Location::RequiresRegister());
6050 summary->set_out(0, Location::RequiresRegister());
6051 return summary;
6052 }
6053
6054
6055 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6056 const Register value = locs()->in(0).reg();
6057 const Register out = locs()->out(0).reg();
6058 ASSERT(value != out);
6059
6060 ASSERT(kSmiTagSize == 1);
6061 if (from_representation() == kUnboxedInt32) {
6062 __ movsxd(out, value);
6063 } else {
6064 ASSERT(from_representation() == kUnboxedUint32);
6065 __ movl(out, value);
6066 }
6067 __ SmiTag(out);
6068 }
6069
6070
6071 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, 5947 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
6072 bool opt) const { 5948 bool opt) const {
6073 const intptr_t kNumInputs = 1; 5949 const intptr_t kNumInputs = 1;
6074 const intptr_t kNumTemps = 0; 5950 const intptr_t kNumTemps = 0;
6075 LocationSummary* summary = new(isolate) LocationSummary( 5951 LocationSummary* summary = new(isolate) LocationSummary(
6076 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5952 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6077 if (from() == kUnboxedMint) { 5953 if (from() == kUnboxedMint) {
6078 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32)); 5954 ASSERT((to() == kUnboxedUint32) || (to() == kUnboxedInt32));
6079 summary->set_in(0, Location::RequiresRegister()); 5955 summary->set_in(0, Location::RequiresRegister());
6080 summary->set_out(0, Location::SameAsFirstInput()); 5956 summary->set_out(0, Location::SameAsFirstInput());
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
6403 __ movq(R10, Immediate(kInvalidObjectPointer)); 6279 __ movq(R10, Immediate(kInvalidObjectPointer));
6404 __ movq(RBX, Immediate(kInvalidObjectPointer)); 6280 __ movq(RBX, Immediate(kInvalidObjectPointer));
6405 #endif 6281 #endif
6406 } 6282 }
6407 6283
6408 } // namespace dart 6284 } // namespace dart
6409 6285
6410 #undef __ 6286 #undef __
6411 6287
6412 #endif // defined TARGET_ARCH_X64 6288 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/intrinsifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698