| 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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 } | 1156 } |
| 1157 } | 1157 } |
| 1158 | 1158 |
| 1159 | 1159 |
| 1160 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { | 1160 LocationSummary* LoadIndexedInstr::MakeLocationSummary() const { |
| 1161 const intptr_t kNumInputs = 2; | 1161 const intptr_t kNumInputs = 2; |
| 1162 const intptr_t kNumTemps = 0; | 1162 const intptr_t kNumTemps = 0; |
| 1163 LocationSummary* locs = | 1163 LocationSummary* locs = |
| 1164 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1164 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1165 locs->set_in(0, Location::RequiresRegister()); | 1165 locs->set_in(0, Location::RequiresRegister()); |
| 1166 // The smi index is either untagged and tagged again at the end of the | 1166 // The smi index is either untagged (element size == 1), or it is left smi |
| 1167 // operation (element size == 1), or it is left smi tagged (for all element | 1167 // tagged (for all element sizes > 1). |
| 1168 // sizes > 1). | 1168 if (index_scale() == 1) { |
| 1169 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1169 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1170 ? Location::RegisterOrSmiConstant(index()) | 1170 ? Location::Constant( |
| 1171 : Location::RequiresRegister()); | 1171 index()->definition()->AsConstant()->value()) |
| 1172 : Location::WritableRegister()); |
| 1173 } else { |
| 1174 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1175 ? Location::Constant( |
| 1176 index()->definition()->AsConstant()->value()) |
| 1177 : Location::RequiresRegister()); |
| 1178 } |
| 1172 if (representation() == kUnboxedDouble) { | 1179 if (representation() == kUnboxedDouble) { |
| 1173 locs->set_out(Location::RequiresFpuRegister()); | 1180 locs->set_out(Location::RequiresFpuRegister()); |
| 1174 } else { | 1181 } else { |
| 1175 locs->set_out(Location::RequiresRegister()); | 1182 locs->set_out(Location::RequiresRegister()); |
| 1176 } | 1183 } |
| 1177 return locs; | 1184 return locs; |
| 1178 } | 1185 } |
| 1179 | 1186 |
| 1180 | 1187 |
| 1181 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1188 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1192 class_id(), index_scale(), result, | 1199 class_id(), index_scale(), result, |
| 1193 Smi::Cast(index.constant()).Value()); | 1200 Smi::Cast(index.constant()).Value()); |
| 1194 ASSERT(index_scale() == 1); | 1201 ASSERT(index_scale() == 1); |
| 1195 if (index.IsRegister()) { | 1202 if (index.IsRegister()) { |
| 1196 __ SmiUntag(index.reg()); | 1203 __ SmiUntag(index.reg()); |
| 1197 } | 1204 } |
| 1198 __ movl(result, | 1205 __ movl(result, |
| 1199 FieldAddress(array, ExternalUint8Array::data_offset())); | 1206 FieldAddress(array, ExternalUint8Array::data_offset())); |
| 1200 __ movzxb(result, element_address); | 1207 __ movzxb(result, element_address); |
| 1201 __ SmiTag(result); | 1208 __ SmiTag(result); |
| 1202 if (index.IsRegister()) { | |
| 1203 __ SmiTag(index.reg()); // Re-tag. | |
| 1204 } | |
| 1205 return; | 1209 return; |
| 1206 } | 1210 } |
| 1207 | 1211 |
| 1208 FieldAddress element_address = index.IsRegister() | 1212 FieldAddress element_address = index.IsRegister() |
| 1209 ? FlowGraphCompiler::ElementAddressForRegIndex( | 1213 ? FlowGraphCompiler::ElementAddressForRegIndex( |
| 1210 class_id(), index_scale(), array, index.reg()) | 1214 class_id(), index_scale(), array, index.reg()) |
| 1211 : FlowGraphCompiler::ElementAddressForIntIndex( | 1215 : FlowGraphCompiler::ElementAddressForIntIndex( |
| 1212 class_id(), index_scale(), array, | 1216 class_id(), index_scale(), array, |
| 1213 Smi::Cast(index.constant()).Value()); | 1217 Smi::Cast(index.constant()).Value()); |
| 1214 | 1218 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1229 break; | 1233 break; |
| 1230 case kFloat32ArrayCid: | 1234 case kFloat32ArrayCid: |
| 1231 // Load single precision float and promote to double. | 1235 // Load single precision float and promote to double. |
| 1232 __ movss(result, element_address); | 1236 __ movss(result, element_address); |
| 1233 __ cvtss2sd(result, locs()->out().fpu_reg()); | 1237 __ cvtss2sd(result, locs()->out().fpu_reg()); |
| 1234 break; | 1238 break; |
| 1235 case kFloat64ArrayCid: | 1239 case kFloat64ArrayCid: |
| 1236 __ movsd(result, element_address); | 1240 __ movsd(result, element_address); |
| 1237 break; | 1241 break; |
| 1238 } | 1242 } |
| 1239 if ((index_scale() == 1) && index.IsRegister()) { | |
| 1240 __ SmiTag(index.reg()); // Re-tag. | |
| 1241 } | |
| 1242 return; | 1243 return; |
| 1243 } | 1244 } |
| 1244 | 1245 |
| 1245 Register result = locs()->out().reg(); | 1246 Register result = locs()->out().reg(); |
| 1246 if ((index_scale() == 1) && index.IsRegister()) { | 1247 if ((index_scale() == 1) && index.IsRegister()) { |
| 1247 __ SmiUntag(index.reg()); | 1248 __ SmiUntag(index.reg()); |
| 1248 } | 1249 } |
| 1249 switch (class_id()) { | 1250 switch (class_id()) { |
| 1250 case kInt8ArrayCid: | 1251 case kInt8ArrayCid: |
| 1251 case kUint8ArrayCid: | 1252 case kUint8ArrayCid: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1284 __ testl(result, Immediate(0xC0000000)); | 1285 __ testl(result, Immediate(0xC0000000)); |
| 1285 __ j(NOT_ZERO, deopt); | 1286 __ j(NOT_ZERO, deopt); |
| 1286 __ SmiTag(result); | 1287 __ SmiTag(result); |
| 1287 } | 1288 } |
| 1288 break; | 1289 break; |
| 1289 default: | 1290 default: |
| 1290 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1291 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
| 1291 __ movl(result, element_address); | 1292 __ movl(result, element_address); |
| 1292 break; | 1293 break; |
| 1293 } | 1294 } |
| 1294 if ((index_scale() == 1) && index.IsRegister()) { | |
| 1295 __ SmiTag(index.reg()); // Re-tag. | |
| 1296 } | |
| 1297 } | 1295 } |
| 1298 | 1296 |
| 1299 | 1297 |
| 1300 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1298 Representation StoreIndexedInstr::RequiredInputRepresentation( |
| 1301 intptr_t idx) const { | 1299 intptr_t idx) const { |
| 1302 if ((idx == 0) || (idx == 1)) return kTagged; | 1300 if ((idx == 0) || (idx == 1)) return kTagged; |
| 1303 ASSERT(idx == 2); | 1301 ASSERT(idx == 2); |
| 1304 switch (class_id_) { | 1302 switch (class_id_) { |
| 1305 case kArrayCid: | 1303 case kArrayCid: |
| 1306 case kInt8ArrayCid: | 1304 case kInt8ArrayCid: |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1321 } | 1319 } |
| 1322 } | 1320 } |
| 1323 | 1321 |
| 1324 | 1322 |
| 1325 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { | 1323 LocationSummary* StoreIndexedInstr::MakeLocationSummary() const { |
| 1326 const intptr_t kNumInputs = 3; | 1324 const intptr_t kNumInputs = 3; |
| 1327 const intptr_t kNumTemps = 0; | 1325 const intptr_t kNumTemps = 0; |
| 1328 LocationSummary* locs = | 1326 LocationSummary* locs = |
| 1329 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 1327 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1330 locs->set_in(0, Location::RequiresRegister()); | 1328 locs->set_in(0, Location::RequiresRegister()); |
| 1331 // The smi index is either untagged and tagged again at the end of the | 1329 // The smi index is either untagged (element size == 1), or it is left smi |
| 1332 // operation (element size == 1), or it is left smi tagged (for all element | 1330 // tagged (for all element sizes > 1). |
| 1333 // sizes > 1). | 1331 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id()); |
| 1334 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) | 1332 if (index_scale == 1) { |
| 1335 ? Location::RegisterOrSmiConstant(index()) | 1333 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1336 : Location::RequiresRegister()); | 1334 ? Location::Constant( |
| 1335 index()->definition()->AsConstant()->value()) |
| 1336 : Location::WritableRegister()); |
| 1337 } else { |
| 1338 locs->set_in(1, CanBeImmediateIndex(index(), class_id()) |
| 1339 ? Location::Constant( |
| 1340 index()->definition()->AsConstant()->value()) |
| 1341 : Location::RequiresRegister()); |
| 1342 } |
| 1337 switch (class_id()) { | 1343 switch (class_id()) { |
| 1338 case kArrayCid: | 1344 case kArrayCid: |
| 1339 locs->set_in(2, ShouldEmitStoreBarrier() | 1345 locs->set_in(2, ShouldEmitStoreBarrier() |
| 1340 ? Location::WritableRegister() | 1346 ? Location::WritableRegister() |
| 1341 : Location::RegisterOrConstant(value())); | 1347 : Location::RegisterOrConstant(value())); |
| 1342 break; | 1348 break; |
| 1343 case kInt8ArrayCid: | 1349 case kInt8ArrayCid: |
| 1344 case kUint8ArrayCid: | 1350 case kUint8ArrayCid: |
| 1345 case kUint8ClampedArrayCid: | 1351 case kUint8ClampedArrayCid: |
| 1346 // TODO(fschneider): Add location constraint for byte registers (EAX, | 1352 // TODO(fschneider): Add location constraint for byte registers (EAX, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 } | 1408 } |
| 1403 if (locs()->in(2).IsConstant()) { | 1409 if (locs()->in(2).IsConstant()) { |
| 1404 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1410 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1405 __ movb(element_address, | 1411 __ movb(element_address, |
| 1406 Immediate(static_cast<int8_t>(constant.Value()))); | 1412 Immediate(static_cast<int8_t>(constant.Value()))); |
| 1407 } else { | 1413 } else { |
| 1408 ASSERT(locs()->in(2).reg() == EAX); | 1414 ASSERT(locs()->in(2).reg() == EAX); |
| 1409 __ SmiUntag(EAX); | 1415 __ SmiUntag(EAX); |
| 1410 __ movb(element_address, AL); | 1416 __ movb(element_address, AL); |
| 1411 } | 1417 } |
| 1412 if (index.IsRegister()) { | |
| 1413 __ SmiTag(index.reg()); // Re-tag. | |
| 1414 } | |
| 1415 break; | 1418 break; |
| 1416 case kUint8ClampedArrayCid: { | 1419 case kUint8ClampedArrayCid: { |
| 1417 if (index.IsRegister()) { | 1420 if (index.IsRegister()) { |
| 1418 __ SmiUntag(index.reg()); | 1421 __ SmiUntag(index.reg()); |
| 1419 } | 1422 } |
| 1420 if (locs()->in(2).IsConstant()) { | 1423 if (locs()->in(2).IsConstant()) { |
| 1421 const Smi& constant = Smi::Cast(locs()->in(2).constant()); | 1424 const Smi& constant = Smi::Cast(locs()->in(2).constant()); |
| 1422 intptr_t value = constant.Value(); | 1425 intptr_t value = constant.Value(); |
| 1423 // Clamp to 0x0 or 0xFF respectively. | 1426 // Clamp to 0x0 or 0xFF respectively. |
| 1424 if (value > 0xFF) { | 1427 if (value > 0xFF) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1436 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump); | 1439 __ j(BELOW_EQUAL, &store_value, Assembler::kNearJump); |
| 1437 // Clamp to 0x0 or 0xFF respectively. | 1440 // Clamp to 0x0 or 0xFF respectively. |
| 1438 __ j(GREATER, &store_0xff); | 1441 __ j(GREATER, &store_0xff); |
| 1439 __ xorl(EAX, EAX); | 1442 __ xorl(EAX, EAX); |
| 1440 __ jmp(&store_value, Assembler::kNearJump); | 1443 __ jmp(&store_value, Assembler::kNearJump); |
| 1441 __ Bind(&store_0xff); | 1444 __ Bind(&store_0xff); |
| 1442 __ movl(EAX, Immediate(0xFF)); | 1445 __ movl(EAX, Immediate(0xFF)); |
| 1443 __ Bind(&store_value); | 1446 __ Bind(&store_value); |
| 1444 __ movb(element_address, AL); | 1447 __ movb(element_address, AL); |
| 1445 } | 1448 } |
| 1446 if (index.IsRegister()) { | |
| 1447 __ SmiTag(index.reg()); // Re-tag. | |
| 1448 } | |
| 1449 break; | 1449 break; |
| 1450 } | 1450 } |
| 1451 case kInt16ArrayCid: | 1451 case kInt16ArrayCid: |
| 1452 case kUint16ArrayCid: { | 1452 case kUint16ArrayCid: { |
| 1453 Register value = locs()->in(2).reg(); | 1453 Register value = locs()->in(2).reg(); |
| 1454 __ SmiUntag(value); | 1454 __ SmiUntag(value); |
| 1455 __ movw(element_address, value); | 1455 __ movw(element_address, value); |
| 1456 break; | 1456 break; |
| 1457 } | 1457 } |
| 1458 case kInt32ArrayCid: | 1458 case kInt32ArrayCid: |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2347 slow_path->entry_label(), | 2347 slow_path->entry_label(), |
| 2348 Assembler::kFarJump, | 2348 Assembler::kFarJump, |
| 2349 out_reg); | 2349 out_reg); |
| 2350 __ Bind(slow_path->exit_label()); | 2350 __ Bind(slow_path->exit_label()); |
| 2351 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); | 2351 __ movsd(FieldAddress(out_reg, Double::value_offset()), value); |
| 2352 } | 2352 } |
| 2353 | 2353 |
| 2354 | 2354 |
| 2355 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { | 2355 LocationSummary* UnboxDoubleInstr::MakeLocationSummary() const { |
| 2356 const intptr_t kNumInputs = 1; | 2356 const intptr_t kNumInputs = 1; |
| 2357 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; | 2357 const intptr_t value_cid = value()->ResultCid(); |
| 2358 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid)); |
| 2359 const bool needs_writable_input = (value_cid == kSmiCid); |
| 2360 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 2358 LocationSummary* summary = | 2361 LocationSummary* summary = |
| 2359 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2362 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2360 summary->set_in(0, Location::RequiresRegister()); | 2363 summary->set_in(0, needs_writable_input |
| 2361 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister()); | 2364 ? Location::WritableRegister() |
| 2365 : Location::RequiresRegister()); |
| 2366 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); |
| 2362 summary->set_out(Location::RequiresFpuRegister()); | 2367 summary->set_out(Location::RequiresFpuRegister()); |
| 2363 return summary; | 2368 return summary; |
| 2364 } | 2369 } |
| 2365 | 2370 |
| 2366 | 2371 |
| 2367 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2372 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2368 const intptr_t value_cid = value()->ResultCid(); | 2373 const intptr_t value_cid = value()->ResultCid(); |
| 2369 const Register value = locs()->in(0).reg(); | 2374 const Register value = locs()->in(0).reg(); |
| 2370 const XmmRegister result = locs()->out().fpu_reg(); | 2375 const XmmRegister result = locs()->out().fpu_reg(); |
| 2371 | 2376 |
| 2372 if (value_cid == kDoubleCid) { | 2377 if (value_cid == kDoubleCid) { |
| 2373 __ movsd(result, FieldAddress(value, Double::value_offset())); | 2378 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 2374 } else if (value_cid == kSmiCid) { | 2379 } else if (value_cid == kSmiCid) { |
| 2375 __ SmiUntag(value); // Untag input before conversion. | 2380 __ SmiUntag(value); // Untag input before conversion. |
| 2376 __ cvtsi2sd(result, value); | 2381 __ cvtsi2sd(result, value); |
| 2377 __ SmiTag(value); // Restore input register. | |
| 2378 } else { | 2382 } else { |
| 2379 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); | 2383 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptBinaryDoubleOp); |
| 2380 compiler->LoadDoubleOrSmiToFpu(result, | 2384 Register temp = locs()->temp(0).reg(); |
| 2381 value, | 2385 Label is_smi, done; |
| 2382 locs()->temp(0).reg(), | 2386 __ testl(value, Immediate(kSmiTagMask)); |
| 2383 deopt); | 2387 __ j(ZERO, &is_smi); |
| 2388 __ CompareClassId(value, kDoubleCid, temp); |
| 2389 __ j(NOT_EQUAL, deopt); |
| 2390 __ movsd(result, FieldAddress(value, Double::value_offset())); |
| 2391 __ jmp(&done); |
| 2392 __ Bind(&is_smi); |
| 2393 __ movl(temp, value); |
| 2394 __ SmiUntag(temp); |
| 2395 __ cvtsi2sd(result, temp); |
| 2396 __ Bind(&done); |
| 2384 } | 2397 } |
| 2385 } | 2398 } |
| 2386 | 2399 |
| 2387 | 2400 |
| 2388 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { | 2401 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary() const { |
| 2389 const intptr_t kNumInputs = 2; | 2402 const intptr_t kNumInputs = 2; |
| 2390 const intptr_t kNumTemps = 0; | 2403 const intptr_t kNumTemps = 0; |
| 2391 LocationSummary* summary = | 2404 LocationSummary* summary = |
| 2392 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2405 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2393 summary->set_in(0, Location::RequiresFpuRegister()); | 2406 summary->set_in(0, Location::RequiresFpuRegister()); |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2802 Register length = locs()->in(0).reg(); | 2815 Register length = locs()->in(0).reg(); |
| 2803 Register index = locs()->in(1).reg(); | 2816 Register index = locs()->in(1).reg(); |
| 2804 __ cmpl(index, length); | 2817 __ cmpl(index, length); |
| 2805 __ j(ABOVE_EQUAL, deopt); | 2818 __ j(ABOVE_EQUAL, deopt); |
| 2806 } | 2819 } |
| 2807 } | 2820 } |
| 2808 | 2821 |
| 2809 | 2822 |
| 2810 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { | 2823 LocationSummary* UnboxIntegerInstr::MakeLocationSummary() const { |
| 2811 const intptr_t kNumInputs = 1; | 2824 const intptr_t kNumInputs = 1; |
| 2812 const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0; | 2825 const intptr_t value_cid = value()->ResultCid(); |
| 2826 const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kMintCid)); |
| 2827 const bool needs_writable_input = (value_cid == kSmiCid); |
| 2828 const intptr_t kNumTemps = needs_temp ? 1 : 0; |
| 2813 LocationSummary* summary = | 2829 LocationSummary* summary = |
| 2814 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 2830 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 2815 summary->set_in(0, Location::RequiresRegister()); | 2831 summary->set_in(0, needs_writable_input |
| 2816 if (CanDeoptimize()) summary->set_temp(0, Location::RequiresRegister()); | 2832 ? Location::WritableRegister() |
| 2833 : Location::RequiresRegister()); |
| 2834 if (needs_temp) summary->set_temp(0, Location::RequiresRegister()); |
| 2817 summary->set_out(Location::RequiresFpuRegister()); | 2835 summary->set_out(Location::RequiresFpuRegister()); |
| 2818 return summary; | 2836 return summary; |
| 2819 } | 2837 } |
| 2820 | 2838 |
| 2821 | 2839 |
| 2822 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 2840 void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 2823 const intptr_t value_cid = value()->ResultCid(); | 2841 const intptr_t value_cid = value()->ResultCid(); |
| 2824 const Register value = locs()->in(0).reg(); | 2842 const Register value = locs()->in(0).reg(); |
| 2825 const XmmRegister result = locs()->out().fpu_reg(); | 2843 const XmmRegister result = locs()->out().fpu_reg(); |
| 2826 | 2844 |
| 2827 if (value_cid == kMintCid) { | 2845 if (value_cid == kMintCid) { |
| 2828 __ movsd(result, FieldAddress(value, Mint::value_offset())); | 2846 __ movsd(result, FieldAddress(value, Mint::value_offset())); |
| 2829 } else if (value_cid == kSmiCid) { | 2847 } else if (value_cid == kSmiCid) { |
| 2830 __ SmiUntag(value); // Untag input before conversion. | 2848 __ SmiUntag(value); // Untag input before conversion. |
| 2831 __ movd(result, value); | 2849 __ movd(result, value); |
| 2832 __ pmovsxdq(result, result); | 2850 __ pmovsxdq(result, result); |
| 2833 __ SmiTag(value); // Restore input register. | |
| 2834 } else { | 2851 } else { |
| 2835 Register temp = locs()->temp(0).reg(); | 2852 Register temp = locs()->temp(0).reg(); |
| 2836 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); | 2853 Label* deopt = compiler->AddDeoptStub(deopt_id_, kDeoptUnboxInteger); |
| 2837 Label is_smi, done; | 2854 Label is_smi, done; |
| 2838 __ testl(value, Immediate(kSmiTagMask)); | 2855 __ testl(value, Immediate(kSmiTagMask)); |
| 2839 __ j(ZERO, &is_smi); | 2856 __ j(ZERO, &is_smi); |
| 2840 __ CompareClassId(value, kMintCid, temp); | 2857 __ CompareClassId(value, kMintCid, temp); |
| 2841 __ j(NOT_EQUAL, deopt); | 2858 __ j(NOT_EQUAL, deopt); |
| 2842 __ movsd(result, FieldAddress(value, Mint::value_offset())); | 2859 __ movsd(result, FieldAddress(value, Mint::value_offset())); |
| 2843 __ jmp(&done); | 2860 __ jmp(&done); |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3417 PcDescriptors::kOther, | 3434 PcDescriptors::kOther, |
| 3418 locs()); | 3435 locs()); |
| 3419 __ Drop(2); // Discard type arguments and receiver. | 3436 __ Drop(2); // Discard type arguments and receiver. |
| 3420 } | 3437 } |
| 3421 | 3438 |
| 3422 } // namespace dart | 3439 } // namespace dart |
| 3423 | 3440 |
| 3424 #undef __ | 3441 #undef __ |
| 3425 | 3442 |
| 3426 #endif // defined TARGET_ARCH_IA32 | 3443 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |