| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/crankshaft/arm64/lithium-codegen-arm64.h" | 5 #include "src/crankshaft/arm64/lithium-codegen-arm64.h" |
| 6 | 6 |
| 7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
| 8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 __ Ldr(double_scratch(), FieldMemOperand(value, | 1724 __ Ldr(double_scratch(), FieldMemOperand(value, |
| 1725 HeapNumber::kValueOffset)); | 1725 HeapNumber::kValueOffset)); |
| 1726 // Test the double value. Zero and NaN are false. | 1726 // Test the double value. Zero and NaN are false. |
| 1727 EmitBranchIfNonZeroNumber(instr, double_scratch(), double_scratch()); | 1727 EmitBranchIfNonZeroNumber(instr, double_scratch(), double_scratch()); |
| 1728 } else if (type.IsString()) { | 1728 } else if (type.IsString()) { |
| 1729 DCHECK(!info()->IsStub()); | 1729 DCHECK(!info()->IsStub()); |
| 1730 Register temp = ToRegister(instr->temp1()); | 1730 Register temp = ToRegister(instr->temp1()); |
| 1731 __ Ldr(temp, FieldMemOperand(value, String::kLengthOffset)); | 1731 __ Ldr(temp, FieldMemOperand(value, String::kLengthOffset)); |
| 1732 EmitCompareAndBranch(instr, ne, temp, 0); | 1732 EmitCompareAndBranch(instr, ne, temp, 0); |
| 1733 } else { | 1733 } else { |
| 1734 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 1734 ToBooleanICStub::Types expected = |
| 1735 instr->hydrogen()->expected_input_types(); |
| 1735 // Avoid deopts in the case where we've never executed this path before. | 1736 // Avoid deopts in the case where we've never executed this path before. |
| 1736 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 1737 if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
| 1737 | 1738 |
| 1738 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 1739 if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
| 1739 // undefined -> false. | 1740 // undefined -> false. |
| 1740 __ JumpIfRoot( | 1741 __ JumpIfRoot( |
| 1741 value, Heap::kUndefinedValueRootIndex, false_label); | 1742 value, Heap::kUndefinedValueRootIndex, false_label); |
| 1742 } | 1743 } |
| 1743 | 1744 |
| 1744 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 1745 if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
| 1745 // Boolean -> its value. | 1746 // Boolean -> its value. |
| 1746 __ JumpIfRoot( | 1747 __ JumpIfRoot( |
| 1747 value, Heap::kTrueValueRootIndex, true_label); | 1748 value, Heap::kTrueValueRootIndex, true_label); |
| 1748 __ JumpIfRoot( | 1749 __ JumpIfRoot( |
| 1749 value, Heap::kFalseValueRootIndex, false_label); | 1750 value, Heap::kFalseValueRootIndex, false_label); |
| 1750 } | 1751 } |
| 1751 | 1752 |
| 1752 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 1753 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
| 1753 // 'null' -> false. | 1754 // 'null' -> false. |
| 1754 __ JumpIfRoot( | 1755 __ JumpIfRoot( |
| 1755 value, Heap::kNullValueRootIndex, false_label); | 1756 value, Heap::kNullValueRootIndex, false_label); |
| 1756 } | 1757 } |
| 1757 | 1758 |
| 1758 if (expected.Contains(ToBooleanStub::SMI)) { | 1759 if (expected.Contains(ToBooleanICStub::SMI)) { |
| 1759 // Smis: 0 -> false, all other -> true. | 1760 // Smis: 0 -> false, all other -> true. |
| 1760 DCHECK(Smi::FromInt(0) == 0); | 1761 DCHECK(Smi::FromInt(0) == 0); |
| 1761 __ Cbz(value, false_label); | 1762 __ Cbz(value, false_label); |
| 1762 __ JumpIfSmi(value, true_label); | 1763 __ JumpIfSmi(value, true_label); |
| 1763 } else if (expected.NeedsMap()) { | 1764 } else if (expected.NeedsMap()) { |
| 1764 // If we need a map later and have a smi, deopt. | 1765 // If we need a map later and have a smi, deopt. |
| 1765 DeoptimizeIfSmi(value, instr, Deoptimizer::kSmi); | 1766 DeoptimizeIfSmi(value, instr, Deoptimizer::kSmi); |
| 1766 } | 1767 } |
| 1767 | 1768 |
| 1768 Register map = NoReg; | 1769 Register map = NoReg; |
| 1769 Register scratch = NoReg; | 1770 Register scratch = NoReg; |
| 1770 | 1771 |
| 1771 if (expected.NeedsMap()) { | 1772 if (expected.NeedsMap()) { |
| 1772 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); | 1773 DCHECK((instr->temp1() != NULL) && (instr->temp2() != NULL)); |
| 1773 map = ToRegister(instr->temp1()); | 1774 map = ToRegister(instr->temp1()); |
| 1774 scratch = ToRegister(instr->temp2()); | 1775 scratch = ToRegister(instr->temp2()); |
| 1775 | 1776 |
| 1776 __ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); | 1777 __ Ldr(map, FieldMemOperand(value, HeapObject::kMapOffset)); |
| 1777 | 1778 |
| 1778 if (expected.CanBeUndetectable()) { | 1779 if (expected.CanBeUndetectable()) { |
| 1779 // Undetectable -> false. | 1780 // Undetectable -> false. |
| 1780 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); | 1781 __ Ldrb(scratch, FieldMemOperand(map, Map::kBitFieldOffset)); |
| 1781 __ TestAndBranchIfAnySet( | 1782 __ TestAndBranchIfAnySet( |
| 1782 scratch, 1 << Map::kIsUndetectable, false_label); | 1783 scratch, 1 << Map::kIsUndetectable, false_label); |
| 1783 } | 1784 } |
| 1784 } | 1785 } |
| 1785 | 1786 |
| 1786 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 1787 if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
| 1787 // spec object -> true. | 1788 // spec object -> true. |
| 1788 __ CompareInstanceType(map, scratch, FIRST_JS_RECEIVER_TYPE); | 1789 __ CompareInstanceType(map, scratch, FIRST_JS_RECEIVER_TYPE); |
| 1789 __ B(ge, true_label); | 1790 __ B(ge, true_label); |
| 1790 } | 1791 } |
| 1791 | 1792 |
| 1792 if (expected.Contains(ToBooleanStub::STRING)) { | 1793 if (expected.Contains(ToBooleanICStub::STRING)) { |
| 1793 // String value -> false iff empty. | 1794 // String value -> false iff empty. |
| 1794 Label not_string; | 1795 Label not_string; |
| 1795 __ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); | 1796 __ CompareInstanceType(map, scratch, FIRST_NONSTRING_TYPE); |
| 1796 __ B(ge, ¬_string); | 1797 __ B(ge, ¬_string); |
| 1797 __ Ldr(scratch, FieldMemOperand(value, String::kLengthOffset)); | 1798 __ Ldr(scratch, FieldMemOperand(value, String::kLengthOffset)); |
| 1798 __ Cbz(scratch, false_label); | 1799 __ Cbz(scratch, false_label); |
| 1799 __ B(true_label); | 1800 __ B(true_label); |
| 1800 __ Bind(¬_string); | 1801 __ Bind(¬_string); |
| 1801 } | 1802 } |
| 1802 | 1803 |
| 1803 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 1804 if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
| 1804 // Symbol value -> true. | 1805 // Symbol value -> true. |
| 1805 __ CompareInstanceType(map, scratch, SYMBOL_TYPE); | 1806 __ CompareInstanceType(map, scratch, SYMBOL_TYPE); |
| 1806 __ B(eq, true_label); | 1807 __ B(eq, true_label); |
| 1807 } | 1808 } |
| 1808 | 1809 |
| 1809 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 1810 if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
| 1810 // SIMD value -> true. | 1811 // SIMD value -> true. |
| 1811 __ CompareInstanceType(map, scratch, SIMD128_VALUE_TYPE); | 1812 __ CompareInstanceType(map, scratch, SIMD128_VALUE_TYPE); |
| 1812 __ B(eq, true_label); | 1813 __ B(eq, true_label); |
| 1813 } | 1814 } |
| 1814 | 1815 |
| 1815 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1816 if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
| 1816 Label not_heap_number; | 1817 Label not_heap_number; |
| 1817 __ JumpIfNotRoot(map, Heap::kHeapNumberMapRootIndex, ¬_heap_number); | 1818 __ JumpIfNotRoot(map, Heap::kHeapNumberMapRootIndex, ¬_heap_number); |
| 1818 | 1819 |
| 1819 __ Ldr(double_scratch(), | 1820 __ Ldr(double_scratch(), |
| 1820 FieldMemOperand(value, HeapNumber::kValueOffset)); | 1821 FieldMemOperand(value, HeapNumber::kValueOffset)); |
| 1821 __ Fcmp(double_scratch(), 0.0); | 1822 __ Fcmp(double_scratch(), 0.0); |
| 1822 // If we got a NaN (overflow bit is set), jump to the false branch. | 1823 // If we got a NaN (overflow bit is set), jump to the false branch. |
| 1823 __ B(vs, false_label); | 1824 __ B(vs, false_label); |
| 1824 __ B(eq, false_label); | 1825 __ B(eq, false_label); |
| 1825 __ B(true_label); | 1826 __ B(true_label); |
| (...skipping 3826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5652 | 5653 |
| 5653 | 5654 |
| 5654 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { | 5655 void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) { |
| 5655 Register context = ToRegister(instr->context()); | 5656 Register context = ToRegister(instr->context()); |
| 5656 __ Str(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 5657 __ Str(context, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 5657 } | 5658 } |
| 5658 | 5659 |
| 5659 | 5660 |
| 5660 } // namespace internal | 5661 } // namespace internal |
| 5661 } // namespace v8 | 5662 } // namespace v8 |
| OLD | NEW |