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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
875 Node* value = assembler->Float64Add(lhs_value, rhs_value); | 875 Node* value = assembler->Float64Add(lhs_value, rhs_value); |
876 Node* result = assembler->ChangeFloat64ToTagged(value); | 876 Node* result = assembler->ChangeFloat64ToTagged(value); |
877 var_result.Bind(result); | 877 var_result.Bind(result); |
878 assembler->Goto(&end); | 878 assembler->Goto(&end); |
879 } | 879 } |
880 assembler->Bind(&end); | 880 assembler->Bind(&end); |
881 return var_result.value(); | 881 return var_result.value(); |
882 } | 882 } |
883 | 883 |
884 // static | 884 // static |
885 compiler::Node* AddSmiStub::Generate(CodeStubAssembler* assembler, | |
886 compiler::Node* left, | |
887 compiler::Node* right, | |
888 compiler::Node* context) { | |
889 typedef CodeStubAssembler::Label Label; | |
890 typedef compiler::Node Node; | |
891 typedef CodeStubAssembler::Variable Variable; | |
892 | |
893 Variable var_result(assembler, MachineRepresentation::kTagged); | |
894 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), | |
895 end(assembler); | |
896 | |
897 // {right} is known to be a Smi. | |
rmcilroy
2016/07/04 12:35:32
Maybe add some code under FLAG_debug_code which ab
oth
2016/07/04 14:56:24
Done. CodeStubAssembler::Assert is conditional on
| |
898 // Check if the {left} is a Smi take the fast path. | |
899 assembler->BranchIf(assembler->WordIsSmi(left), &fastpath, &slowpath); | |
900 assembler->Bind(&fastpath); | |
901 { | |
902 // Try fast Smi addition first. | |
903 Node* pair = assembler->SmiAddWithOverflow(left, right); | |
904 Node* overflow = assembler->Projection(1, pair); | |
905 | |
906 // Check if the Smi additon overflowed. | |
907 Label if_notoverflow(assembler); | |
908 assembler->BranchIf(overflow, &slowpath, &if_notoverflow); | |
909 assembler->Bind(&if_notoverflow); | |
910 { | |
911 var_result.Bind(assembler->Projection(0, pair)); | |
912 assembler->Goto(&end); | |
913 } | |
914 } | |
915 assembler->Bind(&slowpath); | |
rmcilroy
2016/07/04 12:35:32
I wonder if it is worth doing the check for heap-n
oth
2016/07/04 14:56:24
Yes, I tried this. For x64 the stub size increases
| |
916 { | |
917 Callable callable = CodeFactory::Add(assembler->isolate()); | |
918 var_result.Bind(assembler->CallStub(callable, context, left, right)); | |
919 assembler->Goto(&end); | |
920 } | |
921 assembler->Bind(&end); | |
922 return var_result.value(); | |
923 } | |
924 | |
925 // static | |
885 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, | 926 compiler::Node* SubtractStub::Generate(CodeStubAssembler* assembler, |
886 compiler::Node* left, | 927 compiler::Node* left, |
887 compiler::Node* right, | 928 compiler::Node* right, |
888 compiler::Node* context) { | 929 compiler::Node* context) { |
889 typedef CodeStubAssembler::Label Label; | 930 typedef CodeStubAssembler::Label Label; |
890 typedef compiler::Node Node; | 931 typedef compiler::Node Node; |
891 typedef CodeStubAssembler::Variable Variable; | 932 typedef CodeStubAssembler::Variable Variable; |
892 | 933 |
893 // Shared entry for floating point subtraction. | 934 // Shared entry for floating point subtraction. |
894 Label do_fsub(assembler), end(assembler); | 935 Label do_fsub(assembler), end(assembler); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 Node* rhs_value = var_fsub_rhs.value(); | 1091 Node* rhs_value = var_fsub_rhs.value(); |
1051 Node* value = assembler->Float64Sub(lhs_value, rhs_value); | 1092 Node* value = assembler->Float64Sub(lhs_value, rhs_value); |
1052 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); | 1093 var_result.Bind(assembler->ChangeFloat64ToTagged(value)); |
1053 assembler->Goto(&end); | 1094 assembler->Goto(&end); |
1054 } | 1095 } |
1055 assembler->Bind(&end); | 1096 assembler->Bind(&end); |
1056 return var_result.value(); | 1097 return var_result.value(); |
1057 } | 1098 } |
1058 | 1099 |
1059 // static | 1100 // static |
1101 compiler::Node* SubtractSmiStub::Generate(CodeStubAssembler* assembler, | |
1102 compiler::Node* left, | |
1103 compiler::Node* right, | |
1104 compiler::Node* context) { | |
1105 typedef CodeStubAssembler::Label Label; | |
1106 typedef compiler::Node Node; | |
1107 typedef CodeStubAssembler::Variable Variable; | |
1108 | |
1109 Variable var_result(assembler, MachineRepresentation::kTagged); | |
1110 Label fastpath(assembler), slowpath(assembler, Label::kDeferred), | |
1111 end(assembler); | |
1112 | |
1113 // {right} is known to be a Smi. | |
1114 // Check if the {left} is a Smi take the fast path. | |
1115 assembler->BranchIf(assembler->WordIsSmi(left), &fastpath, &slowpath); | |
1116 assembler->Bind(&fastpath); | |
1117 { | |
1118 // Try fast Smi subtraction first. | |
1119 Node* pair = assembler->SmiSubWithOverflow(left, right); | |
1120 Node* overflow = assembler->Projection(1, pair); | |
1121 | |
1122 // Check if the Smi subtraction overflowed. | |
1123 Label if_notoverflow(assembler); | |
1124 assembler->BranchIf(overflow, &slowpath, &if_notoverflow); | |
1125 assembler->Bind(&if_notoverflow); | |
1126 { | |
1127 var_result.Bind(assembler->Projection(0, pair)); | |
1128 assembler->Goto(&end); | |
1129 } | |
1130 } | |
1131 assembler->Bind(&slowpath); | |
1132 { | |
1133 Callable callable = CodeFactory::Subtract(assembler->isolate()); | |
1134 var_result.Bind(assembler->CallStub(callable, context, left, right)); | |
1135 assembler->Goto(&end); | |
1136 } | |
1137 assembler->Bind(&end); | |
1138 return var_result.value(); | |
1139 } | |
1140 | |
1141 // static | |
1060 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, | 1142 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
1061 compiler::Node* left, | 1143 compiler::Node* left, |
1062 compiler::Node* right, | 1144 compiler::Node* right, |
1063 compiler::Node* context) { | 1145 compiler::Node* context) { |
1064 using compiler::Node; | 1146 using compiler::Node; |
1065 typedef CodeStubAssembler::Label Label; | 1147 typedef CodeStubAssembler::Label Label; |
1066 typedef CodeStubAssembler::Variable Variable; | 1148 typedef CodeStubAssembler::Variable Variable; |
1067 | 1149 |
1068 // Shared entry point for floating point multiplication. | 1150 // Shared entry point for floating point multiplication. |
1069 Label do_fmul(assembler); | 1151 Label do_fmul(assembler); |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1586 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1668 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1587 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1669 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1588 Node* shift_count = | 1670 Node* shift_count = |
1589 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1671 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); |
1590 Node* value = assembler->Word32Shl(lhs_value, shift_count); | 1672 Node* value = assembler->Word32Shl(lhs_value, shift_count); |
1591 Node* result = assembler->ChangeInt32ToTagged(value); | 1673 Node* result = assembler->ChangeInt32ToTagged(value); |
1592 return result; | 1674 return result; |
1593 } | 1675 } |
1594 | 1676 |
1595 // static | 1677 // static |
1678 compiler::Node* ShiftLeftSmiStub::Generate(CodeStubAssembler* assembler, | |
1679 compiler::Node* left, | |
1680 compiler::Node* right, | |
1681 compiler::Node* context) { | |
1682 using compiler::Node; | |
1683 | |
1684 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | |
1685 Node* rhs_value = assembler->SmiToWord32(right); | |
1686 Node* shift_count = | |
1687 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | |
1688 Node* value = assembler->Word32Shl(lhs_value, shift_count); | |
1689 Node* result = assembler->ChangeInt32ToTagged(value); | |
1690 return result; | |
1691 } | |
1692 | |
1693 // static | |
1596 compiler::Node* ShiftRightStub::Generate(CodeStubAssembler* assembler, | 1694 compiler::Node* ShiftRightStub::Generate(CodeStubAssembler* assembler, |
1597 compiler::Node* left, | 1695 compiler::Node* left, |
1598 compiler::Node* right, | 1696 compiler::Node* right, |
1599 compiler::Node* context) { | 1697 compiler::Node* context) { |
1600 using compiler::Node; | 1698 using compiler::Node; |
1601 | 1699 |
1602 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1700 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1603 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1701 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1604 Node* shift_count = | 1702 Node* shift_count = |
1605 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1703 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); |
1606 Node* value = assembler->Word32Sar(lhs_value, shift_count); | 1704 Node* value = assembler->Word32Sar(lhs_value, shift_count); |
1607 Node* result = assembler->ChangeInt32ToTagged(value); | 1705 Node* result = assembler->ChangeInt32ToTagged(value); |
1608 return result; | 1706 return result; |
1609 } | 1707 } |
1610 | 1708 |
1611 // static | 1709 // static |
1710 compiler::Node* ShiftRightSmiStub::Generate(CodeStubAssembler* assembler, | |
1711 compiler::Node* left, | |
1712 compiler::Node* right, | |
1713 compiler::Node* context) { | |
1714 using compiler::Node; | |
1715 | |
1716 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | |
1717 Node* rhs_value = assembler->SmiToWord32(right); | |
1718 Node* shift_count = | |
1719 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | |
1720 Node* value = assembler->Word32Sar(lhs_value, shift_count); | |
1721 Node* result = assembler->ChangeInt32ToTagged(value); | |
1722 return result; | |
1723 } | |
1724 | |
1725 // static | |
1612 compiler::Node* ShiftRightLogicalStub::Generate(CodeStubAssembler* assembler, | 1726 compiler::Node* ShiftRightLogicalStub::Generate(CodeStubAssembler* assembler, |
1613 compiler::Node* left, | 1727 compiler::Node* left, |
1614 compiler::Node* right, | 1728 compiler::Node* right, |
1615 compiler::Node* context) { | 1729 compiler::Node* context) { |
1616 using compiler::Node; | 1730 using compiler::Node; |
1617 | 1731 |
1618 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1732 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1619 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1733 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1620 Node* shift_count = | 1734 Node* shift_count = |
1621 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); | 1735 assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f)); |
(...skipping 10 matching lines...) Expand all Loading... | |
1632 using compiler::Node; | 1746 using compiler::Node; |
1633 | 1747 |
1634 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1748 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1635 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1749 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1636 Node* value = assembler->Word32And(lhs_value, rhs_value); | 1750 Node* value = assembler->Word32And(lhs_value, rhs_value); |
1637 Node* result = assembler->ChangeInt32ToTagged(value); | 1751 Node* result = assembler->ChangeInt32ToTagged(value); |
1638 return result; | 1752 return result; |
1639 } | 1753 } |
1640 | 1754 |
1641 // static | 1755 // static |
1756 compiler::Node* BitwiseAndSmiStub::Generate(CodeStubAssembler* assembler, | |
1757 compiler::Node* left, | |
1758 compiler::Node* right, | |
1759 compiler::Node* context) { | |
1760 using compiler::Node; | |
1761 | |
1762 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | |
1763 Node* rhs_value = assembler->SmiToWord32(right); | |
1764 Node* value = assembler->Word32And(lhs_value, rhs_value); | |
1765 Node* result = assembler->ChangeInt32ToTagged(value); | |
1766 return result; | |
1767 } | |
1768 | |
1769 // static | |
1642 compiler::Node* BitwiseOrStub::Generate(CodeStubAssembler* assembler, | 1770 compiler::Node* BitwiseOrStub::Generate(CodeStubAssembler* assembler, |
1643 compiler::Node* left, | 1771 compiler::Node* left, |
1644 compiler::Node* right, | 1772 compiler::Node* right, |
1645 compiler::Node* context) { | 1773 compiler::Node* context) { |
1646 using compiler::Node; | 1774 using compiler::Node; |
1647 | 1775 |
1648 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1776 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1649 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1777 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1650 Node* value = assembler->Word32Or(lhs_value, rhs_value); | 1778 Node* value = assembler->Word32Or(lhs_value, rhs_value); |
1651 Node* result = assembler->ChangeInt32ToTagged(value); | 1779 Node* result = assembler->ChangeInt32ToTagged(value); |
1652 return result; | 1780 return result; |
1653 } | 1781 } |
1654 | 1782 |
1655 // static | 1783 // static |
1784 compiler::Node* BitwiseOrSmiStub::Generate(CodeStubAssembler* assembler, | |
1785 compiler::Node* left, | |
1786 compiler::Node* right, | |
1787 compiler::Node* context) { | |
1788 using compiler::Node; | |
1789 | |
1790 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | |
1791 Node* rhs_value = assembler->SmiToWord32(right); | |
1792 Node* value = assembler->Word32Or(lhs_value, rhs_value); | |
1793 Node* result = assembler->ChangeInt32ToTagged(value); | |
1794 return result; | |
1795 } | |
1796 | |
1797 // static | |
1656 compiler::Node* BitwiseXorStub::Generate(CodeStubAssembler* assembler, | 1798 compiler::Node* BitwiseXorStub::Generate(CodeStubAssembler* assembler, |
1657 compiler::Node* left, | 1799 compiler::Node* left, |
1658 compiler::Node* right, | 1800 compiler::Node* right, |
1659 compiler::Node* context) { | 1801 compiler::Node* context) { |
1660 using compiler::Node; | 1802 using compiler::Node; |
1661 | 1803 |
1662 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); | 1804 Node* lhs_value = assembler->TruncateTaggedToWord32(context, left); |
1663 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); | 1805 Node* rhs_value = assembler->TruncateTaggedToWord32(context, right); |
1664 Node* value = assembler->Word32Xor(lhs_value, rhs_value); | 1806 Node* value = assembler->Word32Xor(lhs_value, rhs_value); |
1665 Node* result = assembler->ChangeInt32ToTagged(value); | 1807 Node* result = assembler->ChangeInt32ToTagged(value); |
(...skipping 25 matching lines...) Expand all Loading... | |
1691 Label if_issmi(assembler), if_isnotsmi(assembler); | 1833 Label if_issmi(assembler), if_isnotsmi(assembler); |
1692 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); | 1834 assembler->Branch(assembler->WordIsSmi(value), &if_issmi, &if_isnotsmi); |
1693 | 1835 |
1694 assembler->Bind(&if_issmi); | 1836 assembler->Bind(&if_issmi); |
1695 { | 1837 { |
1696 // Try fast Smi addition first. | 1838 // Try fast Smi addition first. |
1697 Node* one = assembler->SmiConstant(Smi::FromInt(1)); | 1839 Node* one = assembler->SmiConstant(Smi::FromInt(1)); |
1698 Node* pair = assembler->SmiAddWithOverflow(value, one); | 1840 Node* pair = assembler->SmiAddWithOverflow(value, one); |
1699 Node* overflow = assembler->Projection(1, pair); | 1841 Node* overflow = assembler->Projection(1, pair); |
1700 | 1842 |
1701 // Check if the Smi additon overflowed. | 1843 // Check if the Smi addition overflowed. |
1702 Label if_overflow(assembler), if_notoverflow(assembler); | 1844 Label if_overflow(assembler), if_notoverflow(assembler); |
1703 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | 1845 assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
1704 | 1846 |
1705 assembler->Bind(&if_notoverflow); | 1847 assembler->Bind(&if_notoverflow); |
1706 result_var.Bind(assembler->Projection(0, pair)); | 1848 result_var.Bind(assembler->Projection(0, pair)); |
1707 assembler->Goto(&end); | 1849 assembler->Goto(&end); |
1708 | 1850 |
1709 assembler->Bind(&if_overflow); | 1851 assembler->Bind(&if_overflow); |
1710 { | 1852 { |
1711 var_finc_value.Bind(assembler->SmiToFloat64(value)); | 1853 var_finc_value.Bind(assembler->SmiToFloat64(value)); |
(...skipping 3148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4860 if (type->Is(Type::UntaggedPointer())) { | 5002 if (type->Is(Type::UntaggedPointer())) { |
4861 return Representation::External(); | 5003 return Representation::External(); |
4862 } | 5004 } |
4863 | 5005 |
4864 DCHECK(!type->Is(Type::Untagged())); | 5006 DCHECK(!type->Is(Type::Untagged())); |
4865 return Representation::Tagged(); | 5007 return Representation::Tagged(); |
4866 } | 5008 } |
4867 | 5009 |
4868 } // namespace internal | 5010 } // namespace internal |
4869 } // namespace v8 | 5011 } // namespace v8 |
OLD | NEW |