| Index: src/arm64/builtins-arm64.cc
|
| diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
|
| index 8a498533baf4a23b8534bd26fdd3012dba2816d7..091e89c261a8569f5899b7e265d04ddbb3c40f52 100644
|
| --- a/src/arm64/builtins-arm64.cc
|
| +++ b/src/arm64/builtins-arm64.cc
|
| @@ -147,18 +147,17 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
|
| // -----------------------------------
|
| ASM_LOCATION("Builtins::Generate_MathMaxMin");
|
|
|
| - Condition const cc_done = (kind == MathMaxMinKind::kMin) ? mi : gt;
|
| - Condition const cc_swap = (kind == MathMaxMinKind::kMin) ? gt : mi;
|
| Heap::RootListIndex const root_index =
|
| (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex
|
| : Heap::kMinusInfinityValueRootIndex;
|
| - DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1;
|
|
|
| // Load the accumulator with the default return value (either -Infinity or
|
| // +Infinity), with the tagged value in x1 and the double value in d1.
|
| __ LoadRoot(x1, root_index);
|
| __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset));
|
| - __ Mov(x4, x0);
|
| +
|
| + // Remember how many slots to drop (including the receiver).
|
| + __ Add(x4, x0, 1);
|
|
|
| Label done_loop, loop;
|
| __ Bind(&loop);
|
| @@ -172,11 +171,9 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
|
|
|
| // Load the double value of the parameter into d2, maybe converting the
|
| // parameter to a number first using the ToNumberStub if necessary.
|
| - Label convert, convert_smi, convert_number, done_convert;
|
| - __ Bind(&convert);
|
| + Label convert_smi, convert_number, done_convert;
|
| __ JumpIfSmi(x2, &convert_smi);
|
| - __ Ldr(x3, FieldMemOperand(x2, HeapObject::kMapOffset));
|
| - __ JumpIfRoot(x3, Heap::kHeapNumberMapRootIndex, &convert_number);
|
| + __ JumpIfHeapNumber(x2, &convert_number);
|
| {
|
| // Parameter is not a Number, use the ToNumberStub to convert it.
|
| FrameScope scope(masm, StackFrame::INTERNAL);
|
| @@ -190,54 +187,44 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
|
| __ Pop(x4, x1, x0);
|
| {
|
| // Restore the double accumulator value (d1).
|
| - Label restore_smi, done_restore;
|
| - __ JumpIfSmi(x1, &restore_smi);
|
| + Label done_restore;
|
| + __ SmiUntagToDouble(d1, x1, kSpeculativeUntag);
|
| + __ JumpIfSmi(x1, &done_restore);
|
| __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset));
|
| - __ B(&done_restore);
|
| - __ Bind(&restore_smi);
|
| - __ SmiUntagToDouble(d1, x1);
|
| - __ bind(&done_restore);
|
| + __ Bind(&done_restore);
|
| }
|
| __ SmiUntag(x4);
|
| __ SmiUntag(x0);
|
| }
|
| - __ B(&convert);
|
| + __ AssertNumber(x2);
|
| + __ JumpIfSmi(x2, &convert_smi);
|
| +
|
| __ Bind(&convert_number);
|
| __ Ldr(d2, FieldMemOperand(x2, HeapNumber::kValueOffset));
|
| __ B(&done_convert);
|
| +
|
| __ Bind(&convert_smi);
|
| __ SmiUntagToDouble(d2, x2);
|
| __ Bind(&done_convert);
|
|
|
| - // Perform the actual comparison with the accumulator value on the left hand
|
| - // side (d1) and the next parameter value on the right hand side (d2).
|
| - Label compare_nan, compare_swap;
|
| - __ Fcmp(d1, d2);
|
| - __ B(cc_done, &loop);
|
| - __ B(cc_swap, &compare_swap);
|
| - __ B(vs, &compare_nan);
|
| -
|
| - // Left and right hand side are equal, check for -0 vs. +0.
|
| - __ Fmov(x3, reg);
|
| - __ TestAndBranchIfAllClear(x3, V8_INT64_C(0x8000000000000000), &loop);
|
| -
|
| - // Result is on the right hand side.
|
| - __ Bind(&compare_swap);
|
| - __ Fmov(d1, d2);
|
| - __ Mov(x1, x2);
|
| - __ B(&loop);
|
| -
|
| - // At least one side is NaN, which means that the result will be NaN too.
|
| - __ Bind(&compare_nan);
|
| - __ LoadRoot(x1, Heap::kNanValueRootIndex);
|
| - __ Ldr(d1, FieldMemOperand(x1, HeapNumber::kValueOffset));
|
| + // We can use a single fmin/fmax for the operation itself, but we then need
|
| + // to work out which HeapNumber (or smi) the result came from.
|
| + __ Fmov(x11, d1);
|
| + if (kind == MathMaxMinKind::kMin) {
|
| + __ Fmin(d1, d1, d2);
|
| + } else {
|
| + DCHECK(kind == MathMaxMinKind::kMax);
|
| + __ Fmax(d1, d1, d2);
|
| + }
|
| + __ Fmov(x10, d1);
|
| + __ Cmp(x10, x11);
|
| + __ Csel(x1, x1, x2, eq);
|
| __ B(&loop);
|
| }
|
|
|
| __ Bind(&done_loop);
|
| __ Mov(x0, x1);
|
| __ Drop(x4);
|
| - __ Drop(1);
|
| __ Ret();
|
| }
|
|
|
|
|