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