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:
Heiher 2016-07-19 23:43:39 +08:00
parent b7fdb50a58
commit dfc7553d21
3 changed files with 105 additions and 77 deletions

View File

@ -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

View File

@ -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)
{

View File

@ -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);