| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1288 __ popl(temp); | 1288 __ popl(temp); |
| 1289 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); | 1289 __ movsd(XMM0, FieldAddress(temp, Double::value_offset())); |
| 1290 __ DoubleNegate(XMM0); | 1290 __ DoubleNegate(XMM0); |
| 1291 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1291 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1292 } else { | 1292 } else { |
| 1293 UNREACHABLE(); | 1293 UNREACHABLE(); |
| 1294 } | 1294 } |
| 1295 } | 1295 } |
| 1296 | 1296 |
| 1297 | 1297 |
| 1298 LocationSummary* ToDoubleComp::MakeLocationSummary() const { |
| 1299 const intptr_t kNumInputs = 1; |
| 1300 const intptr_t kNumTemps = 1; |
| 1301 if (from() == kDouble) { |
| 1302 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| 1303 locs->set_in(0, Location::RequiresRegister()); |
| 1304 locs->set_out(Location::SameAsFirstInput()); |
| 1305 return locs; |
| 1306 } else { |
| 1307 ASSERT(from() == kSmi); |
| 1308 return LocationSummary::Make(kNumInputs, Location::RegisterLocation(EAX)); |
| 1309 } |
| 1310 } |
| 1311 |
| 1312 |
| 1313 void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1314 Register value = locs()->in(0).reg(); |
| 1315 Register result = locs()->out().reg(); |
| 1316 |
| 1317 const DeoptReasonId deopt_reason = (from() == kDouble) ? |
| 1318 kDeoptDoubleToDouble : kDeoptIntegerToDouble; |
| 1319 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), |
| 1320 instance_call()->token_index(), |
| 1321 instance_call()->try_index(), |
| 1322 deopt_reason, |
| 1323 value, |
| 1324 kNoRegister); |
| 1325 |
| 1326 if (from() == kDouble) { |
| 1327 Register temp = locs()->temp(0).reg(); |
| 1328 __ testl(value, Immediate(kSmiTagMask)); |
| 1329 __ j(ZERO, deopt); // Deoptimize if Smi. |
| 1330 __ CompareClassId(value, kDouble, temp); |
| 1331 __ j(NOT_EQUAL, deopt); // Deoptimize if not Double. |
| 1332 ASSERT(value == result); |
| 1333 return; |
| 1334 } |
| 1335 |
| 1336 ASSERT(from() == kSmi); |
| 1337 |
| 1338 // TODO(vegorov): allocate a single ZoneHandle in FlowGraphCompiler for |
| 1339 // double class. |
| 1340 const Class& double_class = |
| 1341 Class::ZoneHandle(Isolate::Current()->object_store()->double_class()); |
| 1342 |
| 1343 const Code& stub = |
| 1344 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| 1345 |
| 1346 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| 1347 |
| 1348 // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping. |
| 1349 __ pushl(value); |
| 1350 compiler->GenerateCall(instance_call()->token_index(), |
| 1351 instance_call()->try_index(), |
| 1352 &label, |
| 1353 PcDescriptors::kOther); |
| 1354 ASSERT(result == EAX); |
| 1355 __ popl(value); |
| 1356 |
| 1357 __ testl(value, Immediate(kSmiTagMask)); |
| 1358 __ j(NOT_ZERO, deopt); // Deoptimize if not Smi. |
| 1359 __ SmiUntag(value); |
| 1360 __ cvtsi2sd(XMM0, value); |
| 1361 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1362 } |
| 1363 |
| 1364 |
| 1298 } // namespace dart | 1365 } // namespace dart |
| 1299 | 1366 |
| 1300 #undef __ | 1367 #undef __ |
| 1301 | 1368 |
| 1302 #endif // defined TARGET_ARCH_X64 | 1369 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |