зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1245112 - Part 10: Move MacroAssembler::branchTruncateDouble into generic macro assembler. r=nbp
This commit is contained in:
Родитель
6bd8a4b588
Коммит
850ab25efd
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче