| 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_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 "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1301 } | 1301 } |
| 1302 | 1302 |
| 1303 | 1303 |
| 1304 LocationSummary* BinaryOpComp::MakeLocationSummary() const { | 1304 LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| 1305 const intptr_t kNumInputs = 2; | 1305 const intptr_t kNumInputs = 2; |
| 1306 | 1306 |
| 1307 if (operands_type() == kDoubleOperands) { | 1307 if (operands_type() == kDoubleOperands) { |
| 1308 return MakeCallSummary(); // Calls into a stub for allocation. | 1308 return MakeCallSummary(); // Calls into a stub for allocation. |
| 1309 } | 1309 } |
| 1310 | 1310 |
| 1311 if (operands_type() == kMintOperands) { |
| 1312 ASSERT(op_kind() == Token::kBIT_AND); |
| 1313 const intptr_t kNumTemps = 1; |
| 1314 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1315 summary->set_in(0, Location::RequiresRegister()); |
| 1316 summary->set_in(1, Location::RequiresRegister()); |
| 1317 summary->set_out(Location::SameAsFirstInput()); |
| 1318 summary->set_temp(0, Location::RequiresRegister()); |
| 1319 return summary; |
| 1320 } |
| 1321 |
| 1311 ASSERT(operands_type() == kSmiOperands); | 1322 ASSERT(operands_type() == kSmiOperands); |
| 1312 | 1323 |
| 1313 if (op_kind() == Token::kTRUNCDIV) { | 1324 if (op_kind() == Token::kTRUNCDIV) { |
| 1314 const intptr_t kNumTemps = 3; | 1325 const intptr_t kNumTemps = 3; |
| 1315 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); | 1326 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| 1316 summary->set_in(0, Location::RegisterLocation(RAX)); | 1327 summary->set_in(0, Location::RegisterLocation(RAX)); |
| 1317 summary->set_in(1, Location::RegisterLocation(RCX)); | 1328 summary->set_in(1, Location::RegisterLocation(RCX)); |
| 1318 summary->set_out(Location::SameAsFirstInput()); | 1329 summary->set_out(Location::SameAsFirstInput()); |
| 1319 summary->set_temp(0, Location::RegisterLocation(RBX)); | 1330 summary->set_temp(0, Location::RegisterLocation(RBX)); |
| 1320 // Will be used for for sign extension. | 1331 // Will be used for for sign extension. |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1475 UNREACHABLE(); | 1486 UNREACHABLE(); |
| 1476 break; | 1487 break; |
| 1477 } | 1488 } |
| 1478 default: | 1489 default: |
| 1479 UNREACHABLE(); | 1490 UNREACHABLE(); |
| 1480 break; | 1491 break; |
| 1481 } | 1492 } |
| 1482 } | 1493 } |
| 1483 | 1494 |
| 1484 | 1495 |
| 1496 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { |
| 1497 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi |
| 1498 // receiver and a Smi argument. |
| 1499 Register left = comp->locs()->in(0).reg(); |
| 1500 Register right = comp->locs()->in(1).reg(); |
| 1501 Register result = comp->locs()->out().reg(); |
| 1502 Register temp = comp->locs()->temp(0).reg(); |
| 1503 ASSERT(left == result); |
| 1504 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->cid(), |
| 1505 comp->instance_call()->token_index(), |
| 1506 comp->instance_call()->try_index(), |
| 1507 kDeoptMintBinaryOp, |
| 1508 temp, |
| 1509 right); |
| 1510 __ testq(right, Immediate(kSmiTagMask)); // Argument must be Smi. |
| 1511 __ j(NOT_ZERO, deopt); |
| 1512 __ testq(left, Immediate(kSmiTagMask)); // Receiver can be Smi. |
| 1513 Label two_smi; |
| 1514 __ j(ZERO, &two_smi); |
| 1515 __ CompareClassId(left, kMint); // Receiver must be Mint. |
| 1516 __ j(NOT_EQUAL, deopt); |
| 1517 |
| 1518 ASSERT(comp->op_kind() == Token::kBIT_AND); |
| 1519 |
| 1520 // Load lower Mint word, convert to Smi. It is OK to loose bits. |
| 1521 ASSERT(result == left); |
| 1522 __ movq(result, FieldAddress(left, Mint::value_offset())); |
| 1523 __ SmiTag(result); |
| 1524 __ Bind(&two_smi); |
| 1525 __ andq(result, right); |
| 1526 } |
| 1527 |
| 1528 |
| 1485 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, | 1529 static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| 1486 BinaryOpComp* comp) { | 1530 BinaryOpComp* comp) { |
| 1487 Register left = RBX; | 1531 Register left = RBX; |
| 1488 Register right = RCX; | 1532 Register right = RCX; |
| 1489 Register temp = RDX; | 1533 Register temp = RDX; |
| 1490 Register result = comp->locs()->out().reg(); | 1534 Register result = comp->locs()->out().reg(); |
| 1491 | 1535 |
| 1492 const Class& double_class = compiler->double_class(); | 1536 const Class& double_class = compiler->double_class(); |
| 1493 const Code& stub = | 1537 const Code& stub = |
| 1494 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); | 1538 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1523 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); | 1567 __ movsd(FieldAddress(result, Double::value_offset()), XMM0); |
| 1524 } | 1568 } |
| 1525 | 1569 |
| 1526 | 1570 |
| 1527 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 1571 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1528 switch (operands_type()) { | 1572 switch (operands_type()) { |
| 1529 case kSmiOperands: | 1573 case kSmiOperands: |
| 1530 EmitSmiBinaryOp(compiler, this); | 1574 EmitSmiBinaryOp(compiler, this); |
| 1531 break; | 1575 break; |
| 1532 | 1576 |
| 1577 case kMintOperands: |
| 1578 EmitMintBinaryOp(compiler, this); |
| 1579 break; |
| 1580 |
| 1533 case kDoubleOperands: | 1581 case kDoubleOperands: |
| 1534 EmitDoubleBinaryOp(compiler, this); | 1582 EmitDoubleBinaryOp(compiler, this); |
| 1535 break; | 1583 break; |
| 1536 | 1584 |
| 1537 default: | 1585 default: |
| 1538 UNREACHABLE(); | 1586 UNREACHABLE(); |
| 1539 } | 1587 } |
| 1540 } | 1588 } |
| 1541 | 1589 |
| 1542 | 1590 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1755 instance_call()->argument_names()); | 1803 instance_call()->argument_names()); |
| 1756 } | 1804 } |
| 1757 __ Bind(&done); | 1805 __ Bind(&done); |
| 1758 } | 1806 } |
| 1759 | 1807 |
| 1760 } // namespace dart | 1808 } // namespace dart |
| 1761 | 1809 |
| 1762 #undef __ | 1810 #undef __ |
| 1763 | 1811 |
| 1764 #endif // defined TARGET_ARCH_X64 | 1812 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |