| Index: src/mips64/macro-assembler-mips64.cc
|
| diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc
|
| index 536c74f41b32741758a68397d44a32876bdcae4c..a042bfe45634cd762f59556ee5bd97cc3b499f96 100644
|
| --- a/src/mips64/macro-assembler-mips64.cc
|
| +++ b/src/mips64/macro-assembler-mips64.cc
|
| @@ -4854,6 +4854,91 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| sdc1(double_result, MemOperand(scratch1, 0));
|
| }
|
|
|
| +void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd,
|
| + FPURegister fs,
|
| + FPURegister ft) {
|
| + Label maybe_nan, nan2008, not_nan2008, done;
|
| + Register scratch1 = t8;
|
| + Register scratch2 = t9;
|
| + DoubleRegister double_scratch = f8;
|
| +
|
| + sub_s(fd, fs, ft);
|
| + // Check if the result of subtraction is NaN or infinity.
|
| + sub_s(double_scratch, fd, fd);
|
| + BranchF32(&done, nullptr, eq, double_scratch, kDoubleRegZero);
|
| +
|
| + // Check if first operand is a possible NaN.
|
| + dmfc1(scratch1, fs);
|
| + And(scratch2, scratch1, Operand(FloatConstants::kExponentMask));
|
| + Branch(&maybe_nan, eq, scratch2, Operand(FloatConstants::kExponentMask));
|
| + // Check if second operand is a possible NaN.
|
| + dmfc1(scratch1, ft);
|
| + And(scratch2, scratch1, Operand(FloatConstants::kExponentMask));
|
| + Branch(&done, ne, scratch2, Operand(FloatConstants::kExponentMask));
|
| +
|
| + // Check if possible NaN is actually NaN.
|
| + bind(&maybe_nan);
|
| + And(scratch2, scratch1, Operand(FloatConstants::kMantissaMask));
|
| + Branch(&done, eq, scratch2, Operand(zero_reg));
|
| + // If NaN is found, return it as qNaN with same payload.
|
| + // Determine the qNaN encoding for the current architecture.
|
| + LoadRoot(scratch2, Heap::kNanValueRootIndex);
|
| + ldc1(double_scratch, FieldMemOperand(scratch2, HeapNumber::kValueOffset));
|
| + dmfc1(scratch2, double_scratch);
|
| + And(scratch2, scratch2, Operand(DoubleConstants::kNanTypeMask));
|
| + // Make NaN quiet.
|
| + Branch(&nan2008, gt, scratch2, Operand(zero_reg));
|
| + And(scratch1, scratch1, Operand(~FloatConstants::kNanTypeMask));
|
| + Branch(¬_nan2008);
|
| + bind(&nan2008);
|
| + Or(scratch1, scratch1, Operand(FloatConstants::kNanTypeMask));
|
| + bind(¬_nan2008);
|
| + dmtc1(scratch1, fd);
|
| + bind(&done);
|
| +}
|
| +
|
| +void MacroAssembler::SubNanPreservePayloadAndSign_d(FPURegister fd,
|
| + FPURegister fs,
|
| + FPURegister ft) {
|
| + Label maybe_nan, nan2008, not_nan2008, done;
|
| + Register scratch1 = t8;
|
| + Register scratch2 = t9;
|
| + DoubleRegister double_scratch = f8;
|
| +
|
| + sub_d(fd, fs, ft);
|
| + // Check if the result of subtraction is NaN or infinity.
|
| + sub_d(double_scratch, fd, fd);
|
| + BranchF64(&done, nullptr, eq, double_scratch, kDoubleRegZero);
|
| +
|
| + // Check if first operand is a possible NaN.
|
| + dmfc1(scratch1, fs);
|
| + And(scratch2, scratch1, Operand(DoubleConstants::kExponentMask));
|
| + Branch(&maybe_nan, eq, scratch2, Operand(DoubleConstants::kExponentMask));
|
| + // Check if second operand is a possible NaN.
|
| + dmfc1(scratch1, ft);
|
| + And(scratch2, scratch1, Operand(DoubleConstants::kExponentMask));
|
| + Branch(&done, ne, scratch2, Operand(DoubleConstants::kExponentMask));
|
| +
|
| + // Check if possible NaN is actually NaN.
|
| + bind(&maybe_nan);
|
| + And(scratch2, scratch1, Operand(DoubleConstants::kMantissaMask));
|
| + Branch(&done, eq, scratch2, Operand(zero_reg));
|
| + // If NaN is found, return it as qNaN with same payload.
|
| + // Determine the qNaN encoding for the current architecture.
|
| + LoadRoot(scratch2, Heap::kNanValueRootIndex);
|
| + ldc1(double_scratch, FieldMemOperand(scratch2, HeapNumber::kValueOffset));
|
| + dmfc1(scratch2, double_scratch);
|
| + And(scratch2, scratch2, Operand(DoubleConstants::kNanTypeMask));
|
| + // Make NaN quiet.
|
| + Branch(&nan2008, gt, scratch2, Operand(zero_reg));
|
| + And(scratch1, scratch1, Operand(~DoubleConstants::kNanTypeMask));
|
| + Branch(¬_nan2008);
|
| + bind(&nan2008);
|
| + Or(scratch1, scratch1, Operand(DoubleConstants::kNanTypeMask));
|
| + bind(¬_nan2008);
|
| + dmtc1(scratch1, fd);
|
| + bind(&done);
|
| +}
|
|
|
| void MacroAssembler::CompareMapAndBranch(Register obj,
|
| Register scratch,
|
|
|