OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 Safepoint::DeoptMode deopt_mode_; | 58 Safepoint::DeoptMode deopt_mode_; |
59 }; | 59 }; |
60 | 60 |
61 | 61 |
62 #define __ masm()-> | 62 #define __ masm()-> |
63 | 63 |
64 bool LCodeGen::GenerateCode() { | 64 bool LCodeGen::GenerateCode() { |
65 HPhase phase("Z_Code generation", chunk()); | 65 HPhase phase("Z_Code generation", chunk()); |
66 ASSERT(is_unused()); | 66 ASSERT(is_unused()); |
67 status_ = GENERATING; | 67 status_ = GENERATING; |
68 CpuFeatures::Scope scope(FPU); | 68 CpuFeatureScope scope(masm(), FPU); |
69 | 69 |
70 // Open a frame scope to indicate that there is a frame on the stack. The | 70 // Open a frame scope to indicate that there is a frame on the stack. The |
71 // NONE indicates that the scope shouldn't actually generate code to set up | 71 // NONE indicates that the scope shouldn't actually generate code to set up |
72 // the frame (that is done in GeneratePrologue). | 72 // the frame (that is done in GeneratePrologue). |
73 FrameScope frame_scope(masm_, StackFrame::NONE); | 73 FrameScope frame_scope(masm_, StackFrame::NONE); |
74 | 74 |
75 return GeneratePrologue() && | 75 return GeneratePrologue() && |
76 GenerateBody() && | 76 GenerateBody() && |
77 GenerateDeferredCode() && | 77 GenerateDeferredCode() && |
78 GenerateDeoptJumpTable() && | 78 GenerateDeoptJumpTable() && |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); | 187 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); |
188 __ Branch(&loop, ne, a0, Operand(sp)); | 188 __ Branch(&loop, ne, a0, Operand(sp)); |
189 __ pop(a1); | 189 __ pop(a1); |
190 __ pop(a0); | 190 __ pop(a0); |
191 } else { | 191 } else { |
192 __ Subu(sp, sp, Operand(slots * kPointerSize)); | 192 __ Subu(sp, sp, Operand(slots * kPointerSize)); |
193 } | 193 } |
194 } | 194 } |
195 | 195 |
196 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { | 196 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { |
197 CpuFeatures::Scope scope(FPU); | 197 CpuFeatureScope scope(masm(), FPU); |
198 Comment(";;; Save clobbered callee double registers"); | 198 Comment(";;; Save clobbered callee double registers"); |
199 int count = 0; | 199 int count = 0; |
200 BitVector* doubles = chunk()->allocated_double_registers(); | 200 BitVector* doubles = chunk()->allocated_double_registers(); |
201 BitVector::Iterator save_iterator(doubles); | 201 BitVector::Iterator save_iterator(doubles); |
202 while (!save_iterator.Done()) { | 202 while (!save_iterator.Done()) { |
203 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), | 203 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
204 MemOperand(sp, count * kDoubleSize)); | 204 MemOperand(sp, count * kDoubleSize)); |
205 save_iterator.Advance(); | 205 save_iterator.Advance(); |
206 count++; | 206 count++; |
207 } | 207 } |
(...skipping 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 | 1455 |
1456 void LCodeGen::DoConstantI(LConstantI* instr) { | 1456 void LCodeGen::DoConstantI(LConstantI* instr) { |
1457 ASSERT(instr->result()->IsRegister()); | 1457 ASSERT(instr->result()->IsRegister()); |
1458 __ li(ToRegister(instr->result()), Operand(instr->value())); | 1458 __ li(ToRegister(instr->result()), Operand(instr->value())); |
1459 } | 1459 } |
1460 | 1460 |
1461 | 1461 |
1462 void LCodeGen::DoConstantD(LConstantD* instr) { | 1462 void LCodeGen::DoConstantD(LConstantD* instr) { |
1463 ASSERT(instr->result()->IsDoubleRegister()); | 1463 ASSERT(instr->result()->IsDoubleRegister()); |
1464 DoubleRegister result = ToDoubleRegister(instr->result()); | 1464 DoubleRegister result = ToDoubleRegister(instr->result()); |
1465 CpuFeatures::Scope scope(FPU); | 1465 CpuFeatureScope scope(masm(), FPU); |
1466 double v = instr->value(); | 1466 double v = instr->value(); |
1467 __ Move(result, v); | 1467 __ Move(result, v); |
1468 } | 1468 } |
1469 | 1469 |
1470 | 1470 |
1471 void LCodeGen::DoConstantT(LConstantT* instr) { | 1471 void LCodeGen::DoConstantT(LConstantT* instr) { |
1472 Handle<Object> value = instr->value(); | 1472 Handle<Object> value = instr->value(); |
1473 if (value->IsSmi()) { | 1473 if (value->IsSmi()) { |
1474 __ li(ToRegister(instr->result()), Operand(value)); | 1474 __ li(ToRegister(instr->result()), Operand(value)); |
1475 } else { | 1475 } else { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1653 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); | 1653 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); |
1654 __ mov(result_reg, left_reg); | 1654 __ mov(result_reg, left_reg); |
1655 __ Branch(&done); | 1655 __ Branch(&done); |
1656 } | 1656 } |
1657 __ Branch(&done, condition, left_reg, right_op); | 1657 __ Branch(&done, condition, left_reg, right_op); |
1658 __ bind(&return_right); | 1658 __ bind(&return_right); |
1659 __ Addu(result_reg, zero_reg, right_op); | 1659 __ Addu(result_reg, zero_reg, right_op); |
1660 __ bind(&done); | 1660 __ bind(&done); |
1661 } else { | 1661 } else { |
1662 ASSERT(instr->hydrogen()->representation().IsDouble()); | 1662 ASSERT(instr->hydrogen()->representation().IsDouble()); |
1663 CpuFeatures::Scope scope(FPU); | 1663 CpuFeatureScope scope(masm(), FPU); |
1664 FPURegister left_reg = ToDoubleRegister(left); | 1664 FPURegister left_reg = ToDoubleRegister(left); |
1665 FPURegister right_reg = ToDoubleRegister(right); | 1665 FPURegister right_reg = ToDoubleRegister(right); |
1666 FPURegister result_reg = ToDoubleRegister(instr->result()); | 1666 FPURegister result_reg = ToDoubleRegister(instr->result()); |
1667 Label check_nan_left, check_zero, return_left, return_right, done; | 1667 Label check_nan_left, check_zero, return_left, return_right, done; |
1668 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); | 1668 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); |
1669 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); | 1669 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); |
1670 __ Branch(&return_right); | 1670 __ Branch(&return_right); |
1671 | 1671 |
1672 __ bind(&check_zero); | 1672 __ bind(&check_zero); |
1673 // left == right != 0. | 1673 // left == right != 0. |
(...skipping 20 matching lines...) Expand all Loading... |
1694 __ bind(&return_left); | 1694 __ bind(&return_left); |
1695 if (!left_reg.is(result_reg)) { | 1695 if (!left_reg.is(result_reg)) { |
1696 __ mov_d(result_reg, left_reg); | 1696 __ mov_d(result_reg, left_reg); |
1697 } | 1697 } |
1698 __ bind(&done); | 1698 __ bind(&done); |
1699 } | 1699 } |
1700 } | 1700 } |
1701 | 1701 |
1702 | 1702 |
1703 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 1703 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
1704 CpuFeatures::Scope scope(FPU); | 1704 CpuFeatureScope scope(masm(), FPU); |
1705 DoubleRegister left = ToDoubleRegister(instr->left()); | 1705 DoubleRegister left = ToDoubleRegister(instr->left()); |
1706 DoubleRegister right = ToDoubleRegister(instr->right()); | 1706 DoubleRegister right = ToDoubleRegister(instr->right()); |
1707 DoubleRegister result = ToDoubleRegister(instr->result()); | 1707 DoubleRegister result = ToDoubleRegister(instr->result()); |
1708 switch (instr->op()) { | 1708 switch (instr->op()) { |
1709 case Token::ADD: | 1709 case Token::ADD: |
1710 __ add_d(result, left, right); | 1710 __ add_d(result, left, right); |
1711 break; | 1711 break; |
1712 case Token::SUB: | 1712 case Token::SUB: |
1713 __ sub_d(result, left, right); | 1713 __ sub_d(result, left, right); |
1714 break; | 1714 break; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1804 | 1804 |
1805 void LCodeGen::DoBranch(LBranch* instr) { | 1805 void LCodeGen::DoBranch(LBranch* instr) { |
1806 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1806 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1807 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1807 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1808 | 1808 |
1809 Representation r = instr->hydrogen()->value()->representation(); | 1809 Representation r = instr->hydrogen()->value()->representation(); |
1810 if (r.IsInteger32()) { | 1810 if (r.IsInteger32()) { |
1811 Register reg = ToRegister(instr->value()); | 1811 Register reg = ToRegister(instr->value()); |
1812 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); | 1812 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); |
1813 } else if (r.IsDouble()) { | 1813 } else if (r.IsDouble()) { |
1814 CpuFeatures::Scope scope(FPU); | 1814 CpuFeatureScope scope(masm(), FPU); |
1815 DoubleRegister reg = ToDoubleRegister(instr->value()); | 1815 DoubleRegister reg = ToDoubleRegister(instr->value()); |
1816 // Test the double value. Zero and NaN are false. | 1816 // Test the double value. Zero and NaN are false. |
1817 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); | 1817 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); |
1818 } else { | 1818 } else { |
1819 ASSERT(r.IsTagged()); | 1819 ASSERT(r.IsTagged()); |
1820 Register reg = ToRegister(instr->value()); | 1820 Register reg = ToRegister(instr->value()); |
1821 HType type = instr->hydrogen()->value()->type(); | 1821 HType type = instr->hydrogen()->value()->type(); |
1822 if (type.IsBoolean()) { | 1822 if (type.IsBoolean()) { |
1823 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1823 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
1824 EmitBranch(true_block, false_block, eq, reg, Operand(at)); | 1824 EmitBranch(true_block, false_block, eq, reg, Operand(at)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1882 Label not_string; | 1882 Label not_string; |
1883 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 1883 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
1884 __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); | 1884 __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); |
1885 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); | 1885 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); |
1886 __ Branch(true_label, ne, at, Operand(zero_reg)); | 1886 __ Branch(true_label, ne, at, Operand(zero_reg)); |
1887 __ Branch(false_label); | 1887 __ Branch(false_label); |
1888 __ bind(¬_string); | 1888 __ bind(¬_string); |
1889 } | 1889 } |
1890 | 1890 |
1891 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1891 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
1892 CpuFeatures::Scope scope(FPU); | 1892 CpuFeatureScope scope(masm(), FPU); |
1893 // heap number -> false iff +0, -0, or NaN. | 1893 // heap number -> false iff +0, -0, or NaN. |
1894 DoubleRegister dbl_scratch = double_scratch0(); | 1894 DoubleRegister dbl_scratch = double_scratch0(); |
1895 Label not_heap_number; | 1895 Label not_heap_number; |
1896 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 1896 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
1897 __ Branch(¬_heap_number, ne, map, Operand(at)); | 1897 __ Branch(¬_heap_number, ne, map, Operand(at)); |
1898 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 1898 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
1899 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); | 1899 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); |
1900 // Falls through if dbl_scratch == 0. | 1900 // Falls through if dbl_scratch == 0. |
1901 __ Branch(false_label); | 1901 __ Branch(false_label); |
1902 __ bind(¬_heap_number); | 1902 __ bind(¬_heap_number); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 1962 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
1963 // We can statically evaluate the comparison. | 1963 // We can statically evaluate the comparison. |
1964 double left_val = ToDouble(LConstantOperand::cast(left)); | 1964 double left_val = ToDouble(LConstantOperand::cast(left)); |
1965 double right_val = ToDouble(LConstantOperand::cast(right)); | 1965 double right_val = ToDouble(LConstantOperand::cast(right)); |
1966 int next_block = | 1966 int next_block = |
1967 EvalComparison(instr->op(), left_val, right_val) ? true_block | 1967 EvalComparison(instr->op(), left_val, right_val) ? true_block |
1968 : false_block; | 1968 : false_block; |
1969 EmitGoto(next_block); | 1969 EmitGoto(next_block); |
1970 } else { | 1970 } else { |
1971 if (instr->is_double()) { | 1971 if (instr->is_double()) { |
1972 CpuFeatures::Scope scope(FPU); | 1972 CpuFeatureScope scope(masm(), FPU); |
1973 // Compare left and right as doubles and load the | 1973 // Compare left and right as doubles and load the |
1974 // resulting flags into the normal status register. | 1974 // resulting flags into the normal status register. |
1975 FPURegister left_reg = ToDoubleRegister(left); | 1975 FPURegister left_reg = ToDoubleRegister(left); |
1976 FPURegister right_reg = ToDoubleRegister(right); | 1976 FPURegister right_reg = ToDoubleRegister(right); |
1977 | 1977 |
1978 // If a NaN is involved, i.e. the result is unordered, | 1978 // If a NaN is involved, i.e. the result is unordered, |
1979 // jump to false block label. | 1979 // jump to false block label. |
1980 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, | 1980 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, |
1981 left_reg, right_reg); | 1981 left_reg, right_reg); |
1982 | 1982 |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2517 | 2517 |
2518 | 2518 |
2519 void LCodeGen::DoReturn(LReturn* instr) { | 2519 void LCodeGen::DoReturn(LReturn* instr) { |
2520 if (FLAG_trace && info()->IsOptimizing()) { | 2520 if (FLAG_trace && info()->IsOptimizing()) { |
2521 // Push the return value on the stack as the parameter. | 2521 // Push the return value on the stack as the parameter. |
2522 // Runtime::TraceExit returns its parameter in v0. | 2522 // Runtime::TraceExit returns its parameter in v0. |
2523 __ push(v0); | 2523 __ push(v0); |
2524 __ CallRuntime(Runtime::kTraceExit, 1); | 2524 __ CallRuntime(Runtime::kTraceExit, 1); |
2525 } | 2525 } |
2526 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { | 2526 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { |
2527 CpuFeatures::Scope scope(FPU); | 2527 CpuFeatureScope scope(masm(), FPU); |
2528 ASSERT(NeedsEagerFrame()); | 2528 ASSERT(NeedsEagerFrame()); |
2529 BitVector* doubles = chunk()->allocated_double_registers(); | 2529 BitVector* doubles = chunk()->allocated_double_registers(); |
2530 BitVector::Iterator save_iterator(doubles); | 2530 BitVector::Iterator save_iterator(doubles); |
2531 int count = 0; | 2531 int count = 0; |
2532 while (!save_iterator.Done()) { | 2532 while (!save_iterator.Done()) { |
2533 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), | 2533 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
2534 MemOperand(sp, count * kDoubleSize)); | 2534 MemOperand(sp, count * kDoubleSize)); |
2535 save_iterator.Advance(); | 2535 save_iterator.Advance(); |
2536 count++; | 2536 count++; |
2537 } | 2537 } |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2896 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2896 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
2897 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2897 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2898 FPURegister result = ToDoubleRegister(instr->result()); | 2898 FPURegister result = ToDoubleRegister(instr->result()); |
2899 if (key_is_constant) { | 2899 if (key_is_constant) { |
2900 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); | 2900 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); |
2901 } else { | 2901 } else { |
2902 __ sll(scratch0(), key, shift_size); | 2902 __ sll(scratch0(), key, shift_size); |
2903 __ Addu(scratch0(), scratch0(), external_pointer); | 2903 __ Addu(scratch0(), scratch0(), external_pointer); |
2904 } | 2904 } |
2905 if (CpuFeatures::IsSupported(FPU)) { | 2905 if (CpuFeatures::IsSupported(FPU)) { |
2906 CpuFeatures::Scope scope(FPU); | 2906 CpuFeatureScope scope(masm(), FPU); |
2907 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2907 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2908 __ lwc1(result, MemOperand(scratch0(), additional_offset)); | 2908 __ lwc1(result, MemOperand(scratch0(), additional_offset)); |
2909 __ cvt_d_s(result, result); | 2909 __ cvt_d_s(result, result); |
2910 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 2910 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2911 __ ldc1(result, MemOperand(scratch0(), additional_offset)); | 2911 __ ldc1(result, MemOperand(scratch0(), additional_offset)); |
2912 } | 2912 } |
2913 } else { | 2913 } else { |
2914 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2914 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2915 Register value = external_pointer; | 2915 Register value = external_pointer; |
2916 __ lw(value, MemOperand(scratch0(), additional_offset)); | 2916 __ lw(value, MemOperand(scratch0(), additional_offset)); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3025 key = ToRegister(instr->key()); | 3025 key = ToRegister(instr->key()); |
3026 } | 3026 } |
3027 | 3027 |
3028 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3028 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
3029 ((constant_key + instr->additional_index()) << element_size_shift); | 3029 ((constant_key + instr->additional_index()) << element_size_shift); |
3030 if (!key_is_constant) { | 3030 if (!key_is_constant) { |
3031 __ sll(scratch, key, shift_size); | 3031 __ sll(scratch, key, shift_size); |
3032 __ Addu(elements, elements, scratch); | 3032 __ Addu(elements, elements, scratch); |
3033 } | 3033 } |
3034 if (CpuFeatures::IsSupported(FPU)) { | 3034 if (CpuFeatures::IsSupported(FPU)) { |
3035 CpuFeatures::Scope scope(FPU); | 3035 CpuFeatureScope scope(masm(), FPU); |
3036 __ Addu(elements, elements, Operand(base_offset)); | 3036 __ Addu(elements, elements, Operand(base_offset)); |
3037 __ ldc1(result, MemOperand(elements)); | 3037 __ ldc1(result, MemOperand(elements)); |
3038 if (instr->hydrogen()->RequiresHoleCheck()) { | 3038 if (instr->hydrogen()->RequiresHoleCheck()) { |
3039 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 3039 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
3040 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | 3040 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
3041 } | 3041 } |
3042 } else { | 3042 } else { |
3043 __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); | 3043 __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); |
3044 __ lw(sfpd_lo, MemOperand(elements, base_offset)); | 3044 __ lw(sfpd_lo, MemOperand(elements, base_offset)); |
3045 if (instr->hydrogen()->RequiresHoleCheck()) { | 3045 if (instr->hydrogen()->RequiresHoleCheck()) { |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3488 __ mov(result, input); | 3488 __ mov(result, input); |
3489 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); | 3489 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); |
3490 __ subu(result, zero_reg, input); | 3490 __ subu(result, zero_reg, input); |
3491 // Overflow if result is still negative, i.e. 0x80000000. | 3491 // Overflow if result is still negative, i.e. 0x80000000. |
3492 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); | 3492 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); |
3493 __ bind(&done); | 3493 __ bind(&done); |
3494 } | 3494 } |
3495 | 3495 |
3496 | 3496 |
3497 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3497 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
3498 CpuFeatures::Scope scope(FPU); | 3498 CpuFeatureScope scope(masm(), FPU); |
3499 // Class for deferred case. | 3499 // Class for deferred case. |
3500 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3500 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
3501 public: | 3501 public: |
3502 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3502 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
3503 LUnaryMathOperation* instr) | 3503 LUnaryMathOperation* instr) |
3504 : LDeferredCode(codegen), instr_(instr) { } | 3504 : LDeferredCode(codegen), instr_(instr) { } |
3505 virtual void Generate() { | 3505 virtual void Generate() { |
3506 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3506 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
3507 } | 3507 } |
3508 virtual LInstruction* instr() { return instr_; } | 3508 virtual LInstruction* instr() { return instr_; } |
(...skipping 16 matching lines...) Expand all Loading... |
3525 // Smi check. | 3525 // Smi check. |
3526 __ JumpIfNotSmi(input, deferred->entry()); | 3526 __ JumpIfNotSmi(input, deferred->entry()); |
3527 // If smi, handle it directly. | 3527 // If smi, handle it directly. |
3528 EmitIntegerMathAbs(instr); | 3528 EmitIntegerMathAbs(instr); |
3529 __ bind(deferred->exit()); | 3529 __ bind(deferred->exit()); |
3530 } | 3530 } |
3531 } | 3531 } |
3532 | 3532 |
3533 | 3533 |
3534 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3534 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
3535 CpuFeatures::Scope scope(FPU); | 3535 CpuFeatureScope scope(masm(), FPU); |
3536 DoubleRegister input = ToDoubleRegister(instr->value()); | 3536 DoubleRegister input = ToDoubleRegister(instr->value()); |
3537 Register result = ToRegister(instr->result()); | 3537 Register result = ToRegister(instr->result()); |
3538 Register scratch1 = scratch0(); | 3538 Register scratch1 = scratch0(); |
3539 Register except_flag = ToRegister(instr->temp()); | 3539 Register except_flag = ToRegister(instr->temp()); |
3540 | 3540 |
3541 __ EmitFPUTruncate(kRoundToMinusInf, | 3541 __ EmitFPUTruncate(kRoundToMinusInf, |
3542 result, | 3542 result, |
3543 input, | 3543 input, |
3544 scratch1, | 3544 scratch1, |
3545 double_scratch0(), | 3545 double_scratch0(), |
3546 except_flag); | 3546 except_flag); |
3547 | 3547 |
3548 // Deopt if the operation did not succeed. | 3548 // Deopt if the operation did not succeed. |
3549 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3549 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
3550 | 3550 |
3551 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3551 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3552 // Test for -0. | 3552 // Test for -0. |
3553 Label done; | 3553 Label done; |
3554 __ Branch(&done, ne, result, Operand(zero_reg)); | 3554 __ Branch(&done, ne, result, Operand(zero_reg)); |
3555 __ mfc1(scratch1, input.high()); | 3555 __ mfc1(scratch1, input.high()); |
3556 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 3556 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
3557 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 3557 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
3558 __ bind(&done); | 3558 __ bind(&done); |
3559 } | 3559 } |
3560 } | 3560 } |
3561 | 3561 |
3562 | 3562 |
3563 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3563 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
3564 CpuFeatures::Scope scope(FPU); | 3564 CpuFeatureScope scope(masm(), FPU); |
3565 DoubleRegister input = ToDoubleRegister(instr->value()); | 3565 DoubleRegister input = ToDoubleRegister(instr->value()); |
3566 Register result = ToRegister(instr->result()); | 3566 Register result = ToRegister(instr->result()); |
3567 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3567 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
3568 Register scratch = scratch0(); | 3568 Register scratch = scratch0(); |
3569 Label done, check_sign_on_zero; | 3569 Label done, check_sign_on_zero; |
3570 | 3570 |
3571 // Extract exponent bits. | 3571 // Extract exponent bits. |
3572 __ mfc1(result, input.high()); | 3572 __ mfc1(result, input.high()); |
3573 __ Ext(scratch, | 3573 __ Ext(scratch, |
3574 result, | 3574 result, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3631 __ bind(&check_sign_on_zero); | 3631 __ bind(&check_sign_on_zero); |
3632 __ mfc1(scratch, input.high()); | 3632 __ mfc1(scratch, input.high()); |
3633 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); | 3633 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); |
3634 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3634 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
3635 } | 3635 } |
3636 __ bind(&done); | 3636 __ bind(&done); |
3637 } | 3637 } |
3638 | 3638 |
3639 | 3639 |
3640 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3640 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
3641 CpuFeatures::Scope scope(FPU); | 3641 CpuFeatureScope scope(masm(), FPU); |
3642 DoubleRegister input = ToDoubleRegister(instr->value()); | 3642 DoubleRegister input = ToDoubleRegister(instr->value()); |
3643 DoubleRegister result = ToDoubleRegister(instr->result()); | 3643 DoubleRegister result = ToDoubleRegister(instr->result()); |
3644 __ sqrt_d(result, input); | 3644 __ sqrt_d(result, input); |
3645 } | 3645 } |
3646 | 3646 |
3647 | 3647 |
3648 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 3648 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { |
3649 CpuFeatures::Scope scope(FPU); | 3649 CpuFeatureScope scope(masm(), FPU); |
3650 DoubleRegister input = ToDoubleRegister(instr->value()); | 3650 DoubleRegister input = ToDoubleRegister(instr->value()); |
3651 DoubleRegister result = ToDoubleRegister(instr->result()); | 3651 DoubleRegister result = ToDoubleRegister(instr->result()); |
3652 DoubleRegister temp = ToDoubleRegister(instr->temp()); | 3652 DoubleRegister temp = ToDoubleRegister(instr->temp()); |
3653 | 3653 |
3654 ASSERT(!input.is(result)); | 3654 ASSERT(!input.is(result)); |
3655 | 3655 |
3656 // Note that according to ECMA-262 15.8.2.13: | 3656 // Note that according to ECMA-262 15.8.2.13: |
3657 // Math.pow(-Infinity, 0.5) == Infinity | 3657 // Math.pow(-Infinity, 0.5) == Infinity |
3658 // Math.sqrt(-Infinity) == NaN | 3658 // Math.sqrt(-Infinity) == NaN |
3659 Label done; | 3659 Label done; |
3660 __ Move(temp, -V8_INFINITY); | 3660 __ Move(temp, -V8_INFINITY); |
3661 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); | 3661 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); |
3662 // Set up Infinity in the delay slot. | 3662 // Set up Infinity in the delay slot. |
3663 // result is overwritten if the branch is not taken. | 3663 // result is overwritten if the branch is not taken. |
3664 __ neg_d(result, temp); | 3664 __ neg_d(result, temp); |
3665 | 3665 |
3666 // Add +0 to convert -0 to +0. | 3666 // Add +0 to convert -0 to +0. |
3667 __ add_d(result, input, kDoubleRegZero); | 3667 __ add_d(result, input, kDoubleRegZero); |
3668 __ sqrt_d(result, result); | 3668 __ sqrt_d(result, result); |
3669 __ bind(&done); | 3669 __ bind(&done); |
3670 } | 3670 } |
3671 | 3671 |
3672 | 3672 |
3673 void LCodeGen::DoPower(LPower* instr) { | 3673 void LCodeGen::DoPower(LPower* instr) { |
3674 CpuFeatures::Scope scope(FPU); | 3674 CpuFeatureScope scope(masm(), FPU); |
3675 Representation exponent_type = instr->hydrogen()->right()->representation(); | 3675 Representation exponent_type = instr->hydrogen()->right()->representation(); |
3676 // Having marked this as a call, we can use any registers. | 3676 // Having marked this as a call, we can use any registers. |
3677 // Just make sure that the input/output registers are the expected ones. | 3677 // Just make sure that the input/output registers are the expected ones. |
3678 ASSERT(!instr->right()->IsDoubleRegister() || | 3678 ASSERT(!instr->right()->IsDoubleRegister() || |
3679 ToDoubleRegister(instr->right()).is(f4)); | 3679 ToDoubleRegister(instr->right()).is(f4)); |
3680 ASSERT(!instr->right()->IsRegister() || | 3680 ASSERT(!instr->right()->IsRegister() || |
3681 ToRegister(instr->right()).is(a2)); | 3681 ToRegister(instr->right()).is(a2)); |
3682 ASSERT(ToDoubleRegister(instr->left()).is(f2)); | 3682 ASSERT(ToDoubleRegister(instr->left()).is(f2)); |
3683 ASSERT(ToDoubleRegister(instr->result()).is(f0)); | 3683 ASSERT(ToDoubleRegister(instr->result()).is(f0)); |
3684 | 3684 |
(...skipping 10 matching lines...) Expand all Loading... |
3695 __ CallStub(&stub); | 3695 __ CallStub(&stub); |
3696 } else { | 3696 } else { |
3697 ASSERT(exponent_type.IsDouble()); | 3697 ASSERT(exponent_type.IsDouble()); |
3698 MathPowStub stub(MathPowStub::DOUBLE); | 3698 MathPowStub stub(MathPowStub::DOUBLE); |
3699 __ CallStub(&stub); | 3699 __ CallStub(&stub); |
3700 } | 3700 } |
3701 } | 3701 } |
3702 | 3702 |
3703 | 3703 |
3704 void LCodeGen::DoRandom(LRandom* instr) { | 3704 void LCodeGen::DoRandom(LRandom* instr) { |
3705 CpuFeatures::Scope scope(FPU); | 3705 CpuFeatureScope scope(masm(), FPU); |
3706 class DeferredDoRandom: public LDeferredCode { | 3706 class DeferredDoRandom: public LDeferredCode { |
3707 public: | 3707 public: |
3708 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 3708 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
3709 : LDeferredCode(codegen), instr_(instr) { } | 3709 : LDeferredCode(codegen), instr_(instr) { } |
3710 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } | 3710 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
3711 virtual LInstruction* instr() { return instr_; } | 3711 virtual LInstruction* instr() { return instr_; } |
3712 private: | 3712 private: |
3713 LRandom* instr_; | 3713 LRandom* instr_; |
3714 }; | 3714 }; |
3715 | 3715 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3772 } | 3772 } |
3773 | 3773 |
3774 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 3774 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
3775 __ PrepareCallCFunction(1, scratch0()); | 3775 __ PrepareCallCFunction(1, scratch0()); |
3776 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3776 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3777 // Return value is in v0. | 3777 // Return value is in v0. |
3778 } | 3778 } |
3779 | 3779 |
3780 | 3780 |
3781 void LCodeGen::DoMathExp(LMathExp* instr) { | 3781 void LCodeGen::DoMathExp(LMathExp* instr) { |
3782 CpuFeatures::Scope scope(FPU); | 3782 CpuFeatureScope scope(masm(), FPU); |
3783 DoubleRegister input = ToDoubleRegister(instr->value()); | 3783 DoubleRegister input = ToDoubleRegister(instr->value()); |
3784 DoubleRegister result = ToDoubleRegister(instr->result()); | 3784 DoubleRegister result = ToDoubleRegister(instr->result()); |
3785 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); | 3785 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); |
3786 DoubleRegister double_scratch2 = double_scratch0(); | 3786 DoubleRegister double_scratch2 = double_scratch0(); |
3787 Register temp1 = ToRegister(instr->temp1()); | 3787 Register temp1 = ToRegister(instr->temp1()); |
3788 Register temp2 = ToRegister(instr->temp2()); | 3788 Register temp2 = ToRegister(instr->temp2()); |
3789 | 3789 |
3790 MathExpGenerator::EmitMathExp( | 3790 MathExpGenerator::EmitMathExp( |
3791 masm(), input, result, double_scratch1, double_scratch2, | 3791 masm(), input, result, double_scratch1, double_scratch2, |
3792 temp1, temp2, scratch0()); | 3792 temp1, temp2, scratch0()); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4048 } else { | 4048 } else { |
4049 DeoptimizeIf(hs, | 4049 DeoptimizeIf(hs, |
4050 instr->environment(), | 4050 instr->environment(), |
4051 ToRegister(instr->index()), | 4051 ToRegister(instr->index()), |
4052 Operand(ToRegister(instr->length()))); | 4052 Operand(ToRegister(instr->length()))); |
4053 } | 4053 } |
4054 } | 4054 } |
4055 | 4055 |
4056 | 4056 |
4057 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4057 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4058 CpuFeatures::Scope scope(FPU); | 4058 CpuFeatureScope scope(masm(), FPU); |
4059 Register external_pointer = ToRegister(instr->elements()); | 4059 Register external_pointer = ToRegister(instr->elements()); |
4060 Register key = no_reg; | 4060 Register key = no_reg; |
4061 ElementsKind elements_kind = instr->elements_kind(); | 4061 ElementsKind elements_kind = instr->elements_kind(); |
4062 bool key_is_constant = instr->key()->IsConstantOperand(); | 4062 bool key_is_constant = instr->key()->IsConstantOperand(); |
4063 int constant_key = 0; | 4063 int constant_key = 0; |
4064 if (key_is_constant) { | 4064 if (key_is_constant) { |
4065 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4065 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4066 if (constant_key & 0xF0000000) { | 4066 if (constant_key & 0xF0000000) { |
4067 Abort("array index constant value too big."); | 4067 Abort("array index constant value too big."); |
4068 } | 4068 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4122 case DICTIONARY_ELEMENTS: | 4122 case DICTIONARY_ELEMENTS: |
4123 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4123 case NON_STRICT_ARGUMENTS_ELEMENTS: |
4124 UNREACHABLE(); | 4124 UNREACHABLE(); |
4125 break; | 4125 break; |
4126 } | 4126 } |
4127 } | 4127 } |
4128 } | 4128 } |
4129 | 4129 |
4130 | 4130 |
4131 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4131 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4132 CpuFeatures::Scope scope(FPU); | 4132 CpuFeatureScope scope(masm(), FPU); |
4133 DoubleRegister value = ToDoubleRegister(instr->value()); | 4133 DoubleRegister value = ToDoubleRegister(instr->value()); |
4134 Register elements = ToRegister(instr->elements()); | 4134 Register elements = ToRegister(instr->elements()); |
4135 Register key = no_reg; | 4135 Register key = no_reg; |
4136 Register scratch = scratch0(); | 4136 Register scratch = scratch0(); |
4137 bool key_is_constant = instr->key()->IsConstantOperand(); | 4137 bool key_is_constant = instr->key()->IsConstantOperand(); |
4138 int constant_key = 0; | 4138 int constant_key = 0; |
4139 Label not_nan; | 4139 Label not_nan; |
4140 | 4140 |
4141 // Calculate the effective address of the slot in the array to store the | 4141 // Calculate the effective address of the slot in the array to store the |
4142 // double value. | 4142 // double value. |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4426 | 4426 |
4427 | 4427 |
4428 void LCodeGen::DoStringLength(LStringLength* instr) { | 4428 void LCodeGen::DoStringLength(LStringLength* instr) { |
4429 Register string = ToRegister(instr->string()); | 4429 Register string = ToRegister(instr->string()); |
4430 Register result = ToRegister(instr->result()); | 4430 Register result = ToRegister(instr->result()); |
4431 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); | 4431 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); |
4432 } | 4432 } |
4433 | 4433 |
4434 | 4434 |
4435 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4435 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
4436 CpuFeatures::Scope scope(FPU); | 4436 CpuFeatureScope scope(masm(), FPU); |
4437 LOperand* input = instr->value(); | 4437 LOperand* input = instr->value(); |
4438 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4438 ASSERT(input->IsRegister() || input->IsStackSlot()); |
4439 LOperand* output = instr->result(); | 4439 LOperand* output = instr->result(); |
4440 ASSERT(output->IsDoubleRegister()); | 4440 ASSERT(output->IsDoubleRegister()); |
4441 FPURegister single_scratch = double_scratch0().low(); | 4441 FPURegister single_scratch = double_scratch0().low(); |
4442 if (input->IsStackSlot()) { | 4442 if (input->IsStackSlot()) { |
4443 Register scratch = scratch0(); | 4443 Register scratch = scratch0(); |
4444 __ lw(scratch, ToMemOperand(input)); | 4444 __ lw(scratch, ToMemOperand(input)); |
4445 __ mtc1(scratch, single_scratch); | 4445 __ mtc1(scratch, single_scratch); |
4446 } else { | 4446 } else { |
4447 __ mtc1(ToRegister(input), single_scratch); | 4447 __ mtc1(ToRegister(input), single_scratch); |
4448 } | 4448 } |
4449 __ cvt_d_w(ToDoubleRegister(output), single_scratch); | 4449 __ cvt_d_w(ToDoubleRegister(output), single_scratch); |
4450 } | 4450 } |
4451 | 4451 |
4452 | 4452 |
4453 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4453 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
4454 CpuFeatures::Scope scope(FPU); | 4454 CpuFeatureScope scope(masm(), FPU); |
4455 LOperand* input = instr->value(); | 4455 LOperand* input = instr->value(); |
4456 LOperand* output = instr->result(); | 4456 LOperand* output = instr->result(); |
4457 | 4457 |
4458 FPURegister dbl_scratch = double_scratch0(); | 4458 FPURegister dbl_scratch = double_scratch0(); |
4459 __ mtc1(ToRegister(input), dbl_scratch); | 4459 __ mtc1(ToRegister(input), dbl_scratch); |
4460 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); | 4460 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); |
4461 } | 4461 } |
4462 | 4462 |
4463 | 4463 |
4464 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4464 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4565 Label done; | 4565 Label done; |
4566 if (signedness == SIGNED_INT32) { | 4566 if (signedness == SIGNED_INT32) { |
4567 // There was overflow, so bits 30 and 31 of the original integer | 4567 // There was overflow, so bits 30 and 31 of the original integer |
4568 // disagree. Try to allocate a heap number in new space and store | 4568 // disagree. Try to allocate a heap number in new space and store |
4569 // the value in there. If that fails, call the runtime system. | 4569 // the value in there. If that fails, call the runtime system. |
4570 if (dst.is(src)) { | 4570 if (dst.is(src)) { |
4571 __ SmiUntag(src, dst); | 4571 __ SmiUntag(src, dst); |
4572 __ Xor(src, src, Operand(0x80000000)); | 4572 __ Xor(src, src, Operand(0x80000000)); |
4573 } | 4573 } |
4574 if (CpuFeatures::IsSupported(FPU)) { | 4574 if (CpuFeatures::IsSupported(FPU)) { |
4575 CpuFeatures::Scope scope(FPU); | 4575 CpuFeatureScope scope(masm(), FPU); |
4576 __ mtc1(src, dbl_scratch); | 4576 __ mtc1(src, dbl_scratch); |
4577 __ cvt_d_w(dbl_scratch, dbl_scratch); | 4577 __ cvt_d_w(dbl_scratch, dbl_scratch); |
4578 } else { | 4578 } else { |
4579 FloatingPointHelper::Destination dest = | 4579 FloatingPointHelper::Destination dest = |
4580 FloatingPointHelper::kCoreRegisters; | 4580 FloatingPointHelper::kCoreRegisters; |
4581 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, | 4581 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, |
4582 sfpd_lo, sfpd_hi, | 4582 sfpd_lo, sfpd_hi, |
4583 scratch0(), f2); | 4583 scratch0(), f2); |
4584 } | 4584 } |
4585 } else { | 4585 } else { |
4586 if (CpuFeatures::IsSupported(FPU)) { | 4586 if (CpuFeatures::IsSupported(FPU)) { |
4587 CpuFeatures::Scope scope(FPU); | 4587 CpuFeatureScope scope(masm(), FPU); |
4588 __ mtc1(src, dbl_scratch); | 4588 __ mtc1(src, dbl_scratch); |
4589 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); | 4589 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); |
4590 } else { | 4590 } else { |
4591 Label no_leading_zero, done; | 4591 Label no_leading_zero, done; |
4592 __ And(at, src, Operand(0x80000000)); | 4592 __ And(at, src, Operand(0x80000000)); |
4593 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); | 4593 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); |
4594 | 4594 |
4595 // Integer has one leading zeros. | 4595 // Integer has one leading zeros. |
4596 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1); | 4596 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1); |
4597 __ Branch(&done); | 4597 __ Branch(&done); |
(...skipping 19 matching lines...) Expand all Loading... |
4617 // integer value. | 4617 // integer value. |
4618 __ StoreToSafepointRegisterSlot(zero_reg, dst); | 4618 __ StoreToSafepointRegisterSlot(zero_reg, dst); |
4619 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 4619 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
4620 __ Move(dst, v0); | 4620 __ Move(dst, v0); |
4621 __ Subu(dst, dst, kHeapObjectTag); | 4621 __ Subu(dst, dst, kHeapObjectTag); |
4622 | 4622 |
4623 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4623 // Done. Put the value in dbl_scratch into the value of the allocated heap |
4624 // number. | 4624 // number. |
4625 __ bind(&done); | 4625 __ bind(&done); |
4626 if (CpuFeatures::IsSupported(FPU)) { | 4626 if (CpuFeatures::IsSupported(FPU)) { |
4627 CpuFeatures::Scope scope(FPU); | 4627 CpuFeatureScope scope(masm(), FPU); |
4628 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); | 4628 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); |
4629 } else { | 4629 } else { |
4630 __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | 4630 __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); |
4631 __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); | 4631 __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); |
4632 } | 4632 } |
4633 __ Addu(dst, dst, kHeapObjectTag); | 4633 __ Addu(dst, dst, kHeapObjectTag); |
4634 __ StoreToSafepointRegisterSlot(dst, dst); | 4634 __ StoreToSafepointRegisterSlot(dst, dst); |
4635 } | 4635 } |
4636 | 4636 |
4637 | 4637 |
(...skipping 18 matching lines...) Expand all Loading... |
4656 HValue* change_input = instr->hydrogen()->value(); | 4656 HValue* change_input = instr->hydrogen()->value(); |
4657 if (change_input->IsLoadKeyed()) { | 4657 if (change_input->IsLoadKeyed()) { |
4658 HLoadKeyed* load = HLoadKeyed::cast(change_input); | 4658 HLoadKeyed* load = HLoadKeyed::cast(change_input); |
4659 convert_hole = load->UsesMustHandleHole(); | 4659 convert_hole = load->UsesMustHandleHole(); |
4660 } | 4660 } |
4661 | 4661 |
4662 Label no_special_nan_handling; | 4662 Label no_special_nan_handling; |
4663 Label done; | 4663 Label done; |
4664 if (convert_hole) { | 4664 if (convert_hole) { |
4665 if (CpuFeatures::IsSupported(FPU)) { | 4665 if (CpuFeatures::IsSupported(FPU)) { |
4666 CpuFeatures::Scope scope(FPU); | 4666 CpuFeatureScope scope(masm(), FPU); |
4667 DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 4667 DoubleRegister input_reg = ToDoubleRegister(instr->value()); |
4668 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); | 4668 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); |
4669 __ Move(reg, scratch0(), input_reg); | 4669 __ Move(reg, scratch0(), input_reg); |
4670 Label canonicalize; | 4670 Label canonicalize; |
4671 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); | 4671 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); |
4672 __ li(reg, factory()->the_hole_value()); | 4672 __ li(reg, factory()->the_hole_value()); |
4673 __ Branch(&done); | 4673 __ Branch(&done); |
4674 __ bind(&canonicalize); | 4674 __ bind(&canonicalize); |
4675 __ Move(input_reg, | 4675 __ Move(input_reg, |
4676 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | 4676 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
(...skipping 25 matching lines...) Expand all Loading... |
4702 if (FLAG_inline_new) { | 4702 if (FLAG_inline_new) { |
4703 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4703 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
4704 // We want the untagged address first for performance | 4704 // We want the untagged address first for performance |
4705 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | 4705 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), |
4706 DONT_TAG_RESULT); | 4706 DONT_TAG_RESULT); |
4707 } else { | 4707 } else { |
4708 __ Branch(deferred->entry()); | 4708 __ Branch(deferred->entry()); |
4709 } | 4709 } |
4710 __ bind(deferred->exit()); | 4710 __ bind(deferred->exit()); |
4711 if (CpuFeatures::IsSupported(FPU)) { | 4711 if (CpuFeatures::IsSupported(FPU)) { |
4712 CpuFeatures::Scope scope(FPU); | 4712 CpuFeatureScope scope(masm(), FPU); |
4713 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); | 4713 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); |
4714 } else { | 4714 } else { |
4715 __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); | 4715 __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); |
4716 __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); | 4716 __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); |
4717 } | 4717 } |
4718 // Now that we have finished with the object's real address tag it | 4718 // Now that we have finished with the object's real address tag it |
4719 __ Addu(reg, reg, kHeapObjectTag); | 4719 __ Addu(reg, reg, kHeapObjectTag); |
4720 __ bind(&done); | 4720 __ bind(&done); |
4721 } | 4721 } |
4722 | 4722 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4757 } | 4757 } |
4758 | 4758 |
4759 | 4759 |
4760 void LCodeGen::EmitNumberUntagD(Register input_reg, | 4760 void LCodeGen::EmitNumberUntagD(Register input_reg, |
4761 DoubleRegister result_reg, | 4761 DoubleRegister result_reg, |
4762 bool deoptimize_on_undefined, | 4762 bool deoptimize_on_undefined, |
4763 bool deoptimize_on_minus_zero, | 4763 bool deoptimize_on_minus_zero, |
4764 LEnvironment* env, | 4764 LEnvironment* env, |
4765 NumberUntagDMode mode) { | 4765 NumberUntagDMode mode) { |
4766 Register scratch = scratch0(); | 4766 Register scratch = scratch0(); |
4767 CpuFeatures::Scope scope(FPU); | 4767 CpuFeatureScope scope(masm(), FPU); |
4768 | 4768 |
4769 Label load_smi, heap_number, done; | 4769 Label load_smi, heap_number, done; |
4770 | 4770 |
4771 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4771 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
4772 // Smi check. | 4772 // Smi check. |
4773 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4773 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
4774 | 4774 |
4775 // Heap number map check. | 4775 // Heap number map check. |
4776 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4776 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4777 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4777 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4835 Label done; | 4835 Label done; |
4836 | 4836 |
4837 // The input is a tagged HeapObject. | 4837 // The input is a tagged HeapObject. |
4838 // Heap number map check. | 4838 // Heap number map check. |
4839 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4839 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4840 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4840 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4841 // This 'at' value and scratch1 map value are used for tests in both clauses | 4841 // This 'at' value and scratch1 map value are used for tests in both clauses |
4842 // of the if. | 4842 // of the if. |
4843 | 4843 |
4844 if (instr->truncating()) { | 4844 if (instr->truncating()) { |
4845 CpuFeatures::Scope scope(FPU); | 4845 CpuFeatureScope scope(masm(), FPU); |
4846 Register scratch3 = ToRegister(instr->temp2()); | 4846 Register scratch3 = ToRegister(instr->temp2()); |
4847 FPURegister single_scratch = double_scratch.low(); | 4847 FPURegister single_scratch = double_scratch.low(); |
4848 ASSERT(!scratch3.is(input_reg) && | 4848 ASSERT(!scratch3.is(input_reg) && |
4849 !scratch3.is(scratch1) && | 4849 !scratch3.is(scratch1) && |
4850 !scratch3.is(scratch2)); | 4850 !scratch3.is(scratch2)); |
4851 // Performs a truncating conversion of a floating point number as used by | 4851 // Performs a truncating conversion of a floating point number as used by |
4852 // the JS bitwise operations. | 4852 // the JS bitwise operations. |
4853 Label heap_number; | 4853 Label heap_number; |
4854 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? | 4854 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? |
4855 // Check for undefined. Undefined is converted to zero for truncating | 4855 // Check for undefined. Undefined is converted to zero for truncating |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5090 __ CompareMapAndBranch( | 5090 __ CompareMapAndBranch( |
5091 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); | 5091 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); |
5092 } | 5092 } |
5093 Handle<Map> map = map_set->last(); | 5093 Handle<Map> map = map_set->last(); |
5094 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); | 5094 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); |
5095 __ bind(&success); | 5095 __ bind(&success); |
5096 } | 5096 } |
5097 | 5097 |
5098 | 5098 |
5099 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5099 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
5100 CpuFeatures::Scope vfp_scope(FPU); | 5100 CpuFeatureScope vfp_scope(masm(), FPU); |
5101 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5101 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); |
5102 Register result_reg = ToRegister(instr->result()); | 5102 Register result_reg = ToRegister(instr->result()); |
5103 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 5103 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5104 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); | 5104 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
5105 } | 5105 } |
5106 | 5106 |
5107 | 5107 |
5108 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 5108 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
5109 CpuFeatures::Scope vfp_scope(FPU); | 5109 CpuFeatureScope vfp_scope(masm(), FPU); |
5110 Register unclamped_reg = ToRegister(instr->unclamped()); | 5110 Register unclamped_reg = ToRegister(instr->unclamped()); |
5111 Register result_reg = ToRegister(instr->result()); | 5111 Register result_reg = ToRegister(instr->result()); |
5112 __ ClampUint8(result_reg, unclamped_reg); | 5112 __ ClampUint8(result_reg, unclamped_reg); |
5113 } | 5113 } |
5114 | 5114 |
5115 | 5115 |
5116 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 5116 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
5117 CpuFeatures::Scope vfp_scope(FPU); | 5117 CpuFeatureScope vfp_scope(masm(), FPU); |
5118 Register scratch = scratch0(); | 5118 Register scratch = scratch0(); |
5119 Register input_reg = ToRegister(instr->unclamped()); | 5119 Register input_reg = ToRegister(instr->unclamped()); |
5120 Register result_reg = ToRegister(instr->result()); | 5120 Register result_reg = ToRegister(instr->result()); |
5121 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 5121 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5122 Label is_smi, done, heap_number; | 5122 Label is_smi, done, heap_number; |
5123 | 5123 |
5124 // Both smi and heap number cases are handled. | 5124 // Both smi and heap number cases are handled. |
5125 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); | 5125 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); |
5126 | 5126 |
5127 // Check for heap number | 5127 // Check for heap number |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6038 __ Subu(scratch, result, scratch); | 6038 __ Subu(scratch, result, scratch); |
6039 __ lw(result, FieldMemOperand(scratch, | 6039 __ lw(result, FieldMemOperand(scratch, |
6040 FixedArray::kHeaderSize - kPointerSize)); | 6040 FixedArray::kHeaderSize - kPointerSize)); |
6041 __ bind(&done); | 6041 __ bind(&done); |
6042 } | 6042 } |
6043 | 6043 |
6044 | 6044 |
6045 #undef __ | 6045 #undef __ |
6046 | 6046 |
6047 } } // namespace v8::internal | 6047 } } // namespace v8::internal |
OLD | NEW |