зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1326027: Remove RawF32 and RawF64; r=luke
MozReview-Commit-ID: ArjweiIrq0j --HG-- extra : rebase_source : bfd12340181f8e7f475164e33a076c687e5d8c8c extra : histedit_source : 8c3691d4fc5fea29fa71130655bce79d6fc7e087%2Ce1b529902b4474cc0a0eb56b465a1fcb8a1eefd8
This commit is contained in:
Родитель
84f0acd454
Коммит
73ec7c660f
|
@ -160,9 +160,9 @@ EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* pt
|
|||
// bits. This isn't strictly required for either ES or wasm, but it does
|
||||
// avoid making constant-folding observable.
|
||||
if (ins->type() == MIRType::Double)
|
||||
return MConstant::New(alloc, wasm::RawF64(ret));
|
||||
return MConstant::NewRawDouble(alloc, ret);
|
||||
if (ins->type() == MIRType::Float32)
|
||||
return MConstant::New(alloc, wasm::RawF32(float(ret)));
|
||||
return MConstant::NewRawFloat32(alloc, float(ret));
|
||||
|
||||
Value retVal;
|
||||
retVal.setNumber(JS::CanonicalizeNaN(ret));
|
||||
|
@ -812,6 +812,18 @@ MConstant::New(TempAllocator::Fallible alloc, const Value& v, CompilerConstraint
|
|||
return new(alloc) MConstant(v, constraints);
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::NewRawFloat32(TempAllocator& alloc, float f)
|
||||
{
|
||||
return new(alloc) MConstant(f);
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::NewRawDouble(TempAllocator& alloc, double d)
|
||||
{
|
||||
return new(alloc) MConstant(d);
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::NewFloat32(TempAllocator& alloc, double d)
|
||||
{
|
||||
|
@ -819,22 +831,6 @@ MConstant::NewFloat32(TempAllocator& alloc, double d)
|
|||
return new(alloc) MConstant(float(d));
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::New(TempAllocator& alloc, wasm::RawF32 f)
|
||||
{
|
||||
auto* c = new(alloc) MConstant(Int32Value(f.bits()), nullptr);
|
||||
c->setResultType(MIRType::Float32);
|
||||
return c;
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::New(TempAllocator& alloc, wasm::RawF64 d)
|
||||
{
|
||||
auto* c = new(alloc) MConstant(int64_t(d.bits()));
|
||||
c->setResultType(MIRType::Double);
|
||||
return c;
|
||||
}
|
||||
|
||||
MConstant*
|
||||
MConstant::NewInt64(TempAllocator& alloc, int64_t i)
|
||||
{
|
||||
|
@ -3299,10 +3295,10 @@ MMinMax::foldsTo(TempAllocator& alloc)
|
|||
if (mozilla::NumberEqualsInt32(result, &cast))
|
||||
return MConstant::New(alloc, Int32Value(cast));
|
||||
} else if (type() == MIRType::Float32) {
|
||||
return MConstant::New(alloc, wasm::RawF32(float(result)));
|
||||
return MConstant::NewRawFloat32(alloc, float(result));
|
||||
} else {
|
||||
MOZ_ASSERT(type() == MIRType::Double);
|
||||
return MConstant::New(alloc, wasm::RawF64(result));
|
||||
return MConstant::NewRawDouble(alloc, result);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4340,10 +4336,8 @@ MToDouble::foldsTo(TempAllocator& alloc)
|
|||
if (input->type() == MIRType::Double)
|
||||
return input;
|
||||
|
||||
if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble()) {
|
||||
double out = input->toConstant()->numberToDouble();
|
||||
return MConstant::New(alloc, wasm::RawF64(out));
|
||||
}
|
||||
if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble())
|
||||
return MConstant::NewRawDouble(alloc, input->toConstant()->numberToDouble());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -4366,10 +4360,8 @@ MToFloat32::foldsTo(TempAllocator& alloc)
|
|||
return input->toToDouble()->input();
|
||||
}
|
||||
|
||||
if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble()) {
|
||||
float out = float(input->toConstant()->numberToDouble());
|
||||
return MConstant::New(alloc, wasm::RawF32(out));
|
||||
}
|
||||
if (input->isConstant() && input->toConstant()->isTypeRepresentableAsDouble())
|
||||
return MConstant::NewRawFloat32(alloc, float(input->toConstant()->numberToDouble()));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -1581,8 +1581,8 @@ class MConstant : public MNullaryInstruction
|
|||
static MConstant* New(TempAllocator::Fallible alloc, const Value& v,
|
||||
CompilerConstraintList* constraints = nullptr);
|
||||
static MConstant* New(TempAllocator& alloc, const Value& v, MIRType type);
|
||||
static MConstant* New(TempAllocator& alloc, wasm::RawF32 bits);
|
||||
static MConstant* New(TempAllocator& alloc, wasm::RawF64 bits);
|
||||
static MConstant* NewRawFloat32(TempAllocator& alloc, float f);
|
||||
static MConstant* NewRawDouble(TempAllocator& alloc, double d);
|
||||
static MConstant* NewFloat32(TempAllocator& alloc, double d);
|
||||
static MConstant* NewInt64(TempAllocator& alloc, int64_t i);
|
||||
static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v);
|
||||
|
@ -1650,22 +1650,14 @@ class MConstant : public MNullaryInstruction
|
|||
bool isInt32(int32_t i) const {
|
||||
return type() == MIRType::Int32 && payload_.i32 == i;
|
||||
}
|
||||
double toDouble() const {
|
||||
const double& toDouble() const {
|
||||
MOZ_ASSERT(type() == MIRType::Double);
|
||||
return payload_.d;
|
||||
}
|
||||
wasm::RawF64 toRawF64() const {
|
||||
MOZ_ASSERT(type() == MIRType::Double);
|
||||
return wasm::RawF64::fromBits(payload_.i64);
|
||||
}
|
||||
float toFloat32() const {
|
||||
const float& toFloat32() const {
|
||||
MOZ_ASSERT(type() == MIRType::Float32);
|
||||
return payload_.f;
|
||||
}
|
||||
wasm::RawF32 toRawF32() const {
|
||||
MOZ_ASSERT(type() == MIRType::Float32);
|
||||
return wasm::RawF32::fromBits(payload_.i32);
|
||||
}
|
||||
JSString* toString() const {
|
||||
MOZ_ASSERT(type() == MIRType::String);
|
||||
return payload_.str;
|
||||
|
|
|
@ -2210,17 +2210,16 @@ Assembler::as_BranchPool(uint32_t value, RepatchLabel* label, ARMBuffer::PoolEnt
|
|||
}
|
||||
|
||||
BufferOffset
|
||||
Assembler::as_FImm64Pool(VFPRegister dest, wasm::RawF64 value, Condition c)
|
||||
Assembler::as_FImm64Pool(VFPRegister dest, double d, Condition c)
|
||||
{
|
||||
MOZ_ASSERT(dest.isDouble());
|
||||
PoolHintPun php;
|
||||
php.phd.init(0, c, PoolHintData::PoolVDTR, dest);
|
||||
uint64_t d = value.bits();
|
||||
return allocEntry(1, 2, (uint8_t*)&php.raw, (uint8_t*)&d);
|
||||
}
|
||||
|
||||
BufferOffset
|
||||
Assembler::as_FImm32Pool(VFPRegister dest, wasm::RawF32 value, Condition c)
|
||||
Assembler::as_FImm32Pool(VFPRegister dest, float f, Condition c)
|
||||
{
|
||||
// Insert floats into the double pool as they have the same limitations on
|
||||
// immediate offset. This wastes 4 bytes padding per float. An alternative
|
||||
|
@ -2228,7 +2227,6 @@ Assembler::as_FImm32Pool(VFPRegister dest, wasm::RawF32 value, Condition c)
|
|||
MOZ_ASSERT(dest.isSingle());
|
||||
PoolHintPun php;
|
||||
php.phd.init(0, c, PoolHintData::PoolVDTR, dest);
|
||||
uint32_t f = value.bits();
|
||||
return allocEntry(1, 1, (uint8_t*)&php.raw, (uint8_t*)&f);
|
||||
}
|
||||
|
||||
|
|
|
@ -1551,9 +1551,9 @@ class Assembler : public AssemblerShared
|
|||
Label* documentation = nullptr);
|
||||
|
||||
// Load a 64 bit floating point immediate from a pool into a register.
|
||||
BufferOffset as_FImm64Pool(VFPRegister dest, wasm::RawF64 value, Condition c = Always);
|
||||
BufferOffset as_FImm64Pool(VFPRegister dest, double value, Condition c = Always);
|
||||
// Load a 32 bit floating point immediate from a pool into a register.
|
||||
BufferOffset as_FImm32Pool(VFPRegister dest, wasm::RawF32 value, Condition c = Always);
|
||||
BufferOffset as_FImm32Pool(VFPRegister dest, float value, Condition c = Always);
|
||||
|
||||
// Atomic instructions: ldrex, ldrexh, ldrexb, strex, strexh, strexb.
|
||||
//
|
||||
|
|
|
@ -25,6 +25,7 @@ using namespace jit;
|
|||
|
||||
using mozilla::Abs;
|
||||
using mozilla::BitwiseCast;
|
||||
using mozilla::IsPositiveZero;
|
||||
|
||||
bool
|
||||
isValueDTRDCandidate(ValueOperand& val)
|
||||
|
@ -1527,19 +1528,19 @@ MacroAssemblerARM::ma_vsqrt_f32(FloatRegister src, FloatRegister dest, Condition
|
|||
}
|
||||
|
||||
static inline uint32_t
|
||||
DoubleHighWord(wasm::RawF64 value)
|
||||
DoubleHighWord(double d)
|
||||
{
|
||||
return static_cast<uint32_t>(value.bits() >> 32);
|
||||
return static_cast<uint32_t>(BitwiseCast<uint64_t>(d) >> 32);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
DoubleLowWord(wasm::RawF64 value)
|
||||
DoubleLowWord(double d)
|
||||
{
|
||||
return value.bits() & uint32_t(0xffffffff);
|
||||
return static_cast<uint32_t>(BitwiseCast<uint64_t>(d)) & uint32_t(0xffffffff);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARM::ma_vimm(wasm::RawF64 value, FloatRegister dest, Condition cc)
|
||||
MacroAssemblerARM::ma_vimm(double value, FloatRegister dest, Condition cc)
|
||||
{
|
||||
if (HasVFPv3()) {
|
||||
if (DoubleLowWord(value) == 0) {
|
||||
|
@ -1562,11 +1563,11 @@ MacroAssemblerARM::ma_vimm(wasm::RawF64 value, FloatRegister dest, Condition cc)
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARM::ma_vimm_f32(wasm::RawF32 value, FloatRegister dest, Condition cc)
|
||||
MacroAssemblerARM::ma_vimm_f32(float value, FloatRegister dest, Condition cc)
|
||||
{
|
||||
VFPRegister vd = VFPRegister(dest).singleOverlay();
|
||||
if (HasVFPv3()) {
|
||||
if (value.bits() == 0) {
|
||||
if (IsPositiveZero(value)) {
|
||||
// To zero a register, load 1.0, then execute sN <- sN - sN.
|
||||
as_vimm(vd, VFPImm::One, cc);
|
||||
as_vsub(vd, vd, vd, cc);
|
||||
|
@ -1580,7 +1581,7 @@ MacroAssemblerARM::ma_vimm_f32(wasm::RawF32 value, FloatRegister dest, Condition
|
|||
// paths. It is still necessary to firstly check that the double low
|
||||
// word is zero because some float32 numbers set these bits and this can
|
||||
// not be ignored.
|
||||
wasm::RawF64 doubleValue(double(value.fp()));
|
||||
double doubleValue(value);
|
||||
if (DoubleLowWord(doubleValue) == 0) {
|
||||
VFPImm enc(DoubleHighWord(doubleValue));
|
||||
if (enc.isValid()) {
|
||||
|
@ -3161,12 +3162,6 @@ MacroAssemblerARMCompat::int32ValueToFloat32(const ValueOperand& operand, FloatR
|
|||
|
||||
void
|
||||
MacroAssemblerARMCompat::loadConstantFloat32(float f, FloatRegister dest)
|
||||
{
|
||||
loadConstantFloat32(wasm::RawF32(f), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
||||
{
|
||||
ma_vimm_f32(f, dest);
|
||||
}
|
||||
|
@ -3231,12 +3226,6 @@ MacroAssemblerARMCompat::loadInt32OrDouble(Register base, Register index,
|
|||
|
||||
void
|
||||
MacroAssemblerARMCompat::loadConstantDouble(double dp, FloatRegister dest)
|
||||
{
|
||||
loadConstantDouble(wasm::RawF64(dp), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARMCompat::loadConstantDouble(wasm::RawF64 dp, FloatRegister dest)
|
||||
{
|
||||
ma_vimm(dp, dest);
|
||||
}
|
||||
|
|
|
@ -376,8 +376,8 @@ class MacroAssemblerARM : public Assembler
|
|||
void ma_vsqrt(FloatRegister src, FloatRegister dest, Condition cc = Always);
|
||||
void ma_vsqrt_f32(FloatRegister src, FloatRegister dest, Condition cc = Always);
|
||||
|
||||
void ma_vimm(wasm::RawF64 value, FloatRegister dest, Condition cc = Always);
|
||||
void ma_vimm_f32(wasm::RawF32 value, FloatRegister dest, Condition cc = Always);
|
||||
void ma_vimm(double value, FloatRegister dest, Condition cc = Always);
|
||||
void ma_vimm_f32(float value, FloatRegister dest, Condition cc = Always);
|
||||
|
||||
void ma_vcmp(FloatRegister src1, FloatRegister src2, Condition cc = Always);
|
||||
void ma_vcmp_f32(FloatRegister src1, FloatRegister src2, Condition cc = Always);
|
||||
|
@ -793,7 +793,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
void loadInt32OrDouble(Register base, Register index,
|
||||
FloatRegister dest, int32_t shift = defaultShift);
|
||||
void loadConstantDouble(double dp, FloatRegister dest);
|
||||
void loadConstantDouble(wasm::RawF64 dp, FloatRegister dest);
|
||||
|
||||
// Treat the value as a boolean, and set condition codes accordingly.
|
||||
Condition testInt32Truthy(bool truthy, const ValueOperand& operand);
|
||||
|
@ -804,7 +803,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest);
|
||||
|
||||
void moveValue(const Value& val, Register type, Register data);
|
||||
|
||||
|
|
|
@ -1403,12 +1403,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
|||
convertInt32ToFloat32(operand.valueReg(), dest);
|
||||
}
|
||||
|
||||
void loadConstantDouble(wasm::RawF64 d, FloatRegister dest) {
|
||||
loadConstantDouble(d.fp(), dest);
|
||||
}
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest) {
|
||||
loadConstantFloat32(f.fp(), dest);
|
||||
}
|
||||
void loadConstantDouble(double d, FloatRegister dest) {
|
||||
Fmov(ARMFPRegister(dest, 64), d);
|
||||
}
|
||||
|
|
|
@ -1007,15 +1007,6 @@ MacroAssemblerMIPSShared::ma_lis(FloatRegister dest, float value)
|
|||
moveToFloat32(ScratchRegister, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSShared::ma_lis(FloatRegister dest, wasm::RawF32 value)
|
||||
{
|
||||
Imm32 imm(value.bits());
|
||||
|
||||
ma_li(ScratchRegister, imm);
|
||||
moveToFloat32(ScratchRegister, dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSShared::ma_liNegZero(FloatRegister dest)
|
||||
{
|
||||
|
|
|
@ -164,7 +164,6 @@ class MacroAssemblerMIPSShared : public Assembler
|
|||
|
||||
// fp instructions
|
||||
void ma_lis(FloatRegister dest, float value);
|
||||
void ma_lis(FloatRegister dest, wasm::RawF32 value);
|
||||
void ma_liNegZero(FloatRegister dest);
|
||||
|
||||
void ma_sd(FloatRegister fd, BaseIndex address);
|
||||
|
|
|
@ -1401,12 +1401,6 @@ MacroAssemblerMIPSCompat::loadConstantFloat32(float f, FloatRegister dest)
|
|||
ma_lis(dest, f);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
||||
{
|
||||
ma_lis(dest, f);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::loadInt32OrDouble(const Address& src, FloatRegister dest)
|
||||
{
|
||||
|
@ -1457,34 +1451,6 @@ MacroAssemblerMIPSCompat::loadConstantDouble(double dp, FloatRegister dest)
|
|||
ma_lid(dest, dp);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPSCompat::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
||||
{
|
||||
struct DoubleStruct {
|
||||
uint32_t lo;
|
||||
uint32_t hi;
|
||||
} ;
|
||||
DoubleStruct intStruct = mozilla::BitwiseCast<DoubleStruct>(d.bits());
|
||||
|
||||
// put hi part of 64 bit value into the odd register
|
||||
if (intStruct.hi == 0) {
|
||||
moveToDoubleHi(zero, dest);
|
||||
} else {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
ma_li(scratch, Imm32(intStruct.hi));
|
||||
moveToDoubleHi(scratch, dest);
|
||||
}
|
||||
|
||||
// put low part of 64 bit value into the even register
|
||||
if (intStruct.lo == 0) {
|
||||
moveToDoubleLo(zero, dest);
|
||||
} else {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
ma_li(scratch, Imm32(intStruct.lo));
|
||||
moveToDoubleLo(scratch, dest);
|
||||
}
|
||||
}
|
||||
|
||||
Register
|
||||
MacroAssemblerMIPSCompat::extractObject(const Address& address, Register scratch)
|
||||
{
|
||||
|
|
|
@ -360,12 +360,10 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
|
|||
void loadInt32OrDouble(Register base, Register index,
|
||||
FloatRegister dest, int32_t shift = defaultShift);
|
||||
void loadConstantDouble(double dp, FloatRegister dest);
|
||||
void loadConstantDouble(wasm::RawF64 d, FloatRegister dest);
|
||||
|
||||
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest);
|
||||
|
||||
void testNullSet(Condition cond, const ValueOperand& value, Register dest);
|
||||
|
||||
|
|
|
@ -1664,12 +1664,6 @@ MacroAssemblerMIPS64Compat::loadConstantFloat32(float f, FloatRegister dest)
|
|||
ma_lis(dest, f);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
||||
{
|
||||
ma_lis(dest, f);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::loadInt32OrDouble(const Address& src, FloatRegister dest)
|
||||
{
|
||||
|
@ -1720,15 +1714,6 @@ MacroAssemblerMIPS64Compat::loadConstantDouble(double dp, FloatRegister dest)
|
|||
ma_lid(dest, dp);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerMIPS64Compat::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
||||
{
|
||||
ImmWord imm(d.bits());
|
||||
|
||||
ma_li(ScratchRegister, imm);
|
||||
moveToDouble(ScratchRegister, dest);
|
||||
}
|
||||
|
||||
Register
|
||||
MacroAssemblerMIPS64Compat::extractObject(const Address& address, Register scratch)
|
||||
{
|
||||
|
|
|
@ -409,12 +409,10 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
void loadInt32OrDouble(const Address& src, FloatRegister dest);
|
||||
void loadInt32OrDouble(const BaseIndex& addr, FloatRegister dest);
|
||||
void loadConstantDouble(double dp, FloatRegister dest);
|
||||
void loadConstantDouble(wasm::RawF64 d, FloatRegister dest);
|
||||
|
||||
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest);
|
||||
|
||||
void testNullSet(Condition cond, const ValueOperand& value, Register dest);
|
||||
|
||||
|
|
|
@ -393,8 +393,6 @@ class MacroAssemblerNone : public Assembler
|
|||
|
||||
void loadConstantDouble(double, FloatRegister) { MOZ_CRASH(); }
|
||||
void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
|
||||
void loadConstantDouble(wasm::RawF64, FloatRegister) { MOZ_CRASH(); }
|
||||
void loadConstantFloat32(wasm::RawF32, FloatRegister) { MOZ_CRASH(); }
|
||||
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
|
||||
|
|
|
@ -858,14 +858,14 @@ class LPointer : public LInstructionHelper<1, 0, 0>
|
|||
// Constant double.
|
||||
class LDouble : public LInstructionHelper<1, 0, 0>
|
||||
{
|
||||
wasm::RawF64 d_;
|
||||
double d_;
|
||||
public:
|
||||
LIR_HEADER(Double);
|
||||
|
||||
explicit LDouble(wasm::RawF64 d) : d_(d)
|
||||
explicit LDouble(double d) : d_(d)
|
||||
{ }
|
||||
|
||||
wasm::RawF64 getDouble() const {
|
||||
const double& getDouble() const {
|
||||
return d_;
|
||||
}
|
||||
};
|
||||
|
@ -873,15 +873,15 @@ class LDouble : public LInstructionHelper<1, 0, 0>
|
|||
// Constant float32.
|
||||
class LFloat32 : public LInstructionHelper<1, 0, 0>
|
||||
{
|
||||
wasm::RawF32 f_;
|
||||
float f_;
|
||||
public:
|
||||
LIR_HEADER(Float32);
|
||||
|
||||
explicit LFloat32(wasm::RawF32 f)
|
||||
explicit LFloat32(float f)
|
||||
: f_(f)
|
||||
{ }
|
||||
|
||||
wasm::RawF32 getFloat() const {
|
||||
const float& getFloat() const {
|
||||
return f_;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -81,10 +81,10 @@ LIRGeneratorShared::visitConstant(MConstant* ins)
|
|||
|
||||
switch (ins->type()) {
|
||||
case MIRType::Double:
|
||||
define(new(alloc()) LDouble(ins->toRawF64()), ins);
|
||||
define(new(alloc()) LDouble(ins->toDouble()), ins);
|
||||
break;
|
||||
case MIRType::Float32:
|
||||
define(new(alloc()) LFloat32(ins->toRawF32()), ins);
|
||||
define(new(alloc()) LFloat32(ins->toFloat32()), ins);
|
||||
break;
|
||||
case MIRType::Boolean:
|
||||
define(new(alloc()) LInteger(ins->toBoolean()), ins);
|
||||
|
|
|
@ -271,10 +271,10 @@ class LIRGeneratorShared : public MDefinitionVisitor
|
|||
|
||||
public:
|
||||
void lowerConstantDouble(double d, MInstruction* mir) {
|
||||
define(new(alloc()) LDouble(wasm::RawF64(d)), mir);
|
||||
define(new(alloc()) LDouble(d), mir);
|
||||
}
|
||||
void lowerConstantFloat32(float f, MInstruction* mir) {
|
||||
define(new(alloc()) LFloat32(wasm::RawF32(f)), mir);
|
||||
define(new(alloc()) LFloat32(f), mir);
|
||||
}
|
||||
|
||||
void visitConstant(MConstant* ins) override;
|
||||
|
|
|
@ -19,7 +19,7 @@ using namespace js;
|
|||
using namespace js::jit;
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
||||
MacroAssemblerX64::loadConstantDouble(double d, FloatRegister dest)
|
||||
{
|
||||
if (maybeInlineDouble(d, dest))
|
||||
return;
|
||||
|
@ -36,7 +36,7 @@ MacroAssemblerX64::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
||||
MacroAssemblerX64::loadConstantFloat32(float f, FloatRegister dest)
|
||||
{
|
||||
if (maybeInlineFloat(f, dest))
|
||||
return;
|
||||
|
@ -60,18 +60,6 @@ MacroAssemblerX64::loadConstantSimd128Int(const SimdConstant& v, FloatRegister d
|
|||
propagateOOM(val->uses.append(CodeOffset(j.offset())));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadConstantFloat32(float f, FloatRegister dest)
|
||||
{
|
||||
loadConstantFloat32(wasm::RawF32(f), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadConstantDouble(double d, FloatRegister dest)
|
||||
{
|
||||
loadConstantDouble(wasm::RawF64(d), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX64::loadConstantSimd128Float(const SimdConstant&v, FloatRegister dest)
|
||||
{
|
||||
|
@ -265,14 +253,14 @@ MacroAssemblerX64::finish()
|
|||
masm.haltingAlign(sizeof(double));
|
||||
for (const Double& d : doubles_) {
|
||||
bindOffsets(d.uses);
|
||||
masm.int64Constant(d.value);
|
||||
masm.doubleConstant(d.value);
|
||||
}
|
||||
|
||||
if (!floats_.empty())
|
||||
masm.haltingAlign(sizeof(float));
|
||||
for (const Float& f : floats_) {
|
||||
bindOffsets(f.uses);
|
||||
masm.int32Constant(f.value);
|
||||
masm.floatConstant(f.value);
|
||||
}
|
||||
|
||||
// SIMD memory values must be suitably aligned.
|
||||
|
|
|
@ -857,8 +857,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
|
||||
void loadConstantDouble(double d, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
void loadConstantDouble(wasm::RawF64 d, FloatRegister dest);
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest);
|
||||
|
||||
void loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest);
|
||||
void loadConstantSimd128Float(const SimdConstant& v, FloatRegister dest);
|
||||
|
|
|
@ -254,15 +254,15 @@ MacroAssemblerX86Shared::getConstant(const typename T::Pod& value, Map& map,
|
|||
}
|
||||
|
||||
MacroAssemblerX86Shared::Float*
|
||||
MacroAssemblerX86Shared::getFloat(wasm::RawF32 f)
|
||||
MacroAssemblerX86Shared::getFloat(float f)
|
||||
{
|
||||
return getConstant<Float, FloatMap>(f.bits(), floatMap_, floats_);
|
||||
return getConstant<Float, FloatMap>(f, floatMap_, floats_);
|
||||
}
|
||||
|
||||
MacroAssemblerX86Shared::Double*
|
||||
MacroAssemblerX86Shared::getDouble(wasm::RawF64 d)
|
||||
MacroAssemblerX86Shared::getDouble(double d)
|
||||
{
|
||||
return getConstant<Double, DoubleMap>(d.bits(), doubleMap_, doubles_);
|
||||
return getConstant<Double, DoubleMap>(d, doubleMap_, doubles_);
|
||||
}
|
||||
|
||||
MacroAssemblerX86Shared::SimdData*
|
||||
|
|
|
@ -66,14 +66,14 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
// Containers use SystemAllocPolicy since wasm releases memory after each
|
||||
// function is compiled, and these need to live until after all functions
|
||||
// are compiled.
|
||||
using Double = Constant<uint64_t>;
|
||||
using Double = Constant<double>;
|
||||
Vector<Double, 0, SystemAllocPolicy> doubles_;
|
||||
typedef HashMap<uint64_t, size_t, DefaultHasher<uint64_t>, SystemAllocPolicy> DoubleMap;
|
||||
typedef HashMap<double, size_t, DefaultHasher<double>, SystemAllocPolicy> DoubleMap;
|
||||
DoubleMap doubleMap_;
|
||||
|
||||
using Float = Constant<uint32_t>;
|
||||
using Float = Constant<float>;
|
||||
Vector<Float, 0, SystemAllocPolicy> floats_;
|
||||
typedef HashMap<uint32_t, size_t, DefaultHasher<uint32_t>, SystemAllocPolicy> FloatMap;
|
||||
typedef HashMap<float, size_t, DefaultHasher<float>, SystemAllocPolicy> FloatMap;
|
||||
FloatMap floatMap_;
|
||||
|
||||
struct SimdData : public Constant<SimdConstant> {
|
||||
|
@ -90,8 +90,8 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
template<class T, class Map>
|
||||
T* getConstant(const typename T::Pod& value, Map& map, Vector<T, 0, SystemAllocPolicy>& vec);
|
||||
|
||||
Float* getFloat(wasm::RawF32 f);
|
||||
Double* getDouble(wasm::RawF64 d);
|
||||
Float* getFloat(float f);
|
||||
Double* getDouble(double d);
|
||||
SimdData* getSimdData(const SimdConstant& v);
|
||||
|
||||
public:
|
||||
|
@ -1210,9 +1210,9 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
|
||||
inline void clampIntToUint8(Register reg);
|
||||
|
||||
bool maybeInlineDouble(wasm::RawF64 d, FloatRegister dest) {
|
||||
bool maybeInlineDouble(double d, FloatRegister dest) {
|
||||
// Loading zero with xor is specially optimized in hardware.
|
||||
if (d.bits() == 0) {
|
||||
if (mozilla::IsPositiveZero(d)) {
|
||||
zeroDouble(dest);
|
||||
return true;
|
||||
}
|
||||
|
@ -1228,9 +1228,9 @@ class MacroAssemblerX86Shared : public Assembler
|
|||
return false;
|
||||
}
|
||||
|
||||
bool maybeInlineFloat(wasm::RawF32 f, FloatRegister dest) {
|
||||
bool maybeInlineFloat(float f, FloatRegister dest) {
|
||||
// See comment above
|
||||
if (f.bits() == 0) {
|
||||
if (mozilla::IsPositiveZero(f)) {
|
||||
zeroFloat32(dest);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -184,7 +184,7 @@ MacroAssembler::add64(Imm64 imm, Register64 dest)
|
|||
void
|
||||
MacroAssembler::addConstantDouble(double d, FloatRegister dest)
|
||||
{
|
||||
Double* dbl = getDouble(wasm::RawF64(d));
|
||||
Double* dbl = getDouble(d);
|
||||
if (!dbl)
|
||||
return;
|
||||
masm.vaddsd_mr(nullptr, dest.encoding(), dest.encoding());
|
||||
|
|
|
@ -111,7 +111,7 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, FloatRegister dest, Reg
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
||||
MacroAssemblerX86::loadConstantDouble(double d, FloatRegister dest)
|
||||
{
|
||||
if (maybeInlineDouble(d, dest))
|
||||
return;
|
||||
|
@ -123,13 +123,7 @@ MacroAssemblerX86::loadConstantDouble(wasm::RawF64 d, FloatRegister dest)
|
|||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::loadConstantDouble(double d, FloatRegister dest)
|
||||
{
|
||||
loadConstantDouble(wasm::RawF64(d), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
||||
MacroAssemblerX86::loadConstantFloat32(float f, FloatRegister dest)
|
||||
{
|
||||
if (maybeInlineFloat(f, dest))
|
||||
return;
|
||||
|
@ -140,12 +134,6 @@ MacroAssemblerX86::loadConstantFloat32(wasm::RawF32 f, FloatRegister dest)
|
|||
propagateOOM(flt->uses.append(CodeOffset(masm.size())));
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::loadConstantFloat32(float f, FloatRegister dest)
|
||||
{
|
||||
loadConstantFloat32(wasm::RawF32(f), dest);
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerX86::loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest)
|
||||
{
|
||||
|
@ -179,7 +167,7 @@ MacroAssemblerX86::finish()
|
|||
CodeOffset cst(masm.currentOffset());
|
||||
for (CodeOffset use : d.uses)
|
||||
addCodeLabel(CodeLabel(use, cst));
|
||||
masm.int64Constant(d.value);
|
||||
masm.doubleConstant(d.value);
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
}
|
||||
|
@ -190,7 +178,7 @@ MacroAssemblerX86::finish()
|
|||
CodeOffset cst(masm.currentOffset());
|
||||
for (CodeOffset use : f.uses)
|
||||
addCodeLabel(CodeLabel(use, cst));
|
||||
masm.int32Constant(f.value);
|
||||
masm.floatConstant(f.value);
|
||||
if (!enoughMemory_)
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -779,8 +779,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||
|
||||
void loadConstantDouble(double d, FloatRegister dest);
|
||||
void loadConstantFloat32(float f, FloatRegister dest);
|
||||
void loadConstantDouble(wasm::RawF64 d, FloatRegister dest);
|
||||
void loadConstantFloat32(wasm::RawF32 f, FloatRegister dest);
|
||||
|
||||
void loadConstantSimd128Int(const SimdConstant& v, FloatRegister dest);
|
||||
void loadConstantSimd128Float(const SimdConstant& v, FloatRegister dest);
|
||||
|
|
|
@ -59,6 +59,7 @@ using mozilla::Compression::LZ4;
|
|||
using mozilla::HashGeneric;
|
||||
using mozilla::IsNaN;
|
||||
using mozilla::IsNegativeZero;
|
||||
using mozilla::IsPositiveZero;
|
||||
using mozilla::IsPowerOfTwo;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Move;
|
||||
|
@ -888,14 +889,14 @@ class NumLit
|
|||
return (uint32_t)toInt32();
|
||||
}
|
||||
|
||||
RawF64 toDouble() const {
|
||||
double toDouble() const {
|
||||
MOZ_ASSERT(which_ == Double);
|
||||
return RawF64(u.scalar_.toDouble());
|
||||
return u.scalar_.toDouble();
|
||||
}
|
||||
|
||||
RawF32 toFloat() const {
|
||||
float toFloat() const {
|
||||
MOZ_ASSERT(which_ == Float);
|
||||
return RawF32(float(u.scalar_.toDouble()));
|
||||
return float(u.scalar_.toDouble());
|
||||
}
|
||||
|
||||
Value scalarValue() const {
|
||||
|
@ -928,9 +929,9 @@ class NumLit
|
|||
case NumLit::BigUnsigned:
|
||||
return toInt32() == 0;
|
||||
case NumLit::Double:
|
||||
return toDouble().bits() == 0;
|
||||
return IsPositiveZero(toDouble());
|
||||
case NumLit::Float:
|
||||
return toFloat().bits() == 0;
|
||||
return IsPositiveZero(toFloat());
|
||||
case NumLit::Int8x16:
|
||||
case NumLit::Uint8x16:
|
||||
case NumLit::Bool8x16:
|
||||
|
@ -7516,14 +7517,14 @@ ValidateGlobalVariable(JSContext* cx, const AsmJSGlobal& global, HandleValue imp
|
|||
float f;
|
||||
if (!RoundFloat32(cx, v, &f))
|
||||
return false;
|
||||
*val = Val(RawF32(f));
|
||||
*val = Val(f);
|
||||
return true;
|
||||
}
|
||||
case ValType::F64: {
|
||||
double d;
|
||||
if (!ToNumber(cx, v, &d))
|
||||
return false;
|
||||
*val = Val(RawF64(d));
|
||||
*val = Val(d);
|
||||
return true;
|
||||
}
|
||||
case ValType::I8x16: {
|
||||
|
|
|
@ -877,8 +877,8 @@ class BaseCompiler
|
|||
RegF64 f64reg_;
|
||||
int32_t i32val_;
|
||||
int64_t i64val_;
|
||||
RawF32 f32val_;
|
||||
RawF64 f64val_;
|
||||
float f32val_;
|
||||
double f64val_;
|
||||
uint32_t slot_;
|
||||
uint32_t offs_;
|
||||
};
|
||||
|
@ -894,8 +894,11 @@ class BaseCompiler
|
|||
RegF64 f64reg() const { MOZ_ASSERT(kind_ == RegisterF64); return f64reg_; }
|
||||
int32_t i32val() const { MOZ_ASSERT(kind_ == ConstI32); return i32val_; }
|
||||
int64_t i64val() const { MOZ_ASSERT(kind_ == ConstI64); return i64val_; }
|
||||
RawF32 f32val() const { MOZ_ASSERT(kind_ == ConstF32); return f32val_; }
|
||||
RawF64 f64val() const { MOZ_ASSERT(kind_ == ConstF64); return f64val_; }
|
||||
// For these two, use an out-param instead of simply returning, to
|
||||
// use the normal stack and not the x87 FP stack (which has effect on
|
||||
// NaNs with the signaling bit set).
|
||||
void f32val(float* out) const { MOZ_ASSERT(kind_ == ConstF32); *out = f32val_; }
|
||||
void f64val(double* out) const { MOZ_ASSERT(kind_ == ConstF64); *out = f64val_; }
|
||||
uint32_t slot() const { MOZ_ASSERT(kind_ > MemLast && kind_ <= LocalLast); return slot_; }
|
||||
uint32_t offs() const { MOZ_ASSERT(isMem()); return offs_; }
|
||||
|
||||
|
@ -905,8 +908,8 @@ class BaseCompiler
|
|||
void setF64Reg(RegF64 r) { kind_ = RegisterF64; f64reg_ = r; }
|
||||
void setI32Val(int32_t v) { kind_ = ConstI32; i32val_ = v; }
|
||||
void setI64Val(int64_t v) { kind_ = ConstI64; i64val_ = v; }
|
||||
void setF32Val(RawF32 v) { kind_ = ConstF32; f32val_ = v; }
|
||||
void setF64Val(RawF64 v) { kind_ = ConstF64; f64val_ = v; }
|
||||
void setF32Val(float v) { kind_ = ConstF32; f32val_ = v; }
|
||||
void setF64Val(double v) { kind_ = ConstF64; f64val_ = v; }
|
||||
void setSlot(Kind k, uint32_t v) { MOZ_ASSERT(k > MemLast && k <= LocalLast); kind_ = k; slot_ = v; }
|
||||
void setOffs(Kind k, uint32_t v) { MOZ_ASSERT(k <= MemLast); kind_ = k; offs_ = v; }
|
||||
};
|
||||
|
@ -1116,7 +1119,9 @@ class BaseCompiler
|
|||
}
|
||||
|
||||
void loadConstF64(FloatRegister r, Stk &src) {
|
||||
masm.loadConstantDouble(src.f64val(), r);
|
||||
double d;
|
||||
src.f64val(&d);
|
||||
masm.loadConstantDouble(d, r);
|
||||
}
|
||||
|
||||
void loadMemF64(FloatRegister r, Stk& src) {
|
||||
|
@ -1133,7 +1138,9 @@ class BaseCompiler
|
|||
}
|
||||
|
||||
void loadConstF32(FloatRegister r, Stk &src) {
|
||||
masm.loadConstantFloat32(src.f32val(), r);
|
||||
float f;
|
||||
src.f32val(&f);
|
||||
masm.loadConstantFloat32(f, r);
|
||||
}
|
||||
|
||||
void loadMemF32(FloatRegister r, Stk& src) {
|
||||
|
@ -1447,12 +1454,12 @@ class BaseCompiler
|
|||
x.setI64Val(v);
|
||||
}
|
||||
|
||||
void pushF64(RawF64 v) {
|
||||
void pushF64(double v) {
|
||||
Stk& x = push();
|
||||
x.setF64Val(v);
|
||||
}
|
||||
|
||||
void pushF32(RawF32 v) {
|
||||
void pushF32(float v) {
|
||||
Stk& x = push();
|
||||
x.setF32Val(v);
|
||||
}
|
||||
|
@ -7168,7 +7175,7 @@ BaseCompiler::emitBody()
|
|||
|
||||
// F32
|
||||
case uint16_t(Op::F32Const): {
|
||||
RawF32 f32;
|
||||
float f32;
|
||||
CHECK(iter_.readF32Const(&f32));
|
||||
if (!deadCode_)
|
||||
pushF32(f32);
|
||||
|
@ -7237,7 +7244,7 @@ BaseCompiler::emitBody()
|
|||
|
||||
// F64
|
||||
case uint16_t(Op::F64Const): {
|
||||
RawF64 f64;
|
||||
double f64;
|
||||
CHECK(iter_.readF64Const(&f64));
|
||||
if (!deadCode_)
|
||||
pushF64(f64);
|
||||
|
|
|
@ -308,16 +308,16 @@ class MOZ_STACK_CLASS OpIter : private Policy
|
|||
*out = d_.uncheckedReadVarU64();
|
||||
return true;
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedF32(RawF32* out) {
|
||||
MOZ_MUST_USE bool readFixedF32(float* out) {
|
||||
if (Validate)
|
||||
return d_.readFixedF32(out);
|
||||
*out = d_.uncheckedReadFixedF32();
|
||||
d_.uncheckedReadFixedF32(out);
|
||||
return true;
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedF64(RawF64* out) {
|
||||
MOZ_MUST_USE bool readFixedF64(double* out) {
|
||||
if (Validate)
|
||||
return d_.readFixedF64(out);
|
||||
*out = d_.uncheckedReadFixedF64();
|
||||
d_.uncheckedReadFixedF64(out);
|
||||
return true;
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedI8x16(I8x16* out) {
|
||||
|
@ -575,8 +575,8 @@ class MOZ_STACK_CLASS OpIter : private Policy
|
|||
MOZ_MUST_USE bool readTeeGlobal(const GlobalDescVector& globals, uint32_t* id, Value* value);
|
||||
MOZ_MUST_USE bool readI32Const(int32_t* i32);
|
||||
MOZ_MUST_USE bool readI64Const(int64_t* i64);
|
||||
MOZ_MUST_USE bool readF32Const(RawF32* f32);
|
||||
MOZ_MUST_USE bool readF64Const(RawF64* f64);
|
||||
MOZ_MUST_USE bool readF32Const(float* f32);
|
||||
MOZ_MUST_USE bool readF64Const(double* f64);
|
||||
MOZ_MUST_USE bool readI8x16Const(I8x16* i8x16);
|
||||
MOZ_MUST_USE bool readI16x8Const(I16x8* i16x8);
|
||||
MOZ_MUST_USE bool readI32x4Const(I32x4* i32x4);
|
||||
|
@ -1618,11 +1618,11 @@ OpIter<Policy>::readI64Const(int64_t* i64)
|
|||
|
||||
template <typename Policy>
|
||||
inline bool
|
||||
OpIter<Policy>::readF32Const(RawF32* f32)
|
||||
OpIter<Policy>::readF32Const(float* f32)
|
||||
{
|
||||
MOZ_ASSERT(Classify(op_) == OpKind::F32);
|
||||
|
||||
RawF32 unused;
|
||||
float unused;
|
||||
if (!readFixedF32(Output ? f32 : &unused))
|
||||
return false;
|
||||
|
||||
|
@ -1634,11 +1634,11 @@ OpIter<Policy>::readF32Const(RawF32* f32)
|
|||
|
||||
template <typename Policy>
|
||||
inline bool
|
||||
OpIter<Policy>::readF64Const(RawF64* f64)
|
||||
OpIter<Policy>::readF64Const(double* f64)
|
||||
{
|
||||
MOZ_ASSERT(Classify(op_) == OpKind::F64);
|
||||
|
||||
RawF64 unused;
|
||||
double unused;
|
||||
if (!readFixedF64(Output ? f64 : &unused))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1044,7 +1044,7 @@ AstDecodeExpr(AstDecodeContext& c)
|
|||
return false;
|
||||
break;
|
||||
case uint16_t(Op::F32Const): {
|
||||
RawF32 f32;
|
||||
float f32;
|
||||
if (!c.iter().readF32Const(&f32))
|
||||
return false;
|
||||
tmp = new(c.lifo) AstConst(Val(f32));
|
||||
|
@ -1053,7 +1053,7 @@ AstDecodeExpr(AstDecodeContext& c)
|
|||
break;
|
||||
}
|
||||
case uint16_t(Op::F64Const): {
|
||||
RawF64 f64;
|
||||
double f64;
|
||||
if (!c.iter().readF64Const(&f64))
|
||||
return false;
|
||||
tmp = new(c.lifo) AstConst(Val(f64));
|
||||
|
|
|
@ -164,13 +164,12 @@ PrintInt64(WasmPrintContext& c, int64_t num)
|
|||
}
|
||||
|
||||
static bool
|
||||
PrintDouble(WasmPrintContext& c, RawF64 num)
|
||||
PrintDouble(WasmPrintContext& c, double d)
|
||||
{
|
||||
double d = num.fp();
|
||||
if (IsNegativeZero(d))
|
||||
return c.buffer.append("-0.0");
|
||||
if (IsNaN(d))
|
||||
return RenderNaN(c.sb(), num);
|
||||
return RenderNaN(c.sb(), d);
|
||||
if (IsInfinite(d)) {
|
||||
if (d > 0)
|
||||
return c.buffer.append("infinity");
|
||||
|
@ -192,12 +191,11 @@ PrintDouble(WasmPrintContext& c, RawF64 num)
|
|||
}
|
||||
|
||||
static bool
|
||||
PrintFloat32(WasmPrintContext& c, RawF32 num)
|
||||
PrintFloat32(WasmPrintContext& c, float f)
|
||||
{
|
||||
float f = num.fp();
|
||||
if (IsNaN(f))
|
||||
return RenderNaN(c.sb(), num) && c.buffer.append(".f");
|
||||
return PrintDouble(c, RawF64(double(f))) &&
|
||||
return RenderNaN(c.sb(), f) && c.buffer.append(".f");
|
||||
return PrintDouble(c, double(f)) &&
|
||||
c.buffer.append("f");
|
||||
}
|
||||
|
||||
|
|
|
@ -101,11 +101,10 @@ RenderInt64(WasmRenderContext& c, int64_t num)
|
|||
}
|
||||
|
||||
static bool
|
||||
RenderDouble(WasmRenderContext& c, RawF64 num)
|
||||
RenderDouble(WasmRenderContext& c, double d)
|
||||
{
|
||||
double d = num.fp();
|
||||
if (IsNaN(d))
|
||||
return RenderNaN(c.sb(), num);
|
||||
return RenderNaN(c.sb(), d);
|
||||
if (IsNegativeZero(d))
|
||||
return c.buffer.append("-0");
|
||||
if (IsInfinite(d)) {
|
||||
|
@ -117,12 +116,11 @@ RenderDouble(WasmRenderContext& c, RawF64 num)
|
|||
}
|
||||
|
||||
static bool
|
||||
RenderFloat32(WasmRenderContext& c, RawF32 num)
|
||||
RenderFloat32(WasmRenderContext& c, float f)
|
||||
{
|
||||
float f = num.fp();
|
||||
if (IsNaN(f))
|
||||
return RenderNaN(c.sb(), num);
|
||||
return RenderDouble(c, RawF64(double(f)));
|
||||
return RenderNaN(c.sb(), f);
|
||||
return RenderDouble(c, double(f));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -343,6 +343,24 @@ class FunctionCompiler
|
|||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(float f)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
MConstant* constant = MConstant::NewRawFloat32(alloc(), f);
|
||||
curBlock_->add(constant);
|
||||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(double d)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
MConstant* constant = MConstant::NewRawDouble(alloc(), d);
|
||||
curBlock_->add(constant);
|
||||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(int64_t i)
|
||||
{
|
||||
if (inDeadCode())
|
||||
|
@ -352,24 +370,6 @@ class FunctionCompiler
|
|||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(RawF32 f)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
MConstant* constant = MConstant::New(alloc(), f);
|
||||
curBlock_->add(constant);
|
||||
return constant;
|
||||
}
|
||||
|
||||
MDefinition* constant(RawF64 d)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
MConstant* constant = MConstant::New(alloc(), d);
|
||||
curBlock_->add(constant);
|
||||
return constant;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
MDefinition* unary(MDefinition* op)
|
||||
{
|
||||
|
@ -3334,7 +3334,7 @@ EmitExpr(FunctionCompiler& f)
|
|||
|
||||
// F32
|
||||
case Op::F32Const: {
|
||||
RawF32 f32;
|
||||
float f32;
|
||||
if (!f.iter().readF32Const(&f32))
|
||||
return false;
|
||||
|
||||
|
@ -3392,7 +3392,7 @@ EmitExpr(FunctionCompiler& f)
|
|||
|
||||
// F64
|
||||
case Op::F64Const: {
|
||||
RawF64 f64;
|
||||
double f64;
|
||||
if (!f.iter().readF64Const(&f64))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
using namespace js;
|
||||
using namespace js::jit;
|
||||
using namespace js::wasm;
|
||||
|
||||
using mozilla::BitwiseCast;
|
||||
using mozilla::CheckedInt;
|
||||
using mozilla::IsNaN;
|
||||
using mozilla::IsSame;
|
||||
|
@ -304,7 +306,9 @@ GetImports(JSContext* cx,
|
|||
uint32_t bits;
|
||||
if (!ReadCustomFloat32NaNObject(cx, v, &bits))
|
||||
return false;
|
||||
val = Val(RawF32::fromBits(bits));
|
||||
float f;
|
||||
BitwiseCast(bits, &f);
|
||||
val = Val(f);
|
||||
break;
|
||||
}
|
||||
if (!v.isNumber())
|
||||
|
@ -312,7 +316,7 @@ GetImports(JSContext* cx,
|
|||
double d;
|
||||
if (!ToNumber(cx, v, &d))
|
||||
return false;
|
||||
val = Val(RawF32(float(d)));
|
||||
val = Val(float(d));
|
||||
break;
|
||||
}
|
||||
case ValType::F64: {
|
||||
|
@ -320,7 +324,9 @@ GetImports(JSContext* cx,
|
|||
uint64_t bits;
|
||||
if (!ReadCustomDoubleNaNObject(cx, v, &bits))
|
||||
return false;
|
||||
val = Val(RawF64::fromBits(bits));
|
||||
double d;
|
||||
BitwiseCast(bits, &d);
|
||||
val = Val(d);
|
||||
break;
|
||||
}
|
||||
if (!v.isNumber())
|
||||
|
@ -328,7 +334,7 @@ GetImports(JSContext* cx,
|
|||
double d;
|
||||
if (!ToNumber(cx, v, &d))
|
||||
return false;
|
||||
val = Val(RawF64(d));
|
||||
val = Val(d);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -766,10 +766,9 @@ GetGlobalExport(JSContext* cx, const GlobalDescVector& globals, uint32_t globalI
|
|||
return true;
|
||||
}
|
||||
case ValType::F32: {
|
||||
float f = val.f32().fp();
|
||||
float f = val.f32();
|
||||
if (JitOptions.wasmTestMode && IsNaN(f)) {
|
||||
uint32_t bits = val.f32().bits();
|
||||
RootedObject obj(cx, CreateCustomNaNObject(cx, (float*)&bits));
|
||||
RootedObject obj(cx, CreateCustomNaNObject(cx, &f));
|
||||
if (!obj)
|
||||
return false;
|
||||
jsval.set(ObjectValue(*obj));
|
||||
|
@ -779,10 +778,9 @@ GetGlobalExport(JSContext* cx, const GlobalDescVector& globals, uint32_t globalI
|
|||
return true;
|
||||
}
|
||||
case ValType::F64: {
|
||||
double d = val.f64().fp();
|
||||
double d = val.f64();
|
||||
if (JitOptions.wasmTestMode && IsNaN(d)) {
|
||||
uint64_t bits = val.f64().bits();
|
||||
RootedObject obj(cx, CreateCustomNaNObject(cx, (double*)&bits));
|
||||
RootedObject obj(cx, CreateCustomNaNObject(cx, &d));
|
||||
if (!obj)
|
||||
return false;
|
||||
jsval.set(ObjectValue(*obj));
|
||||
|
|
|
@ -1780,7 +1780,10 @@ ParseNaNLiteral(WasmParseContext& c, WasmToken token, const char16_t* cur, bool
|
|||
}
|
||||
|
||||
value = (isNegated ? Traits::kSignBit : 0) | Traits::kExponentBits | value;
|
||||
return new (c.lifo) AstConst(Val(Raw<Float>::fromBits(value)));
|
||||
|
||||
Float flt;
|
||||
BitwiseCast(value, &flt);
|
||||
return new (c.lifo) AstConst(Val(flt));
|
||||
|
||||
error:
|
||||
c.ts.generateError(token, c.error);
|
||||
|
@ -1932,7 +1935,7 @@ ParseFloatLiteral(WasmParseContext& c, WasmToken token)
|
|||
}
|
||||
|
||||
if (token.kind() != WasmToken::Float)
|
||||
return new (c.lifo) AstConst(Val(Raw<Float>(result)));
|
||||
return new (c.lifo) AstConst(Val(Float(result)));
|
||||
|
||||
const char16_t* begin = token.begin();
|
||||
const char16_t* end = token.end();
|
||||
|
@ -1983,7 +1986,7 @@ ParseFloatLiteral(WasmParseContext& c, WasmToken token)
|
|||
if (isNegated)
|
||||
result = -result;
|
||||
|
||||
return new (c.lifo) AstConst(Val(Raw<Float>(result)));
|
||||
return new (c.lifo) AstConst(Val(Float(result)));
|
||||
}
|
||||
|
||||
static AstConst*
|
||||
|
|
|
@ -54,18 +54,20 @@ template bool wasm::RenderInBase<10>(StringBuffer& sb, uint64_t num);
|
|||
|
||||
template<class T>
|
||||
bool
|
||||
wasm::RenderNaN(StringBuffer& sb, Raw<T> num)
|
||||
wasm::RenderNaN(StringBuffer& sb, T num)
|
||||
{
|
||||
typedef typename mozilla::SelectTrait<T> Traits;
|
||||
typedef typename Traits::Bits Bits;
|
||||
|
||||
MOZ_ASSERT(IsNaN(num.fp()));
|
||||
MOZ_ASSERT(IsNaN(num));
|
||||
|
||||
if ((num.bits() & Traits::kSignBit) && !sb.append("-"))
|
||||
Bits bits = mozilla::BitwiseCast<Bits>(num);
|
||||
if ((bits & Traits::kSignBit) && !sb.append("-"))
|
||||
return false;
|
||||
if (!sb.append("nan"))
|
||||
return false;
|
||||
|
||||
typename Traits::Bits payload = num.bits() & Traits::kSignificandBits;
|
||||
Bits payload = bits & Traits::kSignificandBits;
|
||||
// Only render the payload if it's not the spec's default NaN.
|
||||
if (payload == ((Traits::kSignificandBits + 1) >> 1))
|
||||
return true;
|
||||
|
@ -74,5 +76,5 @@ wasm::RenderNaN(StringBuffer& sb, Raw<T> num)
|
|||
RenderInBase<16>(sb, payload);
|
||||
}
|
||||
|
||||
template MOZ_MUST_USE bool wasm::RenderNaN(StringBuffer& b, Raw<float> num);
|
||||
template MOZ_MUST_USE bool wasm::RenderNaN(StringBuffer& b, Raw<double> num);
|
||||
template MOZ_MUST_USE bool wasm::RenderNaN(StringBuffer& b, float num);
|
||||
template MOZ_MUST_USE bool wasm::RenderNaN(StringBuffer& b, double num);
|
||||
|
|
|
@ -30,12 +30,9 @@ template<size_t base>
|
|||
MOZ_MUST_USE bool
|
||||
RenderInBase(StringBuffer& sb, uint64_t num);
|
||||
|
||||
template<class T>
|
||||
class Raw;
|
||||
|
||||
template<class T>
|
||||
MOZ_MUST_USE bool
|
||||
RenderNaN(StringBuffer& sb, Raw<T> num);
|
||||
RenderNaN(StringBuffer& sb, T num);
|
||||
|
||||
// Helper class, StringBuffer wrapper, to track the position (line and column)
|
||||
// within the generated source.
|
||||
|
|
|
@ -337,41 +337,6 @@ ToCString(ValType type)
|
|||
return ToCString(ToExprType(type));
|
||||
}
|
||||
|
||||
// Because WebAssembly allows one to define the payload of a NaN value,
|
||||
// including the signal/quiet bit (highest order bit of payload), another
|
||||
// represenation of floating-point values is required: on some platforms (x86
|
||||
// without SSE2), passing a floating-point argument to a function call may use
|
||||
// the x87 stack, which has the side-effect of clearing the signal/quiet bit.
|
||||
// Because the signal/quiet bit must be preserved (by spec), we use the raw
|
||||
// punned integer representation of floating points instead, in function calls.
|
||||
//
|
||||
// When we leave the WebAssembly sandbox back to JS, NaNs are canonicalized, so
|
||||
// this isn't observable from JS.
|
||||
|
||||
template<class T>
|
||||
class Raw
|
||||
{
|
||||
typedef typename mozilla::FloatingPoint<T>::Bits Bits;
|
||||
Bits value_;
|
||||
|
||||
public:
|
||||
Raw() : value_(0) {}
|
||||
|
||||
explicit Raw(T value)
|
||||
: value_(mozilla::BitwiseCast<Bits>(value))
|
||||
{}
|
||||
|
||||
template<class U> MOZ_IMPLICIT Raw(U) = delete;
|
||||
|
||||
static Raw fromBits(Bits bits) { Raw r; r.value_ = bits; return r; }
|
||||
|
||||
Bits bits() const { return value_; }
|
||||
T fp() const { return mozilla::BitwiseCast<T>(value_); }
|
||||
};
|
||||
|
||||
using RawF64 = Raw<double>;
|
||||
using RawF32 = Raw<float>;
|
||||
|
||||
// The Val class represents a single WebAssembly value of a given value type,
|
||||
// mostly for the purpose of numeric literals and initializers. A Val does not
|
||||
// directly map to a JS value since there is not (currently) a precise
|
||||
|
@ -385,8 +350,8 @@ class Val
|
|||
union U {
|
||||
uint32_t i32_;
|
||||
uint64_t i64_;
|
||||
RawF32 f32_;
|
||||
RawF64 f64_;
|
||||
float f32_;
|
||||
double f64_;
|
||||
I8x16 i8x16_;
|
||||
I16x8 i16x8_;
|
||||
I32x4 i32x4_;
|
||||
|
@ -400,10 +365,8 @@ class Val
|
|||
explicit Val(uint32_t i32) : type_(ValType::I32) { u.i32_ = i32; }
|
||||
explicit Val(uint64_t i64) : type_(ValType::I64) { u.i64_ = i64; }
|
||||
|
||||
explicit Val(RawF32 f32) : type_(ValType::F32) { u.f32_ = f32; }
|
||||
explicit Val(RawF64 f64) : type_(ValType::F64) { u.f64_ = f64; }
|
||||
MOZ_IMPLICIT Val(float) = delete;
|
||||
MOZ_IMPLICIT Val(double) = delete;
|
||||
explicit Val(float f32) : type_(ValType::F32) { u.f32_ = f32; }
|
||||
explicit Val(double f64) : type_(ValType::F64) { u.f64_ = f64; }
|
||||
|
||||
explicit Val(const I8x16& i8x16, ValType type = ValType::I8x16) : type_(type) {
|
||||
MOZ_ASSERT(type_ == ValType::I8x16 || type_ == ValType::B8x16);
|
||||
|
@ -426,8 +389,8 @@ class Val
|
|||
|
||||
uint32_t i32() const { MOZ_ASSERT(type_ == ValType::I32); return u.i32_; }
|
||||
uint64_t i64() const { MOZ_ASSERT(type_ == ValType::I64); return u.i64_; }
|
||||
RawF32 f32() const { MOZ_ASSERT(type_ == ValType::F32); return u.f32_; }
|
||||
RawF64 f64() const { MOZ_ASSERT(type_ == ValType::F64); return u.f64_; }
|
||||
const float& f32() const { MOZ_ASSERT(type_ == ValType::F32); return u.f32_; }
|
||||
const double& f64() const { MOZ_ASSERT(type_ == ValType::F64); return u.f64_; }
|
||||
|
||||
const I8x16& i8x16() const {
|
||||
MOZ_ASSERT(type_ == ValType::I8x16 || type_ == ValType::B8x16);
|
||||
|
|
|
@ -1139,14 +1139,14 @@ DecodeInitializerExpression(Decoder& d, const GlobalDescVector& globals, ValType
|
|||
break;
|
||||
}
|
||||
case uint16_t(Op::F32Const): {
|
||||
RawF32 f32;
|
||||
float f32;
|
||||
if (!d.readFixedF32(&f32))
|
||||
return d.fail("failed to read initializer f32 expression");
|
||||
*init = InitExpr(Val(f32));
|
||||
break;
|
||||
}
|
||||
case uint16_t(Op::F64Const): {
|
||||
RawF64 f64;
|
||||
double f64;
|
||||
if (!d.readFixedF64(&f64))
|
||||
return d.fail("failed to read initializer f64 expression");
|
||||
*init = InitExpr(Val(f64));
|
||||
|
|
|
@ -198,11 +198,11 @@ class Encoder
|
|||
MOZ_MUST_USE bool writeFixedU32(uint32_t i) {
|
||||
return write<uint32_t>(i);
|
||||
}
|
||||
MOZ_MUST_USE bool writeFixedF32(RawF32 f) {
|
||||
return write<uint32_t>(f.bits());
|
||||
MOZ_MUST_USE bool writeFixedF32(float f) {
|
||||
return write<float>(f);
|
||||
}
|
||||
MOZ_MUST_USE bool writeFixedF64(RawF64 d) {
|
||||
return write<uint64_t>(d.bits());
|
||||
MOZ_MUST_USE bool writeFixedF64(double d) {
|
||||
return write<double>(d);
|
||||
}
|
||||
MOZ_MUST_USE bool writeFixedI8x16(const I8x16& i8x16) {
|
||||
return write<I8x16>(i8x16);
|
||||
|
@ -437,19 +437,11 @@ class Decoder
|
|||
MOZ_MUST_USE bool readFixedU32(uint32_t* u) {
|
||||
return read<uint32_t>(u);
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedF32(RawF32* f) {
|
||||
uint32_t u;
|
||||
if (!read<uint32_t>(&u))
|
||||
return false;
|
||||
*f = RawF32::fromBits(u);
|
||||
return true;
|
||||
MOZ_MUST_USE bool readFixedF32(float* f) {
|
||||
return read<float>(f);
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedF64(RawF64* d) {
|
||||
uint64_t u;
|
||||
if (!read<uint64_t>(&u))
|
||||
return false;
|
||||
*d = RawF64::fromBits(u);
|
||||
return true;
|
||||
MOZ_MUST_USE bool readFixedF64(double* d) {
|
||||
return read<double>(d);
|
||||
}
|
||||
MOZ_MUST_USE bool readFixedI8x16(I8x16* i8x16) {
|
||||
return read<I8x16>(i8x16);
|
||||
|
@ -556,11 +548,11 @@ class Decoder
|
|||
uint32_t uncheckedReadFixedU32() {
|
||||
return uncheckedRead<uint32_t>();
|
||||
}
|
||||
RawF32 uncheckedReadFixedF32() {
|
||||
return RawF32::fromBits(uncheckedRead<uint32_t>());
|
||||
void uncheckedReadFixedF32(float* out) {
|
||||
uncheckedRead<float>(out);
|
||||
}
|
||||
RawF64 uncheckedReadFixedF64() {
|
||||
return RawF64::fromBits(uncheckedRead<uint64_t>());
|
||||
void uncheckedReadFixedF64(double* out) {
|
||||
uncheckedRead<double>(out);
|
||||
}
|
||||
template <typename UInt>
|
||||
UInt uncheckedReadVarU() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче