diff --git a/js/src/asmjs/WasmBaselineCompile.cpp b/js/src/asmjs/WasmBaselineCompile.cpp index c9ffc1a54de4..16b8e5ad2b61 100644 --- a/js/src/asmjs/WasmBaselineCompile.cpp +++ b/js/src/asmjs/WasmBaselineCompile.cpp @@ -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); } diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 9e1e0cf433f8..2392530e40da 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -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); diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 3d27bc55ef30..d577c5f0792c 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -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); diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index e0fcd98d4137..a90ffe8b4d4f 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -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); diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index a74dd46d547a..dfceeab71874 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -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)); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index c9b88fd404a4..4e21a74f5bb3 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -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); diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 12b22df59633..260bafcff5e3 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -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(); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 7a77c026ad83..f0279a3b8be3 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -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); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index b023c3c14e7c..05f5afb8e181 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -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(); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 563ddabc9cad..b9bdb7a031e3 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -380,7 +380,8 @@ class MacroAssemblerNone : public Assembler template 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(); } diff --git a/js/src/jit/x64/CodeGenerator-x64.cpp b/js/src/jit/x64/CodeGenerator-x64.cpp index 800b0238e8b0..17b9b31d9913 100644 --- a/js/src/jit/x64/CodeGenerator-x64.cpp +++ b/js/src/jit/x64/CodeGenerator-x64.cpp @@ -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); } diff --git a/js/src/jit/x64/Lowering-x64.cpp b/js/src/jit/x64/Lowering-x64.cpp index 2acc0e7e0261..6185bfd2b24e 100644 --- a/js/src/jit/x64/Lowering-x64.cpp +++ b/js/src/jit/x64/Lowering-x64.cpp @@ -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 diff --git a/js/src/jit/x64/MacroAssembler-x64.cpp b/js/src/jit/x64/MacroAssembler-x64.cpp index 2b8dd4d684de..51b03fa96c66 100644 --- a/js/src/jit/x64/MacroAssembler-x64.cpp +++ b/js/src/jit/x64/MacroAssembler-x64.cpp @@ -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); diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 9453bf593299..0213ba6829d8 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -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); diff --git a/js/src/jit/x86-shared/LIR-x86-shared.h b/js/src/jit/x86-shared/LIR-x86-shared.h index 86b83f6b1a55..842719d5ea08 100644 --- a/js/src/jit/x86-shared/LIR-x86-shared.h +++ b/js/src/jit/x86-shared/LIR-x86-shared.h @@ -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 diff --git a/js/src/jit/x86/CodeGenerator-x86.cpp b/js/src/jit/x86/CodeGenerator-x86.cpp index 69ec5ae533ac..81b2bc695f31 100644 --- a/js/src/jit/x86/CodeGenerator-x86.cpp +++ b/js/src/jit/x86/CodeGenerator-x86.cpp @@ -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); } diff --git a/js/src/jit/x86/Lowering-x86.cpp b/js/src/jit/x86/Lowering-x86.cpp index 97666fdb234f..42926f9797c7 100644 --- a/js/src/jit/x86/Lowering-x86.cpp +++ b/js/src/jit/x86/Lowering-x86.cpp @@ -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 diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 37711f8b4258..12d41d9d3eda 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -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(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) diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index c97504283ed6..993f2036e2bb 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -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);