Chromium Code Reviews| 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)); |
| } |