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 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1371 | 1371 |
1372 | 1372 |
1373 void LCodeGen::DoValueOf(LValueOf* instr) { | 1373 void LCodeGen::DoValueOf(LValueOf* instr) { |
1374 Register input = ToRegister(instr->InputAt(0)); | 1374 Register input = ToRegister(instr->InputAt(0)); |
1375 Register result = ToRegister(instr->result()); | 1375 Register result = ToRegister(instr->result()); |
1376 Register map = ToRegister(instr->TempAt(0)); | 1376 Register map = ToRegister(instr->TempAt(0)); |
1377 ASSERT(input.is(result)); | 1377 ASSERT(input.is(result)); |
1378 Label done; | 1378 Label done; |
1379 | 1379 |
1380 // If the object is a smi return the object. | 1380 // If the object is a smi return the object. |
1381 __ tst(input, Operand(kSmiTagMask)); | 1381 __ JumpIfSmi(input, &done); |
1382 __ b(eq, &done); | |
1383 | 1382 |
1384 // If the object is not a value type, return the object. | 1383 // If the object is not a value type, return the object. |
1385 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); | 1384 __ CompareObjectType(input, map, map, JS_VALUE_TYPE); |
1386 __ b(ne, &done); | 1385 __ b(ne, &done); |
1387 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); | 1386 __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); |
1388 | 1387 |
1389 __ bind(&done); | 1388 __ bind(&done); |
1390 } | 1389 } |
1391 | 1390 |
1392 | 1391 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 __ cmp(reg, ip); | 1536 __ cmp(reg, ip); |
1538 __ b(eq, false_label); | 1537 __ b(eq, false_label); |
1539 __ LoadRoot(ip, Heap::kTrueValueRootIndex); | 1538 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
1540 __ cmp(reg, ip); | 1539 __ cmp(reg, ip); |
1541 __ b(eq, true_label); | 1540 __ b(eq, true_label); |
1542 __ LoadRoot(ip, Heap::kFalseValueRootIndex); | 1541 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
1543 __ cmp(reg, ip); | 1542 __ cmp(reg, ip); |
1544 __ b(eq, false_label); | 1543 __ b(eq, false_label); |
1545 __ cmp(reg, Operand(0)); | 1544 __ cmp(reg, Operand(0)); |
1546 __ b(eq, false_label); | 1545 __ b(eq, false_label); |
1547 __ tst(reg, Operand(kSmiTagMask)); | 1546 __ JumpIfSmi(reg, true_label); |
1548 __ b(eq, true_label); | |
1549 | 1547 |
1550 // Test double values. Zero and NaN are false. | 1548 // Test double values. Zero and NaN are false. |
1551 Label call_stub; | 1549 Label call_stub; |
1552 DoubleRegister dbl_scratch = d0; | 1550 DoubleRegister dbl_scratch = d0; |
1553 Register scratch = scratch0(); | 1551 Register scratch = scratch0(); |
1554 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1552 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1555 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 1553 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
1556 __ cmp(scratch, Operand(ip)); | 1554 __ cmp(scratch, Operand(ip)); |
1557 __ b(ne, &call_stub); | 1555 __ b(ne, &call_stub); |
1558 __ sub(ip, reg, Operand(kHeapObjectTag)); | 1556 __ sub(ip, reg, Operand(kHeapObjectTag)); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1754 __ cmp(reg, ip); | 1752 __ cmp(reg, ip); |
1755 if (instr->is_strict()) { | 1753 if (instr->is_strict()) { |
1756 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); | 1754 __ LoadRoot(result, Heap::kTrueValueRootIndex, eq); |
1757 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); | 1755 __ LoadRoot(result, Heap::kFalseValueRootIndex, ne); |
1758 } else { | 1756 } else { |
1759 Label true_value, false_value, done; | 1757 Label true_value, false_value, done; |
1760 __ b(eq, &true_value); | 1758 __ b(eq, &true_value); |
1761 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1759 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
1762 __ cmp(ip, reg); | 1760 __ cmp(ip, reg); |
1763 __ b(eq, &true_value); | 1761 __ b(eq, &true_value); |
1764 __ tst(reg, Operand(kSmiTagMask)); | 1762 __ JumpIfSmi(reg, &false_value); |
1765 __ b(eq, &false_value); | |
1766 // Check for undetectable objects by looking in the bit field in | 1763 // Check for undetectable objects by looking in the bit field in |
1767 // the map. The object has already been smi checked. | 1764 // the map. The object has already been smi checked. |
1768 Register scratch = result; | 1765 Register scratch = result; |
1769 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1766 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1770 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 1767 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
1771 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); | 1768 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); |
1772 __ b(ne, &true_value); | 1769 __ b(ne, &true_value); |
1773 __ bind(&false_value); | 1770 __ bind(&false_value); |
1774 __ LoadRoot(result, Heap::kFalseValueRootIndex); | 1771 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
1775 __ jmp(&done); | 1772 __ jmp(&done); |
(...skipping 18 matching lines...) Expand all Loading... |
1794 __ cmp(reg, ip); | 1791 __ cmp(reg, ip); |
1795 if (instr->is_strict()) { | 1792 if (instr->is_strict()) { |
1796 EmitBranch(true_block, false_block, eq); | 1793 EmitBranch(true_block, false_block, eq); |
1797 } else { | 1794 } else { |
1798 Label* true_label = chunk_->GetAssemblyLabel(true_block); | 1795 Label* true_label = chunk_->GetAssemblyLabel(true_block); |
1799 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1796 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
1800 __ b(eq, true_label); | 1797 __ b(eq, true_label); |
1801 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 1798 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
1802 __ cmp(reg, ip); | 1799 __ cmp(reg, ip); |
1803 __ b(eq, true_label); | 1800 __ b(eq, true_label); |
1804 __ tst(reg, Operand(kSmiTagMask)); | 1801 __ JumpIfSmi(reg, false_label); |
1805 __ b(eq, false_label); | |
1806 // Check for undetectable objects by looking in the bit field in | 1802 // Check for undetectable objects by looking in the bit field in |
1807 // the map. The object has already been smi checked. | 1803 // the map. The object has already been smi checked. |
1808 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 1804 __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
1809 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); | 1805 __ ldrb(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset)); |
1810 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); | 1806 __ tst(scratch, Operand(1 << Map::kIsUndetectable)); |
1811 EmitBranch(true_block, false_block, ne); | 1807 EmitBranch(true_block, false_block, ne); |
1812 } | 1808 } |
1813 } | 1809 } |
1814 | 1810 |
1815 | 1811 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1874 EmitIsObject(reg, temp1, temp2, false_label, true_label); | 1870 EmitIsObject(reg, temp1, temp2, false_label, true_label); |
1875 | 1871 |
1876 EmitBranch(true_block, false_block, true_cond); | 1872 EmitBranch(true_block, false_block, true_cond); |
1877 } | 1873 } |
1878 | 1874 |
1879 | 1875 |
1880 void LCodeGen::DoIsSmi(LIsSmi* instr) { | 1876 void LCodeGen::DoIsSmi(LIsSmi* instr) { |
1881 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1877 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
1882 Register result = ToRegister(instr->result()); | 1878 Register result = ToRegister(instr->result()); |
1883 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); | 1879 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); |
1884 __ tst(input_reg, Operand(kSmiTagMask)); | 1880 Label done; |
1885 __ LoadRoot(result, Heap::kTrueValueRootIndex); | 1881 __ LoadRoot(result, Heap::kTrueValueRootIndex); |
1886 Label done; | 1882 __ JumpIfSmi(input_reg, &done); |
1887 __ b(eq, &done); | |
1888 __ LoadRoot(result, Heap::kFalseValueRootIndex); | 1883 __ LoadRoot(result, Heap::kFalseValueRootIndex); |
1889 __ bind(&done); | 1884 __ bind(&done); |
1890 } | 1885 } |
1891 | 1886 |
1892 | 1887 |
1893 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { | 1888 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { |
1894 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1889 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1895 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1890 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1896 | 1891 |
1897 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); | 1892 Register input_reg = EmitLoadRegister(instr->InputAt(0), ip); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1953 return eq; | 1948 return eq; |
1954 } | 1949 } |
1955 | 1950 |
1956 | 1951 |
1957 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { | 1952 void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { |
1958 Register input = ToRegister(instr->InputAt(0)); | 1953 Register input = ToRegister(instr->InputAt(0)); |
1959 Register result = ToRegister(instr->result()); | 1954 Register result = ToRegister(instr->result()); |
1960 | 1955 |
1961 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); | 1956 ASSERT(instr->hydrogen()->value()->representation().IsTagged()); |
1962 Label done; | 1957 Label done; |
1963 __ tst(input, Operand(kSmiTagMask)); | |
1964 __ LoadRoot(result, Heap::kFalseValueRootIndex, eq); | 1958 __ LoadRoot(result, Heap::kFalseValueRootIndex, eq); |
1965 __ b(eq, &done); | 1959 __ JumpIfSmi(input, &done); |
1966 __ CompareObjectType(input, result, result, TestType(instr->hydrogen())); | 1960 __ CompareObjectType(input, result, result, TestType(instr->hydrogen())); |
1967 Condition cond = BranchCondition(instr->hydrogen()); | 1961 Condition cond = BranchCondition(instr->hydrogen()); |
1968 __ LoadRoot(result, Heap::kTrueValueRootIndex, cond); | 1962 __ LoadRoot(result, Heap::kTrueValueRootIndex, cond); |
1969 __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond)); | 1963 __ LoadRoot(result, Heap::kFalseValueRootIndex, NegateCondition(cond)); |
1970 __ bind(&done); | 1964 __ bind(&done); |
1971 } | 1965 } |
1972 | 1966 |
1973 | 1967 |
1974 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { | 1968 void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { |
1975 Register scratch = scratch0(); | 1969 Register scratch = scratch0(); |
1976 Register input = ToRegister(instr->InputAt(0)); | 1970 Register input = ToRegister(instr->InputAt(0)); |
1977 | 1971 |
1978 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1972 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1979 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1973 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1980 | 1974 |
1981 Label* false_label = chunk_->GetAssemblyLabel(false_block); | 1975 Label* false_label = chunk_->GetAssemblyLabel(false_block); |
1982 | 1976 |
1983 __ tst(input, Operand(kSmiTagMask)); | 1977 __ JumpIfSmi(input, false_label); |
1984 __ b(eq, false_label); | |
1985 | 1978 |
1986 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); | 1979 __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); |
1987 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); | 1980 EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); |
1988 } | 1981 } |
1989 | 1982 |
1990 | 1983 |
1991 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { | 1984 void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) { |
1992 Register input = ToRegister(instr->InputAt(0)); | 1985 Register input = ToRegister(instr->InputAt(0)); |
1993 Register result = ToRegister(instr->result()); | 1986 Register result = ToRegister(instr->result()); |
1994 | 1987 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2033 // Branches to a label or falls through with the answer in flags. Trashes | 2026 // Branches to a label or falls through with the answer in flags. Trashes |
2034 // the temp registers, but not the input. Only input and temp2 may alias. | 2027 // the temp registers, but not the input. Only input and temp2 may alias. |
2035 void LCodeGen::EmitClassOfTest(Label* is_true, | 2028 void LCodeGen::EmitClassOfTest(Label* is_true, |
2036 Label* is_false, | 2029 Label* is_false, |
2037 Handle<String>class_name, | 2030 Handle<String>class_name, |
2038 Register input, | 2031 Register input, |
2039 Register temp, | 2032 Register temp, |
2040 Register temp2) { | 2033 Register temp2) { |
2041 ASSERT(!input.is(temp)); | 2034 ASSERT(!input.is(temp)); |
2042 ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register. | 2035 ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register. |
2043 __ tst(input, Operand(kSmiTagMask)); | 2036 __ JumpIfSmi(input, is_false); |
2044 __ b(eq, is_false); | |
2045 __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE); | 2037 __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE); |
2046 __ b(lt, is_false); | 2038 __ b(lt, is_false); |
2047 | 2039 |
2048 // Map is now in temp. | 2040 // Map is now in temp. |
2049 // Functions have class 'Function'. | 2041 // Functions have class 'Function'. |
2050 __ CompareInstanceType(temp, temp2, FIRST_CALLABLE_SPEC_OBJECT_TYPE); | 2042 __ CompareInstanceType(temp, temp2, FIRST_CALLABLE_SPEC_OBJECT_TYPE); |
2051 if (class_name->IsEqualTo(CStrVector("Function"))) { | 2043 if (class_name->IsEqualTo(CStrVector("Function"))) { |
2052 __ b(ge, is_true); | 2044 __ b(ge, is_true); |
2053 } else { | 2045 } else { |
2054 __ b(ge, is_false); | 2046 __ b(ge, is_false); |
(...skipping 1792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3847 DoubleRegister result_reg, | 3839 DoubleRegister result_reg, |
3848 bool deoptimize_on_undefined, | 3840 bool deoptimize_on_undefined, |
3849 LEnvironment* env) { | 3841 LEnvironment* env) { |
3850 Register scratch = scratch0(); | 3842 Register scratch = scratch0(); |
3851 SwVfpRegister flt_scratch = s0; | 3843 SwVfpRegister flt_scratch = s0; |
3852 ASSERT(!result_reg.is(d0)); | 3844 ASSERT(!result_reg.is(d0)); |
3853 | 3845 |
3854 Label load_smi, heap_number, done; | 3846 Label load_smi, heap_number, done; |
3855 | 3847 |
3856 // Smi check. | 3848 // Smi check. |
3857 __ tst(input_reg, Operand(kSmiTagMask)); | 3849 __ JumpIfSmi(input_reg, &load_smi); |
3858 __ b(eq, &load_smi); | |
3859 | 3850 |
3860 // Heap number map check. | 3851 // Heap number map check. |
3861 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 3852 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
3862 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 3853 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
3863 __ cmp(scratch, Operand(ip)); | 3854 __ cmp(scratch, Operand(ip)); |
3864 if (deoptimize_on_undefined) { | 3855 if (deoptimize_on_undefined) { |
3865 DeoptimizeIf(ne, env); | 3856 DeoptimizeIf(ne, env); |
3866 } else { | 3857 } else { |
3867 Label heap_number; | 3858 Label heap_number; |
3868 __ b(eq, &heap_number); | 3859 __ b(eq, &heap_number); |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4588 ASSERT(osr_pc_offset_ == -1); | 4579 ASSERT(osr_pc_offset_ == -1); |
4589 osr_pc_offset_ = masm()->pc_offset(); | 4580 osr_pc_offset_ = masm()->pc_offset(); |
4590 } | 4581 } |
4591 | 4582 |
4592 | 4583 |
4593 | 4584 |
4594 | 4585 |
4595 #undef __ | 4586 #undef __ |
4596 | 4587 |
4597 } } // namespace v8::internal | 4588 } } // namespace v8::internal |
OLD | NEW |