mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-30 13:45:27 +00:00
Bug 1287351 - IonMonkey: MIPS: Expose max and min in the MacroAssembler + move code. r=lth
--- .../jit/mips-shared/CodeGenerator-mips-shared.cpp | 87 +++------------------ .../jit/mips-shared/MacroAssembler-mips-shared.cpp | 90 ++++++++++++++++++++++ .../jit/mips-shared/MacroAssembler-mips-shared.h | 5 ++ 3 files changed, 105 insertions(+), 77 deletions(-)
This commit is contained in:
parent
b7fdb50a58
commit
dfc7553d21
@ -214,47 +214,13 @@ CodeGeneratorMIPSShared::visitMinMaxD(LMinMaxD* ins)
|
||||
{
|
||||
FloatRegister first = ToFloatRegister(ins->first());
|
||||
FloatRegister second = ToFloatRegister(ins->second());
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
|
||||
MOZ_ASSERT(first == output);
|
||||
MOZ_ASSERT(first == ToFloatRegister(ins->output()));
|
||||
|
||||
Assembler::DoubleCondition cond = ins->mir()->isMax()
|
||||
? Assembler::DoubleLessThanOrEqual
|
||||
: Assembler::DoubleGreaterThanOrEqual;
|
||||
Label nan, equal, returnSecond, done;
|
||||
|
||||
// First or second is NaN, result is NaN.
|
||||
masm.ma_bc1d(first, second, &nan, Assembler::DoubleUnordered, ShortJump);
|
||||
// Make sure we handle -0 and 0 right.
|
||||
masm.ma_bc1d(first, second, &equal, Assembler::DoubleEqual, ShortJump);
|
||||
masm.ma_bc1d(first, second, &returnSecond, cond, ShortJump);
|
||||
masm.ma_b(&done, ShortJump);
|
||||
|
||||
// Check for zero.
|
||||
masm.bind(&equal);
|
||||
masm.loadConstantDouble(0.0, ScratchDoubleReg);
|
||||
// First wasn't 0 or -0, so just return it.
|
||||
masm.ma_bc1d(first, ScratchDoubleReg, &done, Assembler::DoubleNotEqualOrUnordered, ShortJump);
|
||||
|
||||
// So now both operands are either -0 or 0.
|
||||
if (ins->mir()->isMax()) {
|
||||
// -0 + -0 = -0 and -0 + 0 = 0.
|
||||
masm.addDouble(second, first);
|
||||
} else {
|
||||
masm.negateDouble(first);
|
||||
masm.subDouble(second, first);
|
||||
masm.negateDouble(first);
|
||||
}
|
||||
masm.ma_b(&done, ShortJump);
|
||||
|
||||
masm.bind(&nan);
|
||||
masm.loadConstantDouble(GenericNaN(), output);
|
||||
masm.ma_b(&done, ShortJump);
|
||||
|
||||
masm.bind(&returnSecond);
|
||||
masm.moveDouble(second, output);
|
||||
|
||||
masm.bind(&done);
|
||||
if (ins->mir()->isMax())
|
||||
masm.maxDouble(second, first, true);
|
||||
else
|
||||
masm.minDouble(second, first, true);
|
||||
}
|
||||
|
||||
void
|
||||
@ -262,46 +228,13 @@ CodeGeneratorMIPSShared::visitMinMaxF(LMinMaxF* ins)
|
||||
{
|
||||
FloatRegister first = ToFloatRegister(ins->first());
|
||||
FloatRegister second = ToFloatRegister(ins->second());
|
||||
FloatRegister output = ToFloatRegister(ins->output());
|
||||
|
||||
MOZ_ASSERT(first == output);
|
||||
MOZ_ASSERT(first == ToFloatRegister(ins->output()));
|
||||
|
||||
Assembler::DoubleCondition cond = ins->mir()->isMax()
|
||||
? Assembler::DoubleLessThanOrEqual
|
||||
: Assembler::DoubleGreaterThanOrEqual;
|
||||
Label nan, equal, returnSecond, done;
|
||||
|
||||
// First or second is NaN, result is NaN.
|
||||
masm.ma_bc1s(first, second, &nan, Assembler::DoubleUnordered, ShortJump);
|
||||
// Make sure we handle -0 and 0 right.
|
||||
masm.ma_bc1s(first, second, &equal, Assembler::DoubleEqual, ShortJump);
|
||||
masm.ma_bc1s(first, second, &returnSecond, cond, ShortJump);
|
||||
masm.ma_b(&done, ShortJump);
|
||||
|
||||
// Check for zero.
|
||||
masm.bind(&equal);
|
||||
masm.loadConstantFloat32(0.0f, ScratchFloat32Reg);
|
||||
// First wasn't 0 or -0, so just return it.
|
||||
masm.ma_bc1s(first, ScratchFloat32Reg, &done, Assembler::DoubleNotEqualOrUnordered, ShortJump);
|
||||
|
||||
// So now both operands are either -0 or 0.
|
||||
if (ins->mir()->isMax()) {
|
||||
// -0 + -0 = -0 and -0 + 0 = 0.
|
||||
masm.as_adds(first, first, second);
|
||||
} else {
|
||||
masm.as_negs(first, first);
|
||||
masm.as_subs(first, first, second);
|
||||
masm.as_negs(first, first);
|
||||
}
|
||||
masm.ma_b(&done, ShortJump);
|
||||
|
||||
masm.bind(&nan);
|
||||
masm.loadConstantFloat32(GenericNaN(), output);
|
||||
masm.ma_b(&done, ShortJump);
|
||||
masm.bind(&returnSecond);
|
||||
masm.as_movs(output, second);
|
||||
|
||||
masm.bind(&done);
|
||||
if (ins->mir()->isMax())
|
||||
masm.maxFloat32(second, first, true);
|
||||
else
|
||||
masm.minFloat32(second, first, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -815,6 +815,96 @@ MacroAssemblerMIPSShared::ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label* l
|
||||
asMasm().branchWithCode(getBranchCode(testKind, fcc), label, jumpKind);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSShared::minMaxDouble(FloatRegister srcDest, FloatRegister second,
|
||||
bool handleNaN, bool isMax)
|
||||
{
|
||||
FloatRegister first = srcDest;
|
||||
|
||||
Assembler::DoubleCondition cond = isMax
|
||||
? Assembler::DoubleLessThanOrEqual
|
||||
: Assembler::DoubleGreaterThanOrEqual;
|
||||
Label nan, equal, returnSecond, done;
|
||||
|
||||
// First or second is NaN, result is NaN.
|
||||
ma_bc1d(first, second, &nan, Assembler::DoubleUnordered, ShortJump);
|
||||
// Make sure we handle -0 and 0 right.
|
||||
ma_bc1d(first, second, &equal, Assembler::DoubleEqual, ShortJump);
|
||||
ma_bc1d(first, second, &returnSecond, cond, ShortJump);
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
// Check for zero.
|
||||
bind(&equal);
|
||||
asMasm().loadConstantDouble(0.0, ScratchDoubleReg);
|
||||
// First wasn't 0 or -0, so just return it.
|
||||
ma_bc1d(first, ScratchDoubleReg, &done, Assembler::DoubleNotEqualOrUnordered, ShortJump);
|
||||
|
||||
// So now both operands are either -0 or 0.
|
||||
if (isMax) {
|
||||
// -0 + -0 = -0 and -0 + 0 = 0.
|
||||
as_addd(first, first, second);
|
||||
} else {
|
||||
as_negd(first, first);
|
||||
as_subd(first, first, second);
|
||||
as_negd(first, first);
|
||||
}
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
bind(&nan);
|
||||
asMasm().loadConstantDouble(JS::GenericNaN(), srcDest);
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
bind(&returnSecond);
|
||||
as_movd(srcDest, second);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSShared::minMaxFloat32(FloatRegister srcDest, FloatRegister second,
|
||||
bool handleNaN, bool isMax)
|
||||
{
|
||||
FloatRegister first = srcDest;
|
||||
|
||||
Assembler::DoubleCondition cond = isMax
|
||||
? Assembler::DoubleLessThanOrEqual
|
||||
: Assembler::DoubleGreaterThanOrEqual;
|
||||
Label nan, equal, returnSecond, done;
|
||||
|
||||
// First or second is NaN, result is NaN.
|
||||
ma_bc1s(first, second, &nan, Assembler::DoubleUnordered, ShortJump);
|
||||
// Make sure we handle -0 and 0 right.
|
||||
ma_bc1s(first, second, &equal, Assembler::DoubleEqual, ShortJump);
|
||||
ma_bc1s(first, second, &returnSecond, cond, ShortJump);
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
// Check for zero.
|
||||
bind(&equal);
|
||||
asMasm().loadConstantFloat32(0.0f, ScratchFloat32Reg);
|
||||
// First wasn't 0 or -0, so just return it.
|
||||
ma_bc1s(first, ScratchFloat32Reg, &done, Assembler::DoubleNotEqualOrUnordered, ShortJump);
|
||||
|
||||
// So now both operands are either -0 or 0.
|
||||
if (isMax) {
|
||||
// -0 + -0 = -0 and -0 + 0 = 0.
|
||||
as_adds(first, first, second);
|
||||
} else {
|
||||
as_negs(first, first);
|
||||
as_subs(first, first, second);
|
||||
as_negs(first, first);
|
||||
}
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
bind(&nan);
|
||||
asMasm().loadConstantFloat32(JS::GenericNaN(), srcDest);
|
||||
ma_b(&done, ShortJump);
|
||||
|
||||
bind(&returnSecond);
|
||||
as_movs(srcDest, second);
|
||||
|
||||
bind(&done);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSShared::ma_call(ImmPtr dest)
|
||||
{
|
||||
|
@ -190,6 +190,11 @@ class MacroAssemblerMIPSShared : public Assembler
|
||||
as_mfc1(dest, src);
|
||||
}
|
||||
|
||||
// Evaluate srcDest = minmax<isMax>{Float32,Double}(srcDest, other).
|
||||
// Handle NaN specially if handleNaN is true.
|
||||
void minMaxDouble(FloatRegister srcDest, FloatRegister other, bool handleNaN, bool isMax);
|
||||
void minMaxFloat32(FloatRegister srcDest, FloatRegister other, bool handleNaN, bool isMax);
|
||||
|
||||
private:
|
||||
void atomicEffectOpMIPSr2(int nbytes, AtomicOp op, const Register& value, const Register& addr,
|
||||
Register flagTemp, Register valueTemp, Register offsetTemp, Register maskTemp);
|
||||
|
Loading…
Reference in New Issue
Block a user