Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Side by Side Diff: src/arm64/lithium-codegen-arm64.cc

Issue 258793002: ARM64: Generate optimized code for Math.floor and Math.round with double outputs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Change C-style comments to C++-style comments Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm64/lithium-arm64.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm64/lithium-arm64.cc ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698