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 |