Chromium Code Reviews| 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_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 Loading... | |
| 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; |
| 3220 case kUnboxedFloat32x4: | |
| 3221 case kUnboxedFloat64x2: | |
| 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, | |
| 3222 bool opt) const { | 3233 bool opt) const { |
|
Florian Schneider
2014/10/30 15:43:23
Indentation.
Vyacheslav Egorov (Google)
2014/10/30 17:57:39
Done.
| |
| 3223 const intptr_t kNumInputs = 1; | 3234 const intptr_t kNumInputs = 1; |
| 3224 const intptr_t kNumTemps = 0; | 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 { | 3349 bool opt) const { |
|
Florian Schneider
2014/10/30 15:43:23
Indentation.
Vyacheslav Egorov (Google)
2014/10/30 17:57:39
Done.
| |
| 3277 const intptr_t kNumInputs = 1; | 3350 const intptr_t kNumInputs = 1; |
| 3278 const intptr_t kNumTemps = 0; | 3351 const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0; |
| 3279 LocationSummary* summary = new(isolate) LocationSummary( | 3352 LocationSummary* summary = new(isolate) LocationSummary( |
| 3280 isolate, kNumInputs, | 3353 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 3281 kNumTemps, | 3354 summary->set_in(0, Location::RequiresRegister()); |
| 3282 LocationSummary::kCallOnSlowPath); | 3355 summary->set_out(0, Location::SameAsFirstInput()); |
| 3283 summary->set_in(0, Location::RequiresFpuRegister()); | 3356 if (kNumTemps > 0) { |
| 3284 summary->set_out(0, Location::RequiresRegister()); | 3357 summary->set_temp(0, Location::RequiresRegister()); |
| 3285 return summary; | 3358 } |
| 3286 } | 3359 return summary; |
| 3287 | 3360 } |
| 3288 | 3361 |
| 3289 void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 3362 |
| 3290 Register out_reg = locs()->out(0).reg(); | 3363 void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 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 { | |
| 3301 const intptr_t kNumInputs = 1; | |
| 3302 return LocationSummary::Make(isolate, | |
| 3303 kNumInputs, | |
| 3304 Location::RequiresFpuRegister(), | |
| 3305 LocationSummary::kNoCall); | |
| 3306 } | |
| 3307 | |
| 3308 | |
| 3309 void UnboxFloat32x4Instr::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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |