Chromium Code Reviews| Index: src/code-stubs.cc |
| diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
| index f4ec29b65c98dd1c71807a0b2547b9eb3695ee1c..ca8bebe58efaab5669073ce76f9395cebd043314 100644 |
| --- a/src/code-stubs.cc |
| +++ b/src/code-stubs.cc |
| @@ -1067,6 +1067,7 @@ compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
| // Shared entry point for floating point multiplication. |
| Label do_fmul(assembler); |
| + Label end(assembler); |
|
Benedikt Meurer
2016/07/12 04:09:28
Nit: Can you rename this to return_result and add
mvstanton
2016/07/12 08:52:49
Done.
|
| Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), |
| var_rhs_float64(assembler, MachineRepresentation::kFloat64); |
| @@ -1074,7 +1075,8 @@ compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
| // We might need to loop one or two times due to ToNumber conversions. |
| Variable var_lhs(assembler, MachineRepresentation::kTagged), |
| - var_rhs(assembler, MachineRepresentation::kTagged); |
| + var_rhs(assembler, MachineRepresentation::kTagged), |
| + var_result(assembler, MachineRepresentation::kTagged); |
| Variable* loop_variables[] = {&var_lhs, &var_rhs}; |
| Label loop(assembler, 2, loop_variables); |
| var_lhs.Bind(left); |
| @@ -1098,6 +1100,44 @@ compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
| { |
| // Both {lhs} and {rhs} are Smis. Convert them to double and multiply. |
| // TODO(epertoso): use SmiMulWithOverflow once available. |
|
Benedikt Meurer
2016/07/12 04:09:28
Remove this TODO.
mvstanton
2016/07/12 08:52:49
Done.
|
| + Node* lhs32 = assembler->SmiToWord32(lhs); |
| + Node* rhs32 = assembler->SmiToWord32(rhs); |
| + Node* pair = assembler->Int32MulWithOverflow(lhs32, rhs32); |
| + |
| + Node* overflow = assembler->Projection(1, pair); |
| + |
| + // Check if the multiplication overflowed. |
| + Label if_overflow(assembler), if_notoverflow(assembler); |
|
Benedikt Meurer
2016/07/12 04:09:28
Make the if_overflow label deferred.
mvstanton
2016/07/12 08:52:49
Done.
|
| + assembler->Branch(overflow, &if_overflow, &if_notoverflow); |
| + |
| + assembler->Bind(&if_notoverflow); |
|
Benedikt Meurer
2016/07/12 04:09:28
Add braces around the actual blocks for improved r
mvstanton
2016/07/12 08:52:49
Done.
|
| + // If the answer is zero, we may need to return -0.0, depending on the |
| + // input. |
| + Label answer_zero(assembler), answer_not_zero(assembler); |
| + Node* answer = assembler->Projection(0, pair); |
| + Node* zero = assembler->Int32Constant(0); |
| + assembler->Branch(assembler->WordEqual(answer, zero), &answer_zero, |
| + &answer_not_zero); |
| + |
| + assembler->Bind(&answer_not_zero); |
| + var_result.Bind(assembler->ChangeInt32ToTagged(answer)); |
| + assembler->Goto(&end); |
| + |
| + assembler->Bind(&answer_zero); |
| + Node* or_result = assembler->Word32Or(lhs32, rhs32); |
| + Label if_should_be_negative_zero(assembler), |
| + if_should_be_zero(assembler); |
| + assembler->Branch(assembler->Int32LessThan(or_result, zero), |
| + &if_should_be_negative_zero, &if_should_be_zero); |
| + assembler->Bind(&if_should_be_negative_zero); |
| + var_result.Bind(assembler->MinusZeroConstant()); |
| + assembler->Goto(&end); |
| + |
| + assembler->Bind(&if_should_be_zero); |
| + var_result.Bind(zero); |
| + assembler->Goto(&end); |
| + |
| + assembler->Bind(&if_overflow); |
| var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); |
| var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); |
| assembler->Goto(&do_fmul); |
| @@ -1201,8 +1241,12 @@ compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
| Node* value = |
| assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
| Node* result = assembler->ChangeFloat64ToTagged(value); |
| - return result; |
| + var_result.Bind(result); |
| + assembler->Goto(&end); |
| } |
| + |
| + assembler->Bind(&end); |
| + return var_result.value(); |
| } |
| // static |