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 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" | 7 #include "src/crankshaft/ia32/lithium-codegen-ia32.h" |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 DCHECK(!info()->IsStub()); | 1862 DCHECK(!info()->IsStub()); |
1863 XMMRegister xmm_scratch = double_scratch0(); | 1863 XMMRegister xmm_scratch = double_scratch0(); |
1864 __ xorps(xmm_scratch, xmm_scratch); | 1864 __ xorps(xmm_scratch, xmm_scratch); |
1865 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 1865 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
1866 EmitBranch(instr, not_equal); | 1866 EmitBranch(instr, not_equal); |
1867 } else if (type.IsString()) { | 1867 } else if (type.IsString()) { |
1868 DCHECK(!info()->IsStub()); | 1868 DCHECK(!info()->IsStub()); |
1869 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 1869 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
1870 EmitBranch(instr, not_equal); | 1870 EmitBranch(instr, not_equal); |
1871 } else { | 1871 } else { |
1872 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 1872 ToBooleanICStub::Types expected = |
1873 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 1873 instr->hydrogen()->expected_input_types(); |
| 1874 if (expected.IsEmpty()) expected = ToBooleanICStub::Types::Generic(); |
1874 | 1875 |
1875 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 1876 if (expected.Contains(ToBooleanICStub::UNDEFINED)) { |
1876 // undefined -> false. | 1877 // undefined -> false. |
1877 __ cmp(reg, factory()->undefined_value()); | 1878 __ cmp(reg, factory()->undefined_value()); |
1878 __ j(equal, instr->FalseLabel(chunk_)); | 1879 __ j(equal, instr->FalseLabel(chunk_)); |
1879 } | 1880 } |
1880 if (expected.Contains(ToBooleanStub::BOOLEAN)) { | 1881 if (expected.Contains(ToBooleanICStub::BOOLEAN)) { |
1881 // true -> true. | 1882 // true -> true. |
1882 __ cmp(reg, factory()->true_value()); | 1883 __ cmp(reg, factory()->true_value()); |
1883 __ j(equal, instr->TrueLabel(chunk_)); | 1884 __ j(equal, instr->TrueLabel(chunk_)); |
1884 // false -> false. | 1885 // false -> false. |
1885 __ cmp(reg, factory()->false_value()); | 1886 __ cmp(reg, factory()->false_value()); |
1886 __ j(equal, instr->FalseLabel(chunk_)); | 1887 __ j(equal, instr->FalseLabel(chunk_)); |
1887 } | 1888 } |
1888 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { | 1889 if (expected.Contains(ToBooleanICStub::NULL_TYPE)) { |
1889 // 'null' -> false. | 1890 // 'null' -> false. |
1890 __ cmp(reg, factory()->null_value()); | 1891 __ cmp(reg, factory()->null_value()); |
1891 __ j(equal, instr->FalseLabel(chunk_)); | 1892 __ j(equal, instr->FalseLabel(chunk_)); |
1892 } | 1893 } |
1893 | 1894 |
1894 if (expected.Contains(ToBooleanStub::SMI)) { | 1895 if (expected.Contains(ToBooleanICStub::SMI)) { |
1895 // Smis: 0 -> false, all other -> true. | 1896 // Smis: 0 -> false, all other -> true. |
1896 __ test(reg, Operand(reg)); | 1897 __ test(reg, Operand(reg)); |
1897 __ j(equal, instr->FalseLabel(chunk_)); | 1898 __ j(equal, instr->FalseLabel(chunk_)); |
1898 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); | 1899 __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); |
1899 } else if (expected.NeedsMap()) { | 1900 } else if (expected.NeedsMap()) { |
1900 // If we need a map later and have a Smi -> deopt. | 1901 // If we need a map later and have a Smi -> deopt. |
1901 __ test(reg, Immediate(kSmiTagMask)); | 1902 __ test(reg, Immediate(kSmiTagMask)); |
1902 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); | 1903 DeoptimizeIf(zero, instr, Deoptimizer::kSmi); |
1903 } | 1904 } |
1904 | 1905 |
1905 Register map = no_reg; // Keep the compiler happy. | 1906 Register map = no_reg; // Keep the compiler happy. |
1906 if (expected.NeedsMap()) { | 1907 if (expected.NeedsMap()) { |
1907 map = ToRegister(instr->temp()); | 1908 map = ToRegister(instr->temp()); |
1908 DCHECK(!map.is(reg)); | 1909 DCHECK(!map.is(reg)); |
1909 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); | 1910 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); |
1910 | 1911 |
1911 if (expected.CanBeUndetectable()) { | 1912 if (expected.CanBeUndetectable()) { |
1912 // Undetectable -> false. | 1913 // Undetectable -> false. |
1913 __ test_b(FieldOperand(map, Map::kBitFieldOffset), | 1914 __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
1914 1 << Map::kIsUndetectable); | 1915 1 << Map::kIsUndetectable); |
1915 __ j(not_zero, instr->FalseLabel(chunk_)); | 1916 __ j(not_zero, instr->FalseLabel(chunk_)); |
1916 } | 1917 } |
1917 } | 1918 } |
1918 | 1919 |
1919 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { | 1920 if (expected.Contains(ToBooleanICStub::SPEC_OBJECT)) { |
1920 // spec object -> true. | 1921 // spec object -> true. |
1921 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); | 1922 __ CmpInstanceType(map, FIRST_JS_RECEIVER_TYPE); |
1922 __ j(above_equal, instr->TrueLabel(chunk_)); | 1923 __ j(above_equal, instr->TrueLabel(chunk_)); |
1923 } | 1924 } |
1924 | 1925 |
1925 if (expected.Contains(ToBooleanStub::STRING)) { | 1926 if (expected.Contains(ToBooleanICStub::STRING)) { |
1926 // String value -> false iff empty. | 1927 // String value -> false iff empty. |
1927 Label not_string; | 1928 Label not_string; |
1928 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); | 1929 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); |
1929 __ j(above_equal, ¬_string, Label::kNear); | 1930 __ j(above_equal, ¬_string, Label::kNear); |
1930 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 1931 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
1931 __ j(not_zero, instr->TrueLabel(chunk_)); | 1932 __ j(not_zero, instr->TrueLabel(chunk_)); |
1932 __ jmp(instr->FalseLabel(chunk_)); | 1933 __ jmp(instr->FalseLabel(chunk_)); |
1933 __ bind(¬_string); | 1934 __ bind(¬_string); |
1934 } | 1935 } |
1935 | 1936 |
1936 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 1937 if (expected.Contains(ToBooleanICStub::SYMBOL)) { |
1937 // Symbol value -> true. | 1938 // Symbol value -> true. |
1938 __ CmpInstanceType(map, SYMBOL_TYPE); | 1939 __ CmpInstanceType(map, SYMBOL_TYPE); |
1939 __ j(equal, instr->TrueLabel(chunk_)); | 1940 __ j(equal, instr->TrueLabel(chunk_)); |
1940 } | 1941 } |
1941 | 1942 |
1942 if (expected.Contains(ToBooleanStub::SIMD_VALUE)) { | 1943 if (expected.Contains(ToBooleanICStub::SIMD_VALUE)) { |
1943 // SIMD value -> true. | 1944 // SIMD value -> true. |
1944 __ CmpInstanceType(map, SIMD128_VALUE_TYPE); | 1945 __ CmpInstanceType(map, SIMD128_VALUE_TYPE); |
1945 __ j(equal, instr->TrueLabel(chunk_)); | 1946 __ j(equal, instr->TrueLabel(chunk_)); |
1946 } | 1947 } |
1947 | 1948 |
1948 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1949 if (expected.Contains(ToBooleanICStub::HEAP_NUMBER)) { |
1949 // heap number -> false iff +0, -0, or NaN. | 1950 // heap number -> false iff +0, -0, or NaN. |
1950 Label not_heap_number; | 1951 Label not_heap_number; |
1951 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 1952 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
1952 factory()->heap_number_map()); | 1953 factory()->heap_number_map()); |
1953 __ j(not_equal, ¬_heap_number, Label::kNear); | 1954 __ j(not_equal, ¬_heap_number, Label::kNear); |
1954 XMMRegister xmm_scratch = double_scratch0(); | 1955 XMMRegister xmm_scratch = double_scratch0(); |
1955 __ xorps(xmm_scratch, xmm_scratch); | 1956 __ xorps(xmm_scratch, xmm_scratch); |
1956 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 1957 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
1957 __ j(zero, instr->FalseLabel(chunk_)); | 1958 __ j(zero, instr->FalseLabel(chunk_)); |
1958 __ jmp(instr->TrueLabel(chunk_)); | 1959 __ jmp(instr->TrueLabel(chunk_)); |
(...skipping 3237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5196 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), context); | 5197 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), context); |
5197 } | 5198 } |
5198 | 5199 |
5199 | 5200 |
5200 #undef __ | 5201 #undef __ |
5201 | 5202 |
5202 } // namespace internal | 5203 } // namespace internal |
5203 } // namespace v8 | 5204 } // namespace v8 |
5204 | 5205 |
5205 #endif // V8_TARGET_ARCH_IA32 | 5206 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |