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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 if (!locs()->out(0).IsInvalid()) { | 154 if (!locs()->out(0).IsInvalid()) { |
155 Register result = locs()->out(0).reg(); | 155 Register result = locs()->out(0).reg(); |
156 __ LoadObjectSafely(result, value()); | 156 __ LoadObjectSafely(result, value()); |
157 } | 157 } |
158 } | 158 } |
159 | 159 |
160 | 160 |
161 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, | 161 LocationSummary* UnboxedConstantInstr::MakeLocationSummary(Isolate* isolate, |
162 bool opt) const { | 162 bool opt) const { |
163 const intptr_t kNumInputs = 0; | 163 const intptr_t kNumInputs = 0; |
164 const intptr_t kNumTemps = (constant_address() == 0) ? 1 : 0; | 164 const intptr_t kNumTemps = |
| 165 (constant_address() == 0) && (representation() != kUnboxedInt32) ? 1 : 0; |
165 LocationSummary* locs = new(isolate) LocationSummary( | 166 LocationSummary* locs = new(isolate) LocationSummary( |
166 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 167 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
167 locs->set_out(0, Location::RequiresFpuRegister()); | 168 if (representation() == kUnboxedDouble) { |
| 169 locs->set_out(0, Location::RequiresFpuRegister()); |
| 170 } else { |
| 171 ASSERT(representation() == kUnboxedInt32); |
| 172 locs->set_out(0, Location::RequiresRegister()); |
| 173 } |
168 if (kNumTemps == 1) { | 174 if (kNumTemps == 1) { |
169 locs->set_temp(0, Location::RequiresRegister()); | 175 locs->set_temp(0, Location::RequiresRegister()); |
170 } | 176 } |
171 return locs; | 177 return locs; |
172 } | 178 } |
173 | 179 |
174 | 180 |
175 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 181 void UnboxedConstantInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
176 // The register allocator drops constant definitions that have no uses. | 182 // The register allocator drops constant definitions that have no uses. |
177 if (!locs()->out(0).IsInvalid()) { | 183 if (!locs()->out(0).IsInvalid()) { |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1214 case kOneByteStringCid: | 1220 case kOneByteStringCid: |
1215 case kTypedDataInt8ArrayCid: | 1221 case kTypedDataInt8ArrayCid: |
1216 case kTypedDataUint8ArrayCid: | 1222 case kTypedDataUint8ArrayCid: |
1217 case kExternalTypedDataUint8ArrayCid: | 1223 case kExternalTypedDataUint8ArrayCid: |
1218 case kTypedDataUint8ClampedArrayCid: | 1224 case kTypedDataUint8ClampedArrayCid: |
1219 case kExternalTypedDataUint8ClampedArrayCid: | 1225 case kExternalTypedDataUint8ClampedArrayCid: |
1220 case kTypedDataInt16ArrayCid: | 1226 case kTypedDataInt16ArrayCid: |
1221 case kTypedDataUint16ArrayCid: | 1227 case kTypedDataUint16ArrayCid: |
1222 return kTagged; | 1228 return kTagged; |
1223 case kTypedDataInt32ArrayCid: | 1229 case kTypedDataInt32ArrayCid: |
| 1230 return kUnboxedInt32; |
1224 case kTypedDataUint32ArrayCid: | 1231 case kTypedDataUint32ArrayCid: |
1225 return value()->IsSmiValue() ? kTagged : kUnboxedMint; | 1232 return kUnboxedUint32; |
1226 case kTypedDataFloat32ArrayCid: | 1233 case kTypedDataFloat32ArrayCid: |
1227 case kTypedDataFloat64ArrayCid: | 1234 case kTypedDataFloat64ArrayCid: |
1228 return kUnboxedDouble; | 1235 return kUnboxedDouble; |
1229 case kTypedDataFloat32x4ArrayCid: | 1236 case kTypedDataFloat32x4ArrayCid: |
1230 return kUnboxedFloat32x4; | 1237 return kUnboxedFloat32x4; |
1231 case kTypedDataInt32x4ArrayCid: | 1238 case kTypedDataInt32x4ArrayCid: |
1232 return kUnboxedInt32x4; | 1239 return kUnboxedInt32x4; |
1233 case kTypedDataFloat64x2ArrayCid: | 1240 case kTypedDataFloat64x2ArrayCid: |
1234 return kUnboxedFloat64x2; | 1241 return kUnboxedFloat64x2; |
1235 default: | 1242 default: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 // EBX, ECX, EDX) instead of using a fixed register. | 1279 // EBX, ECX, EDX) instead of using a fixed register. |
1273 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); | 1280 locs->set_in(2, Location::FixedRegisterOrSmiConstant(value(), EAX)); |
1274 break; | 1281 break; |
1275 case kTypedDataInt16ArrayCid: | 1282 case kTypedDataInt16ArrayCid: |
1276 case kTypedDataUint16ArrayCid: | 1283 case kTypedDataUint16ArrayCid: |
1277 // Writable register because the value must be untagged before storing. | 1284 // Writable register because the value must be untagged before storing. |
1278 locs->set_in(2, Location::WritableRegister()); | 1285 locs->set_in(2, Location::WritableRegister()); |
1279 break; | 1286 break; |
1280 case kTypedDataInt32ArrayCid: | 1287 case kTypedDataInt32ArrayCid: |
1281 case kTypedDataUint32ArrayCid: | 1288 case kTypedDataUint32ArrayCid: |
1282 // For smis, use a writable register because the value must be untagged | 1289 locs->set_in(2, Location::RequiresRegister()); |
1283 // before storing. Mints are stored in registers pairs. | |
1284 if (value()->IsSmiValue()) { | |
1285 locs->set_in(2, Location::WritableRegister()); | |
1286 } else { | |
1287 // We only move the lower 32-bits so we don't care where the high bits | |
1288 // are located. | |
1289 locs->set_in(2, Location::Pair(Location::RequiresRegister(), | |
1290 Location::Any())); | |
1291 } | |
1292 break; | 1290 break; |
1293 case kTypedDataFloat32ArrayCid: | 1291 case kTypedDataFloat32ArrayCid: |
1294 case kTypedDataFloat64ArrayCid: | 1292 case kTypedDataFloat64ArrayCid: |
1295 // TODO(srdjan): Support Float64 constants. | 1293 // TODO(srdjan): Support Float64 constants. |
1296 locs->set_in(2, Location::RequiresFpuRegister()); | 1294 locs->set_in(2, Location::RequiresFpuRegister()); |
1297 break; | 1295 break; |
1298 case kTypedDataInt32x4ArrayCid: | 1296 case kTypedDataInt32x4ArrayCid: |
1299 case kTypedDataFloat32x4ArrayCid: | 1297 case kTypedDataFloat32x4ArrayCid: |
1300 case kTypedDataFloat64x2ArrayCid: | 1298 case kTypedDataFloat64x2ArrayCid: |
1301 locs->set_in(2, Location::RequiresFpuRegister()); | 1299 locs->set_in(2, Location::RequiresFpuRegister()); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 } | 1380 } |
1383 case kTypedDataInt16ArrayCid: | 1381 case kTypedDataInt16ArrayCid: |
1384 case kTypedDataUint16ArrayCid: { | 1382 case kTypedDataUint16ArrayCid: { |
1385 Register value = locs()->in(2).reg(); | 1383 Register value = locs()->in(2).reg(); |
1386 __ SmiUntag(value); | 1384 __ SmiUntag(value); |
1387 __ movw(element_address, value); | 1385 __ movw(element_address, value); |
1388 break; | 1386 break; |
1389 } | 1387 } |
1390 case kTypedDataInt32ArrayCid: | 1388 case kTypedDataInt32ArrayCid: |
1391 case kTypedDataUint32ArrayCid: | 1389 case kTypedDataUint32ArrayCid: |
1392 if (value()->IsSmiValue()) { | 1390 __ movl(element_address, locs()->in(2).reg()); |
1393 ASSERT(RequiredInputRepresentation(2) == kTagged); | |
1394 Register value = locs()->in(2).reg(); | |
1395 __ SmiUntag(value); | |
1396 __ movl(element_address, value); | |
1397 } else { | |
1398 ASSERT(RequiredInputRepresentation(2) == kUnboxedMint); | |
1399 PairLocation* value_pair = locs()->in(2).AsPairLocation(); | |
1400 Register value1 = value_pair->At(0).reg(); | |
1401 __ movl(element_address, value1); | |
1402 } | |
1403 break; | 1391 break; |
1404 case kTypedDataFloat32ArrayCid: | 1392 case kTypedDataFloat32ArrayCid: |
1405 __ movss(element_address, locs()->in(2).fpu_reg()); | 1393 __ movss(element_address, locs()->in(2).fpu_reg()); |
1406 break; | 1394 break; |
1407 case kTypedDataFloat64ArrayCid: | 1395 case kTypedDataFloat64ArrayCid: |
1408 __ movsd(element_address, locs()->in(2).fpu_reg()); | 1396 __ movsd(element_address, locs()->in(2).fpu_reg()); |
1409 break; | 1397 break; |
1410 case kTypedDataInt32x4ArrayCid: | 1398 case kTypedDataInt32x4ArrayCid: |
1411 case kTypedDataFloat32x4ArrayCid: | 1399 case kTypedDataFloat32x4ArrayCid: |
1412 case kTypedDataFloat64x2ArrayCid: | 1400 case kTypedDataFloat64x2ArrayCid: |
(...skipping 4974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6387 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6375 void UnaryUint32OpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6388 Register out = locs()->out(0).reg(); | 6376 Register out = locs()->out(0).reg(); |
6389 ASSERT(locs()->in(0).reg() == out); | 6377 ASSERT(locs()->in(0).reg() == out); |
6390 | 6378 |
6391 ASSERT(op_kind() == Token::kBIT_NOT); | 6379 ASSERT(op_kind() == Token::kBIT_NOT); |
6392 | 6380 |
6393 __ notl(out); | 6381 __ notl(out); |
6394 } | 6382 } |
6395 | 6383 |
6396 | 6384 |
6397 LocationSummary* BoxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6385 LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate, |
6398 bool opt) const { | |
6399 const intptr_t kNumInputs = 1; | |
6400 const intptr_t kNumTemps = 0; | |
6401 LocationSummary* summary = new(isolate) LocationSummary( | |
6402 isolate, | |
6403 kNumInputs, | |
6404 kNumTemps, | |
6405 ValueFitsSmi() ? LocationSummary::kNoCall | |
6406 : LocationSummary::kCallOnSlowPath); | |
6407 summary->set_in(0, Location::RequiresRegister()); | |
6408 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | |
6409 : Location::RequiresRegister()); | |
6410 return summary; | |
6411 } | |
6412 | |
6413 | |
6414 void BoxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6415 Register value = locs()->in(0).reg(); | |
6416 Register out = locs()->out(0).reg(); | |
6417 | |
6418 Label not_smi, done; | |
6419 | |
6420 if (ValueFitsSmi()) { | |
6421 ASSERT(value == out); | |
6422 __ SmiTag(value); | |
6423 } else { | |
6424 ASSERT(value != out); | |
6425 __ cmpl(value, Immediate(kSmiMax)); | |
6426 __ j(ABOVE, ¬_smi); | |
6427 // Smi. | |
6428 __ movl(out, value); | |
6429 __ SmiTag(out); | |
6430 __ jmp(&done); | |
6431 __ Bind(¬_smi); | |
6432 // Allocate a mint. | |
6433 BoxAllocationSlowPath::Allocate( | |
6434 compiler, this, compiler->mint_class(), out, kNoRegister); | |
6435 // Copy low word into mint. | |
6436 __ movl(FieldAddress(out, Mint::value_offset()), value); | |
6437 // Zero high word. | |
6438 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), Immediate(0)); | |
6439 __ Bind(&done); | |
6440 } | |
6441 } | |
6442 | |
6443 | |
6444 LocationSummary* BoxInt32Instr::MakeLocationSummary(Isolate* isolate, | |
6445 bool opt) const { | 6386 bool opt) const { |
6446 const intptr_t kNumInputs = 1; | 6387 const intptr_t kNumInputs = 1; |
6447 const intptr_t kNumTemps = 0; | 6388 const intptr_t kNumTemps = 0; |
6448 LocationSummary* summary = new(isolate) LocationSummary( | 6389 LocationSummary* summary = new(isolate) LocationSummary( |
6449 isolate, kNumInputs, kNumTemps, | 6390 isolate, kNumInputs, kNumTemps, |
6450 ValueFitsSmi() ? LocationSummary::kNoCall | 6391 ValueFitsSmi() ? LocationSummary::kNoCall |
6451 : LocationSummary::kCallOnSlowPath); | 6392 : LocationSummary::kCallOnSlowPath); |
6452 summary->set_in(0, ValueFitsSmi() ? Location::RequiresRegister() | 6393 const bool needs_writable_input = ValueFitsSmi() || |
6453 : Location::WritableRegister()); | 6394 (from_representation() == kUnboxedUint32); |
| 6395 summary->set_in(0, needs_writable_input ? Location::RequiresRegister() |
| 6396 : Location::WritableRegister()); |
6454 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() | 6397 summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput() |
6455 : Location::RequiresRegister()); | 6398 : Location::RequiresRegister()); |
6456 return summary; | 6399 return summary; |
6457 } | 6400 } |
6458 | 6401 |
6459 | 6402 |
6460 void BoxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6403 void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6461 Register value = locs()->in(0).reg(); | 6404 const Register value = locs()->in(0).reg(); |
6462 Register out = locs()->out(0).reg(); | 6405 const Register out = locs()->out(0).reg(); |
6463 | 6406 |
6464 if (out != value) { | 6407 __ MoveRegister(out, value); |
6465 __ movl(out, value); | 6408 __ shll(out, Immediate(kSmiTagSize)); |
6466 } | |
6467 __ shll(out, Immediate(1)); | |
6468 if (!ValueFitsSmi()) { | 6409 if (!ValueFitsSmi()) { |
6469 Label done; | 6410 Label done; |
6470 __ j(NO_OVERFLOW, &done); | 6411 ASSERT(value != out); |
| 6412 if (from_representation() == kUnboxedInt32) { |
| 6413 __ j(NO_OVERFLOW, &done); |
| 6414 } else { |
| 6415 __ testl(value, Immediate(0xC0000000)); |
| 6416 __ j(ZERO, &done); |
| 6417 } |
| 6418 |
6471 // Allocate a mint. | 6419 // Allocate a mint. |
6472 // Value input is writable register and has to be manually preserved | 6420 // Value input is writable register and has to be manually preserved |
6473 // on the slow path. | 6421 // on the slow path. |
6474 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); | 6422 locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32); |
6475 BoxAllocationSlowPath::Allocate( | 6423 BoxAllocationSlowPath::Allocate( |
6476 compiler, this, compiler->mint_class(), out, kNoRegister); | 6424 compiler, this, compiler->mint_class(), out, kNoRegister); |
6477 __ movl(FieldAddress(out, Mint::value_offset()), value); | 6425 __ movl(FieldAddress(out, Mint::value_offset()), value); |
6478 __ sarl(value, Immediate(31)); // Sign extend. | 6426 if (from_representation() == kUnboxedInt32) { |
6479 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); | 6427 __ sarl(value, Immediate(31)); // Sign extend. |
| 6428 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value); |
| 6429 } else { |
| 6430 __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), |
| 6431 Immediate(0)); |
| 6432 } |
6480 __ Bind(&done); | 6433 __ Bind(&done); |
6481 } | 6434 } |
6482 } | 6435 } |
6483 | 6436 |
6484 | 6437 |
6485 LocationSummary* UnboxUint32Instr::MakeLocationSummary(Isolate* isolate, | 6438 LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate, |
6486 bool opt) const { | 6439 bool opt) const { |
6487 const intptr_t value_cid = value()->Type()->ToCid(); | 6440 const intptr_t value_cid = value()->Type()->ToCid(); |
6488 const intptr_t kNumInputs = 1; | 6441 const intptr_t kNumInputs = 1; |
6489 const intptr_t kNumTemps = | 6442 intptr_t kNumTemps = 0; |
6490 ((value_cid == kMintCid) || (value_cid == kSmiCid)) ? 0 : 1; | 6443 |
| 6444 if (CanDeoptimize()) { |
| 6445 if ((value_cid != kSmiCid) && |
| 6446 (value_cid != kMintCid) && |
| 6447 !is_truncating()) { |
| 6448 kNumTemps = 2; |
| 6449 } else { |
| 6450 kNumTemps = 1; |
| 6451 } |
| 6452 } |
| 6453 |
6491 LocationSummary* summary = new(isolate) LocationSummary( | 6454 LocationSummary* summary = new(isolate) LocationSummary( |
6492 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 6455 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
6493 summary->set_in(0, Location::RequiresRegister()); | 6456 summary->set_in(0, Location::RequiresRegister()); |
6494 if (kNumTemps > 0) { | 6457 for (int i = 0; i < kNumTemps; i++) { |
6495 summary->set_temp(0, Location::RequiresRegister()); | 6458 summary->set_temp(i, Location::RequiresRegister()); |
6496 } | 6459 } |
6497 summary->set_out(0, Location::SameAsFirstInput()); | 6460 summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ? |
6498 return summary; | 6461 Location::SameAsFirstInput() : Location::RequiresRegister()); |
6499 } | |
6500 | |
6501 | |
6502 void UnboxUint32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
6503 const intptr_t value_cid = value()->Type()->ToCid(); | |
6504 const Register value = locs()->in(0).reg(); | |
6505 ASSERT(value == locs()->out(0).reg()); | |
6506 | |
6507 // TODO(johnmccutchan): Emit better code for constant inputs. | |
6508 if (value_cid == kMintCid) { | |
6509 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
6510 } else if (value_cid == kSmiCid) { | |
6511 __ SmiUntag(value); | |
6512 } else { | |
6513 Register temp = locs()->temp(0).reg(); | |
6514 Label* deopt = compiler->AddDeoptStub(deopt_id_, | |
6515 ICData::kDeoptUnboxInteger); | |
6516 Label is_smi, done; | |
6517 __ testl(value, Immediate(kSmiTagMask)); | |
6518 __ j(ZERO, &is_smi); | |
6519 __ CompareClassId(value, kMintCid, temp); | |
6520 __ j(NOT_EQUAL, deopt); | |
6521 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
6522 __ jmp(&done); | |
6523 __ Bind(&is_smi); | |
6524 __ SmiUntag(value); | |
6525 __ Bind(&done); | |
6526 } | |
6527 } | |
6528 | |
6529 | |
6530 LocationSummary* UnboxInt32Instr::MakeLocationSummary(Isolate* isolate, | |
6531 bool opt) const { | |
6532 const intptr_t value_cid = value()->Type()->ToCid(); | |
6533 const intptr_t kNumInputs = 1; | |
6534 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; | |
6535 LocationSummary* summary = new(isolate) LocationSummary( | |
6536 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
6537 summary->set_in(0, Location::RequiresRegister()); | |
6538 if (kNumTemps > 0) { | |
6539 summary->set_temp(0, Location::RequiresRegister()); | |
6540 } | |
6541 summary->set_out(0, (value_cid == kSmiCid) ? Location::SameAsFirstInput() | |
6542 : Location::RequiresRegister()); | |
6543 return summary; | 6462 return summary; |
6544 } | 6463 } |
6545 | 6464 |
6546 | 6465 |
6547 static void LoadInt32FromMint(FlowGraphCompiler* compiler, | 6466 static void LoadInt32FromMint(FlowGraphCompiler* compiler, |
6548 Register mint, | |
6549 Register result, | 6467 Register result, |
| 6468 const Address& lo, |
| 6469 const Address& hi, |
6550 Register temp, | 6470 Register temp, |
6551 Label* deopt) { | 6471 Label* deopt) { |
6552 __ movl(result, FieldAddress(mint, Mint::value_offset())); | 6472 __ movl(result, lo); |
6553 if (deopt != NULL) { | 6473 if (deopt != NULL) { |
| 6474 ASSERT(temp != result); |
6554 __ movl(temp, result); | 6475 __ movl(temp, result); |
6555 __ sarl(temp, Immediate(31)); | 6476 __ sarl(temp, Immediate(31)); |
6556 __ cmpl(temp, FieldAddress(mint, Mint::value_offset() + kWordSize)); | 6477 __ cmpl(temp, hi); |
6557 __ j(NOT_EQUAL, deopt); | 6478 __ j(NOT_EQUAL, deopt); |
6558 } | 6479 } |
6559 } | 6480 } |
6560 | 6481 |
6561 | 6482 |
6562 void UnboxInt32Instr::EmitNativeCode(FlowGraphCompiler* compiler) { | 6483 void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
6563 const intptr_t value_cid = value()->Type()->ToCid(); | 6484 const intptr_t value_cid = value()->Type()->ToCid(); |
6564 const Register value = locs()->in(0).reg(); | 6485 Register value = locs()->in(0).reg(); |
6565 const Register result = locs()->out(0).reg(); | 6486 const Register result = locs()->out(0).reg(); |
| 6487 const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; |
| 6488 Label* deopt = CanDeoptimize() ? |
| 6489 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; |
| 6490 Label* out_of_range = !is_truncating() ? deopt : NULL; |
6566 | 6491 |
6567 // TODO(johnmccutchan): Emit better code for constant inputs. | 6492 const intptr_t lo_offset = Mint::value_offset(); |
6568 if (value_cid == kMintCid) { | 6493 const intptr_t hi_offset = Mint::value_offset() + kWordSize; |
6569 Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister; | 6494 |
6570 Label* deopt = CanDeoptimize() ? | 6495 if (value_cid == kSmiCid) { |
6571 compiler->AddDeoptStub(deopt_id_, ICData::kDeoptUnboxInteger) : NULL; | |
6572 LoadInt32FromMint(compiler, | |
6573 value, | |
6574 result, | |
6575 temp, | |
6576 deopt); | |
6577 } else if (value_cid == kSmiCid) { | |
6578 ASSERT(value == result); | 6496 ASSERT(value == result); |
6579 __ SmiUntag(value); | 6497 __ SmiUntag(value); |
| 6498 } else if (value_cid == kMintCid) { |
| 6499 ASSERT((value != result) || (out_of_range == NULL)); |
| 6500 LoadInt32FromMint(compiler, |
| 6501 result, |
| 6502 FieldAddress(value, lo_offset), |
| 6503 FieldAddress(value, hi_offset), |
| 6504 temp, |
| 6505 out_of_range); |
6580 } else { | 6506 } else { |
6581 Register temp = locs()->temp(0).reg(); | 6507 ASSERT(value == result); |
6582 Label* deopt = compiler->AddDeoptStub(deopt_id_, | 6508 Label done; |
6583 ICData::kDeoptUnboxInteger); | 6509 __ SmiUntagOrCheckClass(value, kMintCid, temp, &done); |
6584 Label is_smi, done; | |
6585 __ testl(value, Immediate(kSmiTagMask)); | |
6586 __ j(ZERO, &is_smi); | |
6587 __ CompareClassId(value, kMintCid, temp); | |
6588 __ j(NOT_EQUAL, deopt); | 6510 __ j(NOT_EQUAL, deopt); |
| 6511 if (out_of_range != NULL) { |
| 6512 Register value_temp = locs()->temp(1).reg(); |
| 6513 __ movl(value_temp, value); |
| 6514 value = value_temp; |
| 6515 } |
6589 LoadInt32FromMint(compiler, | 6516 LoadInt32FromMint(compiler, |
6590 value, | |
6591 result, | 6517 result, |
| 6518 Address(value, TIMES_2, lo_offset), |
| 6519 Address(value, TIMES_2, hi_offset), |
6592 temp, | 6520 temp, |
6593 deopt); | 6521 out_of_range); |
6594 __ movl(value, FieldAddress(value, Mint::value_offset())); | |
6595 __ jmp(&done); | |
6596 __ Bind(&is_smi); | |
6597 __ SmiUntag(value); | |
6598 __ Bind(&done); | 6522 __ Bind(&done); |
6599 } | 6523 } |
6600 } | 6524 } |
6601 | 6525 |
6602 | 6526 |
6603 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, | 6527 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate, |
6604 bool opt) const { | 6528 bool opt) const { |
6605 const intptr_t kNumInputs = 1; | 6529 const intptr_t kNumInputs = 1; |
6606 const intptr_t kNumTemps = 0; | 6530 const intptr_t kNumTemps = 0; |
6607 LocationSummary* summary = new(isolate) LocationSummary( | 6531 LocationSummary* summary = new(isolate) LocationSummary( |
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7037 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6961 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
7038 __ movl(EDX, Immediate(kInvalidObjectPointer)); | 6962 __ movl(EDX, Immediate(kInvalidObjectPointer)); |
7039 #endif | 6963 #endif |
7040 } | 6964 } |
7041 | 6965 |
7042 } // namespace dart | 6966 } // namespace dart |
7043 | 6967 |
7044 #undef __ | 6968 #undef __ |
7045 | 6969 |
7046 #endif // defined TARGET_ARCH_IA32 | 6970 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |