OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1362 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); | 1362 return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); |
1363 } | 1363 } |
1364 | 1364 |
1365 | 1365 |
1366 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { | 1366 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { |
1367 return AssignEnvironment(new(zone()) LDeoptimize); | 1367 return AssignEnvironment(new(zone()) LDeoptimize); |
1368 } | 1368 } |
1369 | 1369 |
1370 | 1370 |
1371 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { | 1371 LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) { |
1372 ASSERT(instr->representation().IsSmiOrInteger32()); | 1372 ASSERT(instr->representation().IsInteger32()); |
1373 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1373 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1374 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1374 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1375 LOperand* dividend = UseRegister(instr->left()); | 1375 LOperand* dividend = UseRegister(instr->left()); |
1376 int32_t divisor = instr->right()->GetInteger32Constant(); | 1376 int32_t divisor = instr->right()->GetInteger32Constant(); |
1377 LInstruction* result = | 1377 LInstruction* result = |
1378 DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor)); | 1378 DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor)); |
1379 bool can_deopt = | 1379 bool can_deopt = |
1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && | 1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
1381 instr->left()->RangeCanInclude(0) && divisor < 0) || | 1381 instr->left()->RangeCanInclude(0) && divisor < 0) || |
1382 (instr->CheckFlag(HValue::kCanOverflow) && | 1382 (instr->CheckFlag(HValue::kCanOverflow) && |
1383 instr->left()->RangeCanInclude(kMinInt) && divisor == -1) || | 1383 instr->left()->RangeCanInclude(kMinInt) && divisor == -1) || |
1384 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1384 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
1385 divisor != 1 && divisor != -1); | 1385 divisor != 1 && divisor != -1); |
1386 return can_deopt ? AssignEnvironment(result) : result; | 1386 return can_deopt ? AssignEnvironment(result) : result; |
1387 } | 1387 } |
1388 | 1388 |
1389 | 1389 |
| 1390 LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) { |
| 1391 ASSERT(instr->representation().IsInteger32()); |
| 1392 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1393 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1394 LOperand* dividend = UseRegister(instr->left()); |
| 1395 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1396 bool truncating = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32); |
| 1397 LOperand* temp = truncating ? NULL : TempRegister(); |
| 1398 LInstruction* result = |
| 1399 DefineAsRegister(new(zone()) LDivByConstI(dividend, divisor, temp)); |
| 1400 bool can_deopt = |
| 1401 divisor == 0 || |
| 1402 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1403 instr->left()->RangeCanInclude(0) && divisor < 0) || |
| 1404 !truncating; |
| 1405 return can_deopt ? AssignEnvironment(result) : result; |
| 1406 } |
| 1407 |
| 1408 |
1390 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { | 1409 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { |
1391 ASSERT(instr->representation().IsSmiOrInteger32()); | 1410 ASSERT(instr->representation().IsSmiOrInteger32()); |
1392 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1411 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1393 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1412 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1394 LOperand* dividend = UseRegister(instr->left()); | 1413 LOperand* dividend = UseRegister(instr->left()); |
1395 LOperand* divisor = UseRegister(instr->right()); | 1414 LOperand* divisor = UseRegister(instr->right()); |
1396 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) | 1415 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
1397 ? NULL : TempRegister(); | 1416 ? NULL : TempRegister(); |
1398 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); | 1417 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
1399 return AssignEnvironment(DefineAsRegister(div)); | 1418 return AssignEnvironment(DefineAsRegister(div)); |
1400 } | 1419 } |
1401 | 1420 |
1402 | 1421 |
1403 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1422 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1404 if (instr->representation().IsSmiOrInteger32()) { | 1423 if (instr->representation().IsSmiOrInteger32()) { |
1405 // TODO(all): Add Smi support to DoDivI and turn this into a ternary. | 1424 if (instr->RightIsPowerOf2()) { |
1406 if (instr->RightIsPowerOf2()) return DoDivByPowerOf2I(instr); | 1425 return DoDivByPowerOf2I(instr); |
1407 if (instr->representation().IsInteger32()) return DoDivI(instr); | 1426 } else if (instr->right()->IsConstant()) { |
1408 return DoArithmeticT(Token::DIV, instr); | 1427 return DoDivByConstI(instr); |
| 1428 } else { |
| 1429 return DoDivI(instr); |
| 1430 } |
1409 } else if (instr->representation().IsDouble()) { | 1431 } else if (instr->representation().IsDouble()) { |
1410 return DoArithmeticD(Token::DIV, instr); | 1432 return DoArithmeticD(Token::DIV, instr); |
1411 } else { | 1433 } else { |
1412 return DoArithmeticT(Token::DIV, instr); | 1434 return DoArithmeticT(Token::DIV, instr); |
1413 } | 1435 } |
1414 } | 1436 } |
1415 | 1437 |
1416 | 1438 |
1417 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 1439 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
1418 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 1440 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1707 } | 1729 } |
1708 | 1730 |
1709 | 1731 |
1710 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1732 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
1711 LOperand* map = UseRegisterAtStart(instr->value()); | 1733 LOperand* map = UseRegisterAtStart(instr->value()); |
1712 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1734 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
1713 } | 1735 } |
1714 | 1736 |
1715 | 1737 |
1716 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { | 1738 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { |
| 1739 ASSERT(instr->representation().IsInteger32()); |
| 1740 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1741 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1717 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1742 LOperand* dividend = UseRegisterAtStart(instr->left()); |
1718 int32_t divisor = instr->right()->GetInteger32Constant(); | 1743 int32_t divisor = instr->right()->GetInteger32Constant(); |
1719 LInstruction* result = | 1744 LInstruction* result = |
1720 DefineSameAsFirst(new(zone()) LFlooringDivByPowerOf2I(dividend, divisor)); | 1745 DefineSameAsFirst(new(zone()) LFlooringDivByPowerOf2I(dividend, divisor)); |
1721 bool can_deopt = | 1746 bool can_deopt = |
1722 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || | 1747 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
1723 (instr->left()->RangeCanInclude(kMinInt) && divisor == -1); | 1748 (instr->left()->RangeCanInclude(kMinInt) && divisor == -1); |
1724 return can_deopt ? AssignEnvironment(result) : result; | 1749 return can_deopt ? AssignEnvironment(result) : result; |
1725 } | 1750 } |
1726 | 1751 |
1727 | 1752 |
| 1753 LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) { |
| 1754 ASSERT(instr->representation().IsInteger32()); |
| 1755 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1756 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1757 LOperand* dividend = UseRegister(instr->left()); |
| 1758 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1759 LInstruction* result = |
| 1760 DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor)); |
| 1761 bool can_deopt = |
| 1762 divisor == 0 || |
| 1763 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1764 instr->left()->RangeCanInclude(0) && divisor < 0); |
| 1765 return can_deopt ? AssignEnvironment(result) : result; |
| 1766 } |
| 1767 |
| 1768 |
1728 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { | 1769 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
1729 LOperand* dividend = UseRegister(instr->left()); | 1770 LOperand* dividend = UseRegister(instr->left()); |
1730 LOperand* divisor = UseRegister(instr->right()); | 1771 LOperand* divisor = UseRegister(instr->right()); |
1731 LOperand* remainder = TempRegister(); | 1772 LOperand* remainder = TempRegister(); |
1732 LInstruction* result = | 1773 LInstruction* result = |
1733 DefineAsRegister(new(zone()) LFlooringDivI(dividend, divisor, remainder)); | 1774 DefineAsRegister(new(zone()) LFlooringDivI(dividend, divisor, remainder)); |
1734 return AssignEnvironment(result); | 1775 return AssignEnvironment(result); |
1735 } | 1776 } |
1736 | 1777 |
1737 | 1778 |
1738 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1779 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
1739 if (instr->RightIsPowerOf2()) { | 1780 if (instr->RightIsPowerOf2()) { |
1740 return DoFlooringDivByPowerOf2I(instr); | 1781 return DoFlooringDivByPowerOf2I(instr); |
1741 } else if (instr->right()->IsConstant()) { | 1782 } else if (instr->right()->IsConstant()) { |
1742 // TODO(svenpanne) Do something more efficient in this case. | 1783 return DoFlooringDivByConstI(instr); |
1743 return DoFlooringDivI(instr); | |
1744 } else { | 1784 } else { |
1745 return DoFlooringDivI(instr); | 1785 return DoFlooringDivI(instr); |
1746 } | 1786 } |
1747 } | 1787 } |
1748 | 1788 |
1749 | 1789 |
1750 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1790 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1751 LOperand* left = NULL; | 1791 LOperand* left = NULL; |
1752 LOperand* right = NULL; | 1792 LOperand* right = NULL; |
1753 if (instr->representation().IsSmiOrInteger32()) { | 1793 if (instr->representation().IsSmiOrInteger32()) { |
1754 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1794 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1755 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1795 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1756 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1796 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1757 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 1797 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
1758 } else { | 1798 } else { |
1759 ASSERT(instr->representation().IsDouble()); | 1799 ASSERT(instr->representation().IsDouble()); |
1760 ASSERT(instr->left()->representation().IsDouble()); | 1800 ASSERT(instr->left()->representation().IsDouble()); |
1761 ASSERT(instr->right()->representation().IsDouble()); | 1801 ASSERT(instr->right()->representation().IsDouble()); |
1762 left = UseRegisterAtStart(instr->left()); | 1802 left = UseRegisterAtStart(instr->left()); |
1763 right = UseRegisterAtStart(instr->right()); | 1803 right = UseRegisterAtStart(instr->right()); |
1764 } | 1804 } |
1765 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1805 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
1766 } | 1806 } |
1767 | 1807 |
1768 | 1808 |
1769 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { | 1809 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
1770 ASSERT(instr->representation().IsSmiOrInteger32()); | 1810 ASSERT(instr->representation().IsInteger32()); |
1771 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1811 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1772 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1812 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1773 LOperand* dividend = UseRegisterAtStart(instr->left()); | 1813 LOperand* dividend = UseRegisterAtStart(instr->left()); |
1774 int32_t divisor = instr->right()->GetInteger32Constant(); | 1814 int32_t divisor = instr->right()->GetInteger32Constant(); |
1775 LInstruction* result = | 1815 LInstruction* result = |
1776 DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor)); | 1816 DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor)); |
1777 bool can_deopt = | 1817 bool can_deopt = |
1778 instr->CheckFlag(HValue::kBailoutOnMinusZero) && | 1818 instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
1779 instr->left()->CanBeNegative(); | 1819 instr->left()->CanBeNegative(); |
1780 return can_deopt ? AssignEnvironment(result) : result; | 1820 return can_deopt ? AssignEnvironment(result) : result; |
1781 } | 1821 } |
1782 | 1822 |
1783 | 1823 |
| 1824 LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) { |
| 1825 ASSERT(instr->representation().IsInteger32()); |
| 1826 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1827 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1828 LOperand* dividend = UseRegister(instr->left()); |
| 1829 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1830 LOperand* temp = TempRegister(); |
| 1831 LInstruction* result = |
| 1832 DefineAsRegister(new(zone()) LModByConstI(dividend, divisor, temp)); |
| 1833 bool can_deopt = |
| 1834 divisor == 0 || |
| 1835 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1836 instr->left()->CanBeNegative()); |
| 1837 return can_deopt ? AssignEnvironment(result) : result; |
| 1838 } |
| 1839 |
| 1840 |
1784 LInstruction* LChunkBuilder::DoModI(HMod* instr) { | 1841 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
1785 ASSERT(instr->representation().IsSmiOrInteger32()); | 1842 ASSERT(instr->representation().IsSmiOrInteger32()); |
1786 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1843 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1787 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1844 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1788 LOperand* dividend = UseRegister(instr->left()); | 1845 LOperand* dividend = UseRegister(instr->left()); |
1789 LOperand* divisor = UseRegister(instr->right()); | 1846 LOperand* divisor = UseRegister(instr->right()); |
1790 LInstruction* result = | 1847 LInstruction* result = |
1791 DefineAsRegister(new(zone()) LModI(dividend, divisor)); | 1848 DefineAsRegister(new(zone()) LModI(dividend, divisor)); |
1792 bool can_deopt = (instr->right()->CanBeZero() || | 1849 bool can_deopt = (instr->right()->CanBeZero() || |
1793 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && | 1850 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
1794 instr->left()->CanBeNegative() && instr->CanBeZero())); | 1851 instr->left()->CanBeNegative() && instr->CanBeZero())); |
1795 return can_deopt ? AssignEnvironment(result) : result; | 1852 return can_deopt ? AssignEnvironment(result) : result; |
1796 } | 1853 } |
1797 | 1854 |
1798 | 1855 |
1799 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1856 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1800 if (instr->representation().IsSmiOrInteger32()) { | 1857 if (instr->representation().IsSmiOrInteger32()) { |
1801 // TODO(all): Add Smi support to DoDivI and turn this into a ternary. | 1858 if (instr->RightIsPowerOf2()) { |
1802 if (instr->RightIsPowerOf2()) return DoModByPowerOf2I(instr); | 1859 return DoModByPowerOf2I(instr); |
1803 if (instr->representation().IsInteger32()) return DoModI(instr); | 1860 } else if (instr->right()->IsConstant()) { |
1804 return DoArithmeticT(Token::MOD, instr); | 1861 return DoModByConstI(instr); |
| 1862 } else { |
| 1863 return DoModI(instr); |
| 1864 } |
1805 } else if (instr->representation().IsDouble()) { | 1865 } else if (instr->representation().IsDouble()) { |
1806 return DoArithmeticD(Token::MOD, instr); | 1866 return DoArithmeticD(Token::MOD, instr); |
1807 } else { | 1867 } else { |
1808 return DoArithmeticT(Token::MOD, instr); | 1868 return DoArithmeticT(Token::MOD, instr); |
1809 } | 1869 } |
1810 } | 1870 } |
1811 | 1871 |
1812 | 1872 |
1813 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1873 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1814 if (instr->representation().IsSmiOrInteger32()) { | 1874 if (instr->representation().IsSmiOrInteger32()) { |
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2492 | 2552 |
2493 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 2553 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
2494 LOperand* receiver = UseRegister(instr->receiver()); | 2554 LOperand* receiver = UseRegister(instr->receiver()); |
2495 LOperand* function = UseRegister(instr->function()); | 2555 LOperand* function = UseRegister(instr->function()); |
2496 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); | 2556 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); |
2497 return AssignEnvironment(DefineAsRegister(result)); | 2557 return AssignEnvironment(DefineAsRegister(result)); |
2498 } | 2558 } |
2499 | 2559 |
2500 | 2560 |
2501 } } // namespace v8::internal | 2561 } } // namespace v8::internal |
OLD | NEW |