OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1412 __ dmod(remainder, dividend, divisor); | 1412 __ dmod(remainder, dividend, divisor); |
1413 } | 1413 } |
1414 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); | 1414 __ Branch(&done, eq, remainder, Operand(zero_reg), USE_DELAY_SLOT); |
1415 __ Xor(remainder, remainder, Operand(divisor)); | 1415 __ Xor(remainder, remainder, Operand(divisor)); |
1416 __ Branch(&done, ge, remainder, Operand(zero_reg)); | 1416 __ Branch(&done, ge, remainder, Operand(zero_reg)); |
1417 __ Dsubu(result, result, Operand(1)); | 1417 __ Dsubu(result, result, Operand(1)); |
1418 __ bind(&done); | 1418 __ bind(&done); |
1419 } | 1419 } |
1420 | 1420 |
1421 | 1421 |
1422 void LCodeGen::DoMulI(LMulI* instr) { | 1422 void LCodeGen::DoMulS(LMulS* instr) { |
1423 Register scratch = scratch0(); | 1423 Register scratch = scratch0(); |
1424 Register result = ToRegister(instr->result()); | 1424 Register result = ToRegister(instr->result()); |
1425 // Note that result may alias left. | 1425 // Note that result may alias left. |
1426 Register left = ToRegister(instr->left()); | 1426 Register left = ToRegister(instr->left()); |
1427 LOperand* right_op = instr->right(); | 1427 LOperand* right_op = instr->right(); |
1428 | 1428 |
1429 bool bailout_on_minus_zero = | 1429 bool bailout_on_minus_zero = |
1430 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 1430 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
1431 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1431 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1432 | 1432 |
1433 if (right_op->IsConstantOperand()) { | 1433 if (right_op->IsConstantOperand()) { |
1434 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); | 1434 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); |
1435 | 1435 |
1436 if (bailout_on_minus_zero && (constant < 0)) { | 1436 if (bailout_on_minus_zero && (constant < 0)) { |
1437 // The case of a null constant will be handled separately. | 1437 // The case of a null constant will be handled separately. |
1438 // If constant is negative and left is null, the result should be -0. | 1438 // If constant is negative and left is null, the result should be -0. |
1439 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); | 1439 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); |
1440 } | 1440 } |
1441 | 1441 |
1442 switch (constant) { | 1442 switch (constant) { |
1443 case -1: | 1443 case -1: |
1444 if (overflow) { | 1444 if (overflow) { |
1445 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); | 1445 __ DsubuAndCheckForOverflow(result, zero_reg, left, scratch); |
1446 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, scratch, | 1446 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, scratch, |
1447 Operand(kMaxInt)); | 1447 Operand(zero_reg)); |
1448 } else { | 1448 } else { |
1449 __ Dsubu(result, zero_reg, left); | 1449 __ Dsubu(result, zero_reg, left); |
1450 } | 1450 } |
1451 break; | 1451 break; |
1452 case 0: | 1452 case 0: |
1453 if (bailout_on_minus_zero) { | 1453 if (bailout_on_minus_zero) { |
1454 // If left is strictly negative and the constant is null, the | 1454 // If left is strictly negative and the constant is null, the |
1455 // result is -0. Deoptimize if required, otherwise return 0. | 1455 // result is -0. Deoptimize if required, otherwise return 0. |
1456 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, | 1456 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, |
1457 Operand(zero_reg)); | 1457 Operand(zero_reg)); |
(...skipping 14 matching lines...) Expand all Loading... |
1472 if (base::bits::IsPowerOfTwo32(constant_abs)) { | 1472 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
1473 int32_t shift = WhichPowerOf2(constant_abs); | 1473 int32_t shift = WhichPowerOf2(constant_abs); |
1474 __ dsll(result, left, shift); | 1474 __ dsll(result, left, shift); |
1475 // Correct the sign of the result if the constant is negative. | 1475 // Correct the sign of the result if the constant is negative. |
1476 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1476 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1477 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { | 1477 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
1478 int32_t shift = WhichPowerOf2(constant_abs - 1); | 1478 int32_t shift = WhichPowerOf2(constant_abs - 1); |
1479 __ dsll(scratch, left, shift); | 1479 __ dsll(scratch, left, shift); |
1480 __ Daddu(result, scratch, left); | 1480 __ Daddu(result, scratch, left); |
1481 // Correct the sign of the result if the constant is negative. | 1481 // Correct the sign of the result if the constant is negative. |
1482 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1482 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1483 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { | 1483 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
1484 int32_t shift = WhichPowerOf2(constant_abs + 1); | 1484 int32_t shift = WhichPowerOf2(constant_abs + 1); |
1485 __ dsll(scratch, left, shift); | 1485 __ dsll(scratch, left, shift); |
1486 __ Dsubu(result, scratch, left); | 1486 __ Dsubu(result, scratch, left); |
1487 // Correct the sign of the result if the constant is negative. | 1487 // Correct the sign of the result if the constant is negative. |
1488 if (constant < 0) __ Dsubu(result, zero_reg, result); | 1488 if (constant < 0) __ Dsubu(result, zero_reg, result); |
1489 } else { | 1489 } else { |
1490 // Generate standard code. | 1490 // Generate standard code. |
1491 __ li(at, constant); | 1491 __ li(at, constant); |
1492 __ Dmul(result, left, at); | 1492 __ Dmul(result, left, at); |
1493 } | 1493 } |
1494 } | 1494 } |
| 1495 } else { |
| 1496 DCHECK(right_op->IsRegister()); |
| 1497 Register right = ToRegister(right_op); |
| 1498 |
| 1499 if (overflow) { |
| 1500 // hi:lo = left * right. |
| 1501 __ Dmulh(result, left, right); |
| 1502 __ dsra32(scratch, result, 0); |
| 1503 __ sra(at, result, 31); |
| 1504 __ SmiTag(result); |
| 1505 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); |
| 1506 } else { |
| 1507 __ SmiUntag(result, left); |
| 1508 __ dmul(result, result, right); |
| 1509 } |
| 1510 |
| 1511 if (bailout_on_minus_zero) { |
| 1512 Label done; |
| 1513 __ Xor(at, left, right); |
| 1514 __ Branch(&done, ge, at, Operand(zero_reg)); |
| 1515 // Bail out if the result is minus zero. |
| 1516 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, |
| 1517 Operand(zero_reg)); |
| 1518 __ bind(&done); |
| 1519 } |
| 1520 } |
| 1521 } |
| 1522 |
| 1523 |
| 1524 void LCodeGen::DoMulI(LMulI* instr) { |
| 1525 Register scratch = scratch0(); |
| 1526 Register result = ToRegister(instr->result()); |
| 1527 // Note that result may alias left. |
| 1528 Register left = ToRegister(instr->left()); |
| 1529 LOperand* right_op = instr->right(); |
| 1530 |
| 1531 bool bailout_on_minus_zero = |
| 1532 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
| 1533 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1534 |
| 1535 if (right_op->IsConstantOperand()) { |
| 1536 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); |
| 1537 |
| 1538 if (bailout_on_minus_zero && (constant < 0)) { |
| 1539 // The case of a null constant will be handled separately. |
| 1540 // If constant is negative and left is null, the result should be -0. |
| 1541 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, left, Operand(zero_reg)); |
| 1542 } |
| 1543 |
| 1544 switch (constant) { |
| 1545 case -1: |
| 1546 if (overflow) { |
| 1547 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); |
| 1548 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, scratch, |
| 1549 Operand(zero_reg)); |
| 1550 } else { |
| 1551 __ Subu(result, zero_reg, left); |
| 1552 } |
| 1553 break; |
| 1554 case 0: |
| 1555 if (bailout_on_minus_zero) { |
| 1556 // If left is strictly negative and the constant is null, the |
| 1557 // result is -0. Deoptimize if required, otherwise return 0. |
| 1558 DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero, left, |
| 1559 Operand(zero_reg)); |
| 1560 } |
| 1561 __ mov(result, zero_reg); |
| 1562 break; |
| 1563 case 1: |
| 1564 // Nothing to do. |
| 1565 __ Move(result, left); |
| 1566 break; |
| 1567 default: |
| 1568 // Multiplying by powers of two and powers of two plus or minus |
| 1569 // one can be done faster with shifted operands. |
| 1570 // For other constants we emit standard code. |
| 1571 int32_t mask = constant >> 31; |
| 1572 uint32_t constant_abs = (constant + mask) ^ mask; |
| 1573 |
| 1574 if (base::bits::IsPowerOfTwo32(constant_abs)) { |
| 1575 int32_t shift = WhichPowerOf2(constant_abs); |
| 1576 __ sll(result, left, shift); |
| 1577 // Correct the sign of the result if the constant is negative. |
| 1578 if (constant < 0) __ Subu(result, zero_reg, result); |
| 1579 } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) { |
| 1580 int32_t shift = WhichPowerOf2(constant_abs - 1); |
| 1581 __ sll(scratch, left, shift); |
| 1582 __ addu(result, scratch, left); |
| 1583 // Correct the sign of the result if the constant is negative. |
| 1584 if (constant < 0) __ Subu(result, zero_reg, result); |
| 1585 } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) { |
| 1586 int32_t shift = WhichPowerOf2(constant_abs + 1); |
| 1587 __ sll(scratch, left, shift); |
| 1588 __ Subu(result, scratch, left); |
| 1589 // Correct the sign of the result if the constant is negative. |
| 1590 if (constant < 0) __ Subu(result, zero_reg, result); |
| 1591 } else { |
| 1592 // Generate standard code. |
| 1593 __ li(at, constant); |
| 1594 __ Mul(result, left, at); |
| 1595 } |
| 1596 } |
1495 | 1597 |
1496 } else { | 1598 } else { |
1497 DCHECK(right_op->IsRegister()); | 1599 DCHECK(right_op->IsRegister()); |
1498 Register right = ToRegister(right_op); | 1600 Register right = ToRegister(right_op); |
1499 | 1601 |
1500 if (overflow) { | 1602 if (overflow) { |
1501 // hi:lo = left * right. | 1603 // hi:lo = left * right. |
1502 if (instr->hydrogen()->representation().IsSmi()) { | 1604 __ Dmul(result, left, right); |
1503 __ Dmulh(result, left, right); | |
1504 } else { | |
1505 __ Dmul(result, left, right); | |
1506 } | |
1507 __ dsra32(scratch, result, 0); | 1605 __ dsra32(scratch, result, 0); |
1508 __ sra(at, result, 31); | 1606 __ sra(at, result, 31); |
1509 if (instr->hydrogen()->representation().IsSmi()) { | 1607 |
1510 __ SmiTag(result); | |
1511 } | |
1512 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); | 1608 DeoptimizeIf(ne, instr, Deoptimizer::kOverflow, scratch, Operand(at)); |
1513 } else { | 1609 } else { |
1514 if (instr->hydrogen()->representation().IsSmi()) { | 1610 __ mul(result, left, right); |
1515 __ SmiUntag(result, left); | |
1516 __ Dmul(result, result, right); | |
1517 } else { | |
1518 __ Dmul(result, left, right); | |
1519 } | |
1520 } | 1611 } |
1521 | 1612 |
1522 if (bailout_on_minus_zero) { | 1613 if (bailout_on_minus_zero) { |
1523 Label done; | 1614 Label done; |
1524 __ Xor(at, left, right); | 1615 __ Xor(at, left, right); |
1525 __ Branch(&done, ge, at, Operand(zero_reg)); | 1616 __ Branch(&done, ge, at, Operand(zero_reg)); |
1526 // Bail out if the result is minus zero. | 1617 // Bail out if the result is minus zero. |
1527 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, | 1618 DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero, result, |
1528 Operand(zero_reg)); | 1619 Operand(zero_reg)); |
1529 __ bind(&done); | 1620 __ bind(&done); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1645 } | 1736 } |
1646 break; | 1737 break; |
1647 default: | 1738 default: |
1648 UNREACHABLE(); | 1739 UNREACHABLE(); |
1649 break; | 1740 break; |
1650 } | 1741 } |
1651 } | 1742 } |
1652 } | 1743 } |
1653 | 1744 |
1654 | 1745 |
| 1746 void LCodeGen::DoSubS(LSubS* instr) { |
| 1747 LOperand* left = instr->left(); |
| 1748 LOperand* right = instr->right(); |
| 1749 LOperand* result = instr->result(); |
| 1750 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1751 |
| 1752 if (!can_overflow) { |
| 1753 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
| 1754 __ Dsubu(ToRegister(result), ToRegister(left), ToOperand(right)); |
| 1755 } else { // can_overflow. |
| 1756 Register overflow = scratch0(); |
| 1757 Register scratch = scratch1(); |
| 1758 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
| 1759 __ DsubuAndCheckForOverflow(ToRegister(result), ToRegister(left), |
| 1760 ToOperand(right), overflow, scratch); |
| 1761 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, |
| 1762 Operand(zero_reg)); |
| 1763 } |
| 1764 } |
| 1765 |
| 1766 |
1655 void LCodeGen::DoSubI(LSubI* instr) { | 1767 void LCodeGen::DoSubI(LSubI* instr) { |
1656 LOperand* left = instr->left(); | 1768 LOperand* left = instr->left(); |
1657 LOperand* right = instr->right(); | 1769 LOperand* right = instr->right(); |
1658 LOperand* result = instr->result(); | 1770 LOperand* result = instr->result(); |
1659 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1771 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1660 | 1772 |
1661 if (!can_overflow) { | 1773 if (!can_overflow) { |
1662 if (right->IsStackSlot()) { | 1774 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1663 Register right_reg = EmitLoadRegister(right, at); | 1775 __ Subu(ToRegister(result), ToRegister(left), ToOperand(right)); |
1664 __ Dsubu(ToRegister(result), ToRegister(left), Operand(right_reg)); | |
1665 } else { | |
1666 DCHECK(right->IsRegister() || right->IsConstantOperand()); | |
1667 __ Dsubu(ToRegister(result), ToRegister(left), ToOperand(right)); | |
1668 } | |
1669 } else { // can_overflow. | 1776 } else { // can_overflow. |
1670 Register overflow = scratch0(); | 1777 Register overflow = scratch0(); |
1671 Register scratch = scratch1(); | 1778 Register scratch = scratch1(); |
1672 if (right->IsStackSlot() || right->IsConstantOperand()) { | 1779 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1673 Register right_reg = EmitLoadRegister(right, scratch); | 1780 __ SubuAndCheckForOverflow(ToRegister(result), ToRegister(left), |
1674 __ SubuAndCheckForOverflow(ToRegister(result), | 1781 ToOperand(right), overflow, scratch); |
1675 ToRegister(left), | |
1676 right_reg, | |
1677 overflow); // Reg at also used as scratch. | |
1678 } else { | |
1679 DCHECK(right->IsRegister()); | |
1680 // Due to overflow check macros not supporting constant operands, | |
1681 // handling the IsConstantOperand case was moved to prev if clause. | |
1682 __ SubuAndCheckForOverflow(ToRegister(result), | |
1683 ToRegister(left), | |
1684 ToRegister(right), | |
1685 overflow); // Reg at also used as scratch. | |
1686 } | |
1687 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, | 1782 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, |
1688 Operand(zero_reg)); | 1783 Operand(zero_reg)); |
1689 if (!instr->hydrogen()->representation().IsSmi()) { | |
1690 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, ToRegister(result), | |
1691 Operand(kMaxInt)); | |
1692 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, ToRegister(result), | |
1693 Operand(kMinInt)); | |
1694 } | |
1695 } | 1784 } |
1696 } | 1785 } |
1697 | 1786 |
1698 | 1787 |
1699 void LCodeGen::DoConstantI(LConstantI* instr) { | 1788 void LCodeGen::DoConstantI(LConstantI* instr) { |
1700 __ li(ToRegister(instr->result()), Operand(instr->value())); | 1789 __ li(ToRegister(instr->result()), Operand(instr->value())); |
1701 } | 1790 } |
1702 | 1791 |
1703 | 1792 |
1704 void LCodeGen::DoConstantS(LConstantS* instr) { | 1793 void LCodeGen::DoConstantS(LConstantS* instr) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 LOperand* result = instr->result(); | 1937 LOperand* result = instr->result(); |
1849 LOperand* left = instr->left(); | 1938 LOperand* left = instr->left(); |
1850 LOperand* right = instr->right(); | 1939 LOperand* right = instr->right(); |
1851 | 1940 |
1852 DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); | 1941 DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)); |
1853 DCHECK(right->IsRegister() || right->IsConstantOperand()); | 1942 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1854 __ Daddu(ToRegister(result), ToRegister(left), ToOperand(right)); | 1943 __ Daddu(ToRegister(result), ToRegister(left), ToOperand(right)); |
1855 } | 1944 } |
1856 | 1945 |
1857 | 1946 |
1858 void LCodeGen::DoAddI(LAddI* instr) { | 1947 void LCodeGen::DoAddS(LAddS* instr) { |
1859 LOperand* left = instr->left(); | 1948 LOperand* left = instr->left(); |
1860 LOperand* right = instr->right(); | 1949 LOperand* right = instr->right(); |
1861 LOperand* result = instr->result(); | 1950 LOperand* result = instr->result(); |
1862 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 1951 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
1863 | 1952 |
1864 if (!can_overflow) { | 1953 if (!can_overflow) { |
1865 DCHECK(right->IsRegister() || right->IsConstantOperand()); | 1954 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1866 __ Daddu(ToRegister(result), ToRegister(left), ToOperand(right)); | 1955 __ Daddu(ToRegister(result), ToRegister(left), ToOperand(right)); |
1867 } else { // can_overflow. | 1956 } else { // can_overflow. |
1868 Register overflow = scratch0(); | 1957 Register overflow = scratch0(); |
1869 Register scratch = scratch1(); | 1958 Register scratch = scratch1(); |
1870 if (right->IsConstantOperand()) { | 1959 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
1871 Register right_reg = EmitLoadRegister(right, scratch); | 1960 __ DadduAndCheckForOverflow(ToRegister(result), ToRegister(left), |
1872 __ AdduAndCheckForOverflow(ToRegister(result), | 1961 ToOperand(right), overflow, scratch); |
1873 ToRegister(left), | |
1874 right_reg, | |
1875 overflow); // Reg at also used as scratch. | |
1876 } else { | |
1877 DCHECK(right->IsRegister()); | |
1878 // Due to overflow check macros not supporting constant operands, | |
1879 // handling the IsConstantOperand case was moved to prev if clause. | |
1880 __ AdduAndCheckForOverflow(ToRegister(result), | |
1881 ToRegister(left), | |
1882 ToRegister(right), | |
1883 overflow); // Reg at also used as scratch. | |
1884 } | |
1885 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, | 1962 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, |
1886 Operand(zero_reg)); | 1963 Operand(zero_reg)); |
1887 // if not smi, it must int32. | |
1888 if (!instr->hydrogen()->representation().IsSmi()) { | |
1889 DeoptimizeIf(gt, instr, Deoptimizer::kOverflow, ToRegister(result), | |
1890 Operand(kMaxInt)); | |
1891 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, ToRegister(result), | |
1892 Operand(kMinInt)); | |
1893 } | |
1894 } | 1964 } |
1895 } | 1965 } |
1896 | 1966 |
| 1967 |
| 1968 void LCodeGen::DoAddI(LAddI* instr) { |
| 1969 LOperand* left = instr->left(); |
| 1970 LOperand* right = instr->right(); |
| 1971 LOperand* result = instr->result(); |
| 1972 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 1973 |
| 1974 if (!can_overflow) { |
| 1975 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
| 1976 __ Addu(ToRegister(result), ToRegister(left), ToOperand(right)); |
| 1977 } else { // can_overflow. |
| 1978 Register overflow = scratch0(); |
| 1979 Register scratch = scratch1(); |
| 1980 DCHECK(right->IsRegister() || right->IsConstantOperand()); |
| 1981 __ AdduAndCheckForOverflow(ToRegister(result), ToRegister(left), |
| 1982 ToOperand(right), overflow, scratch); |
| 1983 DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow, |
| 1984 Operand(zero_reg)); |
| 1985 } |
| 1986 } |
| 1987 |
1897 | 1988 |
1898 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { | 1989 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
1899 LOperand* left = instr->left(); | 1990 LOperand* left = instr->left(); |
1900 LOperand* right = instr->right(); | 1991 LOperand* right = instr->right(); |
1901 HMathMinMax::Operation operation = instr->hydrogen()->operation(); | 1992 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
1902 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; | 1993 Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge; |
1903 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { | 1994 if (instr->hydrogen()->representation().IsSmiOrInteger32()) { |
1904 Register left_reg = ToRegister(left); | 1995 Register left_reg = ToRegister(left); |
1905 Register right_reg = EmitLoadRegister(right, scratch0()); | 1996 Register right_reg = EmitLoadRegister(right, scratch0()); |
1906 Register result_reg = ToRegister(instr->result()); | 1997 Register result_reg = ToRegister(instr->result()); |
(...skipping 4171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6078 __ Push(at, ToRegister(instr->function())); | 6169 __ Push(at, ToRegister(instr->function())); |
6079 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6170 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
6080 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6171 RecordSafepoint(Safepoint::kNoLazyDeopt); |
6081 } | 6172 } |
6082 | 6173 |
6083 | 6174 |
6084 #undef __ | 6175 #undef __ |
6085 | 6176 |
6086 } // namespace internal | 6177 } // namespace internal |
6087 } // namespace v8 | 6178 } // namespace v8 |
OLD | NEW |