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); | |
ulan
2014/04/30 09:18:41
I see how it handles 0.0 and negative integers, bu
Alexandre Rames
2014/04/30 09:31:06
If the input is greater or equal to zero, the 'lt'
| |
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 |