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 1350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1361 LOperand* context = UseFixed(instr->context(), cp); | 1361 LOperand* context = UseFixed(instr->context(), cp); |
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) { |
| 1372 ASSERT(instr->representation().IsSmiOrInteger32()); |
| 1373 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1374 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1375 LOperand* dividend = UseRegister(instr->left()); |
| 1376 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1377 LInstruction* result = |
| 1378 DefineAsRegister(new(zone()) LDivByPowerOf2I(dividend, divisor)); |
| 1379 bool can_deopt = |
| 1380 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1381 instr->left()->RangeCanInclude(0) && divisor < 0) || |
| 1382 (instr->CheckFlag(HValue::kCanOverflow) && |
| 1383 instr->left()->RangeCanInclude(kMinInt) && divisor == -1) || |
| 1384 (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1385 divisor != 1 && divisor != -1); |
| 1386 return can_deopt ? AssignEnvironment(result) : result; |
| 1387 } |
| 1388 |
| 1389 |
| 1390 LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { |
| 1391 ASSERT(instr->representation().IsSmiOrInteger32()); |
| 1392 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1393 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1394 LOperand* dividend = UseRegister(instr->left()); |
| 1395 LOperand* divisor = UseRegister(instr->right()); |
| 1396 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) |
| 1397 ? NULL : TempRegister(); |
| 1398 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); |
| 1399 return AssignEnvironment(DefineAsRegister(div)); |
| 1400 } |
| 1401 |
| 1402 |
1371 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { | 1403 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { |
1372 if (instr->representation().IsInteger32()) { | 1404 if (instr->representation().IsSmiOrInteger32()) { |
1373 // TODO(all): Update this case to support smi inputs. | 1405 // TODO(all): Add Smi support to DoDivI and turn this into a ternary. |
1374 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1406 if (instr->RightIsPowerOf2()) return DoDivByPowerOf2I(instr); |
1375 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1407 if (instr->representation().IsInteger32()) return DoDivI(instr); |
1376 if (instr->RightIsPowerOf2()) { | 1408 return DoArithmeticT(Token::DIV, instr); |
1377 ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); | |
1378 LOperand* value = UseRegister(instr->left()); | |
1379 LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); | |
1380 return AssignEnvironment(DefineAsRegister(div)); | |
1381 } | |
1382 LOperand* dividend = UseRegister(instr->left()); | |
1383 LOperand* divisor = UseRegister(instr->right()); | |
1384 LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) | |
1385 ? NULL : TempRegister(); | |
1386 LDivI* div = new(zone()) LDivI(dividend, divisor, temp); | |
1387 return AssignEnvironment(DefineAsRegister(div)); | |
1388 } else if (instr->representation().IsDouble()) { | 1409 } else if (instr->representation().IsDouble()) { |
1389 return DoArithmeticD(Token::DIV, instr); | 1410 return DoArithmeticD(Token::DIV, instr); |
1390 } else { | 1411 } else { |
1391 return DoArithmeticT(Token::DIV, instr); | 1412 return DoArithmeticT(Token::DIV, instr); |
1392 } | 1413 } |
1393 } | 1414 } |
1394 | 1415 |
1395 | 1416 |
1396 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { | 1417 LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { |
1397 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); | 1418 return DefineAsRegister(new(zone()) LDummyUse(UseAny(instr->value()))); |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 return DefineAsRegister(new(zone()) LLoadRoot); | 1706 return DefineAsRegister(new(zone()) LLoadRoot); |
1686 } | 1707 } |
1687 | 1708 |
1688 | 1709 |
1689 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { | 1710 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) { |
1690 LOperand* map = UseRegisterAtStart(instr->value()); | 1711 LOperand* map = UseRegisterAtStart(instr->value()); |
1691 return DefineAsRegister(new(zone()) LMapEnumLength(map)); | 1712 return DefineAsRegister(new(zone()) LMapEnumLength(map)); |
1692 } | 1713 } |
1693 | 1714 |
1694 | 1715 |
| 1716 LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { |
| 1717 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1718 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1719 LInstruction* result = |
| 1720 DefineSameAsFirst(new(zone()) LFlooringDivByPowerOf2I(dividend, divisor)); |
| 1721 bool can_deopt = |
| 1722 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || |
| 1723 (instr->left()->RangeCanInclude(kMinInt) && divisor == -1); |
| 1724 return can_deopt ? AssignEnvironment(result) : result; |
| 1725 } |
| 1726 |
| 1727 |
| 1728 LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) { |
| 1729 LOperand* dividend = UseRegister(instr->left()); |
| 1730 LOperand* divisor = UseRegister(instr->right()); |
| 1731 LOperand* remainder = TempRegister(); |
| 1732 LInstruction* result = |
| 1733 DefineAsRegister(new(zone()) LFlooringDivI(dividend, divisor, remainder)); |
| 1734 return AssignEnvironment(result); |
| 1735 } |
| 1736 |
| 1737 |
1695 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1738 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
1696 HValue* right = instr->right(); | 1739 if (instr->RightIsPowerOf2()) { |
1697 LOperand* dividend = UseRegister(instr->left()); | 1740 return DoFlooringDivByPowerOf2I(instr); |
1698 LOperand* divisor = UseRegister(right); | 1741 } else if (instr->right()->IsConstant()) { |
1699 LOperand* remainder = TempRegister(); | 1742 // TODO(svenpanne) Do something more efficient in this case. |
1700 return AssignEnvironment(DefineAsRegister( | 1743 return DoFlooringDivI(instr); |
1701 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); | 1744 } else { |
| 1745 return DoFlooringDivI(instr); |
| 1746 } |
1702 } | 1747 } |
1703 | 1748 |
1704 | 1749 |
1705 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { | 1750 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) { |
1706 LOperand* left = NULL; | 1751 LOperand* left = NULL; |
1707 LOperand* right = NULL; | 1752 LOperand* right = NULL; |
1708 if (instr->representation().IsSmiOrInteger32()) { | 1753 if (instr->representation().IsSmiOrInteger32()) { |
1709 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1754 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1710 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1755 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1711 left = UseRegisterAtStart(instr->BetterLeftOperand()); | 1756 left = UseRegisterAtStart(instr->BetterLeftOperand()); |
1712 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); | 1757 right = UseRegisterOrConstantAtStart(instr->BetterRightOperand()); |
1713 } else { | 1758 } else { |
1714 ASSERT(instr->representation().IsDouble()); | 1759 ASSERT(instr->representation().IsDouble()); |
1715 ASSERT(instr->left()->representation().IsDouble()); | 1760 ASSERT(instr->left()->representation().IsDouble()); |
1716 ASSERT(instr->right()->representation().IsDouble()); | 1761 ASSERT(instr->right()->representation().IsDouble()); |
1717 left = UseRegisterAtStart(instr->left()); | 1762 left = UseRegisterAtStart(instr->left()); |
1718 right = UseRegisterAtStart(instr->right()); | 1763 right = UseRegisterAtStart(instr->right()); |
1719 } | 1764 } |
1720 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); | 1765 return DefineAsRegister(new(zone()) LMathMinMax(left, right)); |
1721 } | 1766 } |
1722 | 1767 |
1723 | 1768 |
1724 LInstruction* LChunkBuilder::DoMod(HMod* hmod) { | 1769 LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) { |
1725 HValue* hleft = hmod->left(); | 1770 ASSERT(instr->representation().IsSmiOrInteger32()); |
1726 HValue* hright = hmod->right(); | 1771 ASSERT(instr->left()->representation().Equals(instr->representation())); |
| 1772 ASSERT(instr->right()->representation().Equals(instr->representation())); |
| 1773 LOperand* dividend = UseRegisterAtStart(instr->left()); |
| 1774 int32_t divisor = instr->right()->GetInteger32Constant(); |
| 1775 LInstruction* result = |
| 1776 DefineSameAsFirst(new(zone()) LModByPowerOf2I(dividend, divisor)); |
| 1777 bool can_deopt = |
| 1778 instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1779 instr->left()->CanBeNegative(); |
| 1780 return can_deopt ? AssignEnvironment(result) : result; |
| 1781 } |
1727 | 1782 |
1728 // TODO(jbramley): Add smi support. | |
1729 if (hmod->representation().IsInteger32()) { | |
1730 ASSERT(hleft->representation().IsInteger32()); | |
1731 ASSERT(hleft->representation().IsInteger32()); | |
1732 LOperand* left_op; | |
1733 LOperand* right_op; | |
1734 | 1783 |
1735 if (hmod->RightIsPowerOf2()) { | 1784 LInstruction* LChunkBuilder::DoModI(HMod* instr) { |
1736 left_op = UseRegisterAtStart(hleft); | 1785 ASSERT(instr->representation().IsSmiOrInteger32()); |
1737 right_op = UseConstant(hright); | 1786 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1738 } else { | 1787 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1739 right_op = UseRegister(hright); | 1788 LOperand* dividend = UseRegister(instr->left()); |
1740 left_op = UseRegister(hleft); | 1789 LOperand* divisor = UseRegister(instr->right()); |
1741 } | 1790 LInstruction* result = |
| 1791 DefineAsRegister(new(zone()) LModI(dividend, divisor)); |
| 1792 bool can_deopt = (instr->right()->CanBeZero() || |
| 1793 (instr->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1794 instr->left()->CanBeNegative() && instr->CanBeZero())); |
| 1795 return can_deopt ? AssignEnvironment(result) : result; |
| 1796 } |
1742 | 1797 |
1743 LModI* lmod = new(zone()) LModI(left_op, right_op); | |
1744 | 1798 |
1745 if (hmod->right()->CanBeZero() || | 1799 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
1746 (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && | 1800 if (instr->representation().IsSmiOrInteger32()) { |
1747 hmod->left()->CanBeNegative() && hmod->CanBeZero())) { | 1801 // TODO(all): Add Smi support to DoDivI and turn this into a ternary. |
1748 AssignEnvironment(lmod); | 1802 if (instr->RightIsPowerOf2()) return DoModByPowerOf2I(instr); |
1749 } | 1803 if (instr->representation().IsInteger32()) return DoModI(instr); |
1750 return DefineAsRegister(lmod); | 1804 return DoArithmeticT(Token::MOD, instr); |
1751 | 1805 } else if (instr->representation().IsDouble()) { |
1752 } else if (hmod->representation().IsSmiOrTagged()) { | 1806 return DoArithmeticD(Token::MOD, instr); |
1753 return DoArithmeticT(Token::MOD, hmod); | |
1754 } else { | 1807 } else { |
1755 return DoArithmeticD(Token::MOD, hmod); | 1808 return DoArithmeticT(Token::MOD, instr); |
1756 } | 1809 } |
1757 } | 1810 } |
1758 | 1811 |
1759 | 1812 |
1760 LInstruction* LChunkBuilder::DoMul(HMul* instr) { | 1813 LInstruction* LChunkBuilder::DoMul(HMul* instr) { |
1761 if (instr->representation().IsSmiOrInteger32()) { | 1814 if (instr->representation().IsSmiOrInteger32()) { |
1762 ASSERT(instr->left()->representation().Equals(instr->representation())); | 1815 ASSERT(instr->left()->representation().Equals(instr->representation())); |
1763 ASSERT(instr->right()->representation().Equals(instr->representation())); | 1816 ASSERT(instr->right()->representation().Equals(instr->representation())); |
1764 | 1817 |
1765 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); | 1818 bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); |
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2439 | 2492 |
2440 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { | 2493 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { |
2441 LOperand* receiver = UseRegister(instr->receiver()); | 2494 LOperand* receiver = UseRegister(instr->receiver()); |
2442 LOperand* function = UseRegister(instr->function()); | 2495 LOperand* function = UseRegister(instr->function()); |
2443 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); | 2496 LWrapReceiver* result = new(zone()) LWrapReceiver(receiver, function); |
2444 return AssignEnvironment(DefineAsRegister(result)); | 2497 return AssignEnvironment(DefineAsRegister(result)); |
2445 } | 2498 } |
2446 | 2499 |
2447 | 2500 |
2448 } } // namespace v8::internal | 2501 } } // namespace v8::internal |
OLD | NEW |