[ignition] Improve implementation of unary-minus

For the HeapNumber case, use Float64Neg directly instead of a
Float64Mul by -1.0.

For the Smi case, logic is added to handle the boundary conditions
(0 and Smi::kMinValue), and the general case is handled by a SmiSub
from 0.

Change-Id: I110916d9d1eb5d22d618fbf358d8d5b63cc71b3a
Reviewed-on: https://chromium-review.googlesource.com/663945
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47995}
This commit is contained in:
Adam Klein 2017-09-12 14:01:58 -07:00 committed by Commit Bot
parent 5077e79446
commit cf9386c7b9

View File

@ -1254,22 +1254,33 @@ IGNITION_HANDLER(Negate, InterpreterAssembler) {
BIND(&if_smi);
{
// TODO(adamk): Use something more efficient than multiplication for this
// operation, being careful to maintain float behavior regarding -0.
Node* result = SmiMul(operand, SmiConstant(-1));
var_type_feedback.Bind(SelectSmiConstant(
TaggedIsSmi(result), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber));
var_result.Bind(result);
Label if_zero(this), if_min_smi(this);
// Return -0 if operand is 0.
GotoIf(SmiEqual(operand, SmiConstant(0)), &if_zero);
// Special-case the minimum smi to avoid overflow.
GotoIf(SmiEqual(operand, SmiConstant(Smi::kMinValue)), &if_min_smi);
// Else simply subtract operand from 0.
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kSignedSmall));
var_result.Bind(SmiSub(SmiConstant(0), operand));
Goto(&end);
BIND(&if_zero);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
var_result.Bind(MinusZeroConstant());
Goto(&end);
BIND(&if_min_smi);
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
var_result.Bind(AllocateHeapNumberWithValue(
Float64Constant(-static_cast<double>(Smi::kMinValue))));
Goto(&end);
}
BIND(&if_heapnumber);
{
// TODO(adamk): Use something more efficient than multiplication for this
// operation, being careful to maintain float behavior regarding -0.
Node* result =
Float64Mul(LoadHeapNumberValue(operand), Float64Constant(-1.0));
Node* result = Float64Neg(LoadHeapNumberValue(operand));
var_type_feedback.Bind(SmiConstant(BinaryOperationFeedback::kNumber));
var_result.Bind(AllocateHeapNumberWithValue(result));
Goto(&end);