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 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 | 1467 |
1468 void LCodeGen::DoConstantI(LConstantI* instr) { | 1468 void LCodeGen::DoConstantI(LConstantI* instr) { |
1469 ASSERT(instr->result()->IsRegister()); | 1469 ASSERT(instr->result()->IsRegister()); |
1470 __ li(ToRegister(instr->result()), Operand(instr->value())); | 1470 __ li(ToRegister(instr->result()), Operand(instr->value())); |
1471 } | 1471 } |
1472 | 1472 |
1473 | 1473 |
1474 void LCodeGen::DoConstantD(LConstantD* instr) { | 1474 void LCodeGen::DoConstantD(LConstantD* instr) { |
1475 ASSERT(instr->result()->IsDoubleRegister()); | 1475 ASSERT(instr->result()->IsDoubleRegister()); |
1476 DoubleRegister result = ToDoubleRegister(instr->result()); | 1476 DoubleRegister result = ToDoubleRegister(instr->result()); |
1477 CpuFeatures::Scope scope(FPU); | 1477 CpuFeatureScope scope(masm(), FPU); |
1478 double v = instr->value(); | 1478 double v = instr->value(); |
1479 __ Move(result, v); | 1479 __ Move(result, v); |
1480 } | 1480 } |
1481 | 1481 |
1482 | 1482 |
1483 void LCodeGen::DoConstantT(LConstantT* instr) { | 1483 void LCodeGen::DoConstantT(LConstantT* instr) { |
1484 Handle<Object> value = instr->value(); | 1484 Handle<Object> value = instr->value(); |
1485 if (value->IsSmi()) { | 1485 if (value->IsSmi()) { |
1486 __ li(ToRegister(instr->result()), Operand(value)); | 1486 __ li(ToRegister(instr->result()), Operand(value)); |
1487 } else { | 1487 } else { |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); | 1665 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); |
1666 __ mov(result_reg, left_reg); | 1666 __ mov(result_reg, left_reg); |
1667 __ Branch(&done); | 1667 __ Branch(&done); |
1668 } | 1668 } |
1669 __ Branch(&done, condition, left_reg, right_op); | 1669 __ Branch(&done, condition, left_reg, right_op); |
1670 __ bind(&return_right); | 1670 __ bind(&return_right); |
1671 __ Addu(result_reg, zero_reg, right_op); | 1671 __ Addu(result_reg, zero_reg, right_op); |
1672 __ bind(&done); | 1672 __ bind(&done); |
1673 } else { | 1673 } else { |
1674 ASSERT(instr->hydrogen()->representation().IsDouble()); | 1674 ASSERT(instr->hydrogen()->representation().IsDouble()); |
1675 CpuFeatures::Scope scope(FPU); | 1675 CpuFeatureScope scope(masm(), FPU); |
1676 FPURegister left_reg = ToDoubleRegister(left); | 1676 FPURegister left_reg = ToDoubleRegister(left); |
1677 FPURegister right_reg = ToDoubleRegister(right); | 1677 FPURegister right_reg = ToDoubleRegister(right); |
1678 FPURegister result_reg = ToDoubleRegister(instr->result()); | 1678 FPURegister result_reg = ToDoubleRegister(instr->result()); |
1679 Label check_nan_left, check_zero, return_left, return_right, done; | 1679 Label check_nan_left, check_zero, return_left, return_right, done; |
1680 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); | 1680 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); |
1681 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); | 1681 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); |
1682 __ Branch(&return_right); | 1682 __ Branch(&return_right); |
1683 | 1683 |
1684 __ bind(&check_zero); | 1684 __ bind(&check_zero); |
1685 // left == right != 0. | 1685 // left == right != 0. |
(...skipping 20 matching lines...) Expand all Loading... |
1706 __ bind(&return_left); | 1706 __ bind(&return_left); |
1707 if (!left_reg.is(result_reg)) { | 1707 if (!left_reg.is(result_reg)) { |
1708 __ mov_d(result_reg, left_reg); | 1708 __ mov_d(result_reg, left_reg); |
1709 } | 1709 } |
1710 __ bind(&done); | 1710 __ bind(&done); |
1711 } | 1711 } |
1712 } | 1712 } |
1713 | 1713 |
1714 | 1714 |
1715 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 1715 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
1716 CpuFeatures::Scope scope(FPU); | 1716 CpuFeatureScope scope(masm(), FPU); |
1717 DoubleRegister left = ToDoubleRegister(instr->left()); | 1717 DoubleRegister left = ToDoubleRegister(instr->left()); |
1718 DoubleRegister right = ToDoubleRegister(instr->right()); | 1718 DoubleRegister right = ToDoubleRegister(instr->right()); |
1719 DoubleRegister result = ToDoubleRegister(instr->result()); | 1719 DoubleRegister result = ToDoubleRegister(instr->result()); |
1720 switch (instr->op()) { | 1720 switch (instr->op()) { |
1721 case Token::ADD: | 1721 case Token::ADD: |
1722 __ add_d(result, left, right); | 1722 __ add_d(result, left, right); |
1723 break; | 1723 break; |
1724 case Token::SUB: | 1724 case Token::SUB: |
1725 __ sub_d(result, left, right); | 1725 __ sub_d(result, left, right); |
1726 break; | 1726 break; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1816 | 1816 |
1817 void LCodeGen::DoBranch(LBranch* instr) { | 1817 void LCodeGen::DoBranch(LBranch* instr) { |
1818 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1818 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1819 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1819 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1820 | 1820 |
1821 Representation r = instr->hydrogen()->value()->representation(); | 1821 Representation r = instr->hydrogen()->value()->representation(); |
1822 if (r.IsInteger32()) { | 1822 if (r.IsInteger32()) { |
1823 Register reg = ToRegister(instr->value()); | 1823 Register reg = ToRegister(instr->value()); |
1824 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); | 1824 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); |
1825 } else if (r.IsDouble()) { | 1825 } else if (r.IsDouble()) { |
1826 CpuFeatures::Scope scope(FPU); | 1826 CpuFeatureScope scope(masm(), FPU); |
1827 DoubleRegister reg = ToDoubleRegister(instr->value()); | 1827 DoubleRegister reg = ToDoubleRegister(instr->value()); |
1828 // Test the double value. Zero and NaN are false. | 1828 // Test the double value. Zero and NaN are false. |
1829 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); | 1829 EmitBranchF(true_block, false_block, ne, reg, kDoubleRegZero); |
1830 } else { | 1830 } else { |
1831 ASSERT(r.IsTagged()); | 1831 ASSERT(r.IsTagged()); |
1832 Register reg = ToRegister(instr->value()); | 1832 Register reg = ToRegister(instr->value()); |
1833 HType type = instr->hydrogen()->value()->type(); | 1833 HType type = instr->hydrogen()->value()->type(); |
1834 if (type.IsBoolean()) { | 1834 if (type.IsBoolean()) { |
1835 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1835 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
1836 EmitBranch(true_block, false_block, eq, reg, Operand(at)); | 1836 EmitBranch(true_block, false_block, eq, reg, Operand(at)); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 Label not_string; | 1894 Label not_string; |
1895 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 1895 __ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
1896 __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); | 1896 __ Branch(¬_string, ge , at, Operand(FIRST_NONSTRING_TYPE)); |
1897 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); | 1897 __ lw(at, FieldMemOperand(reg, String::kLengthOffset)); |
1898 __ Branch(true_label, ne, at, Operand(zero_reg)); | 1898 __ Branch(true_label, ne, at, Operand(zero_reg)); |
1899 __ Branch(false_label); | 1899 __ Branch(false_label); |
1900 __ bind(¬_string); | 1900 __ bind(¬_string); |
1901 } | 1901 } |
1902 | 1902 |
1903 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1903 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
1904 CpuFeatures::Scope scope(FPU); | 1904 CpuFeatureScope scope(masm(), FPU); |
1905 // heap number -> false iff +0, -0, or NaN. | 1905 // heap number -> false iff +0, -0, or NaN. |
1906 DoubleRegister dbl_scratch = double_scratch0(); | 1906 DoubleRegister dbl_scratch = double_scratch0(); |
1907 Label not_heap_number; | 1907 Label not_heap_number; |
1908 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 1908 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
1909 __ Branch(¬_heap_number, ne, map, Operand(at)); | 1909 __ Branch(¬_heap_number, ne, map, Operand(at)); |
1910 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 1910 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
1911 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); | 1911 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); |
1912 // Falls through if dbl_scratch == 0. | 1912 // Falls through if dbl_scratch == 0. |
1913 __ Branch(false_label); | 1913 __ Branch(false_label); |
1914 __ bind(¬_heap_number); | 1914 __ bind(¬_heap_number); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 1974 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
1975 // We can statically evaluate the comparison. | 1975 // We can statically evaluate the comparison. |
1976 double left_val = ToDouble(LConstantOperand::cast(left)); | 1976 double left_val = ToDouble(LConstantOperand::cast(left)); |
1977 double right_val = ToDouble(LConstantOperand::cast(right)); | 1977 double right_val = ToDouble(LConstantOperand::cast(right)); |
1978 int next_block = | 1978 int next_block = |
1979 EvalComparison(instr->op(), left_val, right_val) ? true_block | 1979 EvalComparison(instr->op(), left_val, right_val) ? true_block |
1980 : false_block; | 1980 : false_block; |
1981 EmitGoto(next_block); | 1981 EmitGoto(next_block); |
1982 } else { | 1982 } else { |
1983 if (instr->is_double()) { | 1983 if (instr->is_double()) { |
1984 CpuFeatures::Scope scope(FPU); | 1984 CpuFeatureScope scope(masm(), FPU); |
1985 // Compare left and right as doubles and load the | 1985 // Compare left and right as doubles and load the |
1986 // resulting flags into the normal status register. | 1986 // resulting flags into the normal status register. |
1987 FPURegister left_reg = ToDoubleRegister(left); | 1987 FPURegister left_reg = ToDoubleRegister(left); |
1988 FPURegister right_reg = ToDoubleRegister(right); | 1988 FPURegister right_reg = ToDoubleRegister(right); |
1989 | 1989 |
1990 // If a NaN is involved, i.e. the result is unordered, | 1990 // If a NaN is involved, i.e. the result is unordered, |
1991 // jump to false block label. | 1991 // jump to false block label. |
1992 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, | 1992 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, |
1993 left_reg, right_reg); | 1993 left_reg, right_reg); |
1994 | 1994 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2537 | 2537 |
2538 | 2538 |
2539 void LCodeGen::DoReturn(LReturn* instr) { | 2539 void LCodeGen::DoReturn(LReturn* instr) { |
2540 if (FLAG_trace && info()->IsOptimizing()) { | 2540 if (FLAG_trace && info()->IsOptimizing()) { |
2541 // Push the return value on the stack as the parameter. | 2541 // Push the return value on the stack as the parameter. |
2542 // Runtime::TraceExit returns its parameter in v0. | 2542 // Runtime::TraceExit returns its parameter in v0. |
2543 __ push(v0); | 2543 __ push(v0); |
2544 __ CallRuntime(Runtime::kTraceExit, 1); | 2544 __ CallRuntime(Runtime::kTraceExit, 1); |
2545 } | 2545 } |
2546 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { | 2546 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { |
2547 CpuFeatures::Scope scope(FPU); | 2547 CpuFeatureScope scope(masm(), FPU); |
2548 ASSERT(NeedsEagerFrame()); | 2548 ASSERT(NeedsEagerFrame()); |
2549 BitVector* doubles = chunk()->allocated_double_registers(); | 2549 BitVector* doubles = chunk()->allocated_double_registers(); |
2550 BitVector::Iterator save_iterator(doubles); | 2550 BitVector::Iterator save_iterator(doubles); |
2551 int count = 0; | 2551 int count = 0; |
2552 while (!save_iterator.Done()) { | 2552 while (!save_iterator.Done()) { |
2553 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), | 2553 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
2554 MemOperand(sp, count * kDoubleSize)); | 2554 MemOperand(sp, count * kDoubleSize)); |
2555 save_iterator.Advance(); | 2555 save_iterator.Advance(); |
2556 count++; | 2556 count++; |
2557 } | 2557 } |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2916 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2916 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
2917 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2917 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2918 FPURegister result = ToDoubleRegister(instr->result()); | 2918 FPURegister result = ToDoubleRegister(instr->result()); |
2919 if (key_is_constant) { | 2919 if (key_is_constant) { |
2920 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); | 2920 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); |
2921 } else { | 2921 } else { |
2922 __ sll(scratch0(), key, shift_size); | 2922 __ sll(scratch0(), key, shift_size); |
2923 __ Addu(scratch0(), scratch0(), external_pointer); | 2923 __ Addu(scratch0(), scratch0(), external_pointer); |
2924 } | 2924 } |
2925 if (CpuFeatures::IsSupported(FPU)) { | 2925 if (CpuFeatures::IsSupported(FPU)) { |
2926 CpuFeatures::Scope scope(FPU); | 2926 CpuFeatureScope scope(masm(), FPU); |
2927 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2927 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2928 __ lwc1(result, MemOperand(scratch0(), additional_offset)); | 2928 __ lwc1(result, MemOperand(scratch0(), additional_offset)); |
2929 __ cvt_d_s(result, result); | 2929 __ cvt_d_s(result, result); |
2930 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | 2930 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2931 __ ldc1(result, MemOperand(scratch0(), additional_offset)); | 2931 __ ldc1(result, MemOperand(scratch0(), additional_offset)); |
2932 } | 2932 } |
2933 } else { | 2933 } else { |
2934 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2934 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2935 Register value = external_pointer; | 2935 Register value = external_pointer; |
2936 __ lw(value, MemOperand(scratch0(), additional_offset)); | 2936 __ lw(value, MemOperand(scratch0(), additional_offset)); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 key = ToRegister(instr->key()); | 3045 key = ToRegister(instr->key()); |
3046 } | 3046 } |
3047 | 3047 |
3048 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3048 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
3049 ((constant_key + instr->additional_index()) << element_size_shift); | 3049 ((constant_key + instr->additional_index()) << element_size_shift); |
3050 if (!key_is_constant) { | 3050 if (!key_is_constant) { |
3051 __ sll(scratch, key, shift_size); | 3051 __ sll(scratch, key, shift_size); |
3052 __ Addu(elements, elements, scratch); | 3052 __ Addu(elements, elements, scratch); |
3053 } | 3053 } |
3054 if (CpuFeatures::IsSupported(FPU)) { | 3054 if (CpuFeatures::IsSupported(FPU)) { |
3055 CpuFeatures::Scope scope(FPU); | 3055 CpuFeatureScope scope(masm(), FPU); |
3056 __ Addu(elements, elements, Operand(base_offset)); | 3056 __ Addu(elements, elements, Operand(base_offset)); |
3057 __ ldc1(result, MemOperand(elements)); | 3057 __ ldc1(result, MemOperand(elements)); |
3058 if (instr->hydrogen()->RequiresHoleCheck()) { | 3058 if (instr->hydrogen()->RequiresHoleCheck()) { |
3059 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | 3059 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
3060 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | 3060 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
3061 } | 3061 } |
3062 } else { | 3062 } else { |
3063 __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); | 3063 __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); |
3064 __ lw(sfpd_lo, MemOperand(elements, base_offset)); | 3064 __ lw(sfpd_lo, MemOperand(elements, base_offset)); |
3065 if (instr->hydrogen()->RequiresHoleCheck()) { | 3065 if (instr->hydrogen()->RequiresHoleCheck()) { |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3508 __ mov(result, input); | 3508 __ mov(result, input); |
3509 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); | 3509 ASSERT_EQ(2, masm()->InstructionsGeneratedSince(&done)); |
3510 __ subu(result, zero_reg, input); | 3510 __ subu(result, zero_reg, input); |
3511 // Overflow if result is still negative, i.e. 0x80000000. | 3511 // Overflow if result is still negative, i.e. 0x80000000. |
3512 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); | 3512 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); |
3513 __ bind(&done); | 3513 __ bind(&done); |
3514 } | 3514 } |
3515 | 3515 |
3516 | 3516 |
3517 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 3517 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
3518 CpuFeatures::Scope scope(FPU); | 3518 CpuFeatureScope scope(masm(), FPU); |
3519 // Class for deferred case. | 3519 // Class for deferred case. |
3520 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3520 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
3521 public: | 3521 public: |
3522 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 3522 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
3523 LUnaryMathOperation* instr) | 3523 LUnaryMathOperation* instr) |
3524 : LDeferredCode(codegen), instr_(instr) { } | 3524 : LDeferredCode(codegen), instr_(instr) { } |
3525 virtual void Generate() { | 3525 virtual void Generate() { |
3526 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3526 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
3527 } | 3527 } |
3528 virtual LInstruction* instr() { return instr_; } | 3528 virtual LInstruction* instr() { return instr_; } |
(...skipping 16 matching lines...) Expand all Loading... |
3545 // Smi check. | 3545 // Smi check. |
3546 __ JumpIfNotSmi(input, deferred->entry()); | 3546 __ JumpIfNotSmi(input, deferred->entry()); |
3547 // If smi, handle it directly. | 3547 // If smi, handle it directly. |
3548 EmitIntegerMathAbs(instr); | 3548 EmitIntegerMathAbs(instr); |
3549 __ bind(deferred->exit()); | 3549 __ bind(deferred->exit()); |
3550 } | 3550 } |
3551 } | 3551 } |
3552 | 3552 |
3553 | 3553 |
3554 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3554 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
3555 CpuFeatures::Scope scope(FPU); | 3555 CpuFeatureScope scope(masm(), FPU); |
3556 DoubleRegister input = ToDoubleRegister(instr->value()); | 3556 DoubleRegister input = ToDoubleRegister(instr->value()); |
3557 Register result = ToRegister(instr->result()); | 3557 Register result = ToRegister(instr->result()); |
3558 Register scratch1 = scratch0(); | 3558 Register scratch1 = scratch0(); |
3559 Register except_flag = ToRegister(instr->temp()); | 3559 Register except_flag = ToRegister(instr->temp()); |
3560 | 3560 |
3561 __ EmitFPUTruncate(kRoundToMinusInf, | 3561 __ EmitFPUTruncate(kRoundToMinusInf, |
3562 result, | 3562 result, |
3563 input, | 3563 input, |
3564 scratch1, | 3564 scratch1, |
3565 double_scratch0(), | 3565 double_scratch0(), |
3566 except_flag); | 3566 except_flag); |
3567 | 3567 |
3568 // Deopt if the operation did not succeed. | 3568 // Deopt if the operation did not succeed. |
3569 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3569 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
3570 | 3570 |
3571 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3571 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3572 // Test for -0. | 3572 // Test for -0. |
3573 Label done; | 3573 Label done; |
3574 __ Branch(&done, ne, result, Operand(zero_reg)); | 3574 __ Branch(&done, ne, result, Operand(zero_reg)); |
3575 __ mfc1(scratch1, input.high()); | 3575 __ mfc1(scratch1, input.high()); |
3576 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 3576 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
3577 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 3577 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
3578 __ bind(&done); | 3578 __ bind(&done); |
3579 } | 3579 } |
3580 } | 3580 } |
3581 | 3581 |
3582 | 3582 |
3583 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3583 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
3584 CpuFeatures::Scope scope(FPU); | 3584 CpuFeatureScope scope(masm(), FPU); |
3585 DoubleRegister input = ToDoubleRegister(instr->value()); | 3585 DoubleRegister input = ToDoubleRegister(instr->value()); |
3586 Register result = ToRegister(instr->result()); | 3586 Register result = ToRegister(instr->result()); |
3587 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3587 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
3588 Register scratch = scratch0(); | 3588 Register scratch = scratch0(); |
3589 Label done, check_sign_on_zero; | 3589 Label done, check_sign_on_zero; |
3590 | 3590 |
3591 // Extract exponent bits. | 3591 // Extract exponent bits. |
3592 __ mfc1(result, input.high()); | 3592 __ mfc1(result, input.high()); |
3593 __ Ext(scratch, | 3593 __ Ext(scratch, |
3594 result, | 3594 result, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3651 __ bind(&check_sign_on_zero); | 3651 __ bind(&check_sign_on_zero); |
3652 __ mfc1(scratch, input.high()); | 3652 __ mfc1(scratch, input.high()); |
3653 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); | 3653 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); |
3654 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3654 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
3655 } | 3655 } |
3656 __ bind(&done); | 3656 __ bind(&done); |
3657 } | 3657 } |
3658 | 3658 |
3659 | 3659 |
3660 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3660 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
3661 CpuFeatures::Scope scope(FPU); | 3661 CpuFeatureScope scope(masm(), FPU); |
3662 DoubleRegister input = ToDoubleRegister(instr->value()); | 3662 DoubleRegister input = ToDoubleRegister(instr->value()); |
3663 DoubleRegister result = ToDoubleRegister(instr->result()); | 3663 DoubleRegister result = ToDoubleRegister(instr->result()); |
3664 __ sqrt_d(result, input); | 3664 __ sqrt_d(result, input); |
3665 } | 3665 } |
3666 | 3666 |
3667 | 3667 |
3668 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 3668 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { |
3669 CpuFeatures::Scope scope(FPU); | 3669 CpuFeatureScope scope(masm(), FPU); |
3670 DoubleRegister input = ToDoubleRegister(instr->value()); | 3670 DoubleRegister input = ToDoubleRegister(instr->value()); |
3671 DoubleRegister result = ToDoubleRegister(instr->result()); | 3671 DoubleRegister result = ToDoubleRegister(instr->result()); |
3672 DoubleRegister temp = ToDoubleRegister(instr->temp()); | 3672 DoubleRegister temp = ToDoubleRegister(instr->temp()); |
3673 | 3673 |
3674 ASSERT(!input.is(result)); | 3674 ASSERT(!input.is(result)); |
3675 | 3675 |
3676 // Note that according to ECMA-262 15.8.2.13: | 3676 // Note that according to ECMA-262 15.8.2.13: |
3677 // Math.pow(-Infinity, 0.5) == Infinity | 3677 // Math.pow(-Infinity, 0.5) == Infinity |
3678 // Math.sqrt(-Infinity) == NaN | 3678 // Math.sqrt(-Infinity) == NaN |
3679 Label done; | 3679 Label done; |
3680 __ Move(temp, -V8_INFINITY); | 3680 __ Move(temp, -V8_INFINITY); |
3681 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); | 3681 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); |
3682 // Set up Infinity in the delay slot. | 3682 // Set up Infinity in the delay slot. |
3683 // result is overwritten if the branch is not taken. | 3683 // result is overwritten if the branch is not taken. |
3684 __ neg_d(result, temp); | 3684 __ neg_d(result, temp); |
3685 | 3685 |
3686 // Add +0 to convert -0 to +0. | 3686 // Add +0 to convert -0 to +0. |
3687 __ add_d(result, input, kDoubleRegZero); | 3687 __ add_d(result, input, kDoubleRegZero); |
3688 __ sqrt_d(result, result); | 3688 __ sqrt_d(result, result); |
3689 __ bind(&done); | 3689 __ bind(&done); |
3690 } | 3690 } |
3691 | 3691 |
3692 | 3692 |
3693 void LCodeGen::DoPower(LPower* instr) { | 3693 void LCodeGen::DoPower(LPower* instr) { |
3694 CpuFeatures::Scope scope(FPU); | 3694 CpuFeatureScope scope(masm(), FPU); |
3695 Representation exponent_type = instr->hydrogen()->right()->representation(); | 3695 Representation exponent_type = instr->hydrogen()->right()->representation(); |
3696 // Having marked this as a call, we can use any registers. | 3696 // Having marked this as a call, we can use any registers. |
3697 // Just make sure that the input/output registers are the expected ones. | 3697 // Just make sure that the input/output registers are the expected ones. |
3698 ASSERT(!instr->right()->IsDoubleRegister() || | 3698 ASSERT(!instr->right()->IsDoubleRegister() || |
3699 ToDoubleRegister(instr->right()).is(f4)); | 3699 ToDoubleRegister(instr->right()).is(f4)); |
3700 ASSERT(!instr->right()->IsRegister() || | 3700 ASSERT(!instr->right()->IsRegister() || |
3701 ToRegister(instr->right()).is(a2)); | 3701 ToRegister(instr->right()).is(a2)); |
3702 ASSERT(ToDoubleRegister(instr->left()).is(f2)); | 3702 ASSERT(ToDoubleRegister(instr->left()).is(f2)); |
3703 ASSERT(ToDoubleRegister(instr->result()).is(f0)); | 3703 ASSERT(ToDoubleRegister(instr->result()).is(f0)); |
3704 | 3704 |
(...skipping 10 matching lines...) Expand all Loading... |
3715 __ CallStub(&stub); | 3715 __ CallStub(&stub); |
3716 } else { | 3716 } else { |
3717 ASSERT(exponent_type.IsDouble()); | 3717 ASSERT(exponent_type.IsDouble()); |
3718 MathPowStub stub(MathPowStub::DOUBLE); | 3718 MathPowStub stub(MathPowStub::DOUBLE); |
3719 __ CallStub(&stub); | 3719 __ CallStub(&stub); |
3720 } | 3720 } |
3721 } | 3721 } |
3722 | 3722 |
3723 | 3723 |
3724 void LCodeGen::DoRandom(LRandom* instr) { | 3724 void LCodeGen::DoRandom(LRandom* instr) { |
3725 CpuFeatures::Scope scope(FPU); | 3725 CpuFeatureScope scope(masm(), FPU); |
3726 class DeferredDoRandom: public LDeferredCode { | 3726 class DeferredDoRandom: public LDeferredCode { |
3727 public: | 3727 public: |
3728 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 3728 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
3729 : LDeferredCode(codegen), instr_(instr) { } | 3729 : LDeferredCode(codegen), instr_(instr) { } |
3730 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } | 3730 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
3731 virtual LInstruction* instr() { return instr_; } | 3731 virtual LInstruction* instr() { return instr_; } |
3732 private: | 3732 private: |
3733 LRandom* instr_; | 3733 LRandom* instr_; |
3734 }; | 3734 }; |
3735 | 3735 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3792 } | 3792 } |
3793 | 3793 |
3794 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 3794 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
3795 __ PrepareCallCFunction(1, scratch0()); | 3795 __ PrepareCallCFunction(1, scratch0()); |
3796 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3796 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3797 // Return value is in v0. | 3797 // Return value is in v0. |
3798 } | 3798 } |
3799 | 3799 |
3800 | 3800 |
3801 void LCodeGen::DoMathExp(LMathExp* instr) { | 3801 void LCodeGen::DoMathExp(LMathExp* instr) { |
3802 CpuFeatures::Scope scope(FPU); | 3802 CpuFeatureScope scope(masm(), FPU); |
3803 DoubleRegister input = ToDoubleRegister(instr->value()); | 3803 DoubleRegister input = ToDoubleRegister(instr->value()); |
3804 DoubleRegister result = ToDoubleRegister(instr->result()); | 3804 DoubleRegister result = ToDoubleRegister(instr->result()); |
3805 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); | 3805 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); |
3806 DoubleRegister double_scratch2 = double_scratch0(); | 3806 DoubleRegister double_scratch2 = double_scratch0(); |
3807 Register temp1 = ToRegister(instr->temp1()); | 3807 Register temp1 = ToRegister(instr->temp1()); |
3808 Register temp2 = ToRegister(instr->temp2()); | 3808 Register temp2 = ToRegister(instr->temp2()); |
3809 | 3809 |
3810 MathExpGenerator::EmitMathExp( | 3810 MathExpGenerator::EmitMathExp( |
3811 masm(), input, result, double_scratch1, double_scratch2, | 3811 masm(), input, result, double_scratch1, double_scratch2, |
3812 temp1, temp2, scratch0()); | 3812 temp1, temp2, scratch0()); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4068 } else { | 4068 } else { |
4069 DeoptimizeIf(hs, | 4069 DeoptimizeIf(hs, |
4070 instr->environment(), | 4070 instr->environment(), |
4071 ToRegister(instr->index()), | 4071 ToRegister(instr->index()), |
4072 Operand(ToRegister(instr->length()))); | 4072 Operand(ToRegister(instr->length()))); |
4073 } | 4073 } |
4074 } | 4074 } |
4075 | 4075 |
4076 | 4076 |
4077 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4077 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4078 CpuFeatures::Scope scope(FPU); | 4078 CpuFeatureScope scope(masm(), FPU); |
4079 Register external_pointer = ToRegister(instr->elements()); | 4079 Register external_pointer = ToRegister(instr->elements()); |
4080 Register key = no_reg; | 4080 Register key = no_reg; |
4081 ElementsKind elements_kind = instr->elements_kind(); | 4081 ElementsKind elements_kind = instr->elements_kind(); |
4082 bool key_is_constant = instr->key()->IsConstantOperand(); | 4082 bool key_is_constant = instr->key()->IsConstantOperand(); |
4083 int constant_key = 0; | 4083 int constant_key = 0; |
4084 if (key_is_constant) { | 4084 if (key_is_constant) { |
4085 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4085 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4086 if (constant_key & 0xF0000000) { | 4086 if (constant_key & 0xF0000000) { |
4087 Abort("array index constant value too big."); | 4087 Abort("array index constant value too big."); |
4088 } | 4088 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4142 case DICTIONARY_ELEMENTS: | 4142 case DICTIONARY_ELEMENTS: |
4143 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4143 case NON_STRICT_ARGUMENTS_ELEMENTS: |
4144 UNREACHABLE(); | 4144 UNREACHABLE(); |
4145 break; | 4145 break; |
4146 } | 4146 } |
4147 } | 4147 } |
4148 } | 4148 } |
4149 | 4149 |
4150 | 4150 |
4151 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4151 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4152 CpuFeatures::Scope scope(FPU); | 4152 CpuFeatureScope scope(masm(), FPU); |
4153 DoubleRegister value = ToDoubleRegister(instr->value()); | 4153 DoubleRegister value = ToDoubleRegister(instr->value()); |
4154 Register elements = ToRegister(instr->elements()); | 4154 Register elements = ToRegister(instr->elements()); |
4155 Register key = no_reg; | 4155 Register key = no_reg; |
4156 Register scratch = scratch0(); | 4156 Register scratch = scratch0(); |
4157 bool key_is_constant = instr->key()->IsConstantOperand(); | 4157 bool key_is_constant = instr->key()->IsConstantOperand(); |
4158 int constant_key = 0; | 4158 int constant_key = 0; |
4159 Label not_nan; | 4159 Label not_nan; |
4160 | 4160 |
4161 // Calculate the effective address of the slot in the array to store the | 4161 // Calculate the effective address of the slot in the array to store the |
4162 // double value. | 4162 // double value. |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 | 4446 |
4447 | 4447 |
4448 void LCodeGen::DoStringLength(LStringLength* instr) { | 4448 void LCodeGen::DoStringLength(LStringLength* instr) { |
4449 Register string = ToRegister(instr->string()); | 4449 Register string = ToRegister(instr->string()); |
4450 Register result = ToRegister(instr->result()); | 4450 Register result = ToRegister(instr->result()); |
4451 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); | 4451 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); |
4452 } | 4452 } |
4453 | 4453 |
4454 | 4454 |
4455 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4455 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
4456 CpuFeatures::Scope scope(FPU); | 4456 CpuFeatureScope scope(masm(), FPU); |
4457 LOperand* input = instr->value(); | 4457 LOperand* input = instr->value(); |
4458 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4458 ASSERT(input->IsRegister() || input->IsStackSlot()); |
4459 LOperand* output = instr->result(); | 4459 LOperand* output = instr->result(); |
4460 ASSERT(output->IsDoubleRegister()); | 4460 ASSERT(output->IsDoubleRegister()); |
4461 FPURegister single_scratch = double_scratch0().low(); | 4461 FPURegister single_scratch = double_scratch0().low(); |
4462 if (input->IsStackSlot()) { | 4462 if (input->IsStackSlot()) { |
4463 Register scratch = scratch0(); | 4463 Register scratch = scratch0(); |
4464 __ lw(scratch, ToMemOperand(input)); | 4464 __ lw(scratch, ToMemOperand(input)); |
4465 __ mtc1(scratch, single_scratch); | 4465 __ mtc1(scratch, single_scratch); |
4466 } else { | 4466 } else { |
4467 __ mtc1(ToRegister(input), single_scratch); | 4467 __ mtc1(ToRegister(input), single_scratch); |
4468 } | 4468 } |
4469 __ cvt_d_w(ToDoubleRegister(output), single_scratch); | 4469 __ cvt_d_w(ToDoubleRegister(output), single_scratch); |
4470 } | 4470 } |
4471 | 4471 |
4472 | 4472 |
4473 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4473 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
4474 CpuFeatures::Scope scope(FPU); | 4474 CpuFeatureScope scope(masm(), FPU); |
4475 LOperand* input = instr->value(); | 4475 LOperand* input = instr->value(); |
4476 LOperand* output = instr->result(); | 4476 LOperand* output = instr->result(); |
4477 | 4477 |
4478 FPURegister dbl_scratch = double_scratch0(); | 4478 FPURegister dbl_scratch = double_scratch0(); |
4479 __ mtc1(ToRegister(input), dbl_scratch); | 4479 __ mtc1(ToRegister(input), dbl_scratch); |
4480 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); | 4480 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); |
4481 } | 4481 } |
4482 | 4482 |
4483 | 4483 |
4484 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4484 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4585 Label done; | 4585 Label done; |
4586 if (signedness == SIGNED_INT32) { | 4586 if (signedness == SIGNED_INT32) { |
4587 // There was overflow, so bits 30 and 31 of the original integer | 4587 // There was overflow, so bits 30 and 31 of the original integer |
4588 // disagree. Try to allocate a heap number in new space and store | 4588 // disagree. Try to allocate a heap number in new space and store |
4589 // the value in there. If that fails, call the runtime system. | 4589 // the value in there. If that fails, call the runtime system. |
4590 if (dst.is(src)) { | 4590 if (dst.is(src)) { |
4591 __ SmiUntag(src, dst); | 4591 __ SmiUntag(src, dst); |
4592 __ Xor(src, src, Operand(0x80000000)); | 4592 __ Xor(src, src, Operand(0x80000000)); |
4593 } | 4593 } |
4594 if (CpuFeatures::IsSupported(FPU)) { | 4594 if (CpuFeatures::IsSupported(FPU)) { |
4595 CpuFeatures::Scope scope(FPU); | 4595 CpuFeatureScope scope(masm(), FPU); |
4596 __ mtc1(src, dbl_scratch); | 4596 __ mtc1(src, dbl_scratch); |
4597 __ cvt_d_w(dbl_scratch, dbl_scratch); | 4597 __ cvt_d_w(dbl_scratch, dbl_scratch); |
4598 } else { | 4598 } else { |
4599 FloatingPointHelper::Destination dest = | 4599 FloatingPointHelper::Destination dest = |
4600 FloatingPointHelper::kCoreRegisters; | 4600 FloatingPointHelper::kCoreRegisters; |
4601 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, | 4601 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, |
4602 sfpd_lo, sfpd_hi, | 4602 sfpd_lo, sfpd_hi, |
4603 scratch0(), f2); | 4603 scratch0(), f2); |
4604 } | 4604 } |
4605 } else { | 4605 } else { |
4606 if (CpuFeatures::IsSupported(FPU)) { | 4606 if (CpuFeatures::IsSupported(FPU)) { |
4607 CpuFeatures::Scope scope(FPU); | 4607 CpuFeatureScope scope(masm(), FPU); |
4608 __ mtc1(src, dbl_scratch); | 4608 __ mtc1(src, dbl_scratch); |
4609 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); | 4609 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); |
4610 } else { | 4610 } else { |
4611 Label no_leading_zero, done; | 4611 Label no_leading_zero, done; |
4612 __ And(at, src, Operand(0x80000000)); | 4612 __ And(at, src, Operand(0x80000000)); |
4613 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); | 4613 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); |
4614 | 4614 |
4615 // Integer has one leading zeros. | 4615 // Integer has one leading zeros. |
4616 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1); | 4616 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, t0, 1); |
4617 __ Branch(&done); | 4617 __ Branch(&done); |
(...skipping 19 matching lines...) Expand all Loading... |
4637 // integer value. | 4637 // integer value. |
4638 __ StoreToSafepointRegisterSlot(zero_reg, dst); | 4638 __ StoreToSafepointRegisterSlot(zero_reg, dst); |
4639 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 4639 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
4640 __ Move(dst, v0); | 4640 __ Move(dst, v0); |
4641 __ Subu(dst, dst, kHeapObjectTag); | 4641 __ Subu(dst, dst, kHeapObjectTag); |
4642 | 4642 |
4643 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4643 // Done. Put the value in dbl_scratch into the value of the allocated heap |
4644 // number. | 4644 // number. |
4645 __ bind(&done); | 4645 __ bind(&done); |
4646 if (CpuFeatures::IsSupported(FPU)) { | 4646 if (CpuFeatures::IsSupported(FPU)) { |
4647 CpuFeatures::Scope scope(FPU); | 4647 CpuFeatureScope scope(masm(), FPU); |
4648 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); | 4648 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); |
4649 } else { | 4649 } else { |
4650 __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | 4650 __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); |
4651 __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); | 4651 __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); |
4652 } | 4652 } |
4653 __ Addu(dst, dst, kHeapObjectTag); | 4653 __ Addu(dst, dst, kHeapObjectTag); |
4654 __ StoreToSafepointRegisterSlot(dst, dst); | 4654 __ StoreToSafepointRegisterSlot(dst, dst); |
4655 } | 4655 } |
4656 | 4656 |
4657 | 4657 |
(...skipping 18 matching lines...) Expand all Loading... |
4676 HValue* change_input = instr->hydrogen()->value(); | 4676 HValue* change_input = instr->hydrogen()->value(); |
4677 if (change_input->IsLoadKeyed()) { | 4677 if (change_input->IsLoadKeyed()) { |
4678 HLoadKeyed* load = HLoadKeyed::cast(change_input); | 4678 HLoadKeyed* load = HLoadKeyed::cast(change_input); |
4679 convert_hole = load->UsesMustHandleHole(); | 4679 convert_hole = load->UsesMustHandleHole(); |
4680 } | 4680 } |
4681 | 4681 |
4682 Label no_special_nan_handling; | 4682 Label no_special_nan_handling; |
4683 Label done; | 4683 Label done; |
4684 if (convert_hole) { | 4684 if (convert_hole) { |
4685 if (CpuFeatures::IsSupported(FPU)) { | 4685 if (CpuFeatures::IsSupported(FPU)) { |
4686 CpuFeatures::Scope scope(FPU); | 4686 CpuFeatureScope scope(masm(), FPU); |
4687 DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 4687 DoubleRegister input_reg = ToDoubleRegister(instr->value()); |
4688 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); | 4688 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); |
4689 __ Move(reg, scratch0(), input_reg); | 4689 __ Move(reg, scratch0(), input_reg); |
4690 Label canonicalize; | 4690 Label canonicalize; |
4691 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); | 4691 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); |
4692 __ li(reg, factory()->the_hole_value()); | 4692 __ li(reg, factory()->the_hole_value()); |
4693 __ Branch(&done); | 4693 __ Branch(&done); |
4694 __ bind(&canonicalize); | 4694 __ bind(&canonicalize); |
4695 __ Move(input_reg, | 4695 __ Move(input_reg, |
4696 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | 4696 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
(...skipping 25 matching lines...) Expand all Loading... |
4722 if (FLAG_inline_new) { | 4722 if (FLAG_inline_new) { |
4723 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4723 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
4724 // We want the untagged address first for performance | 4724 // We want the untagged address first for performance |
4725 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | 4725 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), |
4726 DONT_TAG_RESULT); | 4726 DONT_TAG_RESULT); |
4727 } else { | 4727 } else { |
4728 __ Branch(deferred->entry()); | 4728 __ Branch(deferred->entry()); |
4729 } | 4729 } |
4730 __ bind(deferred->exit()); | 4730 __ bind(deferred->exit()); |
4731 if (CpuFeatures::IsSupported(FPU)) { | 4731 if (CpuFeatures::IsSupported(FPU)) { |
4732 CpuFeatures::Scope scope(FPU); | 4732 CpuFeatureScope scope(masm(), FPU); |
4733 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); | 4733 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); |
4734 } else { | 4734 } else { |
4735 __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); | 4735 __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); |
4736 __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); | 4736 __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); |
4737 } | 4737 } |
4738 // Now that we have finished with the object's real address tag it | 4738 // Now that we have finished with the object's real address tag it |
4739 __ Addu(reg, reg, kHeapObjectTag); | 4739 __ Addu(reg, reg, kHeapObjectTag); |
4740 __ bind(&done); | 4740 __ bind(&done); |
4741 } | 4741 } |
4742 | 4742 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4777 } | 4777 } |
4778 | 4778 |
4779 | 4779 |
4780 void LCodeGen::EmitNumberUntagD(Register input_reg, | 4780 void LCodeGen::EmitNumberUntagD(Register input_reg, |
4781 DoubleRegister result_reg, | 4781 DoubleRegister result_reg, |
4782 bool deoptimize_on_undefined, | 4782 bool deoptimize_on_undefined, |
4783 bool deoptimize_on_minus_zero, | 4783 bool deoptimize_on_minus_zero, |
4784 LEnvironment* env, | 4784 LEnvironment* env, |
4785 NumberUntagDMode mode) { | 4785 NumberUntagDMode mode) { |
4786 Register scratch = scratch0(); | 4786 Register scratch = scratch0(); |
4787 CpuFeatures::Scope scope(FPU); | 4787 CpuFeatureScope scope(masm(), FPU); |
4788 | 4788 |
4789 Label load_smi, heap_number, done; | 4789 Label load_smi, heap_number, done; |
4790 | 4790 |
4791 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4791 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
4792 // Smi check. | 4792 // Smi check. |
4793 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4793 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
4794 | 4794 |
4795 // Heap number map check. | 4795 // Heap number map check. |
4796 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4796 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4797 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4797 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4855 Label done; | 4855 Label done; |
4856 | 4856 |
4857 // The input is a tagged HeapObject. | 4857 // The input is a tagged HeapObject. |
4858 // Heap number map check. | 4858 // Heap number map check. |
4859 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4859 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4860 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4860 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4861 // This 'at' value and scratch1 map value are used for tests in both clauses | 4861 // This 'at' value and scratch1 map value are used for tests in both clauses |
4862 // of the if. | 4862 // of the if. |
4863 | 4863 |
4864 if (instr->truncating()) { | 4864 if (instr->truncating()) { |
4865 CpuFeatures::Scope scope(FPU); | 4865 CpuFeatureScope scope(masm(), FPU); |
4866 Register scratch3 = ToRegister(instr->temp2()); | 4866 Register scratch3 = ToRegister(instr->temp2()); |
4867 FPURegister single_scratch = double_scratch.low(); | 4867 FPURegister single_scratch = double_scratch.low(); |
4868 ASSERT(!scratch3.is(input_reg) && | 4868 ASSERT(!scratch3.is(input_reg) && |
4869 !scratch3.is(scratch1) && | 4869 !scratch3.is(scratch1) && |
4870 !scratch3.is(scratch2)); | 4870 !scratch3.is(scratch2)); |
4871 // Performs a truncating conversion of a floating point number as used by | 4871 // Performs a truncating conversion of a floating point number as used by |
4872 // the JS bitwise operations. | 4872 // the JS bitwise operations. |
4873 Label heap_number; | 4873 Label heap_number; |
4874 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? | 4874 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? |
4875 // Check for undefined. Undefined is converted to zero for truncating | 4875 // Check for undefined. Undefined is converted to zero for truncating |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5110 __ CompareMapAndBranch( | 5110 __ CompareMapAndBranch( |
5111 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); | 5111 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); |
5112 } | 5112 } |
5113 Handle<Map> map = map_set->last(); | 5113 Handle<Map> map = map_set->last(); |
5114 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); | 5114 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); |
5115 __ bind(&success); | 5115 __ bind(&success); |
5116 } | 5116 } |
5117 | 5117 |
5118 | 5118 |
5119 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5119 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
5120 CpuFeatures::Scope vfp_scope(FPU); | 5120 CpuFeatureScope vfp_scope(masm(), FPU); |
5121 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5121 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); |
5122 Register result_reg = ToRegister(instr->result()); | 5122 Register result_reg = ToRegister(instr->result()); |
5123 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 5123 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5124 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); | 5124 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
5125 } | 5125 } |
5126 | 5126 |
5127 | 5127 |
5128 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 5128 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
5129 CpuFeatures::Scope vfp_scope(FPU); | 5129 CpuFeatureScope vfp_scope(masm(), FPU); |
5130 Register unclamped_reg = ToRegister(instr->unclamped()); | 5130 Register unclamped_reg = ToRegister(instr->unclamped()); |
5131 Register result_reg = ToRegister(instr->result()); | 5131 Register result_reg = ToRegister(instr->result()); |
5132 __ ClampUint8(result_reg, unclamped_reg); | 5132 __ ClampUint8(result_reg, unclamped_reg); |
5133 } | 5133 } |
5134 | 5134 |
5135 | 5135 |
5136 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 5136 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
5137 CpuFeatures::Scope vfp_scope(FPU); | 5137 CpuFeatureScope vfp_scope(masm(), FPU); |
5138 Register scratch = scratch0(); | 5138 Register scratch = scratch0(); |
5139 Register input_reg = ToRegister(instr->unclamped()); | 5139 Register input_reg = ToRegister(instr->unclamped()); |
5140 Register result_reg = ToRegister(instr->result()); | 5140 Register result_reg = ToRegister(instr->result()); |
5141 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 5141 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5142 Label is_smi, done, heap_number; | 5142 Label is_smi, done, heap_number; |
5143 | 5143 |
5144 // Both smi and heap number cases are handled. | 5144 // Both smi and heap number cases are handled. |
5145 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); | 5145 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); |
5146 | 5146 |
5147 // Check for heap number | 5147 // Check for heap number |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6064 __ Subu(scratch, result, scratch); | 6064 __ Subu(scratch, result, scratch); |
6065 __ lw(result, FieldMemOperand(scratch, | 6065 __ lw(result, FieldMemOperand(scratch, |
6066 FixedArray::kHeaderSize - kPointerSize)); | 6066 FixedArray::kHeaderSize - kPointerSize)); |
6067 __ bind(&done); | 6067 __ bind(&done); |
6068 } | 6068 } |
6069 | 6069 |
6070 | 6070 |
6071 #undef __ | 6071 #undef __ |
6072 | 6072 |
6073 } } // namespace v8::internal | 6073 } } // namespace v8::internal |
OLD | NEW |