Commit c63a4cff authored by Benjamin Bouvier's avatar Benjamin Bouvier
Browse files

Bug 930477: Specialize Round for Float32; r=jandem,mjrosenb

parent 65d48642
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -230,6 +230,45 @@ function testFloorDouble() {
test(setupFloor, testFloor);
test(setupFloorDouble, testFloorDouble);

function setupRound() {
    f32[0] = -5.5;
    f32[1] = -0.6;
    f32[2] = 1.5;
    f32[3] = 1;
}
function setupRoundDouble() {
    f32[4] = NaN;
    f32[5] = -0.49;          // rounded to -0
    f32[6] = Infinity;
    f32[7] = -Infinity;
    f32[8] = Math.pow(2,31); // too big to fit into a int
    f32[9] = -0;
}
function testRound() {
    for (var i = 0; i < 4; ++i) {
        var r32 = Math.round(f32[i]);
        assertFloat32(r32, false); // r32 is an int32

        var r64 = Math.round(-0 + f32[i]);
        assertFloat32(r64, false);

        assertEq(r32, r64);
    }
}
function testRoundDouble() {
    for (var i = 4; i < 10; ++i) {
        var r32 = Math.fround(Math.round(f32[i]));
        assertFloat32(r32, true);

        var r64 = Math.round(-0 + f32[i]);
        assertFloat32(r64, false);

        assertEq(r32, r64);
    }
}
test(setupRound, testRound);
test(setupRoundDouble, testRoundDouble);

function setupCeil() {
    f32[0] = -5.5;
    f32[1] = -1.5;
+1 −0
Original line number Diff line number Diff line
@@ -4306,6 +4306,7 @@ CodeGenerator::visitMathFunctionF(LMathFunctionF *ins)
    void *funptr = nullptr;
    switch (ins->mir()->function()) {
      case MMathFunction::Floor: funptr = JS_FUNC_TO_DATA_PTR(void *, floorf); break;
      case MMathFunction::Round: funptr = JS_FUNC_TO_DATA_PTR(void *, roundf); break;
      case MMathFunction::Ceil:  funptr = JS_FUNC_TO_DATA_PTR(void *, ceilf);  break;
      default:
        MOZ_ASSUME_UNREACHABLE("Unknown or unsupported float32 math function");
+20 −1
Original line number Diff line number Diff line
@@ -4738,7 +4738,7 @@ class LFloorF : public LInstructionHelper<1, 1, 0>
    }
};

// Round a number. Implements Math.round().
// Round a double precision number. Implements Math.round().
class LRound : public LInstructionHelper<1, 1, 1>
{
  public:
@@ -4757,6 +4757,25 @@ class LRound : public LInstructionHelper<1, 1, 1>
    }
};

// Round a single precision number. Implements Math.round().
class LRoundF : public LInstructionHelper<1, 1, 1>
{
  public:
    LIR_HEADER(RoundF)

    LRoundF(const LAllocation &num, const LDefinition &temp) {
        setOperand(0, num);
        setTemp(0, temp);
    }

    const LDefinition *temp() {
        return getTemp(0);
    }
    MRound *mir() const {
        return mir_->toRound();
    }
};

// Load a function's call environment.
class LFunctionEnvironment : public LInstructionHelper<1, 1, 0>
{
+1 −0
Original line number Diff line number Diff line
@@ -261,6 +261,7 @@
    _(Floor)                        \
    _(FloorF)                       \
    _(Round)                        \
    _(RoundF)                       \
    _(In)                           \
    _(InArray)                      \
    _(InstanceOfO)                  \
+11 −2
Original line number Diff line number Diff line
@@ -1179,13 +1179,22 @@ LIRGenerator::visitFloor(MFloor *ins)
bool
LIRGenerator::visitRound(MRound *ins)
{
    JS_ASSERT(ins->num()->type() == MIRType_Double);
    MIRType type = ins->num()->type();
    JS_ASSERT(IsFloatingPointType(type));

    if (type == MIRType_Double) {
        LRound *lir = new (alloc()) LRound(useRegister(ins->num()), tempDouble());
        if (!assignSnapshot(lir))
            return false;
        return define(lir, ins);
    }

    LRoundF *lir = new (alloc()) LRoundF(useRegister(ins->num()), tempDouble());
    if (!assignSnapshot(lir))
        return false;
    return define(lir, ins);
}

bool
LIRGenerator::visitMinMax(MMinMax *ins)
{
Loading