tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 5dbd7fb9849c51326867794fcf3bfd0bc55b8640
parent dae7db185717d82df2e2bc88f51516a521785bc3
Author: André Bargull <andre.bargull@gmail.com>
Date:   Fri, 17 Oct 2025 11:25:45 +0000

Bug 1994190 - Part 4: Simplify rounding instructions for mips64. r=spidermonkey-reviewers,iain

Differential Revision: https://phabricator.services.mozilla.com/D268549

Diffstat:
Mjs/src/jit/mips-shared/Assembler-mips-shared.cpp | 42++++++++++++++++++++++++++++++++++++++++++
Mjs/src/jit/mips-shared/Assembler-mips-shared.h | 6++++++
Mjs/src/jit/mips-shared/MacroAssembler-mips-shared.cpp | 403+++++++++++++++++++++++++++++++++++++------------------------------------------
Mjs/src/jit/mips-shared/MacroAssembler-mips-shared.h | 5-----
4 files changed, 236 insertions(+), 220 deletions(-)

diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.cpp b/js/src/jit/mips-shared/Assembler-mips-shared.cpp @@ -1350,6 +1350,13 @@ BufferOffset AssemblerMIPSShared::as_ceilws(FloatRegister fd, InstReg(op_cop1, rs_s, zero, fs, fd, ff_ceil_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_ceills(FloatRegister fd, + FloatRegister fs) { + spew("ceil.l.s%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_s, zero, fs, fd, ff_ceil_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_floorws(FloatRegister fd, FloatRegister fs) { spew("floor.w.s%3s,%3s", fd.name(), fs.name()); @@ -1357,6 +1364,13 @@ BufferOffset AssemblerMIPSShared::as_floorws(FloatRegister fd, InstReg(op_cop1, rs_s, zero, fs, fd, ff_floor_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_floorls(FloatRegister fd, + FloatRegister fs) { + spew("floor.l.s%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_s, zero, fs, fd, ff_floor_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_roundws(FloatRegister fd, FloatRegister fs) { spew("round.w.s%3s,%3s", fd.name(), fs.name()); @@ -1364,6 +1378,13 @@ BufferOffset AssemblerMIPSShared::as_roundws(FloatRegister fd, InstReg(op_cop1, rs_s, zero, fs, fd, ff_round_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_roundls(FloatRegister fd, + FloatRegister fs) { + spew("round.l.s%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_s, zero, fs, fd, ff_round_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_truncws(FloatRegister fd, FloatRegister fs) { spew("trunc.w.s%3s,%3s", fd.name(), fs.name()); @@ -1386,6 +1407,13 @@ BufferOffset AssemblerMIPSShared::as_ceilwd(FloatRegister fd, InstReg(op_cop1, rs_d, zero, fs, fd, ff_ceil_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_ceilld(FloatRegister fd, + FloatRegister fs) { + spew("ceil.l.d%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_d, zero, fs, fd, ff_ceil_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_floorwd(FloatRegister fd, FloatRegister fs) { spew("floor.w.d%3s,%3s", fd.name(), fs.name()); @@ -1393,6 +1421,13 @@ BufferOffset AssemblerMIPSShared::as_floorwd(FloatRegister fd, InstReg(op_cop1, rs_d, zero, fs, fd, ff_floor_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_floorld(FloatRegister fd, + FloatRegister fs) { + spew("floor.l.d%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_d, zero, fs, fd, ff_floor_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_roundwd(FloatRegister fd, FloatRegister fs) { spew("round.w.d%3s,%3s", fd.name(), fs.name()); @@ -1400,6 +1435,13 @@ BufferOffset AssemblerMIPSShared::as_roundwd(FloatRegister fd, InstReg(op_cop1, rs_d, zero, fs, fd, ff_round_w_fmt).encode()); } +BufferOffset AssemblerMIPSShared::as_roundld(FloatRegister fd, + FloatRegister fs) { + spew("round.l.d%3s,%3s", fd.name(), fs.name()); + return writeInst( + InstReg(op_cop1, rs_d, zero, fs, fd, ff_round_l_fmt).encode()); +} + BufferOffset AssemblerMIPSShared::as_truncwd(FloatRegister fd, FloatRegister fs) { spew("trunc.w.d%3s,%3s", fd.name(), fs.name()); diff --git a/js/src/jit/mips-shared/Assembler-mips-shared.h b/js/src/jit/mips-shared/Assembler-mips-shared.h @@ -1146,14 +1146,20 @@ class AssemblerMIPSShared : public AssemblerShared { public: // FP convert instructions BufferOffset as_ceilws(FloatRegister fd, FloatRegister fs); + BufferOffset as_ceills(FloatRegister fd, FloatRegister fs); BufferOffset as_floorws(FloatRegister fd, FloatRegister fs); + BufferOffset as_floorls(FloatRegister fd, FloatRegister fs); BufferOffset as_roundws(FloatRegister fd, FloatRegister fs); + BufferOffset as_roundls(FloatRegister fd, FloatRegister fs); BufferOffset as_truncws(FloatRegister fd, FloatRegister fs); BufferOffset as_truncls(FloatRegister fd, FloatRegister fs); BufferOffset as_ceilwd(FloatRegister fd, FloatRegister fs); + BufferOffset as_ceilld(FloatRegister fd, FloatRegister fs); BufferOffset as_floorwd(FloatRegister fd, FloatRegister fs); + BufferOffset as_floorld(FloatRegister fd, FloatRegister fs); BufferOffset as_roundwd(FloatRegister fd, FloatRegister fs); + BufferOffset as_roundld(FloatRegister fd, FloatRegister fs); BufferOffset as_truncwd(FloatRegister fd, FloatRegister fs); BufferOffset as_truncld(FloatRegister fd, FloatRegister fs); diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -3163,301 +3163,274 @@ void MacroAssembler::speculationBarrier() { MOZ_CRASH(); } void MacroAssembler::floorFloat32ToInt32(FloatRegister src, Register dest, Label* fail) { ScratchFloat32Scope fscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - - Label skipCheck, done; - - // If Nan, 0 or -0 check for bailout - loadConstantFloat32(0.0f, fscratch); - ma_bc1s(src, fscratch, &skipCheck, Assembler::DoubleNotEqual, ShortJump); - - // If binary value is not zero, it is NaN or -0, so we bail. - moveFromDoubleLo(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&done, ShortJump); + // Round toward negative infinity. + as_floorls(fscratch, src); + moveFromDouble(fscratch, dest); - bind(&skipCheck); - as_floorws(fscratch, src); - moveFromDoubleLo(fscratch, dest); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } - bind(&done); + // We have to check for -0 and NaN when the result is zero. + Label notZero; + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If any of the two most significant bits is set, |src| is -0 or NaN. + moveFromFloat32(src, dest); + ma_srl(dest, dest, Imm32(30)); + branch32(Assembler::NotEqual, dest, zero, fail); + } + bind(&notZero); } void MacroAssembler::floorDoubleToInt32(FloatRegister src, Register dest, Label* fail) { ScratchDoubleScope dscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - - Label skipCheck, done; - - // If Nan, 0 or -0 check for bailout - loadConstantDouble(0.0, dscratch); - ma_bc1d(src, dscratch, &skipCheck, Assembler::DoubleNotEqual, ShortJump); - // If high part is not zero, it is NaN or -0, so we bail. - moveFromDoubleHi(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); + // Round toward negative infinity. + as_floorld(dscratch, src); + moveFromDouble(dscratch, dest); - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&done, ShortJump); - - bind(&skipCheck); - as_floorwd(dscratch, src); - moveFromDoubleLo(dscratch, dest); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } - bind(&done); + // We have to check for -0 and NaN when the result is zero. + Label notZero; + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If any of the two most significant bits is set, |src| is -0 or NaN. + moveFromDouble(src, dest); + ma_dsrl(dest, dest, Imm32(62)); + branchPtr(Assembler::NotEqual, dest, zero, fail); + } + bind(&notZero); } void MacroAssembler::ceilFloat32ToInt32(FloatRegister src, Register dest, Label* fail) { ScratchFloat32Scope fscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - - Label performCeil, done; - - // If x < -1 or x > 0 then perform ceil. - loadConstantFloat32(0.0f, fscratch); - branchFloat(Assembler::DoubleGreaterThan, src, fscratch, &performCeil); - loadConstantFloat32(-1.0f, fscratch); - branchFloat(Assembler::DoubleLessThanOrEqual, src, fscratch, &performCeil); - // If binary value is not zero, the input was not 0, so we bail. - moveFromFloat32(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); + // Round toward positive infinity. + as_ceills(fscratch, src); + moveFromDouble(fscratch, dest); - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&done, ShortJump); - - bind(&performCeil); - as_ceilws(fscratch, src); - moveFromFloat32(fscratch, dest); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } - bind(&done); + // We have to check for (-1, -0] and NaN when the result is zero. + Label notZero; + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If binary value is not zero, the input was not 0, so we bail. + moveFromFloat32(src, dest); + branch32(Assembler::NotEqual, dest, zero, fail); + } + bind(&notZero); } void MacroAssembler::ceilDoubleToInt32(FloatRegister src, Register dest, Label* fail) { ScratchDoubleScope dscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - - Label performCeil, done; - // If x < -1 or x > 0 then perform ceil. - loadConstantDouble(0, dscratch); - branchDouble(Assembler::DoubleGreaterThan, src, dscratch, &performCeil); - loadConstantDouble(-1, dscratch); - branchDouble(Assembler::DoubleLessThanOrEqual, src, dscratch, &performCeil); + // Round toward positive infinity. + as_ceilld(dscratch, src); + moveFromDouble(dscratch, dest); - // If high part is not zero, the input was not 0, so we bail. - moveFromDoubleHi(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); - - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&done, ShortJump); - - bind(&performCeil); - as_ceilwd(dscratch, src); - moveFromDoubleLo(dscratch, dest); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } - bind(&done); + // We have to check for (-1, -0] and NaN when the result is zero. + Label notZero; + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If binary value is not zero, the input was not 0, so we bail. + moveFromDouble(src, dest); + branchPtr(Assembler::NotEqual, dest, zero, fail); + } + bind(&notZero); } void MacroAssembler::roundFloat32ToInt32(FloatRegister src, Register dest, FloatRegister temp, Label* fail) { ScratchFloat32Scope fscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - Label negative, end, skipCheck; + Label negative, end, performRound; - // Load biggest number less than 0.5 in the temp register. - loadConstantFloat32(GetBiggestNumberLessThan(0.5f), temp); - - // Branch to a slow path for negative inputs. Doesn't catch NaN or -0. + // Branch for negative inputs. Doesn't catch NaN or -0. loadConstantFloat32(0.0f, fscratch); ma_bc1s(src, fscratch, &negative, Assembler::DoubleLessThan, ShortJump); - // If Nan, 0 or -0 check for bailout - ma_bc1s(src, fscratch, &skipCheck, Assembler::DoubleNotEqual, ShortJump); - - // If binary value is not zero, it is NaN or -0, so we bail. - moveFromFloat32(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); - - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&end, ShortJump); - - bind(&skipCheck); - as_adds(fscratch, src, temp); - as_floorws(fscratch, fscratch); - - moveFromFloat32(fscratch, dest); - - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); - - jump(&end); + // If non-negative check for bailout. + ma_bc1s(src, fscratch, &performRound, Assembler::DoubleNotEqual, ShortJump); + { + // If binary value is not zero, it is NaN or -0, so we bail. + moveFromFloat32(src, dest); + branch32(Assembler::NotEqual, dest, zero, fail); + ma_b(&end, ShortJump); + } // Input is negative, but isn't -0. bind(&negative); + { + // Inputs in [-0.5, 0) are rounded to -0. Fail. + loadConstantFloat32(-0.5f, fscratch); + branchFloat(Assembler::DoubleGreaterThanOrEqual, src, fscratch, fail); + } - // Inputs in ]-0.5; 0] need to be added 0.5, other negative inputs need to - // be added the biggest double less than 0.5. - Label loadJoin; - loadConstantFloat32(-0.5f, fscratch); - branchFloat(Assembler::DoubleLessThan, src, fscratch, &loadJoin); - loadConstantFloat32(0.5f, temp); - bind(&loadJoin); - - as_adds(temp, src, temp); + bind(&performRound); + { + // Load biggest number less than 0.5 in the temp register. + loadConstantFloat32(GetBiggestNumberLessThan(0.5f), temp); - // If input + 0.5 >= 0, input is a negative number >= -0.5 and the - // result is -0. - branchFloat(Assembler::DoubleGreaterThanOrEqual, temp, fscratch, fail); + // Other inputs need the biggest float less than 0.5 added. + as_adds(fscratch, src, temp); - // Truncate and round toward zero. - // This is off-by-one for everything but integer-valued inputs. - as_floorws(fscratch, temp); - moveFromFloat32(fscratch, dest); + // Round toward negative infinity. + as_floorls(fscratch, fscratch); + moveFromDouble(fscratch, dest); - // Need to test for both INT_MIN and INT_MAX: - // If NAN2008=0, out-of-range (negative) values return INT_MAX. - // If NAN2008=1, out-of-range negative values return INT_MIN. - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } + } bind(&end); } void MacroAssembler::roundDoubleToInt32(FloatRegister src, Register dest, FloatRegister temp, Label* fail) { ScratchDoubleScope dscratch(*this); - UseScratchRegisterScope temps(*this); - Register scratch2 = temps.Acquire(); - Label negative, end, skipCheck; + Label negative, end, performRound; - // Load biggest number less than 0.5 in the temp register. - loadConstantDouble(GetBiggestNumberLessThan(0.5), temp); - - // Branch to a slow path for negative inputs. Doesn't catch NaN or -0. + // Branch for negative inputs. Doesn't catch NaN or -0. loadConstantDouble(0.0, dscratch); ma_bc1d(src, dscratch, &negative, Assembler::DoubleLessThan, ShortJump); - // If Nan, 0 or -0 check for bailout - ma_bc1d(src, dscratch, &skipCheck, Assembler::DoubleNotEqual, ShortJump); - - // If high part is not zero, it is NaN or -0, so we bail. - moveFromDoubleHi(src, scratch2); - branch32(Assembler::NotEqual, scratch2, Imm32(0), fail); - - // Input was zero, so return zero. - move32(Imm32(0), dest); - ma_b(&end, ShortJump); - - bind(&skipCheck); - as_addd(dscratch, src, temp); - as_floorwd(dscratch, dscratch); - - moveFromDoubleLo(dscratch, dest); - - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); - - jump(&end); + // If non-negative check for bailout. + ma_bc1d(src, dscratch, &performRound, Assembler::DoubleNotEqual, ShortJump); + { + // If binary value is not zero, it is NaN or -0, so we bail. + moveFromDouble(src, dest); + branchPtr(Assembler::NotEqual, dest, zero, fail); + ma_b(&end, ShortJump); + } // Input is negative, but isn't -0. bind(&negative); + { + // Inputs in [-0.5, 0) are rounded to -0. Fail. + loadConstantDouble(-0.5, dscratch); + branchDouble(Assembler::DoubleGreaterThanOrEqual, src, dscratch, fail); + } - // Inputs in ]-0.5; 0] need to be added 0.5, other negative inputs need to - // be added the biggest double less than 0.5. - Label loadJoin; - loadConstantDouble(-0.5, dscratch); - branchDouble(Assembler::DoubleLessThan, src, dscratch, &loadJoin); - loadConstantDouble(0.5, temp); - bind(&loadJoin); - - addDouble(src, temp); + bind(&performRound); + { + // Load biggest number less than 0.5 in the temp register. + loadConstantDouble(GetBiggestNumberLessThan(0.5), temp); - // If input + 0.5 >= 0, input is a negative number >= -0.5 and the - // result is -0. - branchDouble(Assembler::DoubleGreaterThanOrEqual, temp, dscratch, fail); + // Other inputs need the biggest double less than 0.5 added. + as_addd(dscratch, src, temp); - // Truncate and round toward zero. - // This is off-by-one for everything but integer-valued inputs. - as_floorwd(dscratch, temp); - moveFromDoubleLo(dscratch, dest); + // Round toward negative infinity. + as_floorld(dscratch, dscratch); + moveFromDouble(dscratch, dest); - // Need to test for both INT_MIN and INT_MAX: - // If NAN2008=0, out-of-range (negative) values return INT_MAX. - // If NAN2008=1, out-of-range negative values return INT_MIN. - branch32(Assembler::Equal, dest, Imm32(INT_MIN), fail); - branch32(Assembler::Equal, dest, Imm32(INT_MAX), fail); + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } + } bind(&end); } void MacroAssembler::truncFloat32ToInt32(FloatRegister src, Register dest, Label* fail) { - UseScratchRegisterScope temps(*this); - Register scratch = temps.Acquire(); + ScratchFloat32Scope fscratch(*this); + + // Round toward zero. + as_truncls(fscratch, src); + moveFromDouble(fscratch, dest); + + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); + + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } + + // We have to check for (-1, -0] and NaN when the result is zero. Label notZero; - // Perform trunc.w.s - as_truncws(ScratchFloat32Reg, src); - // Bail if NaN, Infinity, or int32 overflow. - as_cfc1(scratch, Assembler::FCSR); - ma_ext(scratch, scratch, Assembler::CauseV, 1); - branch32(Assembler::NotEqual, scratch, Imm32(0), fail); - - moveFromFloat32(ScratchFloat32Reg, dest); - ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump); - moveFromFloat32(src, scratch); - // Check if src is in ]-1; -0] range by checking the sign bit. - as_slt(scratch, scratch, zero); - branch32(Assembler::NotEqual, scratch, Imm32(0), fail); + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If any of the two most significant bits is set, |src| is negative or NaN. + moveFromFloat32(src, dest); + ma_srl(dest, dest, Imm32(30)); + branch32(Assembler::NotEqual, dest, zero, fail); + } bind(&notZero); } void MacroAssembler::truncDoubleToInt32(FloatRegister src, Register dest, Label* fail) { - UseScratchRegisterScope temps(*this); - Register scratch = temps.Acquire(); + ScratchDoubleScope dscratch(*this); + + // Round toward zero. + as_truncld(dscratch, src); + moveFromDouble(dscratch, dest); + + // Sign extend lower 32 bits to test if the result isn't an Int32. + { + UseScratchRegisterScope temps(*this); + Register scratch = temps.Acquire(); + + move32SignExtendToPtr(dest, scratch); + branchPtr(Assembler::NotEqual, dest, scratch, fail); + } + + // We have to check for (-1, -0] and NaN when the result is zero. Label notZero; - // Perform trunc.w.d - as_truncwd(ScratchFloat32Reg, src); - // Bail if NaN, Infinity, or int32 overflow. - as_cfc1(scratch, Assembler::FCSR); - ma_ext(scratch, scratch, Assembler::CauseV, 1); - branch32(Assembler::NotEqual, scratch, Imm32(0), fail); - - // Skip the negative zero check if nonzero - moveFromFloat32(ScratchFloat32Reg, dest); - ma_b(dest, Imm32(0), &notZero, Assembler::NotEqual, ShortJump); - moveFromDoubleHi(src, scratch); - // Check if src is in ]-1; -0] range by checking the sign bit. - as_slt(scratch, scratch, zero); - branch32(Assembler::NotEqual, scratch, Imm32(0), fail); + ma_b(dest, zero, &notZero, Assembler::NotEqual, ShortJump); + { + // If any of the two most significant bits is set, |src| is negative or NaN. + moveFromDouble(src, dest); + ma_dsrl(dest, dest, Imm32(62)); + branchPtr(Assembler::NotEqual, dest, zero, fail); + } bind(&notZero); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared.h @@ -206,11 +206,6 @@ class MacroAssemblerMIPSShared : public Assembler { void ma_cmp_set_float32(Register dst, FloatRegister lhs, FloatRegister rhs, DoubleCondition c); - void moveToDoubleLo(Register src, FloatRegister dest) { as_mtc1(src, dest); } - void moveFromDoubleLo(FloatRegister src, Register dest) { - as_mfc1(dest, src); - } - void moveToFloat32(Register src, FloatRegister dest) { as_mtc1(src, dest); } void moveFromFloat32(FloatRegister src, Register dest) { as_mfc1(dest, src); }