mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1010747: Factor out floating-point conversion to int32 and bailout code; r=sunfish
This commit is contained in:
parent
c350674971
commit
13719bae70
@ -1590,9 +1590,7 @@ CodeGeneratorX86Shared::visitFloor(LFloor *lir)
|
||||
// Round toward -Infinity.
|
||||
masm.roundsd(input, scratch, JSC::X86Assembler::RoundDown);
|
||||
|
||||
masm.cvttsd2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(scratch, output, lir->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
Label negative, end;
|
||||
@ -1607,9 +1605,7 @@ CodeGeneratorX86Shared::visitFloor(LFloor *lir)
|
||||
return false;
|
||||
|
||||
// Input is non-negative, so truncation correctly rounds.
|
||||
masm.cvttsd2si(input, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.jump(&end);
|
||||
@ -1621,9 +1617,7 @@ CodeGeneratorX86Shared::visitFloor(LFloor *lir)
|
||||
{
|
||||
// Truncate and round toward zero.
|
||||
// This is off-by-one for everything but integer-valued inputs.
|
||||
masm.cvttsd2si(input, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// Test whether the input double was integer-valued.
|
||||
@ -1659,9 +1653,7 @@ CodeGeneratorX86Shared::visitFloorF(LFloorF *lir)
|
||||
// Round toward -Infinity.
|
||||
masm.roundss(input, scratch, JSC::X86Assembler::RoundDown);
|
||||
|
||||
masm.cvttss2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(scratch, output, lir->snapshot()))
|
||||
return false;
|
||||
} else {
|
||||
Label negative, end;
|
||||
@ -1676,9 +1668,7 @@ CodeGeneratorX86Shared::visitFloorF(LFloorF *lir)
|
||||
return false;
|
||||
|
||||
// Input is non-negative, so truncation correctly rounds.
|
||||
masm.cvttss2si(input, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.jump(&end);
|
||||
@ -1690,9 +1680,7 @@ CodeGeneratorX86Shared::visitFloorF(LFloorF *lir)
|
||||
{
|
||||
// Truncate and round toward zero.
|
||||
// This is off-by-one for everything but integer-valued inputs.
|
||||
masm.cvttss2si(input, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// Test whether the input double was integer-valued.
|
||||
@ -1735,12 +1723,7 @@ CodeGeneratorX86Shared::visitCeil(LCeil *lir)
|
||||
masm.bind(&lessThanMinusOne);
|
||||
// Round toward +Infinity.
|
||||
masm.roundsd(input, scratch, JSC::X86Assembler::RoundUp);
|
||||
|
||||
masm.cvttsd2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
return false;
|
||||
return true;
|
||||
return bailoutCvttsd2si(scratch, output, lir->snapshot());
|
||||
}
|
||||
|
||||
// No SSE4.1
|
||||
@ -1750,9 +1733,7 @@ CodeGeneratorX86Shared::visitCeil(LCeil *lir)
|
||||
// integer (resp. non-integer) values.
|
||||
// Will also work for values >= INT_MAX + 1, as the truncate
|
||||
// operation will return INT_MIN and there'll be a bailout.
|
||||
masm.cvttsd2si(input, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
masm.convertInt32ToDouble(output, scratch);
|
||||
masm.branchDouble(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
|
||||
@ -1766,9 +1747,7 @@ CodeGeneratorX86Shared::visitCeil(LCeil *lir)
|
||||
|
||||
// x <= -1, truncation is the way to go.
|
||||
masm.bind(&lessThanMinusOne);
|
||||
masm.cvttsd2si(input, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.bind(&end);
|
||||
@ -1800,12 +1779,7 @@ CodeGeneratorX86Shared::visitCeilF(LCeilF *lir)
|
||||
masm.bind(&lessThanMinusOne);
|
||||
// Round toward +Infinity.
|
||||
masm.roundss(input, scratch, JSC::X86Assembler::RoundUp);
|
||||
|
||||
masm.cvttss2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
return false;
|
||||
return true;
|
||||
return bailoutCvttss2si(scratch, output, lir->snapshot());
|
||||
}
|
||||
|
||||
// No SSE4.1
|
||||
@ -1815,9 +1789,7 @@ CodeGeneratorX86Shared::visitCeilF(LCeilF *lir)
|
||||
// integer (resp. non-integer) values.
|
||||
// Will also work for values >= INT_MAX + 1, as the truncate
|
||||
// operation will return INT_MIN and there'll be a bailout.
|
||||
masm.cvttss2si(input, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
masm.convertInt32ToFloat32(output, scratch);
|
||||
masm.branchFloat(Assembler::DoubleEqualOrUnordered, input, scratch, &end);
|
||||
@ -1831,9 +1803,7 @@ CodeGeneratorX86Shared::visitCeilF(LCeilF *lir)
|
||||
|
||||
// x <= -1, truncation is the way to go.
|
||||
masm.bind(&lessThanMinusOne);
|
||||
masm.cvttss2si(input, output);
|
||||
masm.cmp32(output, Imm32(1));
|
||||
if (!bailoutIf(Assembler::Overflow, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(input, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.bind(&end);
|
||||
@ -1866,10 +1836,7 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
||||
// have to add the input to the temp register (which contains 0.5) because
|
||||
// we're not allowed to modify the input register.
|
||||
masm.addsd(input, temp);
|
||||
|
||||
masm.cvttsd2si(temp, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(temp, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.jump(&end);
|
||||
@ -1885,9 +1852,7 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
||||
masm.roundsd(temp, scratch, JSC::X86Assembler::RoundDown);
|
||||
|
||||
// Truncate.
|
||||
masm.cvttsd2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(scratch, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// If the result is positive zero, then the actual result is -0. Bail.
|
||||
@ -1908,9 +1873,7 @@ CodeGeneratorX86Shared::visitRound(LRound *lir)
|
||||
|
||||
// Truncate and round toward zero.
|
||||
// This is off-by-one for everything but integer-valued inputs.
|
||||
masm.cvttsd2si(temp, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttsd2si(temp, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// Test whether the truncated double was integer-valued.
|
||||
@ -1955,9 +1918,7 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir)
|
||||
// we're not allowed to modify the input register.
|
||||
masm.addss(input, temp);
|
||||
|
||||
masm.cvttss2si(temp, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(temp, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
masm.jump(&end);
|
||||
@ -1973,9 +1934,7 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir)
|
||||
masm.roundss(temp, scratch, JSC::X86Assembler::RoundDown);
|
||||
|
||||
// Truncate.
|
||||
masm.cvttss2si(scratch, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(scratch, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// If the result is positive zero, then the actual result is -0. Bail.
|
||||
@ -1995,9 +1954,7 @@ CodeGeneratorX86Shared::visitRoundF(LRoundF *lir)
|
||||
|
||||
// Truncate and round toward zero.
|
||||
// This is off-by-one for everything but integer-valued inputs.
|
||||
masm.cvttss2si(temp, output);
|
||||
masm.cmp32(output, Imm32(INT_MIN));
|
||||
if (!bailoutIf(Assembler::Equal, lir->snapshot()))
|
||||
if (!bailoutCvttss2si(temp, output, lir->snapshot()))
|
||||
return false;
|
||||
|
||||
// Test whether the truncated double was integer-valued.
|
||||
|
@ -75,6 +75,21 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
masm.test32(lhs, rhs);
|
||||
return bailoutIf(c, snapshot);
|
||||
}
|
||||
bool bailoutCvttsd2si(FloatRegister src, Register dest, LSnapshot *snapshot) {
|
||||
// cvttsd2si returns 0x80000000 on failure. Test for it by
|
||||
// subtracting 1 and testing overflow. The other possibility is to test
|
||||
// equality for INT_MIN after a comparison, but 1 costs fewer bytes to
|
||||
// materialize.
|
||||
masm.cvttsd2si(src, dest);
|
||||
masm.cmp32(dest, Imm32(1));
|
||||
return bailoutIf(Assembler::Overflow, snapshot);
|
||||
}
|
||||
bool bailoutCvttss2si(FloatRegister src, Register dest, LSnapshot *snapshot) {
|
||||
// Same trick as explained in the above comment.
|
||||
masm.cvttss2si(src, dest);
|
||||
masm.cmp32(dest, Imm32(1));
|
||||
return bailoutIf(Assembler::Overflow, snapshot);
|
||||
}
|
||||
|
||||
protected:
|
||||
bool generatePrologue();
|
||||
|
Loading…
Reference in New Issue
Block a user