| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 __ b(cc, chunk_->GetAssemblyLabel(left_block)); | 1524 __ b(cc, chunk_->GetAssemblyLabel(left_block)); |
| 1525 __ b(chunk_->GetAssemblyLabel(right_block)); | 1525 __ b(chunk_->GetAssemblyLabel(right_block)); |
| 1526 } | 1526 } |
| 1527 } | 1527 } |
| 1528 | 1528 |
| 1529 | 1529 |
| 1530 void LCodeGen::DoBranch(LBranch* instr) { | 1530 void LCodeGen::DoBranch(LBranch* instr) { |
| 1531 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1531 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1532 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1532 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1533 | 1533 |
| 1534 Representation r = instr->hydrogen()->representation(); | 1534 Representation r = instr->hydrogen()->value()->representation(); |
| 1535 if (r.IsInteger32()) { | 1535 if (r.IsInteger32()) { |
| 1536 Register reg = ToRegister(instr->InputAt(0)); | 1536 Register reg = ToRegister(instr->InputAt(0)); |
| 1537 __ cmp(reg, Operand(0)); | 1537 __ cmp(reg, Operand(0)); |
| 1538 EmitBranch(true_block, false_block, ne); | 1538 EmitBranch(true_block, false_block, ne); |
| 1539 } else if (r.IsDouble()) { | 1539 } else if (r.IsDouble()) { |
| 1540 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0)); | 1540 DoubleRegister reg = ToDoubleRegister(instr->InputAt(0)); |
| 1541 Register scratch = scratch0(); | 1541 Register scratch = scratch0(); |
| 1542 | 1542 |
| 1543 // Test the double value. Zero and NaN are false. | 1543 // Test the double value. Zero and NaN are false. |
| 1544 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); | 1544 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); |
| 1545 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); | 1545 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); |
| 1546 EmitBranch(true_block, false_block, ne); | 1546 EmitBranch(true_block, false_block, ne); |
| 1547 } else { | 1547 } else { |
| 1548 ASSERT(r.IsTagged()); | 1548 ASSERT(r.IsTagged()); |
| 1549 Register reg = ToRegister(instr->InputAt(0)); | 1549 Register reg = ToRegister(instr->InputAt(0)); |
| 1550 if (instr->hydrogen()->type().IsBoolean()) { | 1550 if (instr->hydrogen()->value()->type().IsBoolean()) { |
| 1551 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 1551 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 1552 __ cmp(reg, ip); | 1552 __ cmp(reg, ip); |
| 1553 EmitBranch(true_block, false_block, eq); | 1553 EmitBranch(true_block, false_block, eq); |
| 1554 } else { | 1554 } else { |
| 1555 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1555 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1556 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1556 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1557 | 1557 |
| 1558 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1558 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 1559 __ cmp(reg, ip); | 1559 __ cmp(reg, ip); |
| 1560 __ b(eq, false_label); | 1560 __ b(eq, false_label); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 } | 1638 } |
| 1639 return cond; | 1639 return cond; |
| 1640 } | 1640 } |
| 1641 | 1641 |
| 1642 | 1642 |
| 1643 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { | 1643 void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { |
| 1644 __ cmp(ToRegister(left), ToRegister(right)); | 1644 __ cmp(ToRegister(left), ToRegister(right)); |
| 1645 } | 1645 } |
| 1646 | 1646 |
| 1647 | 1647 |
| 1648 void LCodeGen::DoCmpID(LCmpID* instr) { | |
| 1649 LOperand* left = instr->InputAt(0); | |
| 1650 LOperand* right = instr->InputAt(1); | |
| 1651 LOperand* result = instr->result(); | |
| 1652 Register scratch = scratch0(); | |
| 1653 | |
| 1654 Label unordered, done; | |
| 1655 if (instr->is_double()) { | |
| 1656 // Compare left and right as doubles and load the | |
| 1657 // resulting flags into the normal status register. | |
| 1658 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); | |
| 1659 // If a NaN is involved, i.e. the result is unordered (V set), | |
| 1660 // jump to unordered to return false. | |
| 1661 __ b(vs, &unordered); | |
| 1662 } else { | |
| 1663 EmitCmpI(left, right); | |
| 1664 } | |
| 1665 | |
| 1666 Condition cc = TokenToCondition(instr->op(), instr->is_double()); | |
| 1667 __ LoadRoot(ToRegister(result), Heap::kTrueValueRootIndex); | |
| 1668 __ b(cc, &done); | |
| 1669 | |
| 1670 __ bind(&unordered); | |
| 1671 __ LoadRoot(ToRegister(result), Heap::kFalseValueRootIndex); | |
| 1672 __ bind(&done); | |
| 1673 } | |
| 1674 | |
| 1675 | |
| 1676 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { | 1648 void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { |
| 1677 LOperand* left = instr->InputAt(0); | 1649 LOperand* left = instr->InputAt(0); |
| 1678 LOperand* right = instr->InputAt(1); | 1650 LOperand* right = instr->InputAt(1); |
| 1679 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1651 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1680 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1652 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1681 | 1653 |
| 1682 if (instr->is_double()) { | 1654 if (instr->is_double()) { |
| 1683 // Compare left and right as doubles and load the | 1655 // Compare left and right as doubles and load the |
| 1684 // resulting flags into the normal status register. | 1656 // resulting flags into the normal status register. |
| 1685 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); | 1657 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); |
| 1686 // If a NaN is involved, i.e. the result is unordered (V set), | 1658 // If a NaN is involved, i.e. the result is unordered (V set), |
| 1687 // jump to false block label. | 1659 // jump to false block label. |
| 1688 __ b(vs, chunk_->GetAssemblyLabel(false_block)); | 1660 __ b(vs, chunk_->GetAssemblyLabel(false_block)); |
| 1689 } else { | 1661 } else { |
| 1690 EmitCmpI(left, right); | 1662 EmitCmpI(left, right); |
| 1691 } | 1663 } |
| 1692 | 1664 |
| 1693 Condition cc = TokenToCondition(instr->op(), instr->is_double()); | 1665 Condition cc = TokenToCondition(instr->op(), instr->is_double()); |
| 1694 EmitBranch(true_block, false_block, cc); | 1666 EmitBranch(true_block, false_block, cc); |
| 1695 } | 1667 } |
| 1696 | 1668 |
| 1697 | 1669 |
| 1698 void LCodeGen::DoCmpObjectEq(LCmpObjectEq* instr) { | |
| 1699 Register left = ToRegister(instr->InputAt(0)); | |
| 1700 Register right = ToRegister(instr->InputAt(1)); | |
| 1701 Register result = ToRegister(instr->result()); | |
| 1702 | |
| 1703 __ cmp(left, Operand(right)); | |
| 1704 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | |
| 1705 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | |
| 1706 } | |
| 1707 | |
| 1708 | |
| 1709 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { | 1670 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { |
| 1710 Register left = ToRegister(instr->InputAt(0)); | 1671 Register left = ToRegister(instr->InputAt(0)); |
| 1711 Register right = ToRegister(instr->InputAt(1)); | 1672 Register right = ToRegister(instr->InputAt(1)); |
| 1712 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1673 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1713 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1674 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1714 | 1675 |
| 1715 __ cmp(left, Operand(right)); | 1676 __ cmp(left, Operand(right)); |
| 1716 EmitBranch(true_block, false_block, eq); | 1677 EmitBranch(true_block, false_block, eq); |
| 1717 } | 1678 } |
| 1718 | 1679 |
| 1719 | 1680 |
| 1720 void LCodeGen::DoCmpConstantEq(LCmpConstantEq* instr) { | |
| 1721 Register left = ToRegister(instr->InputAt(0)); | |
| 1722 Register result = ToRegister(instr->result()); | |
| 1723 | |
| 1724 Label done; | |
| 1725 __ cmp(left, Operand(instr->hydrogen()->right())); | |
| 1726 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | |
| 1727 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | |
| 1728 } | |
| 1729 | |
| 1730 | |
| 1731 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { | 1681 void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { |
| 1732 Register left = ToRegister(instr->InputAt(0)); | 1682 Register left = ToRegister(instr->InputAt(0)); |
| 1733 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1683 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1734 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1684 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1735 | 1685 |
| 1736 __ cmp(left, Operand(instr->hydrogen()->right())); | 1686 __ cmp(left, Operand(instr->hydrogen()->right())); |
| 1737 EmitBranch(true_block, false_block, eq); | 1687 EmitBranch(true_block, false_block, eq); |
| 1738 } | 1688 } |
| 1739 | 1689 |
| 1740 | 1690 |
| 1741 void LCodeGen::DoIsNull(LIsNull* instr) { | |
| 1742 Register reg = ToRegister(instr->InputAt(0)); | |
| 1743 Register result = ToRegister(instr->result()); | |
| 1744 | |
| 1745 __ LoadRoot(ip, Heap::kNullValueRootIndex); | |
| 1746 __ cmp(reg, ip); | |
| 1747 if (instr->is_strict()) { | |
| 1748 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | |
| 1749 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | |
| 1750 } else { | |
| 1751 Label true_value, false_value, done; | |
| 1752 __ b(eq, &true_value); | |
| 1753 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | |
| 1754 __ cmp(ip, reg); | |
| 1755 __ b(eq, &true_value); | |
| 1756 __ JumpIfSmi(reg, &false_value); | |
| 1757 // Check for undetectable objects by looking in the bit field in | |
| 1758 // the map. The object has already been smi checked. | |
| 1759 Register scratch = result; | |
| 1760 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | |
| 1761 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | |
| 1762 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); | |
| 1763 __ b(ne, &true_value); | |
| 1764 __ bind(&false_value); | |
| 1765 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 1766 __ jmp(&done); | |
| 1767 __ bind(&true_value); | |
| 1768 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 1769 __ bind(&done); | |
| 1770 } | |
| 1771 } | |
| 1772 | |
| 1773 | |
| 1774 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { | 1691 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { |
| 1775 Register scratch = scratch0(); | 1692 Register scratch = scratch0(); |
| 1776 Register reg = ToRegister(instr->InputAt(0)); | 1693 Register reg = ToRegister(instr->InputAt(0)); |
| 1777 | 1694 |
| 1778 // TODO(fsc): If the expression is known to be a smi, then it's | 1695 // TODO(fsc): If the expression is known to be a smi, then it's |
| 1779 // definitely not null. Jump to the false block. | 1696 // definitely not null. Jump to the false block. |
| 1780 | 1697 |
| 1781 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1698 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1782 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1699 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1783 | 1700 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 | 1740 |
| 1824 // Load instance type and check that it is in object type range. | 1741 // Load instance type and check that it is in object type range. |
| 1825 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); | 1742 __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); |
| 1826 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 1743 __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 1827 __ b(lt, is_not_object); | 1744 __ b(lt, is_not_object); |
| 1828 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); | 1745 __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE)); |
| 1829 return le; | 1746 return le; |
| 1830 } | 1747 } |
| 1831 | 1748 |
| 1832 | 1749 |
| 1833 void LCodeGen::DoIsObject(LIsObject* instr) { | |
| 1834 Register reg = ToRegister(instr->InputAt(0)); | |
| 1835 Register result = ToRegister(instr->result()); | |
| 1836 Label is_false, is_true, done; | |
| 1837 | |
| 1838 Condition true_cond = EmitIsObject(reg, result, &is_false, &is_true); | |
| 1839 __ b(true_cond, &is_true); | |
| 1840 | |
| 1841 __ bind(&is_false); | |
| 1842 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 1843 __ b(&done); | |
| 1844 | |
| 1845 __ bind(&is_true); | |
| 1846 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 1847 | |
| 1848 __ bind(&done); | |
| 1849 } | |
| 1850 | |
| 1851 | |
| 1852 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { | 1750 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { |
| 1853 Register reg = ToRegister(instr->InputAt(0)); | 1751 Register reg = ToRegister(instr->InputAt(0)); |
| 1854 Register temp1 = ToRegister(instr->TempAt(0)); | 1752 Register temp1 = ToRegister(instr->TempAt(0)); |
| 1855 Register temp2 = scratch0(); | 1753 Register temp2 = scratch0(); |
| 1856 | 1754 |
| 1857 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1755 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1858 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1756 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1859 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1757 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 1860 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1758 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1861 | 1759 |
| 1862 Condition true_cond = | 1760 Condition true_cond = |
| 1863 EmitIsObject(reg, temp1, false_label, true_label); | 1761 EmitIsObject(reg, temp1, false_label, true_label); |
| 1864 | 1762 |
| 1865 EmitBranch(true_block, false_block, true_cond); | 1763 EmitBranch(true_block, false_block, true_cond); |
| 1866 } | 1764 } |
| 1867 | 1765 |
| 1868 | 1766 |
| 1869 void LCodeGen::DoIsSmi(LIsSmi* instr) { | |
| 1870 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | |
| 1871 Register result = ToRegister(instr->result()); | |
| 1872 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); | |
| 1873 Label done; | |
| 1874 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 1875 __ JumpIfSmi(input_reg, &done); | |
| 1876 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 1877 __ bind(&done); | |
| 1878 } | |
| 1879 | |
| 1880 | |
| 1881 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1767 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
| 1882 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1768 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1883 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1769 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1884 | 1770 |
| 1885 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); | 1771 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); |
| 1886 __ tst(input_reg, Operand(kSmiTagMask)); | 1772 __ tst(input_reg, Operand(kSmiTagMask)); |
| 1887 EmitBranch(true_block, false_block, eq); | 1773 EmitBranch(true_block, false_block, eq); |
| 1888 } | 1774 } |
| 1889 | 1775 |
| 1890 | 1776 |
| 1891 void LCodeGen::DoIsUndetectable(LIsUndetectable* instr) { | |
| 1892 Register input = ToRegister(instr->InputAt(0)); | |
| 1893 Register result = ToRegister(instr->result()); | |
| 1894 | |
| 1895 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | |
| 1896 Label false_label, done; | |
| 1897 __ JumpIfSmi(input, &false_label); | |
| 1898 __ ldr(result, FieldMemOperand(input, HeapObject::kMapOffset)); | |
| 1899 __ ldrb(result, FieldMemOperand(result, Map::kBitFieldOffset)); | |
| 1900 __ tst(result, Operand(1 << Map::kIsUndetectable)); | |
| 1901 __ b(eq, &false_label); | |
| 1902 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 1903 __ jmp(&done); | |
| 1904 __ bind(&false_label); | |
| 1905 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 1906 __ bind(&done); | |
| 1907 } | |
| 1908 | |
| 1909 | |
| 1910 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { | 1777 void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { |
| 1911 Register input = ToRegister(instr->InputAt(0)); | 1778 Register input = ToRegister(instr->InputAt(0)); |
| 1912 Register temp = ToRegister(instr->TempAt(0)); | 1779 Register temp = ToRegister(instr->TempAt(0)); |
| 1913 | 1780 |
| 1914 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1781 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1915 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1782 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1916 | 1783 |
| 1917 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); | 1784 __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); |
| 1918 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); | 1785 __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); |
| 1919 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); | 1786 __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); |
| 1920 __ tst(temp, Operand(1 << Map::kIsUndetectable)); | 1787 __ tst(temp, Operand(1 << Map::kIsUndetectable)); |
| 1921 EmitBranch(true_block, false_block, ne); | 1788 EmitBranch(true_block, false_block, ne); |
| 1922 } | 1789 } |
| 1923 | 1790 |
| 1924 | 1791 |
| 1925 static InstanceType TestType(HHasInstanceType* instr) { | 1792 static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { |
| 1926 InstanceType from = instr->from(); | 1793 InstanceType from = instr->from(); |
| 1927 InstanceType to = instr->to(); | 1794 InstanceType to = instr->to(); |
| 1928 if (from == FIRST_TYPE) return to; | 1795 if (from == FIRST_TYPE) return to; |
| 1929 ASSERT(from == to || to == LAST_TYPE); | 1796 ASSERT(from == to || to == LAST_TYPE); |
| 1930 return from; | 1797 return from; |
| 1931 } | 1798 } |
| 1932 | 1799 |
| 1933 | 1800 |
| 1934 static Condition BranchCondition(HHasInstanceType* instr) { | 1801 static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { |
| 1935 InstanceType from = instr->from(); | 1802 InstanceType from = instr->from(); |
| 1936 InstanceType to = instr->to(); | 1803 InstanceType to = instr->to(); |
| 1937 if (from == to) return eq; | 1804 if (from == to) return eq; |
| 1938 if (to == LAST_TYPE) return hs; | 1805 if (to == LAST_TYPE) return hs; |
| 1939 if (from == FIRST_TYPE) return ls; | 1806 if (from == FIRST_TYPE) return ls; |
| 1940 UNREACHABLE(); | 1807 UNREACHABLE(); |
| 1941 return eq; | 1808 return eq; |
| 1942 } | 1809 } |
| 1943 | 1810 |
| 1944 | 1811 |
| 1945 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | |
| 1946 Register input = ToRegister(instr->InputAt(0)); | |
| 1947 Register result = ToRegister(instr->result()); | |
| 1948 | |
| 1949 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | |
| 1950 Label done; | |
| 1951 __ tst(input, Operand(kSmiTagMask)); | |
| 1952 __ LoadRoot(result, Heap::kFalseValueRootIndex, eq); | |
| 1953 __ b(eq, &done); | |
| 1954 __ CompareObjectType(input, result, result, TestType(instr->hydrogen())); | |
| 1955 Condition cond = BranchCondition(instr->hydrogen()); | |
| 1956 __ LoadRoot(result, Heap::kTrueValueRootIndex, cond); | |
| 1957 __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond)); | |
| 1958 __ bind(&done); | |
| 1959 } | |
| 1960 | |
| 1961 | |
| 1962 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1812 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
| 1963 Register scratch = scratch0(); | 1813 Register scratch = scratch0(); |
| 1964 Register input = ToRegister(instr->InputAt(0)); | 1814 Register input = ToRegister(instr->InputAt(0)); |
| 1965 | 1815 |
| 1966 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1816 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1967 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1817 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1968 | 1818 |
| 1969 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1819 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 1970 | 1820 |
| 1971 __ JumpIfSmi(input, false_label); | 1821 __ JumpIfSmi(input, false_label); |
| 1972 | 1822 |
| 1973 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 1823 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
| 1974 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); | 1824 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); |
| 1975 } | 1825 } |
| 1976 | 1826 |
| 1977 | 1827 |
| 1978 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { | 1828 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { |
| 1979 Register input = ToRegister(instr->InputAt(0)); | 1829 Register input = ToRegister(instr->InputAt(0)); |
| 1980 Register result = ToRegister(instr->result()); | 1830 Register result = ToRegister(instr->result()); |
| 1981 | 1831 |
| 1982 if (FLAG_debug_code) { | 1832 if (FLAG_debug_code) { |
| 1983 __ AbortIfNotString(input); | 1833 __ AbortIfNotString(input); |
| 1984 } | 1834 } |
| 1985 | 1835 |
| 1986 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset)); | 1836 __ ldr(result, FieldMemOperand(input, String::kHashFieldOffset)); |
| 1987 __ IndexFromHash(result, result); | 1837 __ IndexFromHash(result, result); |
| 1988 } | 1838 } |
| 1989 | 1839 |
| 1990 | 1840 |
| 1991 void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { | |
| 1992 Register input = ToRegister(instr->InputAt(0)); | |
| 1993 Register result = ToRegister(instr->result()); | |
| 1994 Register scratch = scratch0(); | |
| 1995 | |
| 1996 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | |
| 1997 __ ldr(scratch, | |
| 1998 FieldMemOperand(input, String::kHashFieldOffset)); | |
| 1999 __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); | |
| 2000 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | |
| 2001 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | |
| 2002 } | |
| 2003 | |
| 2004 | |
| 2005 void LCodeGen::DoHasCachedArrayIndexAndBranch( | 1841 void LCodeGen::DoHasCachedArrayIndexAndBranch( |
| 2006 LHasCachedArrayIndexAndBranch* instr) { | 1842 LHasCachedArrayIndexAndBranch* instr) { |
| 2007 Register input = ToRegister(instr->InputAt(0)); | 1843 Register input = ToRegister(instr->InputAt(0)); |
| 2008 Register scratch = scratch0(); | 1844 Register scratch = scratch0(); |
| 2009 | 1845 |
| 2010 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1846 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 2011 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1847 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 2012 | 1848 |
| 2013 __ ldr(scratch, | 1849 __ ldr(scratch, |
| 2014 FieldMemOperand(input, String::kHashFieldOffset)); | 1850 FieldMemOperand(input, String::kHashFieldOffset)); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 // The name in the constructor is a symbol because of the way the context is | 1903 // The name in the constructor is a symbol because of the way the context is |
| 2068 // booted. This routine isn't expected to work for random API-created | 1904 // booted. This routine isn't expected to work for random API-created |
| 2069 // classes and it doesn't have to because you can't access it with natives | 1905 // classes and it doesn't have to because you can't access it with natives |
| 2070 // syntax. Since both sides are symbols it is sufficient to use an identity | 1906 // syntax. Since both sides are symbols it is sufficient to use an identity |
| 2071 // comparison. | 1907 // comparison. |
| 2072 __ cmp(temp, Operand(class_name)); | 1908 __ cmp(temp, Operand(class_name)); |
| 2073 // End with the answer in flags. | 1909 // End with the answer in flags. |
| 2074 } | 1910 } |
| 2075 | 1911 |
| 2076 | 1912 |
| 2077 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { | |
| 2078 Register input = ToRegister(instr->InputAt(0)); | |
| 2079 Register result = ToRegister(instr->result()); | |
| 2080 ASSERT(input.is(result)); | |
| 2081 Handle<String> class_name = instr->hydrogen()->class_name(); | |
| 2082 | |
| 2083 Label done, is_true, is_false; | |
| 2084 | |
| 2085 EmitClassOfTest(&is_true, &is_false, class_name, input, scratch0(), input); | |
| 2086 __ b(ne, &is_false); | |
| 2087 | |
| 2088 __ bind(&is_true); | |
| 2089 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 2090 __ jmp(&done); | |
| 2091 | |
| 2092 __ bind(&is_false); | |
| 2093 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 2094 __ bind(&done); | |
| 2095 } | |
| 2096 | |
| 2097 | |
| 2098 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { | 1913 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { |
| 2099 Register input = ToRegister(instr->InputAt(0)); | 1914 Register input = ToRegister(instr->InputAt(0)); |
| 2100 Register temp = scratch0(); | 1915 Register temp = scratch0(); |
| 2101 Register temp2 = ToRegister(instr->TempAt(0)); | 1916 Register temp2 = ToRegister(instr->TempAt(0)); |
| 2102 Handle<String> class_name = instr->hydrogen()->class_name(); | 1917 Handle<String> class_name = instr->hydrogen()->class_name(); |
| 2103 | 1918 |
| 2104 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1919 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 2105 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1920 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 2106 | 1921 |
| 2107 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1922 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| (...skipping 2234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4342 } | 4157 } |
| 4343 | 4158 |
| 4344 | 4159 |
| 4345 void LCodeGen::DoTypeof(LTypeof* instr) { | 4160 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 4346 Register input = ToRegister(instr->InputAt(0)); | 4161 Register input = ToRegister(instr->InputAt(0)); |
| 4347 __ push(input); | 4162 __ push(input); |
| 4348 CallRuntime(Runtime::kTypeof, 1, instr); | 4163 CallRuntime(Runtime::kTypeof, 1, instr); |
| 4349 } | 4164 } |
| 4350 | 4165 |
| 4351 | 4166 |
| 4352 void LCodeGen::DoTypeofIs(LTypeofIs* instr) { | |
| 4353 Register input = ToRegister(instr->InputAt(0)); | |
| 4354 Register result = ToRegister(instr->result()); | |
| 4355 Label true_label; | |
| 4356 Label false_label; | |
| 4357 Label done; | |
| 4358 | |
| 4359 Condition final_branch_condition = EmitTypeofIs(&true_label, | |
| 4360 &false_label, | |
| 4361 input, | |
| 4362 instr->type_literal()); | |
| 4363 __ b(final_branch_condition, &true_label); | |
| 4364 __ bind(&false_label); | |
| 4365 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 4366 __ b(&done); | |
| 4367 | |
| 4368 __ bind(&true_label); | |
| 4369 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 4370 | |
| 4371 __ bind(&done); | |
| 4372 } | |
| 4373 | |
| 4374 | |
| 4375 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 4167 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
| 4376 Register input = ToRegister(instr->InputAt(0)); | 4168 Register input = ToRegister(instr->InputAt(0)); |
| 4377 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4169 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4378 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4170 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4379 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 4171 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
| 4380 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 4172 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
| 4381 | 4173 |
| 4382 Condition final_branch_condition = EmitTypeofIs(true_label, | 4174 Condition final_branch_condition = EmitTypeofIs(true_label, |
| 4383 false_label, | 4175 false_label, |
| 4384 input, | 4176 input, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4448 } else { | 4240 } else { |
| 4449 final_branch_condition = ne; | 4241 final_branch_condition = ne; |
| 4450 __ b(false_label); | 4242 __ b(false_label); |
| 4451 // A dead branch instruction will be generated after this point. | 4243 // A dead branch instruction will be generated after this point. |
| 4452 } | 4244 } |
| 4453 | 4245 |
| 4454 return final_branch_condition; | 4246 return final_branch_condition; |
| 4455 } | 4247 } |
| 4456 | 4248 |
| 4457 | 4249 |
| 4458 void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { | |
| 4459 Register result = ToRegister(instr->result()); | |
| 4460 Label true_label; | |
| 4461 Label false_label; | |
| 4462 Label done; | |
| 4463 | |
| 4464 EmitIsConstructCall(result, scratch0()); | |
| 4465 __ b(eq, &true_label); | |
| 4466 | |
| 4467 __ LoadRoot(result, Heap::kFalseValueRootIndex); | |
| 4468 __ b(&done); | |
| 4469 | |
| 4470 | |
| 4471 __ bind(&true_label); | |
| 4472 __ LoadRoot(result, Heap::kTrueValueRootIndex); | |
| 4473 | |
| 4474 __ bind(&done); | |
| 4475 } | |
| 4476 | |
| 4477 | |
| 4478 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { | 4250 void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
| 4479 Register temp1 = ToRegister(instr->TempAt(0)); | 4251 Register temp1 = ToRegister(instr->TempAt(0)); |
| 4480 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 4252 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 4481 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 4253 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 4482 | 4254 |
| 4483 EmitIsConstructCall(temp1, scratch0()); | 4255 EmitIsConstructCall(temp1, scratch0()); |
| 4484 EmitBranch(true_block, false_block, eq); | 4256 EmitBranch(true_block, false_block, eq); |
| 4485 } | 4257 } |
| 4486 | 4258 |
| 4487 | 4259 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4603 ASSERT(osr_pc_offset_ == -1); | 4375 ASSERT(osr_pc_offset_ == -1); |
| 4604 osr_pc_offset_ = masm()->pc_offset(); | 4376 osr_pc_offset_ = masm()->pc_offset(); |
| 4605 } | 4377 } |
| 4606 | 4378 |
| 4607 | 4379 |
| 4608 | 4380 |
| 4609 | 4381 |
| 4610 #undef __ | 4382 #undef __ |
| 4611 | 4383 |
| 4612 } } // namespace v8::internal | 4384 } } // namespace v8::internal |
| OLD | NEW |