| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #include "arm64/lithium-codegen-arm64.h" | 7 #include "arm64/lithium-codegen-arm64.h" |
| 8 #include "arm64/lithium-gap-resolver-arm64.h" | 8 #include "arm64/lithium-gap-resolver-arm64.h" |
| 9 #include "code-stubs.h" | 9 #include "code-stubs.h" |
| 10 #include "stub-cache.h" | 10 #include "stub-cache.h" |
| (...skipping 3743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3754 Register temp1 = ToRegister(instr->temp1()); | 3754 Register temp1 = ToRegister(instr->temp1()); |
| 3755 Register temp2 = ToRegister(instr->temp2()); | 3755 Register temp2 = ToRegister(instr->temp2()); |
| 3756 Register temp3 = ToRegister(instr->temp3()); | 3756 Register temp3 = ToRegister(instr->temp3()); |
| 3757 | 3757 |
| 3758 MathExpGenerator::EmitMathExp(masm(), input, result, | 3758 MathExpGenerator::EmitMathExp(masm(), input, result, |
| 3759 double_temp1, double_temp2, | 3759 double_temp1, double_temp2, |
| 3760 temp1, temp2, temp3); | 3760 temp1, temp2, temp3); |
| 3761 } | 3761 } |
| 3762 | 3762 |
| 3763 | 3763 |
| 3764 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3764 void LCodeGen::DoMathFloorD(LMathFloorD* instr) { |
| 3765 // TODO(jbramley): If we could provide a double result, we could use frintm | 3765 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3766 // and produce a valid double result in a single instruction. | 3766 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3767 |
| 3768 __ Frintm(result, input); |
| 3769 } |
| 3770 |
| 3771 |
| 3772 void LCodeGen::DoMathFloorI(LMathFloorI* instr) { |
| 3767 DoubleRegister input = ToDoubleRegister(instr->value()); | 3773 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 3768 Register result = ToRegister(instr->result()); | 3774 Register result = ToRegister(instr->result()); |
| 3769 | 3775 |
| 3770 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3776 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3771 DeoptimizeIfMinusZero(input, instr->environment()); | 3777 DeoptimizeIfMinusZero(input, instr->environment()); |
| 3772 } | 3778 } |
| 3773 | 3779 |
| 3774 __ Fcvtms(result, input); | 3780 __ Fcvtms(result, input); |
| 3775 | 3781 |
| 3776 // Check that the result fits into a 32-bit integer. | 3782 // Check that the result fits into a 32-bit integer. |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3989 MathPowStub stub(isolate(), MathPowStub::INTEGER); | 3995 MathPowStub stub(isolate(), MathPowStub::INTEGER); |
| 3990 __ CallStub(&stub); | 3996 __ CallStub(&stub); |
| 3991 } else { | 3997 } else { |
| 3992 ASSERT(exponent_type.IsDouble()); | 3998 ASSERT(exponent_type.IsDouble()); |
| 3993 MathPowStub stub(isolate(), MathPowStub::DOUBLE); | 3999 MathPowStub stub(isolate(), MathPowStub::DOUBLE); |
| 3994 __ CallStub(&stub); | 4000 __ CallStub(&stub); |
| 3995 } | 4001 } |
| 3996 } | 4002 } |
| 3997 | 4003 |
| 3998 | 4004 |
| 3999 void LCodeGen::DoMathRound(LMathRound* instr) { | 4005 void LCodeGen::DoMathRoundD(LMathRoundD* instr) { |
| 4000 // TODO(jbramley): We could provide a double result here using frint. | 4006 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 4007 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 4008 DoubleRegister scratch_d = double_scratch(); |
| 4009 |
| 4010 ASSERT(!AreAliased(input, result, scratch_d)); |
| 4011 |
| 4012 Label done; |
| 4013 |
| 4014 __ Frinta(result, input); |
| 4015 __ Fcmp(input, 0.0); |
| 4016 __ Fccmp(result, input, ZFlag, lt); |
| 4017 // The result is correct if the input was in [-0, +infinity], or was a |
| 4018 // negative integral value. |
| 4019 __ B(eq, &done); |
| 4020 |
| 4021 // Here the input is negative, non integral, with an exponent lower than 52. |
| 4022 // We do not have to worry about the 0.49999999999999994 (0x3fdfffffffffffff) |
| 4023 // case. So we can safely add 0.5. |
| 4024 __ Fmov(scratch_d, 0.5); |
| 4025 __ Fadd(result, input, scratch_d); |
| 4026 __ Frintm(result, result); |
| 4027 // The range [-0.5, -0.0[ yielded +0.0. Force the sign to negative. |
| 4028 __ Fabs(result, result); |
| 4029 __ Fneg(result, result); |
| 4030 |
| 4031 __ Bind(&done); |
| 4032 } |
| 4033 |
| 4034 |
| 4035 void LCodeGen::DoMathRoundI(LMathRoundI* instr) { |
| 4001 DoubleRegister input = ToDoubleRegister(instr->value()); | 4036 DoubleRegister input = ToDoubleRegister(instr->value()); |
| 4002 DoubleRegister temp1 = ToDoubleRegister(instr->temp1()); | 4037 DoubleRegister temp1 = ToDoubleRegister(instr->temp1()); |
| 4003 Register result = ToRegister(instr->result()); | 4038 Register result = ToRegister(instr->result()); |
| 4004 Label try_rounding; | 4039 Label try_rounding; |
| 4005 Label done; | 4040 Label done; |
| 4006 | 4041 |
| 4007 // Math.round() rounds to the nearest integer, with ties going towards | 4042 // Math.round() rounds to the nearest integer, with ties going towards |
| 4008 // +infinity. This does not match any IEEE-754 rounding mode. | 4043 // +infinity. This does not match any IEEE-754 rounding mode. |
| 4009 // - Infinities and NaNs are propagated unchanged, but cause deopts because | 4044 // - Infinities and NaNs are propagated unchanged, but cause deopts because |
| 4010 // they can't be represented as integers. | 4045 // they can't be represented as integers. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4029 __ Mov(result, 1); // +0.5. | 4064 __ Mov(result, 1); // +0.5. |
| 4030 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on | 4065 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on |
| 4031 // flag kBailoutOnMinusZero, will return 0 (xzr). | 4066 // flag kBailoutOnMinusZero, will return 0 (xzr). |
| 4032 __ Csel(result, result, xzr, eq); | 4067 __ Csel(result, result, xzr, eq); |
| 4033 __ B(&done); | 4068 __ B(&done); |
| 4034 | 4069 |
| 4035 __ Bind(&try_rounding); | 4070 __ Bind(&try_rounding); |
| 4036 // Since we're providing a 32-bit result, we can implement ties-to-infinity by | 4071 // Since we're providing a 32-bit result, we can implement ties-to-infinity by |
| 4037 // adding 0.5 to the input, then taking the floor of the result. This does not | 4072 // adding 0.5 to the input, then taking the floor of the result. This does not |
| 4038 // work for very large positive doubles because adding 0.5 would cause an | 4073 // work for very large positive doubles because adding 0.5 would cause an |
| 4039 // intermediate rounding stage, so a different approach will be necessary if a | 4074 // intermediate rounding stage, so a different approach is necessary when a |
| 4040 // double result is needed. | 4075 // double result is needed. |
| 4041 __ Fadd(temp1, input, dot_five); | 4076 __ Fadd(temp1, input, dot_five); |
| 4042 __ Fcvtms(result, temp1); | 4077 __ Fcvtms(result, temp1); |
| 4043 | 4078 |
| 4044 // Deopt if | 4079 // Deopt if |
| 4045 // * the input was NaN | 4080 // * the input was NaN |
| 4046 // * the result is not representable using a 32-bit integer. | 4081 // * the result is not representable using a 32-bit integer. |
| 4047 __ Fcmp(input, 0.0); | 4082 __ Fcmp(input, 0.0); |
| 4048 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); | 4083 __ Ccmp(result, Operand(result.W(), SXTW), NoFlag, vc); |
| 4049 DeoptimizeIf(ne, instr->environment()); | 4084 DeoptimizeIf(ne, instr->environment()); |
| (...skipping 1826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5876 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5911 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5877 // Index is equal to negated out of object property index plus 1. | 5912 // Index is equal to negated out of object property index plus 1. |
| 5878 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5913 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5879 __ Ldr(result, FieldMemOperand(result, | 5914 __ Ldr(result, FieldMemOperand(result, |
| 5880 FixedArray::kHeaderSize - kPointerSize)); | 5915 FixedArray::kHeaderSize - kPointerSize)); |
| 5881 __ Bind(deferred->exit()); | 5916 __ Bind(deferred->exit()); |
| 5882 __ Bind(&done); | 5917 __ Bind(&done); |
| 5883 } | 5918 } |
| 5884 | 5919 |
| 5885 } } // namespace v8::internal | 5920 } } // namespace v8::internal |
| OLD | NEW |