| Index: src/mips/macro-assembler-mips.cc
|
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
|
| index 1c404365195df213d96051864bae353ebdc0753d..2b84d89b5f3f1622c6c79654ebf47b30546db2b1 100644
|
| --- a/src/mips/macro-assembler-mips.cc
|
| +++ b/src/mips/macro-assembler-mips.cc
|
| @@ -4715,6 +4715,97 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
|
| bind(&done);
|
| }
|
|
|
| +void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd,
|
| + FPURegister fs,
|
| + FPURegister ft) {
|
| + Label maybe_nan, not_nan2008, 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.
|
| + mfc1(scratch1, fs);
|
| + And(scratch2, scratch1, Operand(FloatConstants::kExponentMask));
|
| + Branch(&maybe_nan, eq, scratch2, Operand(FloatConstants::kExponentMask));
|
| + // Check if second operand is a possible NaN.
|
| + mfc1(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));
|
| + Mfhc1(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);
|
| + mtc1(scratch1, fd);
|
| + bind(&done);
|
| +}
|
| +
|
| +void MacroAssembler::SubNanPreservePayloadAndSign_d(FPURegister fd,
|
| + FPURegister fs,
|
| + FPURegister ft) {
|
| + Label maybe_nan, is_nan, not_nan2008, nan2008, done;
|
| + Register scratch1 = t7;
|
| + Register scratch2 = t8;
|
| + Register scratch3 = 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.
|
| + Mfhc1(scratch1, fs);
|
| + And(scratch2, scratch1, Operand(~DoubleConstants::kSignMask));
|
| + mfc1(scratch3, fs);
|
| + Branch(&is_nan, gt, scratch2, Operand(DoubleConstants::kExponentMask));
|
| + Branch(&maybe_nan, eq, scratch2, Operand(DoubleConstants::kExponentMask));
|
| + // Check if second operand is a possible NaN.
|
| + Mfhc1(scratch1, ft);
|
| + And(scratch2, scratch1, Operand(~DoubleConstants::kSignMask));
|
| + mfc1(scratch3, ft);
|
| + Branch(&is_nan, gt, scratch2, Operand(DoubleConstants::kExponentMask));
|
| + Branch(&done, ne, scratch2, Operand(DoubleConstants::kExponentMask));
|
| +
|
| + // Check if possible NaN is actually NaN.
|
| + bind(&maybe_nan);
|
| + Branch(&done, eq, scratch3, Operand(zero_reg));
|
| + // If NaN is found, return it as qNaN with same payload.
|
| + bind(&is_nan);
|
| + // Determine the qNaN encoding for the current architecture.
|
| + LoadRoot(scratch2, Heap::kNanValueRootIndex);
|
| + ldc1(double_scratch, FieldMemOperand(scratch2, HeapNumber::kValueOffset));
|
| + Mfhc1(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);
|
| + mtc1(scratch3, fd);
|
| + Mthc1(scratch1, fd);
|
| + bind(&done);
|
| +}
|
|
|
| void MacroAssembler::CompareMapAndBranch(Register obj,
|
| Register scratch,
|
|
|