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

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

Issue 191293012: Reland "Handle non-power-of-2 divisors in division-like operations". (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.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 // 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 1039 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) { 1050 void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) {
1051 DeoptimizeBranch(environment, static_cast<BranchType>(cond)); 1051 DeoptimizeBranch(environment, static_cast<BranchType>(cond));
1052 } 1052 }
1053 1053
1054 1054
1055 void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) { 1055 void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) {
1056 DeoptimizeBranch(environment, reg_zero, rt); 1056 DeoptimizeBranch(environment, reg_zero, rt);
1057 } 1057 }
1058 1058
1059 1059
1060 void LCodeGen::DeoptimizeIfNotZero(Register rt, LEnvironment* environment) {
1061 DeoptimizeBranch(environment, reg_not_zero, rt);
1062 }
1063
1064
1060 void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) { 1065 void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) {
1061 int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit; 1066 int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit;
1062 DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit); 1067 DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit);
1063 } 1068 }
1064 1069
1065 1070
1066 void LCodeGen::DeoptimizeIfSmi(Register rt, 1071 void LCodeGen::DeoptimizeIfSmi(Register rt,
1067 LEnvironment* environment) { 1072 LEnvironment* environment) {
1068 DeoptimizeBranch(environment, reg_bit_clear, rt, MaskToBit(kSmiTagMask)); 1073 DeoptimizeBranch(environment, reg_bit_clear, rt, MaskToBit(kSmiTagMask));
1069 } 1074 }
(...skipping 1557 matching lines...) Expand 10 before | Expand all | Expand 10 after
2627 __ Add(result, dividend, Operand(dividend, LSR, 31)); 2632 __ Add(result, dividend, Operand(dividend, LSR, 31));
2628 } else { 2633 } else {
2629 __ Mov(result, Operand(dividend, ASR, 31)); 2634 __ Mov(result, Operand(dividend, ASR, 31));
2630 __ Add(result, dividend, Operand(result, LSR, 32 - shift)); 2635 __ Add(result, dividend, Operand(result, LSR, 32 - shift));
2631 } 2636 }
2632 if (shift > 0) __ Mov(result, Operand(result, ASR, shift)); 2637 if (shift > 0) __ Mov(result, Operand(result, ASR, shift));
2633 if (divisor < 0) __ Neg(result, result); 2638 if (divisor < 0) __ Neg(result, result);
2634 } 2639 }
2635 2640
2636 2641
2642 void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
2643 Register dividend = ToRegister32(instr->dividend());
2644 int32_t divisor = instr->divisor();
2645 Register result = ToRegister32(instr->result());
2646 ASSERT(!AreAliased(dividend, result));
2647
2648 if (divisor == 0) {
2649 Deoptimize(instr->environment());
2650 return;
2651 }
2652
2653 // Check for (0 / -x) that will produce negative zero.
2654 HDiv* hdiv = instr->hydrogen();
2655 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
2656 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
2657 DeoptimizeIfZero(dividend, instr->environment());
2658 }
2659
2660 __ FlooringDiv(result, dividend, Abs(divisor));
2661 __ Add(result, result, Operand(dividend, LSR, 31));
2662 if (divisor < 0) __ Neg(result, result);
2663
2664 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
2665 Register temp = ToRegister32(instr->temp());
2666 ASSERT(!AreAliased(dividend, result, temp));
2667 __ Sxtw(dividend.X(), dividend);
2668 __ Mov(temp, divisor);
2669 __ Smsubl(temp.X(), result, temp, dividend.X());
2670 DeoptimizeIfNotZero(temp, instr->environment());
2671 }
2672 }
2673
2674
2637 void LCodeGen::DoDivI(LDivI* instr) { 2675 void LCodeGen::DoDivI(LDivI* instr) {
2638 Register dividend = ToRegister32(instr->left()); 2676 Register dividend = ToRegister32(instr->left());
2639 Register divisor = ToRegister32(instr->right()); 2677 Register divisor = ToRegister32(instr->right());
2640 Register result = ToRegister32(instr->result()); 2678 Register result = ToRegister32(instr->result());
2641 HValue* hdiv = instr->hydrogen_value(); 2679 HValue* hdiv = instr->hydrogen_value();
2642 2680
2643 // Issue the division first, and then check for any deopt cases whilst the 2681 // Issue the division first, and then check for any deopt cases whilst the
2644 // result is computed. 2682 // result is computed.
2645 __ Sdiv(result, dividend, divisor); 2683 __ Sdiv(result, dividend, divisor);
2646 2684
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after
3832 __ Mov(dividend, kMinInt / divisor); 3870 __ Mov(dividend, kMinInt / divisor);
3833 __ B(&done); 3871 __ B(&done);
3834 } 3872 }
3835 } 3873 }
3836 __ bind(&not_kmin_int); 3874 __ bind(&not_kmin_int);
3837 __ Mov(dividend, Operand(dividend, ASR, shift)); 3875 __ Mov(dividend, Operand(dividend, ASR, shift));
3838 __ bind(&done); 3876 __ bind(&done);
3839 } 3877 }
3840 3878
3841 3879
3880 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
3881 Register dividend = ToRegister32(instr->dividend());
3882 int32_t divisor = instr->divisor();
3883 Register result = ToRegister32(instr->result());
3884 ASSERT(!AreAliased(dividend, result));
3885
3886 if (divisor == 0) {
3887 Deoptimize(instr->environment());
3888 return;
3889 }
3890
3891 // Check for (0 / -x) that will produce negative zero.
3892 HMathFloorOfDiv* hdiv = instr->hydrogen();
3893 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
3894 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
3895 __ Cmp(dividend, 0);
3896 DeoptimizeIf(eq, instr->environment());
3897 }
3898
3899 __ FlooringDiv(result, dividend, divisor);
3900 }
3901
3902
3842 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { 3903 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
3843 Register dividend = ToRegister32(instr->dividend()); 3904 Register dividend = ToRegister32(instr->dividend());
3844 Register divisor = ToRegister32(instr->divisor()); 3905 Register divisor = ToRegister32(instr->divisor());
3845 Register remainder = ToRegister32(instr->temp()); 3906 Register remainder = ToRegister32(instr->temp());
3846 Register result = ToRegister32(instr->result()); 3907 Register result = ToRegister32(instr->result());
3847 3908
3848 // This can't cause an exception on ARM, so we can speculatively 3909 // This can't cause an exception on ARM, so we can speculatively
3849 // execute it already now. 3910 // execute it already now.
3850 __ Sdiv(result, dividend, divisor); 3911 __ Sdiv(result, dividend, divisor);
3851 3912
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
4091 } 4152 }
4092 __ B(&done); 4153 __ B(&done);
4093 } 4154 }
4094 4155
4095 __ bind(&dividend_is_not_negative); 4156 __ bind(&dividend_is_not_negative);
4096 __ And(dividend, dividend, Operand(mask)); 4157 __ And(dividend, dividend, Operand(mask));
4097 __ bind(&done); 4158 __ bind(&done);
4098 } 4159 }
4099 4160
4100 4161
4162 void LCodeGen::DoModByConstI(LModByConstI* instr) {
4163 Register dividend = ToRegister32(instr->dividend());
4164 int32_t divisor = instr->divisor();
4165 Register result = ToRegister32(instr->result());
4166 Register temp = ToRegister32(instr->temp());
4167 ASSERT(!AreAliased(dividend, result, temp));
4168
4169 if (divisor == 0) {
4170 Deoptimize(instr->environment());
4171 return;
4172 }
4173
4174 __ FlooringDiv(result, dividend, Abs(divisor));
4175 __ Add(result, result, Operand(dividend, LSR, 31));
4176 __ Sxtw(dividend.X(), dividend);
4177 __ Mov(temp, Abs(divisor));
4178 __ Smsubl(result.X(), result, temp, dividend.X());
4179
4180 // Check for negative zero.
4181 HMod* hmod = instr->hydrogen();
4182 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
4183 hmod->left()->CanBeNegative()) {
4184 Label remainder_not_zero;
4185 __ Cbnz(result, &remainder_not_zero);
4186 DeoptimizeIfNegative(dividend, instr->environment());
4187 __ bind(&remainder_not_zero);
4188 }
4189 }
4190
4191
4101 void LCodeGen::DoModI(LModI* instr) { 4192 void LCodeGen::DoModI(LModI* instr) {
4102 Register dividend = ToRegister32(instr->left()); 4193 Register dividend = ToRegister32(instr->left());
4103 Register divisor = ToRegister32(instr->right()); 4194 Register divisor = ToRegister32(instr->right());
4104 Register result = ToRegister32(instr->result()); 4195 Register result = ToRegister32(instr->result());
4105 4196
4106 Label deopt, done; 4197 Label deopt, done;
4107 // modulo = dividend - quotient * divisor 4198 // modulo = dividend - quotient * divisor
4108 __ Sdiv(result, dividend, divisor); 4199 __ Sdiv(result, dividend, divisor);
4109 if (instr->hydrogen()->right()->CanBeZero()) { 4200 if (instr->hydrogen()->right()->CanBeZero()) {
4110 // Combine the deoptimization sites. 4201 // Combine the deoptimization sites.
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after
5741 __ Bind(&out_of_object); 5832 __ Bind(&out_of_object);
5742 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 5833 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
5743 // Index is equal to negated out of object property index plus 1. 5834 // Index is equal to negated out of object property index plus 1.
5744 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); 5835 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2));
5745 __ Ldr(result, FieldMemOperand(result, 5836 __ Ldr(result, FieldMemOperand(result,
5746 FixedArray::kHeaderSize - kPointerSize)); 5837 FixedArray::kHeaderSize - kPointerSize));
5747 __ Bind(&done); 5838 __ Bind(&done);
5748 } 5839 }
5749 5840
5750 } } // namespace v8::internal 5841 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698