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

Unified Diff: src/a64/lithium-codegen-a64.cc

Issue 190383002: Handle non-power-of-2 divisors in division-like operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/a64/lithium-codegen-a64.h ('k') | src/a64/macro-assembler-a64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index e35aa2eb63e97a57a43477f5428b6e60c3ec4538..e42ff1089b139e2db96e15f232de2cf1a25714da 100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -1057,6 +1057,11 @@ void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) {
}
+void LCodeGen::DeoptimizeIfNotZero(Register rt, LEnvironment* environment) {
+ DeoptimizeBranch(environment, reg_not_zero, rt);
+}
+
+
void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) {
int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit;
DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit);
@@ -2610,6 +2615,39 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
}
+void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
+ Register dividend = ToRegister32(instr->dividend());
+ int32_t divisor = instr->divisor();
+ Register result = ToRegister32(instr->result());
+ ASSERT(!AreAliased(dividend, result));
+
+ if (divisor == 0) {
+ Deoptimize(instr->environment());
+ return;
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ HDiv* hdiv = instr->hydrogen();
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
+ hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ __ Cmp(dividend, 0);
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ __ FlooringDiv(result, dividend, Abs(divisor));
+ if (divisor < 0) __ Neg(result, result);
+
+ if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+ Register temp = ToRegister32(instr->temp());
+ ASSERT(!AreAliased(dividend, result, temp));
+ __ Sxtw(dividend.X(), dividend);
+ __ Mov(temp, divisor);
+ __ Smsubl(temp.X(), result, temp, dividend.X());
+ DeoptimizeIfNotZero(temp, instr->environment());
+ }
+}
+
+
void LCodeGen::DoDivI(LDivI* instr) {
Register dividend = ToRegister32(instr->left());
Register divisor = ToRegister32(instr->right());
@@ -3820,6 +3858,29 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
}
+void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
+ Register dividend = ToRegister32(instr->dividend());
+ int32_t divisor = instr->divisor();
+ Register result = ToRegister32(instr->result());
+ ASSERT(!AreAliased(dividend, result));
+
+ if (divisor == 0) {
+ Deoptimize(instr->environment());
+ return;
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ HMathFloorOfDiv* hdiv = instr->hydrogen();
+ if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) &&
+ hdiv->left()->RangeCanInclude(0) && divisor < 0) {
+ __ Cmp(dividend, 0);
+ DeoptimizeIf(eq, instr->environment());
+ }
+
+ __ FlooringDiv(result, dividend, divisor);
+}
+
+
void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
Register dividend = ToRegister32(instr->dividend());
Register divisor = ToRegister32(instr->divisor());
@@ -4079,6 +4140,35 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
}
+void LCodeGen::DoModByConstI(LModByConstI* instr) {
+ Register dividend = ToRegister32(instr->dividend());
+ int32_t divisor = instr->divisor();
+ Register result = ToRegister32(instr->result());
+ Register temp = ToRegister32(instr->temp());
+ ASSERT(!AreAliased(dividend, result, temp));
+
+ if (divisor == 0) {
+ Deoptimize(instr->environment());
+ return;
+ }
+
+ __ FlooringDiv(result, dividend, Abs(divisor));
+ __ Sxtw(dividend.X(), dividend);
+ __ Mov(temp, Abs(divisor));
+ __ Smsubl(result.X(), result, temp, dividend.X());
+
+ // Check for negative zero.
+ HMod* hmod = instr->hydrogen();
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) &&
+ hmod->left()->CanBeNegative()) {
+ Label remainder_not_zero;
+ __ Cbnz(result, &remainder_not_zero);
+ DeoptimizeIfNegative(dividend, instr->environment());
+ __ bind(&remainder_not_zero);
+ }
+}
+
+
void LCodeGen::DoModI(LModI* instr) {
Register dividend = ToRegister32(instr->left());
Register divisor = ToRegister32(instr->right());
« 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