Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1253)

Side by Side Diff: runtime/vm/intermediate_language_ia32.cc

Issue 10879005: Split BinaryOp into BinarySmiOp and BinaryMintOp. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1404 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this); 1404 CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
1405 compiler->AddSlowPathCode(slow_path); 1405 compiler->AddSlowPathCode(slow_path);
1406 1406
1407 __ cmpl(ESP, 1407 __ cmpl(ESP,
1408 Address::Absolute(Isolate::Current()->stack_limit_address())); 1408 Address::Absolute(Isolate::Current()->stack_limit_address()));
1409 __ j(BELOW_EQUAL, slow_path->entry_label()); 1409 __ j(BELOW_EQUAL, slow_path->entry_label());
1410 __ Bind(slow_path->exit_label()); 1410 __ Bind(slow_path->exit_label());
1411 } 1411 }
1412 1412
1413 1413
1414 LocationSummary* BinaryOpComp::MakeLocationSummary() const { 1414 LocationSummary* BinarySmiOpComp::MakeLocationSummary() const {
1415 const intptr_t kNumInputs = 2; 1415 const intptr_t kNumInputs = 2;
1416
1417 // Double operation are handled in DoubleBinaryOpComp.
1418 ASSERT(operands_type() != kDoubleOperands);
1419
1420 if (operands_type() == kMintOperands) {
1421 ASSERT(op_kind() == Token::kBIT_AND);
1422 const intptr_t kNumTemps = 1;
1423 LocationSummary* summary =
1424 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1425 summary->set_in(0, Location::RegisterLocation(EAX));
1426 summary->set_in(1, Location::RegisterLocation(ECX));
1427 summary->set_temp(0, Location::RegisterLocation(EDX));
1428 summary->set_out(Location::RegisterLocation(EAX));
1429 return summary;
1430 }
1431
1432 ASSERT(operands_type() == kSmiOperands);
1433
1434 if (op_kind() == Token::kTRUNCDIV) { 1416 if (op_kind() == Token::kTRUNCDIV) {
1435 const intptr_t kNumTemps = 3; 1417 const intptr_t kNumTemps = 3;
1436 LocationSummary* summary = 1418 LocationSummary* summary =
1437 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1419 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1438 summary->set_in(0, Location::RegisterLocation(EAX)); 1420 summary->set_in(0, Location::RegisterLocation(EAX));
1439 summary->set_in(1, Location::RegisterLocation(ECX)); 1421 summary->set_in(1, Location::RegisterLocation(ECX));
1440 summary->set_out(Location::SameAsFirstInput()); 1422 summary->set_out(Location::SameAsFirstInput());
1441 summary->set_temp(0, Location::RegisterLocation(EBX)); 1423 summary->set_temp(0, Location::RegisterLocation(EBX));
1442 // Will be used for for sign extension. 1424 // Will be used for for sign extension.
1443 summary->set_temp(1, Location::RegisterLocation(EDX)); 1425 summary->set_temp(1, Location::RegisterLocation(EDX));
(...skipping 25 matching lines...) Expand all
1469 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 1451 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1470 summary->set_in(0, Location::RequiresRegister()); 1452 summary->set_in(0, Location::RequiresRegister());
1471 summary->set_in(1, Location::RequiresRegister()); 1453 summary->set_in(1, Location::RequiresRegister());
1472 summary->set_out(Location::SameAsFirstInput()); 1454 summary->set_out(Location::SameAsFirstInput());
1473 summary->set_temp(0, Location::RequiresRegister()); 1455 summary->set_temp(0, Location::RequiresRegister());
1474 return summary; 1456 return summary;
1475 } 1457 }
1476 } 1458 }
1477 1459
1478 1460
1479 static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1461 void BinarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1480 Register left = comp->locs()->in(0).reg(); 1462 Register left = locs()->in(0).reg();
1481 Register right = comp->locs()->in(1).reg(); 1463 Register right = locs()->in(1).reg();
1482 Register result = comp->locs()->out().reg(); 1464 Register result = locs()->out().reg();
1483 Register temp = comp->locs()->temp(0).reg(); 1465 Register temp = locs()->temp(0).reg();
1484 ASSERT(left == result); 1466 ASSERT(left == result);
1485 const bool left_is_smi = comp->left()->ResultCid() == kSmiCid; 1467 const bool left_is_smi = this->left()->ResultCid() == kSmiCid;
1486 const bool right_is_smi = comp->right()->ResultCid() == kSmiCid; 1468 const bool right_is_smi = this->right()->ResultCid() == kSmiCid;
1487 bool can_deopt; 1469 bool can_deopt;
1488 switch (comp->op_kind()) { 1470 switch (op_kind()) {
1489 case Token::kBIT_AND: 1471 case Token::kBIT_AND:
1490 case Token::kBIT_OR: 1472 case Token::kBIT_OR:
1491 case Token::kBIT_XOR: 1473 case Token::kBIT_XOR:
1492 can_deopt = !(right_is_smi && left_is_smi); 1474 can_deopt = !(right_is_smi && left_is_smi);
1493 break; 1475 break;
1494 default: 1476 default:
1495 can_deopt = true; 1477 can_deopt = true;
1496 } 1478 }
1497 Label* deopt = NULL; 1479 Label* deopt = NULL;
1498 if (can_deopt) { 1480 if (can_deopt) {
1499 deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1481 deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1500 comp->instance_call()->try_index(), 1482 instance_call()->try_index(),
1501 kDeoptSmiBinaryOp); 1483 kDeoptBinarySmiOp);
1502 } 1484 }
1503 if (!left_is_smi || !right_is_smi) { 1485 if (!left_is_smi || !right_is_smi) {
1504 __ movl(temp, left); 1486 __ movl(temp, left);
1505 __ orl(temp, right); 1487 __ orl(temp, right);
1506 __ testl(temp, Immediate(kSmiTagMask)); 1488 __ testl(temp, Immediate(kSmiTagMask));
1507 __ j(NOT_ZERO, deopt); 1489 __ j(NOT_ZERO, deopt);
1508 } 1490 }
1509 switch (comp->op_kind()) { 1491 switch (op_kind()) {
1510 case Token::kADD: { 1492 case Token::kADD: {
1511 __ addl(left, right); 1493 __ addl(left, right);
1512 __ j(OVERFLOW, deopt); 1494 __ j(OVERFLOW, deopt);
1513 break; 1495 break;
1514 } 1496 }
1515 case Token::kSUB: { 1497 case Token::kSUB: {
1516 __ subl(left, right); 1498 __ subl(left, right);
1517 __ j(OVERFLOW, deopt); 1499 __ j(OVERFLOW, deopt);
1518 break; 1500 break;
1519 } 1501 }
(...skipping 19 matching lines...) Expand all
1539 break; 1521 break;
1540 } 1522 }
1541 case Token::kTRUNCDIV: { 1523 case Token::kTRUNCDIV: {
1542 // Handle divide by zero in runtime. 1524 // Handle divide by zero in runtime.
1543 // Deoptimization requires that temp and right are preserved. 1525 // Deoptimization requires that temp and right are preserved.
1544 __ testl(right, right); 1526 __ testl(right, right);
1545 __ j(ZERO, deopt); 1527 __ j(ZERO, deopt);
1546 ASSERT(left == EAX); 1528 ASSERT(left == EAX);
1547 ASSERT((right != EDX) && (right != EAX)); 1529 ASSERT((right != EDX) && (right != EAX));
1548 ASSERT((temp != EDX) && (temp != EAX)); 1530 ASSERT((temp != EDX) && (temp != EAX));
1549 ASSERT(comp->locs()->temp(1).reg() == EDX); 1531 ASSERT(locs()->temp(1).reg() == EDX);
1550 ASSERT(result == EAX); 1532 ASSERT(result == EAX);
1551 Register right_temp = comp->locs()->temp(2).reg(); 1533 Register right_temp = locs()->temp(2).reg();
1552 __ movl(right_temp, right); 1534 __ movl(right_temp, right);
1553 __ SmiUntag(left); 1535 __ SmiUntag(left);
1554 __ SmiUntag(right_temp); 1536 __ SmiUntag(right_temp);
1555 __ cdq(); // Sign extend EAX -> EDX:EAX. 1537 __ cdq(); // Sign extend EAX -> EDX:EAX.
1556 __ idivl(right_temp); // EAX: quotient, EDX: remainder. 1538 __ idivl(right_temp); // EAX: quotient, EDX: remainder.
1557 // Check the corner case of dividing the 'MIN_SMI' with -1, in which 1539 // Check the corner case of dividing the 'MIN_SMI' with -1, in which
1558 // case we cannot tag the result. 1540 // case we cannot tag the result.
1559 __ cmpl(result, Immediate(0x40000000)); 1541 __ cmpl(result, Immediate(0x40000000));
1560 __ j(EQUAL, deopt); 1542 __ j(EQUAL, deopt);
1561 __ SmiTag(result); 1543 __ SmiTag(result);
(...skipping 16 matching lines...) Expand all
1578 __ SmiTag(left); 1560 __ SmiTag(left);
1579 break; 1561 break;
1580 } 1562 }
1581 case Token::kSHL: { 1563 case Token::kSHL: {
1582 Label call_method, done; 1564 Label call_method, done;
1583 // Check if count too large for handling it inlined. 1565 // Check if count too large for handling it inlined.
1584 __ movl(temp, left); 1566 __ movl(temp, left);
1585 __ cmpl(right, 1567 __ cmpl(right,
1586 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits)))); 1568 Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
1587 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump); 1569 __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
1588 Register right_temp = comp->locs()->temp(1).reg(); 1570 Register right_temp = locs()->temp(1).reg();
1589 ASSERT(right_temp == ECX); // Count must be in ECX 1571 ASSERT(right_temp == ECX); // Count must be in ECX
1590 __ movl(right_temp, right); 1572 __ movl(right_temp, right);
1591 __ SmiUntag(right_temp); 1573 __ SmiUntag(right_temp);
1592 // Overflow test (preserve temp and right); 1574 // Overflow test (preserve temp and right);
1593 __ shll(left, right_temp); 1575 __ shll(left, right_temp);
1594 __ sarl(left, right_temp); 1576 __ sarl(left, right_temp);
1595 __ cmpl(left, temp); 1577 __ cmpl(left, temp);
1596 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow. 1578 __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
1597 // Shift for result now we know there is no overflow. 1579 // Shift for result now we know there is no overflow.
1598 __ shll(left, right_temp); 1580 __ shll(left, right_temp);
1599 __ jmp(&done); 1581 __ jmp(&done);
1600 { 1582 {
1601 __ Bind(&call_method); 1583 __ Bind(&call_method);
1602 Function& target = Function::ZoneHandle( 1584 Function& target = Function::ZoneHandle(
1603 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1585 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1604 ASSERT(!target.IsNull()); 1586 ASSERT(!target.IsNull());
1605 const intptr_t kArgumentCount = 2; 1587 const intptr_t kArgumentCount = 2;
1606 __ pushl(temp); 1588 __ pushl(temp);
1607 __ pushl(right); 1589 __ pushl(right);
1608 compiler->GenerateStaticCall( 1590 compiler->GenerateStaticCall(
1609 comp->instance_call()->deopt_id(), 1591 instance_call()->deopt_id(),
1610 comp->instance_call()->token_pos(), 1592 instance_call()->token_pos(),
1611 comp->instance_call()->try_index(), 1593 instance_call()->try_index(),
1612 target, 1594 target,
1613 kArgumentCount, 1595 kArgumentCount,
1614 Array::Handle(), // No argument names. 1596 Array::Handle(), // No argument names.
1615 comp->locs()->stack_bitmap()); 1597 locs()->stack_bitmap());
1616 ASSERT(result == EAX); 1598 ASSERT(result == EAX);
1617 } 1599 }
1618 __ Bind(&done); 1600 __ Bind(&done);
1619 break; 1601 break;
1620 } 1602 }
1621 case Token::kDIV: { 1603 case Token::kDIV: {
1622 // Dispatches to 'Double./'. 1604 // Dispatches to 'Double./'.
1623 // TODO(srdjan): Implement as conversion to double and double division. 1605 // TODO(srdjan): Implement as conversion to double and double division.
1624 UNREACHABLE(); 1606 UNREACHABLE();
1625 break; 1607 break;
(...skipping 10 matching lines...) Expand all
1636 UNREACHABLE(); 1618 UNREACHABLE();
1637 break; 1619 break;
1638 } 1620 }
1639 default: 1621 default:
1640 UNREACHABLE(); 1622 UNREACHABLE();
1641 break; 1623 break;
1642 } 1624 }
1643 } 1625 }
1644 1626
1645 1627
1646 static void EmitMintBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { 1628 LocationSummary* BinaryMintOpComp::MakeLocationSummary() const {
1629 const intptr_t kNumInputs = 2;
1630 ASSERT(op_kind() == Token::kBIT_AND);
1631 const intptr_t kNumTemps = 1;
1632 LocationSummary* summary =
1633 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1634 summary->set_in(0, Location::RegisterLocation(EAX));
1635 summary->set_in(1, Location::RegisterLocation(ECX));
1636 summary->set_temp(0, Location::RegisterLocation(EDX));
1637 summary->set_out(Location::RegisterLocation(EAX));
1638 return summary;
1639 }
1640
1641
1642 void BinaryMintOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1647 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi 1643 // TODO(regis): For now, we only support Token::kBIT_AND for a Mint or Smi
1648 // receiver and a Mint or Smi argument. We fall back to the run time call if 1644 // receiver and a Mint or Smi argument. We fall back to the run time call if
1649 // both receiver and argument are Mint or if one of them is Mint and the other 1645 // both receiver and argument are Mint or if one of them is Mint and the other
1650 // is a negative Smi. 1646 // is a negative Smi.
1651 Register left = comp->locs()->in(0).reg(); 1647 Register left = locs()->in(0).reg();
1652 Register right = comp->locs()->in(1).reg(); 1648 Register right = locs()->in(1).reg();
1653 Register result = comp->locs()->out().reg(); 1649 Register result = locs()->out().reg();
1654 Register temp = comp->locs()->temp(0).reg(); 1650 Register temp = locs()->temp(0).reg();
1655 ASSERT(left == result); 1651 ASSERT(left == result);
1656 ASSERT(comp->op_kind() == Token::kBIT_AND); 1652 ASSERT(op_kind() == Token::kBIT_AND);
1657 Label* deopt = compiler->AddDeoptStub(comp->instance_call()->deopt_id(), 1653 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1658 comp->instance_call()->try_index(), 1654 instance_call()->try_index(),
1659 kDeoptMintBinaryOp); 1655 kDeoptBinaryMintOp);
1660 Label mint_static_call, smi_static_call, non_smi, smi_smi, done; 1656 Label mint_static_call, smi_static_call, non_smi, smi_smi, done;
1661 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi? 1657 __ testl(left, Immediate(kSmiTagMask)); // Is receiver Smi?
1662 __ j(NOT_ZERO, &non_smi); 1658 __ j(NOT_ZERO, &non_smi);
1663 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi? 1659 __ testl(right, Immediate(kSmiTagMask)); // Is argument Smi?
1664 __ j(ZERO, &smi_smi); 1660 __ j(ZERO, &smi_smi);
1665 __ CompareClassId(right, kMintCid, temp); // Is argument Mint? 1661 __ CompareClassId(right, kMintCid, temp); // Is argument Mint?
1666 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint. 1662 __ j(NOT_EQUAL, deopt); // Argument neither Smi nor Mint.
1667 __ cmpl(left, Immediate(0)); 1663 __ cmpl(left, Immediate(0));
1668 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument. 1664 __ j(LESS, &smi_static_call); // Negative Smi receiver, Mint argument.
1669 1665
(...skipping 16 matching lines...) Expand all
1686 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits. 1682 // Load lower receiver Mint word, convert to Smi. It is OK to loose bits.
1687 __ movl(result, FieldAddress(left, Mint::value_offset())); 1683 __ movl(result, FieldAddress(left, Mint::value_offset()));
1688 __ SmiTag(result); 1684 __ SmiTag(result);
1689 __ Bind(&smi_smi); 1685 __ Bind(&smi_smi);
1690 __ andl(result, right); 1686 __ andl(result, right);
1691 __ jmp(&done); 1687 __ jmp(&done);
1692 1688
1693 __ Bind(&smi_static_call); 1689 __ Bind(&smi_static_call);
1694 { 1690 {
1695 Function& target = Function::ZoneHandle( 1691 Function& target = Function::ZoneHandle(
1696 comp->ic_data()->GetTargetForReceiverClassId(kSmiCid)); 1692 ic_data()->GetTargetForReceiverClassId(kSmiCid));
1697 if (target.IsNull()) { 1693 if (target.IsNull()) {
1698 __ jmp(deopt); 1694 __ jmp(deopt);
1699 } else { 1695 } else {
1700 __ pushl(left); 1696 __ pushl(left);
1701 __ pushl(right); 1697 __ pushl(right);
1702 compiler->GenerateStaticCall( 1698 compiler->GenerateStaticCall(
1703 comp->instance_call()->deopt_id(), 1699 instance_call()->deopt_id(),
1704 comp->instance_call()->token_pos(), 1700 instance_call()->token_pos(),
1705 comp->instance_call()->try_index(), 1701 instance_call()->try_index(),
1706 target, 1702 target,
1707 comp->instance_call()->ArgumentCount(), 1703 instance_call()->ArgumentCount(),
1708 comp->instance_call()->argument_names(), 1704 instance_call()->argument_names(),
1709 comp->locs()->stack_bitmap()); 1705 locs()->stack_bitmap());
1710 ASSERT(result == EAX); 1706 ASSERT(result == EAX);
1711 __ jmp(&done); 1707 __ jmp(&done);
1712 } 1708 }
1713 } 1709 }
1714 1710
1715 __ Bind(&mint_static_call); 1711 __ Bind(&mint_static_call);
1716 { 1712 {
1717 Function& target = Function::ZoneHandle( 1713 Function& target = Function::ZoneHandle(
1718 comp->ic_data()->GetTargetForReceiverClassId(kMintCid)); 1714 ic_data()->GetTargetForReceiverClassId(kMintCid));
1719 if (target.IsNull()) { 1715 if (target.IsNull()) {
1720 __ jmp(deopt); 1716 __ jmp(deopt);
1721 } else { 1717 } else {
1722 __ pushl(left); 1718 __ pushl(left);
1723 __ pushl(right); 1719 __ pushl(right);
1724 compiler->GenerateStaticCall( 1720 compiler->GenerateStaticCall(
1725 comp->instance_call()->deopt_id(), 1721 instance_call()->deopt_id(),
1726 comp->instance_call()->token_pos(), 1722 instance_call()->token_pos(),
1727 comp->instance_call()->try_index(), 1723 instance_call()->try_index(),
1728 target, 1724 target,
1729 comp->instance_call()->ArgumentCount(), 1725 instance_call()->ArgumentCount(),
1730 comp->instance_call()->argument_names(), 1726 instance_call()->argument_names(),
1731 comp->locs()->stack_bitmap()); 1727 locs()->stack_bitmap());
1732 ASSERT(result == EAX); 1728 ASSERT(result == EAX);
1733 } 1729 }
1734 } 1730 }
1735 __ Bind(&done); 1731 __ Bind(&done);
1736 } 1732 }
1737 1733
1738 1734
1739 void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1735 LocationSummary* BinaryDoubleOpComp::MakeLocationSummary() const {
1740 switch (operands_type()) {
1741 case kSmiOperands:
1742 EmitSmiBinaryOp(compiler, this);
1743 break;
1744
1745 case kMintOperands:
1746 EmitMintBinaryOp(compiler, this);
1747 break;
1748
1749 default:
1750 UNREACHABLE();
1751 }
1752 }
1753
1754
1755 LocationSummary* DoubleBinaryOpComp::MakeLocationSummary() const {
1756 return MakeCallSummary(); // Calls into a stub for allocation. 1736 return MakeCallSummary(); // Calls into a stub for allocation.
1757 } 1737 }
1758 1738
1759 1739
1760 void DoubleBinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1740 void BinaryDoubleOpComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1761 Register left = EBX; 1741 Register left = EBX;
1762 Register right = ECX; 1742 Register right = ECX;
1763 Register temp = EDX; 1743 Register temp = EDX;
1764 Register result = locs()->out().reg(); 1744 Register result = locs()->out().reg();
1765 1745
1766 const Class& double_class = compiler->double_class(); 1746 const Class& double_class = compiler->double_class();
1767 const Code& stub = 1747 const Code& stub =
1768 Code::Handle(StubCode::GetAllocationStubForClass(double_class)); 1748 Code::Handle(StubCode::GetAllocationStubForClass(double_class));
1769 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); 1749 const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
1770 compiler->GenerateCall(instance_call()->token_pos(), 1750 compiler->GenerateCall(instance_call()->token_pos(),
1771 instance_call()->try_index(), 1751 instance_call()->try_index(),
1772 &label, 1752 &label,
1773 PcDescriptors::kOther, 1753 PcDescriptors::kOther,
1774 locs()->stack_bitmap()); 1754 locs()->stack_bitmap());
1775 // Newly allocated object is now in the result register (RAX). 1755 // Newly allocated object is now in the result register (RAX).
1776 ASSERT(result == EAX); 1756 ASSERT(result == EAX);
1777 __ movl(right, Address(ESP, 0)); 1757 __ movl(right, Address(ESP, 0));
1778 __ movl(left, Address(ESP, kWordSize)); 1758 __ movl(left, Address(ESP, kWordSize));
1779 1759
1780 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(), 1760 Label* deopt = compiler->AddDeoptStub(instance_call()->deopt_id(),
1781 instance_call()->try_index(), 1761 instance_call()->try_index(),
1782 kDeoptDoubleBinaryOp); 1762 kDeoptBinaryDoubleOp);
1783 1763
1784 // Binary operation of two Smi's produces a Smi not a double. 1764 // Binary operation of two Smi's produces a Smi not a double.
1785 __ movl(temp, left); 1765 __ movl(temp, left);
1786 __ orl(temp, right); 1766 __ orl(temp, right);
1787 __ testl(temp, Immediate(kSmiTagMask)); 1767 __ testl(temp, Immediate(kSmiTagMask));
1788 __ j(ZERO, deopt); 1768 __ j(ZERO, deopt);
1789 1769
1790 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt); 1770 compiler->LoadDoubleOrSmiToXmm(XMM0, left, temp, deopt);
1791 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt); 1771 compiler->LoadDoubleOrSmiToXmm(XMM1, right, temp, deopt);
1792 1772
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
2210 } 2190 }
2211 } 2191 }
2212 __ Bind(&is_ok); 2192 __ Bind(&is_ok);
2213 } 2193 }
2214 2194
2215 } // namespace dart 2195 } // namespace dart
2216 2196
2217 #undef __ 2197 #undef __
2218 2198
2219 #endif // defined TARGET_ARCH_X64 2199 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698