Bug 1073016 - Optimize LRound and LRoundF on x86/x64. r=nbp

This commit is contained in:
Mukilan Thiyagarajan 2014-10-02 17:21:39 +02:00
Родитель f66c67aff6
Коммит b1ad734388
3 изменённых файлов: 47 добавлений и 26 удалений

Просмотреть файл

@ -1903,18 +1903,13 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
FloatRegister scratch = ScratchDoubleReg;
Register output = ToRegister(lir->output());
Label negative, end, bailout;
Label negativeOrZero, negative, end, bailout;
// Branch to a slow path for negative inputs. Doesn't catch NaN or -0.
// Branch to a slow path for non-positive inputs. Doesn't catch NaN.
masm.xorpd(scratch, scratch);
masm.branchDouble(Assembler::DoubleLessThan, input, scratch, &negative);
masm.branchDouble(Assembler::DoubleLessThanOrEqual, input, scratch, &negativeOrZero);
// Bail on negative-zero.
masm.branchNegativeZero(input, output, &bailout);
if (!bailoutFrom(&bailout, lir->snapshot()))
return false;
// Input is non-negative. Add the biggest double less than 0.5 and
// Input is positive. Add the biggest double less than 0.5 and
// truncate, rounding down (because if the input is the biggest double less
// than 0.5, adding 0.5 would undesirably round up to 1). Note that we have
// to add the input to the temp register because we're not allowed to
@ -1926,7 +1921,21 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
masm.jump(&end);
// Input is negative, but isn't -0.
// Input is negative, +0 or -0.
masm.bind(&negativeOrZero);
// Branch on negative input.
masm.j(Assembler::NotEqual, &negative);
// Bail on negative-zero.
masm.branchNegativeZero(input, output, &bailout, /* maybeNonZero = */ false);
if (!bailoutFrom(&bailout, lir->snapshot()))
return false;
// Input is +0
masm.xor32(output, output);
masm.jump(&end);
// Input is negative.
masm.bind(&negative);
masm.loadConstantDouble(0.5, temp);
@ -1984,16 +1993,11 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir)
FloatRegister scratch = ScratchFloat32Reg;
Register output = ToRegister(lir->output());
Label negative, end, bailout;
Label negativeOrZero, negative, end, bailout;
// Branch to a slow path for negative inputs. Doesn't catch NaN or -0.
// Branch to a slow path for non-positive inputs. Doesn't catch NaN.
masm.xorps(scratch, scratch);
masm.branchFloat(Assembler::DoubleLessThan, input, scratch, &negative);
// Bail on negative-zero.
masm.branchNegativeZeroFloat32(input, output, &bailout);
if (!bailoutFrom(&bailout, lir->snapshot()))
return false;
masm.branchFloat(Assembler::DoubleLessThanOrEqual, input, scratch, &negativeOrZero);
// Input is non-negative. Add the biggest float less than 0.5 and truncate,
// rounding down (because if the input is the biggest float less than 0.5,
@ -2008,7 +2012,21 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir)
masm.jump(&end);
// Input is negative, but isn't -0.
// Input is negative, +0 or -0.
masm.bind(&negativeOrZero);
// Branch on negative input.
masm.j(Assembler::NotEqual, &negative);
// Bail on negative-zero.
masm.branchNegativeZeroFloat32(input, output, &bailout);
if (!bailoutFrom(&bailout, lir->snapshot()))
return false;
// Input is +0.
masm.xor32(output, output);
masm.jump(&end);
// Input is negative.
masm.bind(&negative);
masm.loadConstantFloat32(0.5f, temp);

Просмотреть файл

@ -197,7 +197,8 @@ MacroAssemblerX86Shared::buildOOLFakeExitFrame(void *fakeReturnAddr)
void
MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg,
Register scratch,
Label *label)
Label *label,
bool maybeNonZero)
{
// Determines whether the low double contained in the XMM register reg
// is equal to -0.0.
@ -205,12 +206,14 @@ MacroAssemblerX86Shared::branchNegativeZero(FloatRegister reg,
#if defined(JS_CODEGEN_X86)
Label nonZero;
// Compare to zero. Lets through {0, -0}.
xorpd(ScratchDoubleReg, ScratchDoubleReg);
// If reg is non-zero, jump to nonZero.
branchDouble(DoubleNotEqual, reg, ScratchDoubleReg, &nonZero);
// if not already compared to zero
if (maybeNonZero) {
// Compare to zero. Lets through {0, -0}.
xorpd(ScratchDoubleReg, ScratchDoubleReg);
// If reg is non-zero, jump to nonZero.
branchDouble(DoubleNotEqual, reg, ScratchDoubleReg, &nonZero);
}
// Input register is either zero or negative zero. Retrieve sign of input.
movmskpd(reg, scratch);

Просмотреть файл

@ -90,7 +90,7 @@ class MacroAssemblerX86Shared : public Assembler
j(ConditionFromDoubleCondition(cond), label);
}
void branchNegativeZero(FloatRegister reg, Register scratch, Label *label);
void branchNegativeZero(FloatRegister reg, Register scratch, Label *label, bool maybeNonZero = true);
void branchNegativeZeroFloat32(FloatRegister reg, Register scratch, Label *label);
void move32(Imm32 imm, Register dest) {