| Index: src/mips/macro-assembler-mips.cc | 
| diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc | 
| index a58084cfbef4f76a98e8ce55691b7ba81ba77175..fc6d5174535c96528902d5a1cf77b918c60f9a71 100644 | 
| --- a/src/mips/macro-assembler-mips.cc | 
| +++ b/src/mips/macro-assembler-mips.cc | 
| @@ -18,6 +18,20 @@ | 
| namespace v8 { | 
| namespace internal { | 
|  | 
| +// Floating point constants. | 
| +const uint32_t kDoubleSignMask = HeapNumber::kSignMask; | 
| +const uint32_t kDoubleExponentShift = HeapNumber::kExponentShift; | 
| +const uint32_t kDoubleNaNShift = kDoubleExponentShift - 1; | 
| +const uint32_t kDoubleNaNMask = | 
| +    kDoubleSignMask | HeapNumber::kExponentMask | (1 << kDoubleNaNShift); | 
| + | 
| +const uint32_t kSingleSignMask = kBinary32SignMask; | 
| +const uint32_t kSingleExponentMask = kBinary32ExponentMask; | 
| +const uint32_t kSingleExponentShift = kBinary32ExponentShift; | 
| +const uint32_t kSingleNaNShift = kSingleExponentShift - 1; | 
| +const uint32_t kSingleNaNMask = | 
| +    kSingleSignMask | kSingleExponentMask | (1 << kSingleNaNShift); | 
| + | 
| MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size, | 
| CodeObjectRequired create_code_object) | 
| : Assembler(arg_isolate, buffer, size), | 
| @@ -4715,6 +4729,74 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, | 
| bind(&done); | 
| } | 
|  | 
| +void MacroAssembler::SubNanPreservePayloadAndSign_s(FloatRegister fd, | 
| +                                                    FloatRegister fs, | 
| +                                                    FloatRegister ft) { | 
| +  FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; | 
| +  Label check_nan, save_payload, done; | 
| +  Register scratch1 = t8; | 
| +  Register scratch2 = t9; | 
| + | 
| +  sub_s(dest, fs, ft); | 
| +  // Check if the result of subtraction is NaN. | 
| +  BranchF32(nullptr, &check_nan, eq, fs, ft); | 
| +  Branch(USE_DELAY_SLOT, &done); | 
| +  dest.is(fd) ? nop() : mov_s(fd, dest); | 
| + | 
| +  bind(&check_nan); | 
| +  // Check if first operand is a NaN. | 
| +  mfc1(scratch1, fs); | 
| +  BranchF32(nullptr, &save_payload, eq, fs, fs); | 
| +  // Second operand must be a NaN. | 
| +  mfc1(scratch1, ft); | 
| + | 
| +  bind(&save_payload); | 
| +  // Reserve payload. | 
| +  And(scratch1, scratch1, | 
| +      Operand(kSingleSignMask | ((1 << kSingleNaNShift) - 1))); | 
| +  mfc1(scratch2, dest); | 
| +  And(scratch2, scratch2, Operand(kSingleNaNMask)); | 
| +  Or(scratch2, scratch2, scratch1); | 
| +  mtc1(scratch2, fd); | 
| + | 
| +  bind(&done); | 
| +} | 
| + | 
| +void MacroAssembler::SubNanPreservePayloadAndSign_d(DoubleRegister fd, | 
| +                                                    DoubleRegister fs, | 
| +                                                    DoubleRegister ft) { | 
| +  FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; | 
| +  Label check_nan, save_payload, done; | 
| +  Register scratch1 = t8; | 
| +  Register scratch2 = t9; | 
| + | 
| +  sub_d(dest, fs, ft); | 
| +  // Check if the result of subtraction is NaN. | 
| +  BranchF64(nullptr, &check_nan, eq, fs, ft); | 
| +  Branch(USE_DELAY_SLOT, &done); | 
| +  dest.is(fd) ? nop() : mov_d(fd, dest); | 
| + | 
| +  bind(&check_nan); | 
| +  // Check if first operand is a NaN. | 
| +  Mfhc1(scratch1, fs); | 
| +  mov_s(dest, fs); | 
| +  BranchF64(nullptr, &save_payload, eq, fs, fs); | 
| +  // Second operand must be a NaN. | 
| +  Mfhc1(scratch1, ft); | 
| +  mov_s(dest, ft); | 
| + | 
| +  bind(&save_payload); | 
| +  // Reserve payload. | 
| +  And(scratch1, scratch1, | 
| +      Operand(kDoubleSignMask | ((1 << kDoubleNaNShift) - 1))); | 
| +  Mfhc1(scratch2, dest); | 
| +  And(scratch2, scratch2, Operand(kDoubleNaNMask)); | 
| +  Or(scratch2, scratch2, scratch1); | 
| +  Move_s(fd, dest); | 
| +  Mthc1(scratch2, fd); | 
| + | 
| +  bind(&done); | 
| +} | 
|  | 
| void MacroAssembler::CompareMapAndBranch(Register obj, | 
| Register scratch, | 
|  |