mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 22:07:41 +00:00
Bug 1301400: Baseline Wasm Compiler: Part 3: Implement ConvertI64, r=lth
This commit is contained in:
parent
9bff77359e
commit
2c6cdd35ac
@ -2762,23 +2762,31 @@ class BaseCompiler
|
||||
return true;
|
||||
}
|
||||
|
||||
void convertI64ToF32(RegI64 src, bool isUnsigned, RegF32 dest) {
|
||||
#ifdef JS_CODEGEN_X64
|
||||
bool convertI64ToFloatNeedsTemp(bool isUnsigned) const {
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
return isUnsigned && AssemblerX86Shared::HasSSE3();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void convertI64ToF32(RegI64 src, bool isUnsigned, RegF32 dest, RegI32 temp) {
|
||||
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
|
||||
if (isUnsigned)
|
||||
masm.convertUInt64ToFloat32(src.reg.reg, dest.reg);
|
||||
masm.convertUInt64ToFloat32(src.reg, dest.reg, temp.reg);
|
||||
else
|
||||
masm.convertInt64ToFloat32(src.reg.reg, dest.reg);
|
||||
masm.convertInt64ToFloat32(src.reg, dest.reg);
|
||||
#else
|
||||
MOZ_CRASH("BaseCompiler platform hook: convertI64ToF32");
|
||||
#endif
|
||||
}
|
||||
|
||||
void convertI64ToF64(RegI64 src, bool isUnsigned, RegF64 dest) {
|
||||
#ifdef JS_CODEGEN_X64
|
||||
void convertI64ToF64(RegI64 src, bool isUnsigned, RegF64 dest, RegI32 temp) {
|
||||
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_X86)
|
||||
if (isUnsigned)
|
||||
masm.convertUInt64ToDouble(src.reg.reg, dest.reg);
|
||||
masm.convertUInt64ToDouble(src.reg, dest.reg, temp.reg);
|
||||
else
|
||||
masm.convertInt64ToDouble(src.reg.reg, dest.reg);
|
||||
masm.convertInt64ToDouble(src.reg, dest.reg);
|
||||
#else
|
||||
MOZ_CRASH("BaseCompiler platform hook: convertI32ToF64");
|
||||
#endif
|
||||
@ -4328,7 +4336,7 @@ BaseCompiler::emitConvertI64ToF32()
|
||||
{
|
||||
RegI64 r0 = popI64();
|
||||
RegF32 f0 = needF32();
|
||||
convertI64ToF32(r0, IsUnsigned(false), f0);
|
||||
convertI64ToF32(r0, IsUnsigned(false), f0, RegI32());
|
||||
freeI64(r0);
|
||||
pushF32(f0);
|
||||
}
|
||||
@ -4338,7 +4346,12 @@ BaseCompiler::emitConvertU64ToF32()
|
||||
{
|
||||
RegI64 r0 = popI64();
|
||||
RegF32 f0 = needF32();
|
||||
convertI64ToF32(r0, IsUnsigned(true), f0);
|
||||
RegI32 temp;
|
||||
if (convertI64ToFloatNeedsTemp(IsUnsigned(true)))
|
||||
temp = needI32();
|
||||
convertI64ToF32(r0, IsUnsigned(true), f0, temp);
|
||||
if (temp.reg != Register::Invalid())
|
||||
freeI32(temp);
|
||||
freeI64(r0);
|
||||
pushF32(f0);
|
||||
}
|
||||
@ -4378,7 +4391,7 @@ BaseCompiler::emitConvertI64ToF64()
|
||||
{
|
||||
RegI64 r0 = popI64();
|
||||
RegF64 d0 = needF64();
|
||||
convertI64ToF64(r0, IsUnsigned(false), d0);
|
||||
convertI64ToF64(r0, IsUnsigned(false), d0, RegI32());
|
||||
freeI64(r0);
|
||||
pushF64(d0);
|
||||
}
|
||||
@ -4388,7 +4401,12 @@ BaseCompiler::emitConvertU64ToF64()
|
||||
{
|
||||
RegI64 r0 = popI64();
|
||||
RegF64 d0 = needF64();
|
||||
convertI64ToF64(r0, IsUnsigned(true), d0);
|
||||
RegI32 temp;
|
||||
if (convertI64ToFloatNeedsTemp(IsUnsigned(true)))
|
||||
temp = needI32();
|
||||
convertI64ToF64(r0, IsUnsigned(true), d0, temp);
|
||||
if (temp.reg != Register::Invalid())
|
||||
freeI32(temp);
|
||||
freeI64(r0);
|
||||
pushF64(d0);
|
||||
}
|
||||
|
@ -11904,7 +11904,10 @@ CodeGenerator::visitRandom(LRandom* ins)
|
||||
|
||||
masm.and64(Imm64((1ULL << MantissaBits) - 1), s1Reg);
|
||||
|
||||
masm.convertUInt64ToDouble(s1Reg, tempReg, output);
|
||||
if (masm.convertUInt64ToDoubleNeedsTemp())
|
||||
masm.convertUInt64ToDouble(s1Reg, output, tempReg);
|
||||
else
|
||||
masm.convertUInt64ToDouble(s1Reg, output, Register::Invalid());
|
||||
|
||||
// output *= ScaleInv
|
||||
masm.mulDoublePtr(ImmPtr(&ScaleInv), tempReg, output);
|
||||
|
@ -93,9 +93,16 @@ MacroAssemblerARM::convertUInt32ToDouble(Register src, FloatRegister dest_)
|
||||
|
||||
static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
||||
bool
|
||||
MacroAssemblerARMCompat::convertUInt64ToDoubleNeedsTemp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp)
|
||||
{
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
convertUInt32ToDouble(src.high, dest);
|
||||
movePtr(ImmPtr(&TO_DOUBLE_HIGH_SCALE), ScratchRegister);
|
||||
loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg);
|
||||
|
@ -1329,7 +1329,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
||||
void cmpPtr(const Address& lhs, ImmGCPtr rhs);
|
||||
void cmpPtr(const Address& lhs, Imm32 rhs);
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
|
||||
static bool convertUInt64ToDoubleNeedsTemp();
|
||||
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp);
|
||||
|
||||
void setStackArg(Register reg, uint32_t arg);
|
||||
|
||||
|
@ -2238,7 +2238,12 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
||||
vixl::MacroAssembler::Ret(vixl::lr);
|
||||
}
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest) {
|
||||
bool convertUInt64ToDoubleNeedsTemp() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp) {
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
Ucvtf(ARMFPRegister(dest, 64), ARMRegister(src.reg, 64));
|
||||
}
|
||||
|
||||
|
@ -79,9 +79,16 @@ MacroAssemblerMIPSCompat::convertUInt32ToDouble(Register src, FloatRegister dest
|
||||
|
||||
static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
||||
bool
|
||||
MacroAssemblerMIPSCompat::convertUInt64ToDoubleNeedsTemp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp)
|
||||
{
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
convertUInt32ToDouble(src.high, dest);
|
||||
loadConstantDouble(TO_DOUBLE_HIGH_SCALE, ScratchDoubleReg);
|
||||
asMasm().mulDouble(ScratchDoubleReg, dest);
|
||||
|
@ -941,7 +941,8 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
||||
moveToDoubleHi(zero, reg);
|
||||
}
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
|
||||
static bool convertUInt64ToDoubleNeedsTemp();
|
||||
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp);
|
||||
|
||||
void breakpoint();
|
||||
|
||||
|
@ -74,9 +74,17 @@ MacroAssemblerMIPS64Compat::convertUInt32ToDouble(Register src, FloatRegister de
|
||||
as_addd(dest, dest, SecondScratchDoubleReg);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
||||
bool
|
||||
MacroAssemblerMIPS64Compat::convertUInt64ToDoubleNeedsTemp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp)
|
||||
{
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
|
||||
Label positive, done;
|
||||
ma_b(src.reg, src.reg, &positive, NotSigned, ShortJump);
|
||||
|
||||
|
@ -946,7 +946,8 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
||||
moveToDouble(zero, reg);
|
||||
}
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
|
||||
static bool convertUInt64ToDoubleNeedsTemp();
|
||||
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp);
|
||||
|
||||
void breakpoint();
|
||||
|
||||
|
@ -380,7 +380,8 @@ class MacroAssemblerNone : public Assembler
|
||||
|
||||
template <typename T> void convertInt32ToDouble(T, FloatRegister) { MOZ_CRASH(); }
|
||||
void convertFloat32ToDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); }
|
||||
void convertUInt64ToDouble(Register64, Register, FloatRegister) { MOZ_CRASH(); }
|
||||
static bool convertUInt64ToDoubleNeedsTemp() { MOZ_CRASH(); }
|
||||
void convertUInt64ToDouble(Register64, FloatRegister, Register) { MOZ_CRASH(); }
|
||||
|
||||
void boolValueToDouble(ValueOperand, FloatRegister) { MOZ_CRASH(); }
|
||||
void boolValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); }
|
||||
|
@ -839,7 +839,7 @@ CodeGeneratorX64::visitWasmTruncateToInt64(LWasmTruncateToInt64* lir)
|
||||
void
|
||||
CodeGeneratorX64::visitInt64ToFloatingPoint(LInt64ToFloatingPoint* lir)
|
||||
{
|
||||
Register input = ToRegister(lir->input());
|
||||
Register64 input = ToRegister64(lir->getInt64Operand(0));
|
||||
FloatRegister output = ToFloatRegister(lir->output());
|
||||
|
||||
MIRType outputType = lir->mir()->type();
|
||||
@ -847,12 +847,12 @@ CodeGeneratorX64::visitInt64ToFloatingPoint(LInt64ToFloatingPoint* lir)
|
||||
|
||||
if (outputType == MIRType::Double) {
|
||||
if (lir->mir()->isUnsigned())
|
||||
masm.convertUInt64ToDouble(input, output);
|
||||
masm.convertUInt64ToDouble(input, output, Register::Invalid());
|
||||
else
|
||||
masm.convertInt64ToDouble(input, output);
|
||||
} else {
|
||||
if (lir->mir()->isUnsigned())
|
||||
masm.convertUInt64ToFloat32(input, output);
|
||||
masm.convertUInt64ToFloat32(input, output, Register::Invalid());
|
||||
else
|
||||
masm.convertInt64ToFloat32(input, output);
|
||||
}
|
||||
|
@ -485,7 +485,7 @@ LIRGeneratorX64::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins)
|
||||
MOZ_ASSERT(opd->type() == MIRType::Int64);
|
||||
MOZ_ASSERT(IsFloatingPointType(ins->type()));
|
||||
|
||||
define(new(alloc()) LInt64ToFloatingPoint(useInt64Register(opd)), ins);
|
||||
define(new(alloc()) LInt64ToFloatingPoint(useInt64Register(opd), LDefinition::BogusTemp()), ins);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -85,25 +85,34 @@ MacroAssemblerX64::loadConstantSimd128Float(const SimdConstant&v, FloatRegister
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::convertInt64ToDouble(Register input, FloatRegister output)
|
||||
MacroAssemblerX64::convertInt64ToDouble(Register64 input, FloatRegister output)
|
||||
{
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(output);
|
||||
|
||||
vcvtsq2sd(input, output, output);
|
||||
vcvtsq2sd(input.reg, output, output);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::convertInt64ToFloat32(Register input, FloatRegister output)
|
||||
MacroAssemblerX64::convertInt64ToFloat32(Register64 input, FloatRegister output)
|
||||
{
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroFloat32(output);
|
||||
|
||||
vcvtsq2ss(input, output, output);
|
||||
vcvtsq2ss(input.reg, output, output);
|
||||
}
|
||||
void
|
||||
MacroAssemblerX64::convertUInt64ToDouble(Register input, FloatRegister output)
|
||||
|
||||
bool
|
||||
MacroAssemblerX64::convertUInt64ToDoubleNeedsTemp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::convertUInt64ToDouble(Register64 input, FloatRegister output, Register temp)
|
||||
{
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(output);
|
||||
|
||||
@ -112,15 +121,15 @@ MacroAssemblerX64::convertUInt64ToDouble(Register input, FloatRegister output)
|
||||
Label done;
|
||||
Label isSigned;
|
||||
|
||||
testq(input, input);
|
||||
testq(input.reg, input.reg);
|
||||
j(Assembler::Signed, &isSigned);
|
||||
vcvtsq2sd(input, output, output);
|
||||
vcvtsq2sd(input.reg, output, output);
|
||||
jump(&done);
|
||||
|
||||
bind(&isSigned);
|
||||
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
mov(input, scratch);
|
||||
mov(input.reg, scratch);
|
||||
shrq(Imm32(1), scratch);
|
||||
vcvtsq2sd(scratch, output, output);
|
||||
vaddsd(output, output, output);
|
||||
@ -129,8 +138,10 @@ MacroAssemblerX64::convertUInt64ToDouble(Register input, FloatRegister output)
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::convertUInt64ToFloat32(Register input, FloatRegister output)
|
||||
MacroAssemblerX64::convertUInt64ToFloat32(Register64 input, FloatRegister output, Register temp)
|
||||
{
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroFloat32(output);
|
||||
|
||||
@ -139,15 +150,15 @@ MacroAssemblerX64::convertUInt64ToFloat32(Register input, FloatRegister output)
|
||||
Label done;
|
||||
Label isSigned;
|
||||
|
||||
testq(input, input);
|
||||
testq(input.reg, input.reg);
|
||||
j(Assembler::Signed, &isSigned);
|
||||
vcvtsq2ss(input, output, output);
|
||||
vcvtsq2ss(input.reg, output, output);
|
||||
jump(&done);
|
||||
|
||||
bind(&isSigned);
|
||||
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
mov(input, scratch);
|
||||
mov(input.reg, scratch);
|
||||
shrq(Imm32(1), scratch);
|
||||
vcvtsq2ss(scratch, output, output);
|
||||
vaddss(output, output, output);
|
||||
|
@ -870,11 +870,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
void loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest);
|
||||
void loadConstantSimd128Float(const SimdConstant& v, FloatRegister dest);
|
||||
|
||||
void convertInt64ToDouble(Register input, FloatRegister output);
|
||||
void convertInt64ToFloat32(Register input, FloatRegister output);
|
||||
|
||||
void convertUInt64ToDouble(Register input, FloatRegister output);
|
||||
void convertUInt64ToFloat32(Register input, FloatRegister output);
|
||||
void convertInt64ToDouble(Register64 input, FloatRegister output);
|
||||
void convertInt64ToFloat32(Register64 input, FloatRegister output);
|
||||
static bool convertUInt64ToDoubleNeedsTemp();
|
||||
void convertUInt64ToDouble(Register64 input, FloatRegister output, Register temp);
|
||||
void convertUInt64ToFloat32(Register64 input, FloatRegister output, Register temp);
|
||||
|
||||
void wasmTruncateDoubleToInt64(FloatRegister input, Register64 output, Label* oolEntry,
|
||||
Label* oolRejoin, FloatRegister tempDouble);
|
||||
@ -943,15 +943,17 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
||||
}
|
||||
|
||||
void convertUInt32ToDouble(Register src, FloatRegister dest) {
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(dest);
|
||||
|
||||
vcvtsq2sd(src, dest, dest);
|
||||
}
|
||||
|
||||
void convertUInt32ToFloat32(Register src, FloatRegister dest) {
|
||||
vcvtsq2ss(src, dest, dest);
|
||||
}
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(dest);
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest) {
|
||||
vcvtsi2sdq(src.reg, dest);
|
||||
vcvtsq2ss(src, dest, dest);
|
||||
}
|
||||
|
||||
inline void incrementInt32Value(const Address& addr);
|
||||
|
@ -385,18 +385,23 @@ class LSimdValueFloat32x4 : public LInstructionHelper<1, 4, 1>
|
||||
}
|
||||
};
|
||||
|
||||
class LInt64ToFloatingPoint : public LInstructionHelper<1, INT64_PIECES, 0>
|
||||
class LInt64ToFloatingPoint : public LInstructionHelper<1, INT64_PIECES, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(Int64ToFloatingPoint);
|
||||
|
||||
explicit LInt64ToFloatingPoint(const LInt64Allocation& in) {
|
||||
explicit LInt64ToFloatingPoint(const LInt64Allocation& in, const LDefinition& temp) {
|
||||
setInt64Operand(0, in);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
MInt64ToFloatingPoint* mir() const {
|
||||
return mir_->toInt64ToFloatingPoint();
|
||||
}
|
||||
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
@ -1279,18 +1279,19 @@ CodeGeneratorX86::visitInt64ToFloatingPoint(LInt64ToFloatingPoint* lir)
|
||||
{
|
||||
Register64 input = ToRegister64(lir->getInt64Operand(0));
|
||||
FloatRegister output = ToFloatRegister(lir->output());
|
||||
Register temp = lir->temp()->isBogusTemp() ? InvalidReg : ToRegister(lir->temp());
|
||||
|
||||
MIRType outputType = lir->mir()->type();
|
||||
MOZ_ASSERT(outputType == MIRType::Double || outputType == MIRType::Float32);
|
||||
|
||||
if (outputType == MIRType::Double) {
|
||||
if (lir->mir()->isUnsigned())
|
||||
masm.convertUInt64ToFloat64(input, output);
|
||||
masm.convertUInt64ToDouble(input, output, temp);
|
||||
else
|
||||
masm.convertInt64ToFloat64(input, output);
|
||||
masm.convertInt64ToDouble(input, output);
|
||||
} else {
|
||||
if (lir->mir()->isUnsigned())
|
||||
masm.convertUInt64ToFloat32(input, output);
|
||||
masm.convertUInt64ToFloat32(input, output, temp);
|
||||
else
|
||||
masm.convertInt64ToFloat32(input, output);
|
||||
}
|
||||
|
@ -638,7 +638,10 @@ LIRGeneratorX86::visitInt64ToFloatingPoint(MInt64ToFloatingPoint* ins)
|
||||
MOZ_ASSERT(opd->type() == MIRType::Int64);
|
||||
MOZ_ASSERT(IsFloatingPointType(ins->type()));
|
||||
|
||||
define(new(alloc()) LInt64ToFloatingPoint(useInt64Register(opd)), ins);
|
||||
LDefinition maybeTemp =
|
||||
(ins->isUnsigned() && AssemblerX86Shared::HasSSE3()) ? temp() : LDefinition::BogusTemp();
|
||||
|
||||
define(new(alloc()) LInt64ToFloatingPoint(useInt64Register(opd), maybeTemp), ins);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -32,17 +32,37 @@ MOZ_ALIGNED_DECL(static const uint64_t, 16) TO_DOUBLE[4] = {
|
||||
|
||||
static const double TO_DOUBLE_HIGH_SCALE = 0x100000000;
|
||||
|
||||
bool
|
||||
MacroAssemblerX86::convertUInt64ToDoubleNeedsTemp()
|
||||
{
|
||||
return HasSSE3();
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest)
|
||||
MacroAssemblerX86::convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp)
|
||||
{
|
||||
// SUBPD needs SSE2, HADDPD needs SSE3.
|
||||
if (!HasSSE3()) {
|
||||
convertUInt32ToDouble(src.high, dest);
|
||||
movePtr(ImmPtr(&TO_DOUBLE_HIGH_SCALE), temp);
|
||||
loadDouble(Address(temp, 0), ScratchDoubleReg);
|
||||
asMasm().mulDouble(ScratchDoubleReg, dest);
|
||||
convertUInt32ToDouble(src.low, ScratchDoubleReg);
|
||||
asMasm().addDouble(ScratchDoubleReg, dest);
|
||||
MOZ_ASSERT(temp == Register::Invalid());
|
||||
|
||||
// Zero the dest register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(dest);
|
||||
|
||||
asMasm().Push(src.high);
|
||||
asMasm().Push(src.low);
|
||||
fild(Operand(esp, 0));
|
||||
|
||||
Label notNegative;
|
||||
asMasm().branch32(Assembler::NotSigned, src.high, Imm32(0), ¬Negative);
|
||||
double add_constant = 18446744073709551616.0; // 2^64
|
||||
store64(Imm64(mozilla::BitwiseCast<uint64_t>(add_constant)), Address(esp, 0));
|
||||
fld(Operand(esp, 0));
|
||||
faddp();
|
||||
bind(¬Negative);
|
||||
|
||||
fstp(Operand(esp, 0));
|
||||
vmovsd(Address(esp, 0), dest);
|
||||
asMasm().freeStack(2*sizeof(intptr_t));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -70,7 +90,7 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatReg
|
||||
// here, each 64-bit part of dest represents following double:
|
||||
// HI(dest) = 0x 1.00000HHHHHHHH * 2**84 == 2**84 + 0x HHHHHHHH 00000000
|
||||
// LO(dest) = 0x 1.00000LLLLLLLL * 2**52 == 2**52 + 0x 00000000 LLLLLLLL
|
||||
movePtr(ImmPtr(TO_DOUBLE), temp);
|
||||
movePtr(ImmWord((uintptr_t)TO_DOUBLE), temp);
|
||||
vpunpckldq(Operand(temp, 0), dest128, dest128);
|
||||
|
||||
// Subtract a constant C2 from dest, for each 64-bit part:
|
||||
@ -806,6 +826,35 @@ MacroAssembler::wasmTruncateFloat32ToUInt32(FloatRegister input, Register output
|
||||
|
||||
//}}} check_macroassembler_style
|
||||
|
||||
void
|
||||
MacroAssemblerX86::convertInt64ToDouble(Register64 input, FloatRegister output)
|
||||
{
|
||||
// Zero the output register to break dependencies, see convertInt32ToDouble.
|
||||
zeroDouble(output);
|
||||
|
||||
asMasm().Push(input.high);
|
||||
asMasm().Push(input.low);
|
||||
fild(Operand(esp, 0));
|
||||
|
||||
fstp(Operand(esp, 0));
|
||||
vmovsd(Address(esp, 0), output);
|
||||
asMasm().freeStack(2*sizeof(intptr_t));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::convertInt64ToFloat32(Register64 input, FloatRegister output)
|
||||
{
|
||||
convertInt64ToDouble(input, output);
|
||||
convertDoubleToFloat32(output, output);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::convertUInt64ToFloat32(Register64 input, FloatRegister output, Register temp)
|
||||
{
|
||||
convertUInt64ToDouble(input, output.asDouble(), temp);
|
||||
convertDoubleToFloat32(output, output);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::wasmTruncateDoubleToInt64(FloatRegister input, Register64 output, Label* oolEntry,
|
||||
Label* oolRejoin, FloatRegister tempReg)
|
||||
|
@ -834,7 +834,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
||||
// Note: this function clobbers the source register.
|
||||
inline void convertUInt32ToFloat32(Register src, FloatRegister dest);
|
||||
|
||||
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
|
||||
void convertUInt64ToFloat32(Register64 src, FloatRegister dest, Register temp);
|
||||
void convertInt64ToFloat32(Register64 src, FloatRegister dest);
|
||||
static bool convertUInt64ToDoubleNeedsTemp();
|
||||
void convertUInt64ToDouble(Register64 src, FloatRegister dest, Register temp);
|
||||
void convertInt64ToDouble(Register64 src, FloatRegister dest);
|
||||
|
||||
void wasmTruncateDoubleToInt64(FloatRegister input, Register64 output, Label* oolEntry,
|
||||
Label* oolRejoin, FloatRegister tempDouble);
|
||||
|
Loading…
x
Reference in New Issue
Block a user