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