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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 __ Subu(a0, a0, Operand(kPointerSize)); | 185 __ Subu(a0, a0, Operand(kPointerSize)); |
186 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); | 186 __ sw(a1, MemOperand(a0, 2 * kPointerSize)); |
187 __ Branch(&loop, ne, a0, Operand(sp)); | 187 __ Branch(&loop, ne, a0, Operand(sp)); |
188 __ pop(a1); | 188 __ pop(a1); |
189 __ pop(a0); | 189 __ pop(a0); |
190 } else { | 190 } else { |
191 __ Subu(sp, sp, Operand(slots * kPointerSize)); | 191 __ Subu(sp, sp, Operand(slots * kPointerSize)); |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { | 195 if (info()->saves_caller_doubles()) { |
196 CpuFeatureScope scope(masm(), FPU); | |
197 Comment(";;; Save clobbered callee double registers"); | 196 Comment(";;; Save clobbered callee double registers"); |
198 int count = 0; | 197 int count = 0; |
199 BitVector* doubles = chunk()->allocated_double_registers(); | 198 BitVector* doubles = chunk()->allocated_double_registers(); |
200 BitVector::Iterator save_iterator(doubles); | 199 BitVector::Iterator save_iterator(doubles); |
201 while (!save_iterator.Done()) { | 200 while (!save_iterator.Done()) { |
202 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), | 201 __ sdc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
203 MemOperand(sp, count * kDoubleSize)); | 202 MemOperand(sp, count * kDoubleSize)); |
204 save_iterator.Advance(); | 203 save_iterator.Advance(); |
205 count++; | 204 count++; |
206 } | 205 } |
(...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 | 1206 |
1208 | 1207 |
1209 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { | 1208 void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { |
1210 DoubleRegister addend = ToDoubleRegister(instr->addend()); | 1209 DoubleRegister addend = ToDoubleRegister(instr->addend()); |
1211 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); | 1210 DoubleRegister multiplier = ToDoubleRegister(instr->multiplier()); |
1212 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); | 1211 DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand()); |
1213 | 1212 |
1214 // This is computed in-place. | 1213 // This is computed in-place. |
1215 ASSERT(addend.is(ToDoubleRegister(instr->result()))); | 1214 ASSERT(addend.is(ToDoubleRegister(instr->result()))); |
1216 | 1215 |
1217 CpuFeatureScope scope(masm(), FPU); | |
1218 __ madd_d(addend, addend, multiplier, multiplicand); | 1216 __ madd_d(addend, addend, multiplier, multiplicand); |
1219 } | 1217 } |
1220 | 1218 |
1221 | 1219 |
1222 void LCodeGen::DoMulI(LMulI* instr) { | 1220 void LCodeGen::DoMulI(LMulI* instr) { |
1223 Register scratch = scratch0(); | 1221 Register scratch = scratch0(); |
1224 Register result = ToRegister(instr->result()); | 1222 Register result = ToRegister(instr->result()); |
1225 // Note that result may alias left. | 1223 // Note that result may alias left. |
1226 Register left = ToRegister(instr->left()); | 1224 Register left = ToRegister(instr->left()); |
1227 LOperand* right_op = instr->right(); | 1225 LOperand* right_op = instr->right(); |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 | 1468 |
1471 void LCodeGen::DoConstantI(LConstantI* instr) { | 1469 void LCodeGen::DoConstantI(LConstantI* instr) { |
1472 ASSERT(instr->result()->IsRegister()); | 1470 ASSERT(instr->result()->IsRegister()); |
1473 __ li(ToRegister(instr->result()), Operand(instr->value())); | 1471 __ li(ToRegister(instr->result()), Operand(instr->value())); |
1474 } | 1472 } |
1475 | 1473 |
1476 | 1474 |
1477 void LCodeGen::DoConstantD(LConstantD* instr) { | 1475 void LCodeGen::DoConstantD(LConstantD* instr) { |
1478 ASSERT(instr->result()->IsDoubleRegister()); | 1476 ASSERT(instr->result()->IsDoubleRegister()); |
1479 DoubleRegister result = ToDoubleRegister(instr->result()); | 1477 DoubleRegister result = ToDoubleRegister(instr->result()); |
1480 CpuFeatureScope scope(masm(), FPU); | |
1481 double v = instr->value(); | 1478 double v = instr->value(); |
1482 __ Move(result, v); | 1479 __ Move(result, v); |
1483 } | 1480 } |
1484 | 1481 |
1485 | 1482 |
1486 void LCodeGen::DoConstantT(LConstantT* instr) { | 1483 void LCodeGen::DoConstantT(LConstantT* instr) { |
1487 Handle<Object> value = instr->value(); | 1484 Handle<Object> value = instr->value(); |
1488 if (value->IsSmi()) { | 1485 if (value->IsSmi()) { |
1489 __ li(ToRegister(instr->result()), Operand(value)); | 1486 __ li(ToRegister(instr->result()), Operand(value)); |
1490 } else { | 1487 } else { |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); | 1658 __ Branch(&return_right, NegateCondition(condition), left_reg, right_op); |
1662 __ mov(result_reg, left_reg); | 1659 __ mov(result_reg, left_reg); |
1663 __ Branch(&done); | 1660 __ Branch(&done); |
1664 } | 1661 } |
1665 __ Branch(&done, condition, left_reg, right_op); | 1662 __ Branch(&done, condition, left_reg, right_op); |
1666 __ bind(&return_right); | 1663 __ bind(&return_right); |
1667 __ Addu(result_reg, zero_reg, right_op); | 1664 __ Addu(result_reg, zero_reg, right_op); |
1668 __ bind(&done); | 1665 __ bind(&done); |
1669 } else { | 1666 } else { |
1670 ASSERT(instr->hydrogen()->representation().IsDouble()); | 1667 ASSERT(instr->hydrogen()->representation().IsDouble()); |
1671 CpuFeatureScope scope(masm(), FPU); | |
1672 FPURegister left_reg = ToDoubleRegister(left); | 1668 FPURegister left_reg = ToDoubleRegister(left); |
1673 FPURegister right_reg = ToDoubleRegister(right); | 1669 FPURegister right_reg = ToDoubleRegister(right); |
1674 FPURegister result_reg = ToDoubleRegister(instr->result()); | 1670 FPURegister result_reg = ToDoubleRegister(instr->result()); |
1675 Label check_nan_left, check_zero, return_left, return_right, done; | 1671 Label check_nan_left, check_zero, return_left, return_right, done; |
1676 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); | 1672 __ BranchF(&check_zero, &check_nan_left, eq, left_reg, right_reg); |
1677 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); | 1673 __ BranchF(&return_left, NULL, condition, left_reg, right_reg); |
1678 __ Branch(&return_right); | 1674 __ Branch(&return_right); |
1679 | 1675 |
1680 __ bind(&check_zero); | 1676 __ bind(&check_zero); |
1681 // left == right != 0. | 1677 // left == right != 0. |
(...skipping 20 matching lines...) Expand all Loading... |
1702 __ bind(&return_left); | 1698 __ bind(&return_left); |
1703 if (!left_reg.is(result_reg)) { | 1699 if (!left_reg.is(result_reg)) { |
1704 __ mov_d(result_reg, left_reg); | 1700 __ mov_d(result_reg, left_reg); |
1705 } | 1701 } |
1706 __ bind(&done); | 1702 __ bind(&done); |
1707 } | 1703 } |
1708 } | 1704 } |
1709 | 1705 |
1710 | 1706 |
1711 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 1707 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
1712 CpuFeatureScope scope(masm(), FPU); | |
1713 DoubleRegister left = ToDoubleRegister(instr->left()); | 1708 DoubleRegister left = ToDoubleRegister(instr->left()); |
1714 DoubleRegister right = ToDoubleRegister(instr->right()); | 1709 DoubleRegister right = ToDoubleRegister(instr->right()); |
1715 DoubleRegister result = ToDoubleRegister(instr->result()); | 1710 DoubleRegister result = ToDoubleRegister(instr->result()); |
1716 switch (instr->op()) { | 1711 switch (instr->op()) { |
1717 case Token::ADD: | 1712 case Token::ADD: |
1718 __ add_d(result, left, right); | 1713 __ add_d(result, left, right); |
1719 break; | 1714 break; |
1720 case Token::SUB: | 1715 case Token::SUB: |
1721 __ sub_d(result, left, right); | 1716 __ sub_d(result, left, right); |
1722 break; | 1717 break; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1812 | 1807 |
1813 void LCodeGen::DoBranch(LBranch* instr) { | 1808 void LCodeGen::DoBranch(LBranch* instr) { |
1814 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1809 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
1815 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1810 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
1816 | 1811 |
1817 Representation r = instr->hydrogen()->value()->representation(); | 1812 Representation r = instr->hydrogen()->value()->representation(); |
1818 if (r.IsInteger32()) { | 1813 if (r.IsInteger32()) { |
1819 Register reg = ToRegister(instr->value()); | 1814 Register reg = ToRegister(instr->value()); |
1820 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); | 1815 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); |
1821 } else if (r.IsDouble()) { | 1816 } else if (r.IsDouble()) { |
1822 CpuFeatureScope scope(masm(), FPU); | |
1823 DoubleRegister reg = ToDoubleRegister(instr->value()); | 1817 DoubleRegister reg = ToDoubleRegister(instr->value()); |
1824 // Test the double value. Zero and NaN are false. | 1818 // Test the double value. Zero and NaN are false. |
1825 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero); | 1819 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero); |
1826 } else { | 1820 } else { |
1827 ASSERT(r.IsTagged()); | 1821 ASSERT(r.IsTagged()); |
1828 Register reg = ToRegister(instr->value()); | 1822 Register reg = ToRegister(instr->value()); |
1829 HType type = instr->hydrogen()->value()->type(); | 1823 HType type = instr->hydrogen()->value()->type(); |
1830 if (type.IsBoolean()) { | 1824 if (type.IsBoolean()) { |
1831 __ LoadRoot(at, Heap::kTrueValueRootIndex); | 1825 __ LoadRoot(at, Heap::kTrueValueRootIndex); |
1832 EmitBranch(true_block, false_block, eq, reg, Operand(at)); | 1826 EmitBranch(true_block, false_block, eq, reg, Operand(at)); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 } | 1891 } |
1898 | 1892 |
1899 if (expected.Contains(ToBooleanStub::SYMBOL)) { | 1893 if (expected.Contains(ToBooleanStub::SYMBOL)) { |
1900 // Symbol value -> true. | 1894 // Symbol value -> true. |
1901 const Register scratch = scratch1(); | 1895 const Register scratch = scratch1(); |
1902 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); | 1896 __ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset)); |
1903 __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE)); | 1897 __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE)); |
1904 } | 1898 } |
1905 | 1899 |
1906 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 1900 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
1907 CpuFeatureScope scope(masm(), FPU); | |
1908 // heap number -> false iff +0, -0, or NaN. | 1901 // heap number -> false iff +0, -0, or NaN. |
1909 DoubleRegister dbl_scratch = double_scratch0(); | 1902 DoubleRegister dbl_scratch = double_scratch0(); |
1910 Label not_heap_number; | 1903 Label not_heap_number; |
1911 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 1904 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
1912 __ Branch(¬_heap_number, ne, map, Operand(at)); | 1905 __ Branch(¬_heap_number, ne, map, Operand(at)); |
1913 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); | 1906 __ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); |
1914 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); | 1907 __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero); |
1915 // Falls through if dbl_scratch == 0. | 1908 // Falls through if dbl_scratch == 0. |
1916 __ Branch(false_label); | 1909 __ Branch(false_label); |
1917 __ bind(¬_heap_number); | 1910 __ bind(¬_heap_number); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1977 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 1970 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
1978 // We can statically evaluate the comparison. | 1971 // We can statically evaluate the comparison. |
1979 double left_val = ToDouble(LConstantOperand::cast(left)); | 1972 double left_val = ToDouble(LConstantOperand::cast(left)); |
1980 double right_val = ToDouble(LConstantOperand::cast(right)); | 1973 double right_val = ToDouble(LConstantOperand::cast(right)); |
1981 int next_block = | 1974 int next_block = |
1982 EvalComparison(instr->op(), left_val, right_val) ? true_block | 1975 EvalComparison(instr->op(), left_val, right_val) ? true_block |
1983 : false_block; | 1976 : false_block; |
1984 EmitGoto(next_block); | 1977 EmitGoto(next_block); |
1985 } else { | 1978 } else { |
1986 if (instr->is_double()) { | 1979 if (instr->is_double()) { |
1987 CpuFeatureScope scope(masm(), FPU); | |
1988 // Compare left and right as doubles and load the | 1980 // Compare left and right as doubles and load the |
1989 // resulting flags into the normal status register. | 1981 // resulting flags into the normal status register. |
1990 FPURegister left_reg = ToDoubleRegister(left); | 1982 FPURegister left_reg = ToDoubleRegister(left); |
1991 FPURegister right_reg = ToDoubleRegister(right); | 1983 FPURegister right_reg = ToDoubleRegister(right); |
1992 | 1984 |
1993 // If a NaN is involved, i.e. the result is unordered, | 1985 // If a NaN is involved, i.e. the result is unordered, |
1994 // jump to false block label. | 1986 // jump to false block label. |
1995 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, | 1987 __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq, |
1996 left_reg, right_reg); | 1988 left_reg, right_reg); |
1997 | 1989 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 } | 2532 } |
2541 | 2533 |
2542 | 2534 |
2543 void LCodeGen::DoReturn(LReturn* instr) { | 2535 void LCodeGen::DoReturn(LReturn* instr) { |
2544 if (FLAG_trace && info()->IsOptimizing()) { | 2536 if (FLAG_trace && info()->IsOptimizing()) { |
2545 // Push the return value on the stack as the parameter. | 2537 // Push the return value on the stack as the parameter. |
2546 // Runtime::TraceExit returns its parameter in v0. | 2538 // Runtime::TraceExit returns its parameter in v0. |
2547 __ push(v0); | 2539 __ push(v0); |
2548 __ CallRuntime(Runtime::kTraceExit, 1); | 2540 __ CallRuntime(Runtime::kTraceExit, 1); |
2549 } | 2541 } |
2550 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(FPU)) { | 2542 if (info()->saves_caller_doubles()) { |
2551 CpuFeatureScope scope(masm(), FPU); | |
2552 ASSERT(NeedsEagerFrame()); | 2543 ASSERT(NeedsEagerFrame()); |
2553 BitVector* doubles = chunk()->allocated_double_registers(); | 2544 BitVector* doubles = chunk()->allocated_double_registers(); |
2554 BitVector::Iterator save_iterator(doubles); | 2545 BitVector::Iterator save_iterator(doubles); |
2555 int count = 0; | 2546 int count = 0; |
2556 while (!save_iterator.Done()) { | 2547 while (!save_iterator.Done()) { |
2557 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), | 2548 __ ldc1(DoubleRegister::FromAllocationIndex(save_iterator.Current()), |
2558 MemOperand(sp, count * kDoubleSize)); | 2549 MemOperand(sp, count * kDoubleSize)); |
2559 save_iterator.Advance(); | 2550 save_iterator.Advance(); |
2560 count++; | 2551 count++; |
2561 } | 2552 } |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2928 | 2919 |
2929 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 2920 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
2930 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 2921 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
2931 FPURegister result = ToDoubleRegister(instr->result()); | 2922 FPURegister result = ToDoubleRegister(instr->result()); |
2932 if (key_is_constant) { | 2923 if (key_is_constant) { |
2933 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); | 2924 __ Addu(scratch0(), external_pointer, constant_key << element_size_shift); |
2934 } else { | 2925 } else { |
2935 __ sll(scratch0(), key, shift_size); | 2926 __ sll(scratch0(), key, shift_size); |
2936 __ Addu(scratch0(), scratch0(), external_pointer); | 2927 __ Addu(scratch0(), scratch0(), external_pointer); |
2937 } | 2928 } |
2938 if (CpuFeatures::IsSupported(FPU)) { | 2929 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
2939 CpuFeatureScope scope(masm(), FPU); | 2930 __ lwc1(result, MemOperand(scratch0(), additional_offset)); |
2940 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 2931 __ cvt_d_s(result, result); |
2941 __ lwc1(result, MemOperand(scratch0(), additional_offset)); | 2932 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS |
2942 __ cvt_d_s(result, result); | 2933 __ ldc1(result, MemOperand(scratch0(), additional_offset)); |
2943 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS | |
2944 __ ldc1(result, MemOperand(scratch0(), additional_offset)); | |
2945 } | |
2946 } else { | |
2947 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | |
2948 Register value = external_pointer; | |
2949 __ lw(value, MemOperand(scratch0(), additional_offset)); | |
2950 __ And(sfpd_lo, value, Operand(kBinary32MantissaMask)); | |
2951 | |
2952 __ srl(scratch0(), value, kBinary32MantissaBits); | |
2953 __ And(scratch0(), scratch0(), | |
2954 Operand(kBinary32ExponentMask >> kBinary32MantissaBits)); | |
2955 | |
2956 Label exponent_rebiased; | |
2957 __ Xor(at, scratch0(), Operand(0x00)); | |
2958 __ Branch(&exponent_rebiased, eq, at, Operand(zero_reg)); | |
2959 | |
2960 __ Xor(at, scratch0(), Operand(0xff)); | |
2961 Label skip; | |
2962 __ Branch(&skip, ne, at, Operand(zero_reg)); | |
2963 __ li(scratch0(), Operand(0x7ff)); | |
2964 __ bind(&skip); | |
2965 __ Branch(&exponent_rebiased, eq, at, Operand(zero_reg)); | |
2966 | |
2967 // Rebias exponent. | |
2968 __ Addu(scratch0(), | |
2969 scratch0(), | |
2970 Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias)); | |
2971 | |
2972 __ bind(&exponent_rebiased); | |
2973 __ And(sfpd_hi, value, Operand(kBinary32SignMask)); | |
2974 __ sll(at, scratch0(), HeapNumber::kMantissaBitsInTopWord); | |
2975 __ Or(sfpd_hi, sfpd_hi, at); | |
2976 | |
2977 // Shift mantissa. | |
2978 static const int kMantissaShiftForHiWord = | |
2979 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; | |
2980 | |
2981 static const int kMantissaShiftForLoWord = | |
2982 kBitsPerInt - kMantissaShiftForHiWord; | |
2983 | |
2984 __ srl(at, sfpd_lo, kMantissaShiftForHiWord); | |
2985 __ Or(sfpd_hi, sfpd_hi, at); | |
2986 __ sll(sfpd_lo, sfpd_lo, kMantissaShiftForLoWord); | |
2987 | |
2988 } else { | |
2989 __ lw(sfpd_lo, MemOperand(scratch0(), additional_offset)); | |
2990 __ lw(sfpd_hi, MemOperand(scratch0(), | |
2991 additional_offset + kPointerSize)); | |
2992 } | |
2993 } | 2934 } |
2994 } else { | 2935 } else { |
2995 Register result = ToRegister(instr->result()); | 2936 Register result = ToRegister(instr->result()); |
2996 MemOperand mem_operand = PrepareKeyedOperand( | 2937 MemOperand mem_operand = PrepareKeyedOperand( |
2997 key, external_pointer, key_is_constant, constant_key, | 2938 key, external_pointer, key_is_constant, constant_key, |
2998 element_size_shift, shift_size, | 2939 element_size_shift, shift_size, |
2999 instr->additional_index(), additional_offset); | 2940 instr->additional_index(), additional_offset); |
3000 switch (elements_kind) { | 2941 switch (elements_kind) { |
3001 case EXTERNAL_BYTE_ELEMENTS: | 2942 case EXTERNAL_BYTE_ELEMENTS: |
3002 __ lb(result, mem_operand); | 2943 __ lb(result, mem_operand); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3057 } else { | 2998 } else { |
3058 key = ToRegister(instr->key()); | 2999 key = ToRegister(instr->key()); |
3059 } | 3000 } |
3060 | 3001 |
3061 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3002 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
3062 ((constant_key + instr->additional_index()) << element_size_shift); | 3003 ((constant_key + instr->additional_index()) << element_size_shift); |
3063 if (!key_is_constant) { | 3004 if (!key_is_constant) { |
3064 __ sll(scratch, key, shift_size); | 3005 __ sll(scratch, key, shift_size); |
3065 __ Addu(elements, elements, scratch); | 3006 __ Addu(elements, elements, scratch); |
3066 } | 3007 } |
3067 if (CpuFeatures::IsSupported(FPU)) { | 3008 __ Addu(elements, elements, Operand(base_offset)); |
3068 CpuFeatureScope scope(masm(), FPU); | 3009 __ ldc1(result, MemOperand(elements)); |
3069 __ Addu(elements, elements, Operand(base_offset)); | 3010 if (instr->hydrogen()->RequiresHoleCheck()) { |
3070 __ ldc1(result, MemOperand(elements)); | 3011 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); |
3071 if (instr->hydrogen()->RequiresHoleCheck()) { | 3012 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); |
3072 __ lw(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); | |
3073 DeoptimizeIf(eq, instr->environment(), scratch, Operand(kHoleNanUpper32)); | |
3074 } | |
3075 } else { | |
3076 __ lw(sfpd_hi, MemOperand(elements, base_offset + kPointerSize)); | |
3077 __ lw(sfpd_lo, MemOperand(elements, base_offset)); | |
3078 if (instr->hydrogen()->RequiresHoleCheck()) { | |
3079 ASSERT(kPointerSize == sizeof(kHoleNanLower32)); | |
3080 DeoptimizeIf(eq, instr->environment(), sfpd_hi, Operand(kHoleNanUpper32)); | |
3081 } | |
3082 } | 3013 } |
3083 } | 3014 } |
3084 | 3015 |
3085 | 3016 |
3086 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3017 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3087 Register elements = ToRegister(instr->elements()); | 3018 Register elements = ToRegister(instr->elements()); |
3088 Register result = ToRegister(instr->result()); | 3019 Register result = ToRegister(instr->result()); |
3089 Register scratch = scratch0(); | 3020 Register scratch = scratch0(); |
3090 Register store_base = scratch; | 3021 Register store_base = scratch; |
3091 int offset = 0; | 3022 int offset = 0; |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3519 Label done; | 3450 Label done; |
3520 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); | 3451 __ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg)); |
3521 __ mov(result, input); | 3452 __ mov(result, input); |
3522 // Overflow if result is still negative, i.e. 0x80000000. | 3453 // Overflow if result is still negative, i.e. 0x80000000. |
3523 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); | 3454 DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg)); |
3524 __ bind(&done); | 3455 __ bind(&done); |
3525 } | 3456 } |
3526 | 3457 |
3527 | 3458 |
3528 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3459 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
3529 CpuFeatureScope scope(masm(), FPU); | |
3530 // Class for deferred case. | 3460 // Class for deferred case. |
3531 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3461 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
3532 public: | 3462 public: |
3533 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 3463 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
3534 : LDeferredCode(codegen), instr_(instr) { } | 3464 : LDeferredCode(codegen), instr_(instr) { } |
3535 virtual void Generate() { | 3465 virtual void Generate() { |
3536 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3466 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
3537 } | 3467 } |
3538 virtual LInstruction* instr() { return instr_; } | 3468 virtual LInstruction* instr() { return instr_; } |
3539 private: | 3469 private: |
(...skipping 15 matching lines...) Expand all Loading... |
3555 // Smi check. | 3485 // Smi check. |
3556 __ JumpIfNotSmi(input, deferred->entry()); | 3486 __ JumpIfNotSmi(input, deferred->entry()); |
3557 // If smi, handle it directly. | 3487 // If smi, handle it directly. |
3558 EmitIntegerMathAbs(instr); | 3488 EmitIntegerMathAbs(instr); |
3559 __ bind(deferred->exit()); | 3489 __ bind(deferred->exit()); |
3560 } | 3490 } |
3561 } | 3491 } |
3562 | 3492 |
3563 | 3493 |
3564 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3494 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
3565 CpuFeatureScope scope(masm(), FPU); | |
3566 DoubleRegister input = ToDoubleRegister(instr->value()); | 3495 DoubleRegister input = ToDoubleRegister(instr->value()); |
3567 Register result = ToRegister(instr->result()); | 3496 Register result = ToRegister(instr->result()); |
3568 Register scratch1 = scratch0(); | 3497 Register scratch1 = scratch0(); |
3569 Register except_flag = ToRegister(instr->temp()); | 3498 Register except_flag = ToRegister(instr->temp()); |
3570 | 3499 |
3571 __ EmitFPUTruncate(kRoundToMinusInf, | 3500 __ EmitFPUTruncate(kRoundToMinusInf, |
3572 result, | 3501 result, |
3573 input, | 3502 input, |
3574 scratch1, | 3503 scratch1, |
3575 double_scratch0(), | 3504 double_scratch0(), |
3576 except_flag); | 3505 except_flag); |
3577 | 3506 |
3578 // Deopt if the operation did not succeed. | 3507 // Deopt if the operation did not succeed. |
3579 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 3508 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
3580 | 3509 |
3581 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3510 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3582 // Test for -0. | 3511 // Test for -0. |
3583 Label done; | 3512 Label done; |
3584 __ Branch(&done, ne, result, Operand(zero_reg)); | 3513 __ Branch(&done, ne, result, Operand(zero_reg)); |
3585 __ mfc1(scratch1, input.high()); | 3514 __ mfc1(scratch1, input.high()); |
3586 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); | 3515 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
3587 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); | 3516 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
3588 __ bind(&done); | 3517 __ bind(&done); |
3589 } | 3518 } |
3590 } | 3519 } |
3591 | 3520 |
3592 | 3521 |
3593 void LCodeGen::DoMathRound(LMathRound* instr) { | 3522 void LCodeGen::DoMathRound(LMathRound* instr) { |
3594 CpuFeatureScope scope(masm(), FPU); | |
3595 DoubleRegister input = ToDoubleRegister(instr->value()); | 3523 DoubleRegister input = ToDoubleRegister(instr->value()); |
3596 Register result = ToRegister(instr->result()); | 3524 Register result = ToRegister(instr->result()); |
3597 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3525 DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
3598 Register scratch = scratch0(); | 3526 Register scratch = scratch0(); |
3599 Label done, check_sign_on_zero; | 3527 Label done, check_sign_on_zero; |
3600 | 3528 |
3601 // Extract exponent bits. | 3529 // Extract exponent bits. |
3602 __ mfc1(result, input.high()); | 3530 __ mfc1(result, input.high()); |
3603 __ Ext(scratch, | 3531 __ Ext(scratch, |
3604 result, | 3532 result, |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3661 __ bind(&check_sign_on_zero); | 3589 __ bind(&check_sign_on_zero); |
3662 __ mfc1(scratch, input.high()); | 3590 __ mfc1(scratch, input.high()); |
3663 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); | 3591 __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); |
3664 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); | 3592 DeoptimizeIf(ne, instr->environment(), scratch, Operand(zero_reg)); |
3665 } | 3593 } |
3666 __ bind(&done); | 3594 __ bind(&done); |
3667 } | 3595 } |
3668 | 3596 |
3669 | 3597 |
3670 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { | 3598 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { |
3671 CpuFeatureScope scope(masm(), FPU); | |
3672 DoubleRegister input = ToDoubleRegister(instr->value()); | 3599 DoubleRegister input = ToDoubleRegister(instr->value()); |
3673 DoubleRegister result = ToDoubleRegister(instr->result()); | 3600 DoubleRegister result = ToDoubleRegister(instr->result()); |
3674 __ sqrt_d(result, input); | 3601 __ sqrt_d(result, input); |
3675 } | 3602 } |
3676 | 3603 |
3677 | 3604 |
3678 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { | 3605 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { |
3679 CpuFeatureScope scope(masm(), FPU); | |
3680 DoubleRegister input = ToDoubleRegister(instr->value()); | 3606 DoubleRegister input = ToDoubleRegister(instr->value()); |
3681 DoubleRegister result = ToDoubleRegister(instr->result()); | 3607 DoubleRegister result = ToDoubleRegister(instr->result()); |
3682 DoubleRegister temp = ToDoubleRegister(instr->temp()); | 3608 DoubleRegister temp = ToDoubleRegister(instr->temp()); |
3683 | 3609 |
3684 ASSERT(!input.is(result)); | 3610 ASSERT(!input.is(result)); |
3685 | 3611 |
3686 // Note that according to ECMA-262 15.8.2.13: | 3612 // Note that according to ECMA-262 15.8.2.13: |
3687 // Math.pow(-Infinity, 0.5) == Infinity | 3613 // Math.pow(-Infinity, 0.5) == Infinity |
3688 // Math.sqrt(-Infinity) == NaN | 3614 // Math.sqrt(-Infinity) == NaN |
3689 Label done; | 3615 Label done; |
3690 __ Move(temp, -V8_INFINITY); | 3616 __ Move(temp, -V8_INFINITY); |
3691 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); | 3617 __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input); |
3692 // Set up Infinity in the delay slot. | 3618 // Set up Infinity in the delay slot. |
3693 // result is overwritten if the branch is not taken. | 3619 // result is overwritten if the branch is not taken. |
3694 __ neg_d(result, temp); | 3620 __ neg_d(result, temp); |
3695 | 3621 |
3696 // Add +0 to convert -0 to +0. | 3622 // Add +0 to convert -0 to +0. |
3697 __ add_d(result, input, kDoubleRegZero); | 3623 __ add_d(result, input, kDoubleRegZero); |
3698 __ sqrt_d(result, result); | 3624 __ sqrt_d(result, result); |
3699 __ bind(&done); | 3625 __ bind(&done); |
3700 } | 3626 } |
3701 | 3627 |
3702 | 3628 |
3703 void LCodeGen::DoPower(LPower* instr) { | 3629 void LCodeGen::DoPower(LPower* instr) { |
3704 CpuFeatureScope scope(masm(), FPU); | |
3705 Representation exponent_type = instr->hydrogen()->right()->representation(); | 3630 Representation exponent_type = instr->hydrogen()->right()->representation(); |
3706 // Having marked this as a call, we can use any registers. | 3631 // Having marked this as a call, we can use any registers. |
3707 // Just make sure that the input/output registers are the expected ones. | 3632 // Just make sure that the input/output registers are the expected ones. |
3708 ASSERT(!instr->right()->IsDoubleRegister() || | 3633 ASSERT(!instr->right()->IsDoubleRegister() || |
3709 ToDoubleRegister(instr->right()).is(f4)); | 3634 ToDoubleRegister(instr->right()).is(f4)); |
3710 ASSERT(!instr->right()->IsRegister() || | 3635 ASSERT(!instr->right()->IsRegister() || |
3711 ToRegister(instr->right()).is(a2)); | 3636 ToRegister(instr->right()).is(a2)); |
3712 ASSERT(ToDoubleRegister(instr->left()).is(f2)); | 3637 ASSERT(ToDoubleRegister(instr->left()).is(f2)); |
3713 ASSERT(ToDoubleRegister(instr->result()).is(f0)); | 3638 ASSERT(ToDoubleRegister(instr->result()).is(f0)); |
3714 | 3639 |
(...skipping 10 matching lines...) Expand all Loading... |
3725 __ CallStub(&stub); | 3650 __ CallStub(&stub); |
3726 } else { | 3651 } else { |
3727 ASSERT(exponent_type.IsDouble()); | 3652 ASSERT(exponent_type.IsDouble()); |
3728 MathPowStub stub(MathPowStub::DOUBLE); | 3653 MathPowStub stub(MathPowStub::DOUBLE); |
3729 __ CallStub(&stub); | 3654 __ CallStub(&stub); |
3730 } | 3655 } |
3731 } | 3656 } |
3732 | 3657 |
3733 | 3658 |
3734 void LCodeGen::DoRandom(LRandom* instr) { | 3659 void LCodeGen::DoRandom(LRandom* instr) { |
3735 CpuFeatureScope scope(masm(), FPU); | |
3736 class DeferredDoRandom: public LDeferredCode { | 3660 class DeferredDoRandom: public LDeferredCode { |
3737 public: | 3661 public: |
3738 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 3662 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) |
3739 : LDeferredCode(codegen), instr_(instr) { } | 3663 : LDeferredCode(codegen), instr_(instr) { } |
3740 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } | 3664 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } |
3741 virtual LInstruction* instr() { return instr_; } | 3665 virtual LInstruction* instr() { return instr_; } |
3742 private: | 3666 private: |
3743 LRandom* instr_; | 3667 LRandom* instr_; |
3744 }; | 3668 }; |
3745 | 3669 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3802 } | 3726 } |
3803 | 3727 |
3804 void LCodeGen::DoDeferredRandom(LRandom* instr) { | 3728 void LCodeGen::DoDeferredRandom(LRandom* instr) { |
3805 __ PrepareCallCFunction(1, scratch0()); | 3729 __ PrepareCallCFunction(1, scratch0()); |
3806 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); | 3730 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); |
3807 // Return value is in v0. | 3731 // Return value is in v0. |
3808 } | 3732 } |
3809 | 3733 |
3810 | 3734 |
3811 void LCodeGen::DoMathExp(LMathExp* instr) { | 3735 void LCodeGen::DoMathExp(LMathExp* instr) { |
3812 CpuFeatureScope scope(masm(), FPU); | |
3813 DoubleRegister input = ToDoubleRegister(instr->value()); | 3736 DoubleRegister input = ToDoubleRegister(instr->value()); |
3814 DoubleRegister result = ToDoubleRegister(instr->result()); | 3737 DoubleRegister result = ToDoubleRegister(instr->result()); |
3815 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); | 3738 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); |
3816 DoubleRegister double_scratch2 = double_scratch0(); | 3739 DoubleRegister double_scratch2 = double_scratch0(); |
3817 Register temp1 = ToRegister(instr->temp1()); | 3740 Register temp1 = ToRegister(instr->temp1()); |
3818 Register temp2 = ToRegister(instr->temp2()); | 3741 Register temp2 = ToRegister(instr->temp2()); |
3819 | 3742 |
3820 MathExpGenerator::EmitMathExp( | 3743 MathExpGenerator::EmitMathExp( |
3821 masm(), input, result, double_scratch1, double_scratch2, | 3744 masm(), input, result, double_scratch1, double_scratch2, |
3822 temp1, temp2, scratch0()); | 3745 temp1, temp2, scratch0()); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4069 } else { | 3992 } else { |
4070 DeoptimizeIf(hs, | 3993 DeoptimizeIf(hs, |
4071 instr->environment(), | 3994 instr->environment(), |
4072 ToRegister(instr->index()), | 3995 ToRegister(instr->index()), |
4073 Operand(ToRegister(instr->length()))); | 3996 Operand(ToRegister(instr->length()))); |
4074 } | 3997 } |
4075 } | 3998 } |
4076 | 3999 |
4077 | 4000 |
4078 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4001 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
4079 CpuFeatureScope scope(masm(), FPU); | |
4080 Register external_pointer = ToRegister(instr->elements()); | 4002 Register external_pointer = ToRegister(instr->elements()); |
4081 Register key = no_reg; | 4003 Register key = no_reg; |
4082 ElementsKind elements_kind = instr->elements_kind(); | 4004 ElementsKind elements_kind = instr->elements_kind(); |
4083 bool key_is_constant = instr->key()->IsConstantOperand(); | 4005 bool key_is_constant = instr->key()->IsConstantOperand(); |
4084 int constant_key = 0; | 4006 int constant_key = 0; |
4085 if (key_is_constant) { | 4007 if (key_is_constant) { |
4086 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4008 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
4087 if (constant_key & 0xF0000000) { | 4009 if (constant_key & 0xF0000000) { |
4088 Abort("array index constant value too big."); | 4010 Abort("array index constant value too big."); |
4089 } | 4011 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4143 case DICTIONARY_ELEMENTS: | 4065 case DICTIONARY_ELEMENTS: |
4144 case NON_STRICT_ARGUMENTS_ELEMENTS: | 4066 case NON_STRICT_ARGUMENTS_ELEMENTS: |
4145 UNREACHABLE(); | 4067 UNREACHABLE(); |
4146 break; | 4068 break; |
4147 } | 4069 } |
4148 } | 4070 } |
4149 } | 4071 } |
4150 | 4072 |
4151 | 4073 |
4152 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { | 4074 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { |
4153 CpuFeatureScope scope(masm(), FPU); | |
4154 DoubleRegister value = ToDoubleRegister(instr->value()); | 4075 DoubleRegister value = ToDoubleRegister(instr->value()); |
4155 Register elements = ToRegister(instr->elements()); | 4076 Register elements = ToRegister(instr->elements()); |
4156 Register key = no_reg; | 4077 Register key = no_reg; |
4157 Register scratch = scratch0(); | 4078 Register scratch = scratch0(); |
4158 bool key_is_constant = instr->key()->IsConstantOperand(); | 4079 bool key_is_constant = instr->key()->IsConstantOperand(); |
4159 int constant_key = 0; | 4080 int constant_key = 0; |
4160 Label not_nan; | 4081 Label not_nan; |
4161 | 4082 |
4162 // Calculate the effective address of the slot in the array to store the | 4083 // Calculate the effective address of the slot in the array to store the |
4163 // double value. | 4084 // double value. |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4447 | 4368 |
4448 | 4369 |
4449 void LCodeGen::DoStringLength(LStringLength* instr) { | 4370 void LCodeGen::DoStringLength(LStringLength* instr) { |
4450 Register string = ToRegister(instr->string()); | 4371 Register string = ToRegister(instr->string()); |
4451 Register result = ToRegister(instr->result()); | 4372 Register result = ToRegister(instr->result()); |
4452 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); | 4373 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); |
4453 } | 4374 } |
4454 | 4375 |
4455 | 4376 |
4456 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4377 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
4457 CpuFeatureScope scope(masm(), FPU); | |
4458 LOperand* input = instr->value(); | 4378 LOperand* input = instr->value(); |
4459 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4379 ASSERT(input->IsRegister() || input->IsStackSlot()); |
4460 LOperand* output = instr->result(); | 4380 LOperand* output = instr->result(); |
4461 ASSERT(output->IsDoubleRegister()); | 4381 ASSERT(output->IsDoubleRegister()); |
4462 FPURegister single_scratch = double_scratch0().low(); | 4382 FPURegister single_scratch = double_scratch0().low(); |
4463 if (input->IsStackSlot()) { | 4383 if (input->IsStackSlot()) { |
4464 Register scratch = scratch0(); | 4384 Register scratch = scratch0(); |
4465 __ lw(scratch, ToMemOperand(input)); | 4385 __ lw(scratch, ToMemOperand(input)); |
4466 __ mtc1(scratch, single_scratch); | 4386 __ mtc1(scratch, single_scratch); |
4467 } else { | 4387 } else { |
4468 __ mtc1(ToRegister(input), single_scratch); | 4388 __ mtc1(ToRegister(input), single_scratch); |
4469 } | 4389 } |
4470 __ cvt_d_w(ToDoubleRegister(output), single_scratch); | 4390 __ cvt_d_w(ToDoubleRegister(output), single_scratch); |
4471 } | 4391 } |
4472 | 4392 |
4473 | 4393 |
4474 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4394 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
4475 CpuFeatureScope scope(masm(), FPU); | |
4476 LOperand* input = instr->value(); | 4395 LOperand* input = instr->value(); |
4477 LOperand* output = instr->result(); | 4396 LOperand* output = instr->result(); |
4478 | 4397 |
4479 FPURegister dbl_scratch = double_scratch0(); | 4398 FPURegister dbl_scratch = double_scratch0(); |
4480 __ mtc1(ToRegister(input), dbl_scratch); | 4399 __ mtc1(ToRegister(input), dbl_scratch); |
4481 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); | 4400 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); |
4482 } | 4401 } |
4483 | 4402 |
4484 | 4403 |
4485 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4404 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4527 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4446 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
4528 Register reg = ToRegister(input); | 4447 Register reg = ToRegister(input); |
4529 | 4448 |
4530 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4449 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
4531 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); | 4450 __ Branch(deferred->entry(), hi, reg, Operand(Smi::kMaxValue)); |
4532 __ SmiTag(reg, reg); | 4451 __ SmiTag(reg, reg); |
4533 __ bind(deferred->exit()); | 4452 __ bind(deferred->exit()); |
4534 } | 4453 } |
4535 | 4454 |
4536 | 4455 |
4537 // Convert unsigned integer with specified number of leading zeroes in binary | |
4538 // representation to IEEE 754 double. | |
4539 // Integer to convert is passed in register src. | |
4540 // Resulting double is returned in registers hiword:loword. | |
4541 // This functions does not work correctly for 0. | |
4542 static void GenerateUInt2Double(MacroAssembler* masm, | |
4543 Register src, | |
4544 Register hiword, | |
4545 Register loword, | |
4546 Register scratch, | |
4547 int leading_zeroes) { | |
4548 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1; | |
4549 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits; | |
4550 | |
4551 const int mantissa_shift_for_hi_word = | |
4552 meaningful_bits - HeapNumber::kMantissaBitsInTopWord; | |
4553 const int mantissa_shift_for_lo_word = | |
4554 kBitsPerInt - mantissa_shift_for_hi_word; | |
4555 masm->li(scratch, Operand(biased_exponent << HeapNumber::kExponentShift)); | |
4556 if (mantissa_shift_for_hi_word > 0) { | |
4557 masm->sll(loword, src, mantissa_shift_for_lo_word); | |
4558 masm->srl(hiword, src, mantissa_shift_for_hi_word); | |
4559 masm->Or(hiword, scratch, hiword); | |
4560 } else { | |
4561 masm->mov(loword, zero_reg); | |
4562 masm->sll(hiword, src, mantissa_shift_for_hi_word); | |
4563 masm->Or(hiword, scratch, hiword); | |
4564 } | |
4565 | |
4566 // If least significant bit of biased exponent was not 1 it was corrupted | |
4567 // by most significant bit of mantissa so we should fix that. | |
4568 if (!(biased_exponent & 1)) { | |
4569 masm->li(scratch, 1 << HeapNumber::kExponentShift); | |
4570 masm->nor(scratch, scratch, scratch); | |
4571 masm->and_(hiword, hiword, scratch); | |
4572 } | |
4573 } | |
4574 | |
4575 | |
4576 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, | 4456 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
4577 LOperand* value, | 4457 LOperand* value, |
4578 IntegerSignedness signedness) { | 4458 IntegerSignedness signedness) { |
4579 Label slow; | 4459 Label slow; |
4580 Register src = ToRegister(value); | 4460 Register src = ToRegister(value); |
4581 Register dst = ToRegister(instr->result()); | 4461 Register dst = ToRegister(instr->result()); |
4582 DoubleRegister dbl_scratch = double_scratch0(); | 4462 DoubleRegister dbl_scratch = double_scratch0(); |
4583 | 4463 |
4584 // Preserve the value of all registers. | 4464 // Preserve the value of all registers. |
4585 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 4465 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
4586 | 4466 |
4587 Label done; | 4467 Label done; |
4588 if (signedness == SIGNED_INT32) { | 4468 if (signedness == SIGNED_INT32) { |
4589 // There was overflow, so bits 30 and 31 of the original integer | 4469 // There was overflow, so bits 30 and 31 of the original integer |
4590 // disagree. Try to allocate a heap number in new space and store | 4470 // disagree. Try to allocate a heap number in new space and store |
4591 // the value in there. If that fails, call the runtime system. | 4471 // the value in there. If that fails, call the runtime system. |
4592 if (dst.is(src)) { | 4472 if (dst.is(src)) { |
4593 __ SmiUntag(src, dst); | 4473 __ SmiUntag(src, dst); |
4594 __ Xor(src, src, Operand(0x80000000)); | 4474 __ Xor(src, src, Operand(0x80000000)); |
4595 } | 4475 } |
4596 if (CpuFeatures::IsSupported(FPU)) { | 4476 __ mtc1(src, dbl_scratch); |
4597 CpuFeatureScope scope(masm(), FPU); | 4477 __ cvt_d_w(dbl_scratch, dbl_scratch); |
4598 __ mtc1(src, dbl_scratch); | |
4599 __ cvt_d_w(dbl_scratch, dbl_scratch); | |
4600 } else { | |
4601 FloatingPointHelper::Destination dest = | |
4602 FloatingPointHelper::kCoreRegisters; | |
4603 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, f0, | |
4604 sfpd_lo, sfpd_hi, | |
4605 scratch0(), f2); | |
4606 } | |
4607 } else { | 4478 } else { |
4608 if (CpuFeatures::IsSupported(FPU)) { | 4479 __ mtc1(src, dbl_scratch); |
4609 CpuFeatureScope scope(masm(), FPU); | 4480 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); |
4610 __ mtc1(src, dbl_scratch); | |
4611 __ Cvt_d_uw(dbl_scratch, dbl_scratch, f22); | |
4612 } else { | |
4613 Label no_leading_zero, convert_done; | |
4614 __ And(at, src, Operand(0x80000000)); | |
4615 __ Branch(&no_leading_zero, ne, at, Operand(zero_reg)); | |
4616 | |
4617 // Integer has one leading zeros. | |
4618 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 1); | |
4619 __ Branch(&convert_done); | |
4620 | |
4621 __ bind(&no_leading_zero); | |
4622 GenerateUInt2Double(masm(), src, sfpd_hi, sfpd_lo, t0, 0); | |
4623 __ bind(&convert_done); | |
4624 } | |
4625 } | 4481 } |
4626 | 4482 |
4627 if (FLAG_inline_new) { | 4483 if (FLAG_inline_new) { |
4628 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); | 4484 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); |
4629 __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); | 4485 __ AllocateHeapNumber(t1, a3, t0, scratch0(), &slow, DONT_TAG_RESULT); |
4630 __ Move(dst, t1); | 4486 __ Move(dst, t1); |
4631 __ Branch(&done); | 4487 __ Branch(&done); |
4632 } | 4488 } |
4633 | 4489 |
4634 // Slow case: Call the runtime system to do the number allocation. | 4490 // Slow case: Call the runtime system to do the number allocation. |
4635 __ bind(&slow); | 4491 __ bind(&slow); |
4636 | 4492 |
4637 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 4493 // TODO(3095996): Put a valid pointer value in the stack slot where the result |
4638 // register is stored, as this register is in the pointer map, but contains an | 4494 // register is stored, as this register is in the pointer map, but contains an |
4639 // integer value. | 4495 // integer value. |
4640 __ StoreToSafepointRegisterSlot(zero_reg, dst); | 4496 __ StoreToSafepointRegisterSlot(zero_reg, dst); |
4641 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 4497 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
4642 __ Move(dst, v0); | 4498 __ Move(dst, v0); |
4643 __ Subu(dst, dst, kHeapObjectTag); | 4499 __ Subu(dst, dst, kHeapObjectTag); |
4644 | 4500 |
4645 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4501 // Done. Put the value in dbl_scratch into the value of the allocated heap |
4646 // number. | 4502 // number. |
4647 __ bind(&done); | 4503 __ bind(&done); |
4648 if (CpuFeatures::IsSupported(FPU)) { | 4504 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); |
4649 CpuFeatureScope scope(masm(), FPU); | |
4650 __ sdc1(dbl_scratch, MemOperand(dst, HeapNumber::kValueOffset)); | |
4651 } else { | |
4652 __ sw(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset)); | |
4653 __ sw(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset)); | |
4654 } | |
4655 __ Addu(dst, dst, kHeapObjectTag); | 4505 __ Addu(dst, dst, kHeapObjectTag); |
4656 __ StoreToSafepointRegisterSlot(dst, dst); | 4506 __ StoreToSafepointRegisterSlot(dst, dst); |
4657 } | 4507 } |
4658 | 4508 |
4659 | 4509 |
4660 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4510 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
4661 class DeferredNumberTagD: public LDeferredCode { | 4511 class DeferredNumberTagD: public LDeferredCode { |
4662 public: | 4512 public: |
4663 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4513 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
4664 : LDeferredCode(codegen), instr_(instr) { } | 4514 : LDeferredCode(codegen), instr_(instr) { } |
(...skipping 12 matching lines...) Expand all Loading... |
4677 bool convert_hole = false; | 4527 bool convert_hole = false; |
4678 HValue* change_input = instr->hydrogen()->value(); | 4528 HValue* change_input = instr->hydrogen()->value(); |
4679 if (change_input->IsLoadKeyed()) { | 4529 if (change_input->IsLoadKeyed()) { |
4680 HLoadKeyed* load = HLoadKeyed::cast(change_input); | 4530 HLoadKeyed* load = HLoadKeyed::cast(change_input); |
4681 convert_hole = load->UsesMustHandleHole(); | 4531 convert_hole = load->UsesMustHandleHole(); |
4682 } | 4532 } |
4683 | 4533 |
4684 Label no_special_nan_handling; | 4534 Label no_special_nan_handling; |
4685 Label done; | 4535 Label done; |
4686 if (convert_hole) { | 4536 if (convert_hole) { |
4687 if (CpuFeatures::IsSupported(FPU)) { | 4537 DoubleRegister input_reg = ToDoubleRegister(instr->value()); |
4688 CpuFeatureScope scope(masm(), FPU); | 4538 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); |
4689 DoubleRegister input_reg = ToDoubleRegister(instr->value()); | 4539 __ Move(reg, scratch0(), input_reg); |
4690 __ BranchF(&no_special_nan_handling, NULL, eq, input_reg, input_reg); | 4540 Label canonicalize; |
4691 __ Move(reg, scratch0(), input_reg); | 4541 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); |
4692 Label canonicalize; | 4542 __ li(reg, factory()->the_hole_value()); |
4693 __ Branch(&canonicalize, ne, scratch0(), Operand(kHoleNanUpper32)); | 4543 __ Branch(&done); |
4694 __ li(reg, factory()->the_hole_value()); | 4544 __ bind(&canonicalize); |
4695 __ Branch(&done); | 4545 __ Move(input_reg, |
4696 __ bind(&canonicalize); | 4546 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
4697 __ Move(input_reg, | |
4698 FixedDoubleArray::canonical_not_the_hole_nan_as_double()); | |
4699 } else { | |
4700 Label not_hole; | |
4701 __ Branch(¬_hole, ne, sfpd_hi, Operand(kHoleNanUpper32)); | |
4702 __ li(reg, factory()->the_hole_value()); | |
4703 __ Branch(&done); | |
4704 __ bind(¬_hole); | |
4705 __ And(scratch, sfpd_hi, Operand(0x7ff00000)); | |
4706 __ Branch(&no_special_nan_handling, ne, scratch, Operand(0x7ff00000)); | |
4707 Label special_nan_handling; | |
4708 __ And(at, sfpd_hi, Operand(0x000FFFFF)); | |
4709 __ Branch(&special_nan_handling, ne, at, Operand(zero_reg)); | |
4710 __ Branch(&no_special_nan_handling, eq, sfpd_lo, Operand(zero_reg)); | |
4711 __ bind(&special_nan_handling); | |
4712 double canonical_nan = | |
4713 FixedDoubleArray::canonical_not_the_hole_nan_as_double(); | |
4714 uint64_t casted_nan = BitCast<uint64_t>(canonical_nan); | |
4715 __ li(sfpd_lo, | |
4716 Operand(static_cast<uint32_t>(casted_nan & 0xFFFFFFFF))); | |
4717 __ li(sfpd_hi, | |
4718 Operand(static_cast<uint32_t>(casted_nan >> 32))); | |
4719 } | |
4720 } | 4547 } |
4721 | 4548 |
4722 __ bind(&no_special_nan_handling); | 4549 __ bind(&no_special_nan_handling); |
4723 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 4550 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); |
4724 if (FLAG_inline_new) { | 4551 if (FLAG_inline_new) { |
4725 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 4552 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); |
4726 // We want the untagged address first for performance | 4553 // We want the untagged address first for performance |
4727 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), | 4554 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), |
4728 DONT_TAG_RESULT); | 4555 DONT_TAG_RESULT); |
4729 } else { | 4556 } else { |
4730 __ Branch(deferred->entry()); | 4557 __ Branch(deferred->entry()); |
4731 } | 4558 } |
4732 __ bind(deferred->exit()); | 4559 __ bind(deferred->exit()); |
4733 if (CpuFeatures::IsSupported(FPU)) { | 4560 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); |
4734 CpuFeatureScope scope(masm(), FPU); | |
4735 __ sdc1(input_reg, MemOperand(reg, HeapNumber::kValueOffset)); | |
4736 } else { | |
4737 __ sw(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset)); | |
4738 __ sw(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize)); | |
4739 } | |
4740 // Now that we have finished with the object's real address tag it | 4561 // Now that we have finished with the object's real address tag it |
4741 __ Addu(reg, reg, kHeapObjectTag); | 4562 __ Addu(reg, reg, kHeapObjectTag); |
4742 __ bind(&done); | 4563 __ bind(&done); |
4743 } | 4564 } |
4744 | 4565 |
4745 | 4566 |
4746 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4567 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
4747 // TODO(3095996): Get rid of this. For now, we need to make the | 4568 // TODO(3095996): Get rid of this. For now, we need to make the |
4748 // result register contain a valid pointer because it is already | 4569 // result register contain a valid pointer because it is already |
4749 // contained in the register pointer map. | 4570 // contained in the register pointer map. |
(...skipping 29 matching lines...) Expand all Loading... |
4779 } | 4600 } |
4780 | 4601 |
4781 | 4602 |
4782 void LCodeGen::EmitNumberUntagD(Register input_reg, | 4603 void LCodeGen::EmitNumberUntagD(Register input_reg, |
4783 DoubleRegister result_reg, | 4604 DoubleRegister result_reg, |
4784 bool deoptimize_on_undefined, | 4605 bool deoptimize_on_undefined, |
4785 bool deoptimize_on_minus_zero, | 4606 bool deoptimize_on_minus_zero, |
4786 LEnvironment* env, | 4607 LEnvironment* env, |
4787 NumberUntagDMode mode) { | 4608 NumberUntagDMode mode) { |
4788 Register scratch = scratch0(); | 4609 Register scratch = scratch0(); |
4789 CpuFeatureScope scope(masm(), FPU); | |
4790 | 4610 |
4791 Label load_smi, heap_number, done; | 4611 Label load_smi, heap_number, done; |
4792 | 4612 |
4793 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { | 4613 if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { |
4794 // Smi check. | 4614 // Smi check. |
4795 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); | 4615 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); |
4796 | 4616 |
4797 // Heap number map check. | 4617 // Heap number map check. |
4798 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4618 __ lw(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4799 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4619 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4856 | 4676 |
4857 Label done; | 4677 Label done; |
4858 | 4678 |
4859 // The input is a tagged HeapObject. | 4679 // The input is a tagged HeapObject. |
4860 // Heap number map check. | 4680 // Heap number map check. |
4861 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); | 4681 __ lw(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); |
4862 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); | 4682 __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); |
4863 // This 'at' value and scratch1 map value are used for tests in both clauses | 4683 // This 'at' value and scratch1 map value are used for tests in both clauses |
4864 // of the if. | 4684 // of the if. |
4865 | 4685 |
4866 CpuFeatureScope scope(masm(), FPU); | |
4867 if (instr->truncating()) { | 4686 if (instr->truncating()) { |
4868 Register scratch3 = ToRegister(instr->temp2()); | 4687 Register scratch3 = ToRegister(instr->temp2()); |
4869 FPURegister single_scratch = double_scratch.low(); | 4688 FPURegister single_scratch = double_scratch.low(); |
4870 ASSERT(!scratch3.is(input_reg) && | 4689 ASSERT(!scratch3.is(input_reg) && |
4871 !scratch3.is(scratch1) && | 4690 !scratch3.is(scratch1) && |
4872 !scratch3.is(scratch2)); | 4691 !scratch3.is(scratch2)); |
4873 // Performs a truncating conversion of a floating point number as used by | 4692 // Performs a truncating conversion of a floating point number as used by |
4874 // the JS bitwise operations. | 4693 // the JS bitwise operations. |
4875 Label heap_number; | 4694 Label heap_number; |
4876 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? | 4695 __ Branch(&heap_number, eq, scratch1, Operand(at)); // HeapNumber map? |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5112 __ CompareMapAndBranch( | 4931 __ CompareMapAndBranch( |
5113 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); | 4932 map_reg, map, &success, eq, &success, REQUIRE_EXACT_MAP); |
5114 } | 4933 } |
5115 Handle<Map> map = map_set->last(); | 4934 Handle<Map> map = map_set->last(); |
5116 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); | 4935 DoCheckMapCommon(map_reg, map, REQUIRE_EXACT_MAP, instr->environment()); |
5117 __ bind(&success); | 4936 __ bind(&success); |
5118 } | 4937 } |
5119 | 4938 |
5120 | 4939 |
5121 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 4940 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
5122 CpuFeatureScope vfp_scope(masm(), FPU); | |
5123 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); | 4941 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped()); |
5124 Register result_reg = ToRegister(instr->result()); | 4942 Register result_reg = ToRegister(instr->result()); |
5125 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 4943 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5126 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); | 4944 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); |
5127 } | 4945 } |
5128 | 4946 |
5129 | 4947 |
5130 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 4948 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
5131 CpuFeatureScope vfp_scope(masm(), FPU); | |
5132 Register unclamped_reg = ToRegister(instr->unclamped()); | 4949 Register unclamped_reg = ToRegister(instr->unclamped()); |
5133 Register result_reg = ToRegister(instr->result()); | 4950 Register result_reg = ToRegister(instr->result()); |
5134 __ ClampUint8(result_reg, unclamped_reg); | 4951 __ ClampUint8(result_reg, unclamped_reg); |
5135 } | 4952 } |
5136 | 4953 |
5137 | 4954 |
5138 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 4955 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
5139 CpuFeatureScope vfp_scope(masm(), FPU); | |
5140 Register scratch = scratch0(); | 4956 Register scratch = scratch0(); |
5141 Register input_reg = ToRegister(instr->unclamped()); | 4957 Register input_reg = ToRegister(instr->unclamped()); |
5142 Register result_reg = ToRegister(instr->result()); | 4958 Register result_reg = ToRegister(instr->result()); |
5143 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); | 4959 DoubleRegister temp_reg = ToDoubleRegister(instr->temp()); |
5144 Label is_smi, done, heap_number; | 4960 Label is_smi, done, heap_number; |
5145 | 4961 |
5146 // Both smi and heap number cases are handled. | 4962 // Both smi and heap number cases are handled. |
5147 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); | 4963 __ UntagAndJumpIfSmi(scratch, input_reg, &is_smi); |
5148 | 4964 |
5149 // Check for heap number | 4965 // Check for heap number |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5906 __ Subu(scratch, result, scratch); | 5722 __ Subu(scratch, result, scratch); |
5907 __ lw(result, FieldMemOperand(scratch, | 5723 __ lw(result, FieldMemOperand(scratch, |
5908 FixedArray::kHeaderSize - kPointerSize)); | 5724 FixedArray::kHeaderSize - kPointerSize)); |
5909 __ bind(&done); | 5725 __ bind(&done); |
5910 } | 5726 } |
5911 | 5727 |
5912 | 5728 |
5913 #undef __ | 5729 #undef __ |
5914 | 5730 |
5915 } } // namespace v8::internal | 5731 } } // namespace v8::internal |
OLD | NEW |