OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3777 Register temp1 = ToRegister(instr->temp1()); | 3777 Register temp1 = ToRegister(instr->temp1()); |
3778 Register temp2 = ToRegister(instr->temp2()); | 3778 Register temp2 = ToRegister(instr->temp2()); |
3779 Register temp3 = ToRegister(instr->temp3()); | 3779 Register temp3 = ToRegister(instr->temp3()); |
3780 | 3780 |
3781 MathExpGenerator::EmitMathExp(masm(), input, result, | 3781 MathExpGenerator::EmitMathExp(masm(), input, result, |
3782 double_temp1, double_temp2, | 3782 double_temp1, double_temp2, |
3783 temp1, temp2, temp3); | 3783 temp1, temp2, temp3); |
3784 } | 3784 } |
3785 | 3785 |
3786 | 3786 |
3787 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3787 void LCodeGen::DoMathFloorD(LMathFloorD* instr) { |
3788 // TODO(jbramley): If we could provide a double result, we could use frintm | 3788 DoubleRegister input = ToDoubleRegister(instr->value()); |
3789 // and produce a valid double result in a single instruction. | 3789 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3790 |
| 3791 __ Frintm(result, input); |
| 3792 } |
| 3793 |
| 3794 |
| 3795 void LCodeGen::DoMathFloorI(LMathFloorI* instr) { |
3790 DoubleRegister input = ToDoubleRegister(instr->value()); | 3796 DoubleRegister input = ToDoubleRegister(instr->value()); |
3791 Register result = ToRegister(instr->result()); | 3797 Register result = ToRegister(instr->result()); |
3792 | 3798 |
3793 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3799 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
3794 DeoptimizeIfMinusZero(input, instr->environment()); | 3800 DeoptimizeIfMinusZero(input, instr->environment()); |
3795 } | 3801 } |
3796 | 3802 |
3797 __ Fcvtms(result, input); | 3803 __ Fcvtms(result, input); |
3798 | 3804 |
3799 // Check that the result fits into a 32-bit integer. | 3805 // Check that the result fits into a 32-bit integer. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4012 MathPowStub stub(isolate(), MathPowStub::INTEGER); | 4018 MathPowStub stub(isolate(), MathPowStub::INTEGER); |
4013 __ CallStub(&stub); | 4019 __ CallStub(&stub); |
4014 } else { | 4020 } else { |
4015 ASSERT(exponent_type.IsDouble()); | 4021 ASSERT(exponent_type.IsDouble()); |
4016 MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 4022 MathPowStub stub(isolate(), MathPowStub::DOUBLE); |
4017 __ CallStub(&stub); | 4023 __ CallStub(&stub); |
4018 } | 4024 } |
4019 } | 4025 } |
4020 | 4026 |
4021 | 4027 |
4022 void LCodeGen::DoMathRound(LMathRound* instr) { | 4028 void LCodeGen::DoMathRoundD(LMathRoundD* instr) { |
4023 // TODO(jbramley): We could provide a double result here using frint. | 4029 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 4030 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 4031 DoubleRegister scratch_d = crankshaft_fp_scratch; |
| 4032 Register scratch_x = ToRegister(instr->temp()); |
| 4033 |
| 4034 ASSERT(!AreAliased(input, result, scratch_d)); |
| 4035 |
| 4036 Label done; |
| 4037 |
| 4038 // If the exponent is greater than or equal to the width of the mantissa (52), |
| 4039 // there is no fractional part. |
| 4040 __ Fmov(scratch_x, input); |
| 4041 __ Ubfx(scratch_x, scratch_x, kDoubleMantissaBits, kDoubleExponentBits); |
| 4042 __ Cmp(scratch_x, Operand(kDoubleExponentBias + kDoubleMantissaBits)); |
| 4043 __ Fmov(result, input); |
| 4044 __ B(hs, &done); |
| 4045 |
| 4046 // Otherwise except for the range yielding -0.0, the result is the same as |
| 4047 // floor(val + 0.5). |
| 4048 __ Fmov(scratch_d, 0.5); |
| 4049 __ Fadd(result, input, scratch_d); |
| 4050 __ Frintm(result, result); |
| 4051 __ Fcmp(result, 0.0); |
| 4052 __ B(ne, &done); |
| 4053 |
| 4054 // Frintn computes the correct result for [-0.5, 0.5[. |
| 4055 __ Frintn(result, input); |
| 4056 |
| 4057 __ Bind(&done); |
| 4058 } |
| 4059 |
| 4060 |
| 4061 void LCodeGen::DoMathRoundI(LMathRoundI* instr) { |
4024 DoubleRegister input = ToDoubleRegister(instr->value()); | 4062 DoubleRegister input = ToDoubleRegister(instr->value()); |
4025 DoubleRegister temp1 = ToDoubleRegister(instr->temp1()); | 4063 DoubleRegister temp1 = ToDoubleRegister(instr->temp1()); |
4026 Register result = ToRegister(instr->result()); | 4064 Register result = ToRegister(instr->result()); |
4027 Label try_rounding; | 4065 Label try_rounding; |
4028 Label done; | 4066 Label done; |
4029 | 4067 |
4030 // Math.round() rounds to the nearest integer, with ties going towards | 4068 // Math.round() rounds to the nearest integer, with ties going towards |
4031 // +infinity. This does not match any IEEE-754 rounding mode. | 4069 // +infinity. This does not match any IEEE-754 rounding mode. |
4032 // - Infinities and NaNs are propagated unchanged, but cause deopts because | 4070 // - Infinities and NaNs are propagated unchanged, but cause deopts because |
4033 // they can't be represented as integers. | 4071 // they can't be represented as integers. |
(...skipping 18 matching lines...) Expand all Loading... |
4052 __ Mov(result, 1); // +0.5. | 4090 __ Mov(result, 1); // +0.5. |
4053 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on | 4091 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on |
4054 // flag kBailoutOnMinusZero, will return 0 (xzr). | 4092 // flag kBailoutOnMinusZero, will return 0 (xzr). |
4055 __ Csel(result, result, xzr, eq); | 4093 __ Csel(result, result, xzr, eq); |
4056 __ B(&done); | 4094 __ B(&done); |
4057 | 4095 |
4058 __ Bind(&try_rounding); | 4096 __ Bind(&try_rounding); |
4059 // Since we're providing a 32-bit result, we can implement ties-to-infinity by | 4097 // Since we're providing a 32-bit result, we can implement ties-to-infinity by |
4060 // adding 0.5 to the input, then taking the floor of the result. This does not | 4098 // adding 0.5 to the input, then taking the floor of the result. This does not |
4061 // work for very large positive doubles because adding 0.5 would cause an | 4099 // work for very large positive doubles because adding 0.5 would cause an |
4062 // intermediate rounding stage, so a different approach will be necessary if a | 4100 // intermediate rounding stage, so a different approach is necessary when a |
4063 // double result is needed. | 4101 // double result is needed. |
4064 __ Fadd(temp1, input, dot_five); | 4102 __ Fadd(temp1, input, dot_five); |
4065 __ Fcvtms(result, temp1); | 4103 __ Fcvtms(result, temp1); |
4066 | 4104 |
4067 // Deopt if | 4105 // Deopt if |
4068 // * the input was NaN | 4106 // * the input was NaN |
4069 // * the result is not representable using a 32-bit integer. | 4107 // * the result is not representable using a 32-bit integer. |
4070 __ Fcmp(input, 0.0); | 4108 __ Fcmp(input, 0.0); |
4071 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); | 4109 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); |
4072 DeoptimizeIf(ne, instr->environment()); | 4110 DeoptimizeIf(ne, instr->environment()); |
(...skipping 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5899 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5937 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5900 // Index is equal to negated out of object property index plus 1. | 5938 // Index is equal to negated out of object property index plus 1. |
5901 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5939 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5902 __ Ldr(result, FieldMemOperand(result, | 5940 __ Ldr(result, FieldMemOperand(result, |
5903 FixedArray::kHeaderSize - kPointerSize)); | 5941 FixedArray::kHeaderSize - kPointerSize)); |
5904 __ Bind(deferred->exit()); | 5942 __ Bind(deferred->exit()); |
5905 __ Bind(&done); | 5943 __ Bind(&done); |
5906 } | 5944 } |
5907 | 5945 |
5908 } } // namespace v8::internal | 5946 } } // namespace v8::internal |
OLD | NEW |