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

Unified Diff: src/code-stub-assembler.cc

Issue 2138633002: [turbofan] Introduce CheckedInt32Div and CheckedInt32Mod operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 5 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
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 9371fdacab37d732de8f93ecb082d8c08e931ecb..24864d2740fbae1982d5e32b1635508fcd69b263 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -53,6 +53,14 @@ Node* CodeStubAssembler::NoContextConstant() {
return SmiConstant(Smi::FromInt(0));
}
+Node* CodeStubAssembler::MinusZeroConstant() {
+ return LoadRoot(Heap::kMinusZeroValueRootIndex);
+}
+
+Node* CodeStubAssembler::NanConstant() {
+ return LoadRoot(Heap::kNanValueRootIndex);
+}
+
Node* CodeStubAssembler::NullConstant() {
return LoadRoot(Heap::kNullValueRootIndex);
}
@@ -330,6 +338,69 @@ Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
return min.value();
}
+Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
+ Variable var_result(this, MachineRepresentation::kTagged);
+ Label return_result(this, &var_result),
+ return_minuszero(this, Label::kDeferred),
+ return_nan(this, Label::kDeferred);
+
+ // Untag {a} and {b}.
+ a = SmiToWord32(a);
+ b = SmiToWord32(b);
+
+ // Return NaN if {b} is zero.
+ GotoIf(Word32Equal(b, Int32Constant(0)), &return_nan);
+
+ // Check if {a} is positive (or zero).
Jarin 2016/07/11 04:47:20 We call this non-negative.
Benedikt Meurer 2016/07/11 05:03:22 Done.
+ Label if_aispositive(this), if_aisnotpositive(this, Label::kDeferred);
+ Branch(Int32LessThanOrEqual(Int32Constant(0), a), &if_aispositive,
+ &if_aisnotpositive);
+
+ Bind(&if_aispositive);
+ {
+ // Fast case, don't need to check any other edge cases.
+ Node* r = Int32Mod(a, b);
+ var_result.Bind(SmiFromWord32(r));
+ Goto(&return_result);
+ }
+
+ Bind(&if_aisnotpositive);
Jarin 2016/07/11 04:47:20 notpositive -> negative
Benedikt Meurer 2016/07/11 05:03:22 Done.
+ {
+ if (SmiValuesAre32Bits()) {
+ // Check if {a} is kMinInt and {b} is -1 (only relevant if the
+ // kMinInt is actually representable as a Smi).
+ Label join(this);
+ GotoUnless(Word32Equal(a, Int32Constant(kMinInt)), &join);
+ GotoIf(Word32Equal(b, Int32Constant(-1)), &return_minuszero);
+ Goto(&join);
+ Bind(&join);
+ }
+
+ // Perform the integer modulus operation.
+ Node* r = Int32Mod(a, b);
+
+ // Check if {r} is zero, and if so return -0, because we have to
+ // take the sign of the left hand side {a}, which is negative.
+ GotoIf(Word32Equal(r, Int32Constant(0)), &return_minuszero);
+
+ // The remainder {r} can be outside the valid Smi range on 32bit
+ // architectures, so we cannot just say SmiFromWord32(r) here.
+ var_result.Bind(ChangeInt32ToTagged(r));
+ Goto(&return_result);
+ }
+
+ Bind(&return_minuszero);
+ var_result.Bind(MinusZeroConstant());
+ Goto(&return_result);
+
+ Bind(&return_nan);
+ var_result.Bind(NanConstant());
+ Goto(&return_result);
+
+ Bind(&return_result);
+ return var_result.value();
+}
+
Node* CodeStubAssembler::WordIsSmi(Node* a) {
return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0));
}

Powered by Google App Engine
This is Rietveld 408576698