Bug 1245112 - Part 10: Move MacroAssembler::branchTruncateDouble into generic macro assembler. r=nbp

This commit is contained in:
Tooru Fujisawa 2016-02-15 23:01:49 +09:00
Родитель 6bd8a4b588
Коммит 850ab25efd
16 изменённых файлов: 83 добавлений и 97 удалений

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

@ -848,6 +848,8 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
Label* label) PER_SHARED_ARCH;
inline void branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
template <class L>
inline void branchTest32(Condition cond, Register lhs, Register rhs, L label) PER_SHARED_ARCH;

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

@ -634,6 +634,27 @@ MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegis
ma_b(label, ConditionFromDoubleCondition(cond));
}
// There are two options for implementing emitTruncateDouble:
//
// 1. Convert the floating point value to an integer, if it did not fit, then it
// was clamped to INT_MIN/INT_MAX, and we can test it. NOTE: if the value
// really was supposed to be INT_MAX / INT_MIN then it will be wrong.
//
// 2. Convert the floating point value to an integer, if it did not fit, then it
// set one or two bits in the fpcsr. Check those.
void
MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
ScratchDoubleScope scratch(*this);
FloatRegister scratchSIntReg = scratch.sintOverlay();
ma_vcvt_F64_I32(src, scratchSIntReg);
ma_vxfer(scratchSIntReg, dest);
ma_cmp(dest, Imm32(0x7fffffff));
ma_cmp(dest, Imm32(0x80000000), Assembler::NotEqual);
ma_b(fail, Assembler::Equal);
}
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)

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

@ -118,27 +118,6 @@ void MacroAssemblerARM::convertDoubleToFloat32(FloatRegister src, FloatRegister
as_vcvt(VFPRegister(dest).singleOverlay(), VFPRegister(src), false, c);
}
// There are two options for implementing emitTruncateDouble:
//
// 1. Convert the floating point value to an integer, if it did not fit, then it
// was clamped to INT_MIN/INT_MAX, and we can test it. NOTE: if the value
// really was supposed to be INT_MAX / INT_MIN then it will be wrong.
//
// 2. Convert the floating point value to an integer, if it did not fit, then it
// set one or two bits in the fpcsr. Check those.
void
MacroAssemblerARM::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
ScratchDoubleScope scratch(asMasm());
FloatRegister scratchSIntReg = scratch.sintOverlay();
ma_vcvt_F64_I32(src, scratchSIntReg);
ma_vxfer(scratchSIntReg, dest);
ma_cmp(dest, Imm32(0x7fffffff));
ma_cmp(dest, Imm32(0x80000000), Assembler::NotEqual);
ma_b(fail, Assembler::Equal);
}
// Checks whether a double is representable as a 32-bit integer. If so, the
// integer is written to the output register. Otherwise, a bailout is taken to
// the given snapshot. This function overwrites the scratch float register.

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

@ -86,7 +86,6 @@ class MacroAssemblerARM : public Assembler
void convertUInt32ToDouble(Register src, FloatRegister dest);
void convertDoubleToFloat32(FloatRegister src, FloatRegister dest,
Condition c = Always);
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail);
void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
bool negativeZeroCheck = true);
void convertFloat32ToInt32(FloatRegister src, Register dest, Label* fail,

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

@ -716,6 +716,25 @@ MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegis
}
}
void
MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
vixl::UseScratchRegisterScope temps(this);
const ARMRegister scratch64 = temps.AcquireX();
// An out of range integer will be saturated to the destination size.
ARMFPRegister src64(src, 64);
ARMRegister dest64(dest, 64);
MOZ_ASSERT(!scratch64.Is(dest64));
Fcvtzs(dest64, src64);
Add(scratch64, dest64, Operand(0x7fffffffffffffff));
Cmn(scratch64, 3);
B(fail, Assembler::Above);
And(dest64, dest64, Operand(0xffffffff));
}
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)

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

@ -564,23 +564,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
MOZ_CRASH("NYI");
}
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail) {
vixl::UseScratchRegisterScope temps(this);
const ARMRegister scratch64 = temps.AcquireX();
// An out of range integer will be saturated to the destination size.
ARMFPRegister src64(src, 64);
ARMRegister dest64(dest, 64);
MOZ_ASSERT(!scratch64.Is(dest64));
//breakpoint();
Fcvtzs(dest64, src64);
Add(scratch64, dest64, Operand(0x7fffffffffffffff));
Cmn(scratch64, 3);
B(fail, Assembler::Above);
And(dest64, dest64, Operand(0xffffffff));
}
void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
bool negativeZeroCheck = true)
{

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

@ -369,6 +369,21 @@ MacroAssembler::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegis
ma_bc1d(lhs, rhs, label, cond);
}
// Convert the floating point value to an integer, if it did not fit, then it
// was clamped to INT32_MIN/INT32_MAX, and we can test it.
// NOTE: if the value really was supposed to be INT32_MAX / INT32_MIN then it
// will be wrong.
void
MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
Label test, success;
as_truncwd(ScratchDoubleReg, src);
as_mfc1(dest, ScratchDoubleReg);
ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)

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

@ -113,22 +113,6 @@ MacroAssemblerMIPSCompat::convertDoubleToFloat32(FloatRegister src, FloatRegiste
as_cvtsd(dest, src);
}
// Convert the floating point value to an integer, if it did not fit, then it
// was clamped to INT32_MIN/INT32_MAX, and we can test it.
// NOTE: if the value really was supposed to be INT32_MAX / INT32_MIN then it
// will be wrong.
void
MacroAssemblerMIPSCompat::branchTruncateDouble(FloatRegister src, Register dest,
Label* fail)
{
Label test, success;
as_truncwd(ScratchDoubleReg, src);
as_mfc1(dest, ScratchDoubleReg);
ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
// Checks whether a double is representable as a 32-bit integer. If so, the
// integer is written to the output register. Otherwise, a bailout is taken to
// the given snapshot. This function overwrites the scratch float register.

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

@ -164,7 +164,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
void convertUInt32ToDouble(Register src, FloatRegister dest);
void convertUInt32ToFloat32(Register src, FloatRegister dest);
void convertDoubleToFloat32(FloatRegister src, FloatRegister dest);
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail);
void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
bool negativeZeroCheck = true);
void convertFloat32ToInt32(FloatRegister src, Register dest, Label* fail,

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

@ -122,22 +122,6 @@ MacroAssemblerMIPS64Compat::convertDoubleToFloat32(FloatRegister src, FloatRegis
as_cvtsd(dest, src);
}
// Convert the floating point value to an integer, if it did not fit, then it
// was clamped to INT32_MIN/INT32_MAX, and we can test it.
// NOTE: if the value really was supposed to be INT32_MAX / INT32_MIN then it
// will be wrong.
void
MacroAssemblerMIPS64Compat::branchTruncateDouble(FloatRegister src, Register dest,
Label* fail)
{
Label test, success;
as_truncwd(ScratchDoubleReg, src);
as_mfc1(dest, ScratchDoubleReg);
ma_b(dest, Imm32(INT32_MAX), fail, Assembler::Equal);
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
}
// Checks whether a double is representable as a 32-bit integer. If so, the
// integer is written to the output register. Otherwise, a bailout is taken to
// the given snapshot. This function overwrites the scratch float register.

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

@ -174,7 +174,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
void convertUInt32ToDouble(Register src, FloatRegister dest);
void convertUInt32ToFloat32(Register src, FloatRegister dest);
void convertDoubleToFloat32(FloatRegister src, FloatRegister dest);
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail);
void convertDoubleToInt32(FloatRegister src, Register dest, Label* fail,
bool negativeZeroCheck = true);
void convertFloat32ToInt32(FloatRegister src, Register dest, Label* fail,

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

@ -391,8 +391,6 @@ class MacroAssemblerNone : public Assembler
void convertFloat32ToDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); }
void convertUInt64ToDouble(Register64, Register, FloatRegister) { MOZ_CRASH(); }
void branchTruncateDouble(FloatRegister, Register, Label*) { MOZ_CRASH(); }
void boolValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
void boolValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
void int32ValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }

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

@ -310,6 +310,20 @@ MacroAssembler::branchTruncateFloat32(FloatRegister src, Register dest, Label* f
movl(dest, dest); // Zero upper 32-bits.
}
void
MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
vcvttsd2sq(src, dest);
// vcvttsd2sq returns 0x8000000000000000 on failure. Test for it by
// subtracting 1 and testing overflow (this avoids the need to
// materialize that value in a register).
cmpPtr(dest, Imm32(1));
j(Assembler::Overflow, fail);
movl(dest, dest); // Zero upper 32-bits.
}
void
MacroAssembler::branchTest32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
{

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

@ -1083,18 +1083,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
void loadConstantInt32x4(const SimdConstant& v, FloatRegister dest);
void loadConstantFloat32x4(const SimdConstant& v, FloatRegister dest);
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail) {
vcvttsd2sq(src, dest);
// vcvttsd2sq returns 0x8000000000000000 on failure. Test for it by
// subtracting 1 and testing overflow (this avoids the need to
// materialize that value in a register).
cmpPtr(dest, Imm32(1));
j(Assembler::Overflow, fail);
movl(dest, dest); // Zero upper 32-bits.
}
Condition testInt32Truthy(bool truthy, const ValueOperand& operand) {
test32(operand.valueReg(), operand.valueReg());
return truthy ? NonZero : Zero;

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

@ -316,6 +316,18 @@ MacroAssembler::branchTruncateFloat32(FloatRegister src, Register dest, Label* f
j(Assembler::Overflow, fail);
}
void
MacroAssembler::branchTruncateDouble(FloatRegister src, Register dest, Label* fail)
{
vcvttsd2si(src, dest);
// vcvttsd2si returns 0x80000000 on failure. Test for it by
// subtracting 1 and testing overflow (this permits the use of a
// smaller immediate field).
cmp32(dest, Imm32(1));
j(Assembler::Overflow, fail);
}
void
MacroAssembler::branchTest32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
{

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

@ -865,16 +865,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
void loadConstantInt32x4(const SimdConstant& v, FloatRegister dest);
void loadConstantFloat32x4(const SimdConstant& v, FloatRegister dest);
void branchTruncateDouble(FloatRegister src, Register dest, Label* fail) {
vcvttsd2si(src, dest);
// vcvttsd2si returns 0x80000000 on failure. Test for it by
// subtracting 1 and testing overflow (this permits the use of a
// smaller immediate field).
cmp32(dest, Imm32(1));
j(Assembler::Overflow, fail);
}
Condition testInt32Truthy(bool truthy, const ValueOperand& operand) {
test32(operand.payloadReg(), operand.payloadReg());
return truthy ? NonZero : Zero;