mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 870356 - Fix IonMonkey Math.round bug on x86/x64 hardware without SSE 4.1. r=sstangl
This commit is contained in:
parent
ed960be5bf
commit
4dec24de90
@ -326,6 +326,13 @@ CodeGeneratorX86Shared::bailoutIf(Assembler::Condition condition, LSnapshot *sna
|
|||||||
return bailout(BailoutJump(condition), snapshot);
|
return bailout(BailoutJump(condition), snapshot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CodeGeneratorX86Shared::bailoutIf(Assembler::DoubleCondition condition, LSnapshot *snapshot)
|
||||||
|
{
|
||||||
|
JS_ASSERT(Assembler::NaNCondFromDoubleCondition(condition) == Assembler::NaN_HandledByCond);
|
||||||
|
return bailoutIf(Assembler::ConditionFromDoubleCondition(condition), snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CodeGeneratorX86Shared::bailoutFrom(Label *label, LSnapshot *snapshot)
|
CodeGeneratorX86Shared::bailoutFrom(Label *label, LSnapshot *snapshot)
|
||||||
{
|
{
|
||||||
@ -1289,8 +1296,12 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
|||||||
masm.addsd(input, temp);
|
masm.addsd(input, temp);
|
||||||
|
|
||||||
// Round toward -Infinity without the benefit of ROUNDSD.
|
// Round toward -Infinity without the benefit of ROUNDSD.
|
||||||
Label testZero;
|
|
||||||
{
|
{
|
||||||
|
// If input + 0.5 >= 0, input is a negative number >= -0.5 and the result is -0.
|
||||||
|
masm.compareDouble(Assembler::DoubleGreaterThanOrEqual, temp, scratch);
|
||||||
|
if (!bailoutIf(Assembler::DoubleGreaterThanOrEqual, lir->snapshot()))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Truncate and round toward zero.
|
// Truncate and round toward zero.
|
||||||
// This is off-by-one for everything but integer-valued inputs.
|
// This is off-by-one for everything but integer-valued inputs.
|
||||||
masm.cvttsd2si(temp, output);
|
masm.cvttsd2si(temp, output);
|
||||||
@ -1300,19 +1311,13 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
|||||||
|
|
||||||
// Test whether the truncated double was integer-valued.
|
// Test whether the truncated double was integer-valued.
|
||||||
masm.cvtsi2sd(output, scratch);
|
masm.cvtsi2sd(output, scratch);
|
||||||
masm.branchDouble(Assembler::DoubleEqualOrUnordered, temp, scratch, &testZero);
|
masm.branchDouble(Assembler::DoubleEqualOrUnordered, temp, scratch, &end);
|
||||||
|
|
||||||
// Input is not integer-valued, so we rounded off-by-one in the
|
// Input is not integer-valued, so we rounded off-by-one in the
|
||||||
// wrong direction. Correct by subtraction.
|
// wrong direction. Correct by subtraction.
|
||||||
masm.subl(Imm32(1), output);
|
masm.subl(Imm32(1), output);
|
||||||
// Cannot overflow: output was already checked against INT_MIN.
|
// Cannot overflow: output was already checked against INT_MIN.
|
||||||
|
|
||||||
// Fall through to testZero.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
masm.bind(&testZero);
|
|
||||||
if (!bailoutIf(Assembler::Zero, lir->snapshot()))
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
masm.bind(&end);
|
masm.bind(&end);
|
||||||
|
@ -50,6 +50,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
|||||||
MoveResolver::MoveOperand toMoveOperand(const LAllocation *a) const;
|
MoveResolver::MoveOperand toMoveOperand(const LAllocation *a) const;
|
||||||
|
|
||||||
bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot);
|
bool bailoutIf(Assembler::Condition condition, LSnapshot *snapshot);
|
||||||
|
bool bailoutIf(Assembler::DoubleCondition condition, LSnapshot *snapshot);
|
||||||
bool bailoutFrom(Label *label, LSnapshot *snapshot);
|
bool bailoutFrom(Label *label, LSnapshot *snapshot);
|
||||||
bool bailout(LSnapshot *snapshot);
|
bool bailout(LSnapshot *snapshot);
|
||||||
|
|
||||||
|
33
js/src/jit-test/tests/ion/bug870356.js
Normal file
33
js/src/jit-test/tests/ion/bug870356.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
function f1(x) {
|
||||||
|
return Math.round(x);
|
||||||
|
}
|
||||||
|
assertEq(f1(3.3), 3);
|
||||||
|
assertEq(f1(-2.842170943040401e-14), -0);
|
||||||
|
|
||||||
|
function f2(x) {
|
||||||
|
return Math.round(x);
|
||||||
|
}
|
||||||
|
assertEq(f2(3.3), 3);
|
||||||
|
assertEq(f2(-1.3), -1);
|
||||||
|
assertEq(f2(-1.8), -2);
|
||||||
|
assertEq(f2(-0.9), -1);
|
||||||
|
assertEq(f2(-0.6), -1);
|
||||||
|
assertEq(f2(-0.4), -0);
|
||||||
|
|
||||||
|
function f3(x) {
|
||||||
|
return Math.round(x);
|
||||||
|
}
|
||||||
|
assertEq(f3(0.1), 0);
|
||||||
|
assertEq(f3(-0.5), -0);
|
||||||
|
|
||||||
|
function f4(x) {
|
||||||
|
return Math.round(x);
|
||||||
|
}
|
||||||
|
assertEq(f4(0.1), 0);
|
||||||
|
assertEq(f4(-0), -0);
|
||||||
|
|
||||||
|
function f5(x) {
|
||||||
|
return Math.round(x);
|
||||||
|
}
|
||||||
|
assertEq(f5(2.9), 3);
|
||||||
|
assertEq(f5(NaN), NaN);
|
Loading…
Reference in New Issue
Block a user