| Index: src/code-stub-assembler.cc
|
| diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
|
| index f403a4aedb2d4fab545b7cd8d2990415dc9d0fa5..b752e13c67842260fe9efd65467cb162b8f01145 100644
|
| --- a/src/code-stub-assembler.cc
|
| +++ b/src/code-stub-assembler.cc
|
| @@ -401,6 +401,67 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
|
| return var_result.value();
|
| }
|
|
|
| +Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
|
| + Variable var_result(this, MachineRepresentation::kTagged);
|
| + Variable var_lhs_float64(this, MachineRepresentation::kFloat64),
|
| + var_rhs_float64(this, MachineRepresentation::kFloat64);
|
| + Label return_result(this, &var_result);
|
| +
|
| + // Both {a} and {b} are Smis. Convert them to integers and multiply.
|
| + Node* lhs32 = SmiToWord32(a);
|
| + Node* rhs32 = SmiToWord32(b);
|
| + Node* pair = Int32MulWithOverflow(lhs32, rhs32);
|
| +
|
| + Node* overflow = Projection(1, pair);
|
| +
|
| + // Check if the multiplication overflowed.
|
| + Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
|
| + Branch(overflow, &if_overflow, &if_notoverflow);
|
| + Bind(&if_notoverflow);
|
| + {
|
| + // If the answer is zero, we may need to return -0.0, depending on the
|
| + // input.
|
| + Label answer_zero(this), answer_not_zero(this);
|
| + Node* answer = Projection(0, pair);
|
| + Node* zero = Int32Constant(0);
|
| + Branch(WordEqual(answer, zero), &answer_zero, &answer_not_zero);
|
| + Bind(&answer_not_zero);
|
| + {
|
| + var_result.Bind(ChangeInt32ToTagged(answer));
|
| + Goto(&return_result);
|
| + }
|
| + Bind(&answer_zero);
|
| + {
|
| + Node* or_result = Word32Or(lhs32, rhs32);
|
| + Label if_should_be_negative_zero(this), if_should_be_zero(this);
|
| + Branch(Int32LessThan(or_result, zero), &if_should_be_negative_zero,
|
| + &if_should_be_zero);
|
| + Bind(&if_should_be_negative_zero);
|
| + {
|
| + var_result.Bind(MinusZeroConstant());
|
| + Goto(&return_result);
|
| + }
|
| + Bind(&if_should_be_zero);
|
| + {
|
| + var_result.Bind(zero);
|
| + Goto(&return_result);
|
| + }
|
| + }
|
| + }
|
| + Bind(&if_overflow);
|
| + {
|
| + var_lhs_float64.Bind(SmiToFloat64(a));
|
| + var_rhs_float64.Bind(SmiToFloat64(b));
|
| + Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
|
| + Node* result = ChangeFloat64ToTagged(value);
|
| + var_result.Bind(result);
|
| + Goto(&return_result);
|
| + }
|
| +
|
| + Bind(&return_result);
|
| + return var_result.value();
|
| +}
|
| +
|
| Node* CodeStubAssembler::WordIsSmi(Node* a) {
|
| return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask)), IntPtrConstant(0));
|
| }
|
|
|