| 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 |