--- a/js/src/jit/MacroAssembler-inl.h
+++ b/js/src/jit/MacroAssembler-inl.h
@@ -511,16 +511,25 @@ MacroAssembler::addToStackPtr(T t)
template <typename T> void
MacroAssembler::addStackPtrTo(T t)
{
addPtr(getStackPointer(), t);
}
#endif // !JS_CODEGEN_ARM64
+void
+MacroAssembler::canonicalizeFloat(FloatRegister reg)
+{
+ Label notNaN;
+ branchFloat(DoubleOrdered, reg, reg, ¬NaN);
+ loadConstantFloat32(float(JS::GenericNaN()), reg);
+ bind(¬NaN);
+}
+
template <typename T>
void
MacroAssembler::storeObjectOrNull(Register src, const T& dest)
{
Label notNull, done;
branchTestPtr(Assembler::NonZero, src, src, ¬Null);
storeValue(NullValue(), dest);
jump(&done);
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -836,16 +836,19 @@ class MacroAssembler : public MacroAssem
inline void branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs, Label* label)
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
// This function compares a Value (lhs) which is having a private pointer
// boxed inside a js::Value, with a raw pointer (rhs).
inline void branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label) PER_ARCH;
+ inline void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
+ Label* label) PER_SHARED_ARCH;
+
template <class L>
inline void branchTest32(Condition cond, Register lhs, Register rhs, L label) PER_SHARED_ARCH;
template <class L>
inline void branchTest32(Condition cond, Register lhs, Imm32 rhs, L label) PER_SHARED_ARCH;
inline void branchTest32(Condition cond, const Address& lhs, Imm32 rhh, Label* label) PER_SHARED_ARCH;
inline void branchTest32(Condition cond, const AbsoluteAddress& lhs, Imm32 rhs, Label* label)
DEFINED_ON(arm, arm64, mips_shared, x86, x64);
@@ -1117,22 +1120,17 @@ class MacroAssembler : public MacroAssem
void canonicalizeDouble(FloatRegister reg) {
Label notNaN;
branchDouble(DoubleOrdered, reg, reg, ¬NaN);
loadConstantDouble(JS::GenericNaN(), reg);
bind(¬NaN);
}
- void canonicalizeFloat(FloatRegister reg) {
- Label notNaN;
- branchFloat(DoubleOrdered, reg, reg, ¬NaN);
- loadConstantFloat32(float(JS::GenericNaN()), reg);
- bind(¬NaN);
- }
+ inline void canonicalizeFloat(FloatRegister reg);
template<typename T>
void loadFromTypedArray(Scalar::Type arrayType, const T& src, AnyRegister dest, Register temp, Label* fail,
bool canonicalizeDoubles = true, unsigned numElems = 0);
template<typename T>
void loadFromTypedArray(Scalar::Type arrayType, const T& src, const ValueOperand& dest, bool allowDouble,
Register temp, Label* fail);
--- a/js/src/jit/arm/MacroAssembler-arm-inl.h
+++ b/js/src/jit/arm/MacroAssembler-arm-inl.h
@@ -570,16 +570,40 @@ MacroAssembler::branchPtr(Condition cond
}
void
MacroAssembler::branchPrivatePtr(Condition cond, const Address& lhs, Register rhs, Label* label)
{
branchPtr(cond, lhs, rhs, label);
}
+void
+MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
+ Label* label)
+{
+ compareFloat(lhs, rhs);
+
+ if (cond == DoubleNotEqual) {
+ // Force the unordered cases not to jump.
+ Label unordered;
+ ma_b(&unordered, VFP_Unordered);
+ ma_b(label, VFP_NotEqualOrUnordered);
+ bind(&unordered);
+ return;
+ }
+
+ if (cond == DoubleEqualOrUnordered) {
+ ma_b(label, VFP_Unordered);
+ ma_b(label, VFP_Equal);
+ return;
+ }
+
+ ma_b(label, ConditionFromDoubleCondition(cond));
+}
+
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
// x86 likes test foo, foo rather than cmp foo, #0.
// Convert the former into the latter.
if (lhs == rhs && (cond == Zero || cond == NonZero))
--- a/js/src/jit/arm/MacroAssembler-arm.cpp
+++ b/js/src/jit/arm/MacroAssembler-arm.cpp
@@ -2534,40 +2534,16 @@ MacroAssemblerARMCompat::compareFloat(Fl
as_vcmpz(VFPRegister(lhs).singleOverlay());
else
as_vcmp(VFPRegister(lhs).singleOverlay(), VFPRegister(rhs).singleOverlay());
// Move vector status bits to normal status flags.
as_vmrs(pc);
}
-void
-MacroAssemblerARMCompat::branchFloat(DoubleCondition cond, FloatRegister lhs,
- FloatRegister rhs, Label* label)
-{
- compareFloat(lhs, rhs);
-
- if (cond == DoubleNotEqual) {
- // Force the unordered cases not to jump.
- Label unordered;
- ma_b(&unordered, VFP_Unordered);
- ma_b(label, VFP_NotEqualOrUnordered);
- bind(&unordered);
- return;
- }
-
- if (cond == DoubleEqualOrUnordered) {
- ma_b(label, VFP_Unordered);
- ma_b(label, VFP_Equal);
- return;
- }
-
- ma_b(label, ConditionFromDoubleCondition(cond));
-}
-
Assembler::Condition
MacroAssemblerARMCompat::testInt32(Assembler::Condition cond, const ValueOperand& value)
{
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
ma_cmp(value.typeReg(), ImmType(JSVAL_TYPE_INT32));
return cond;
}
--- a/js/src/jit/arm/MacroAssembler-arm.h
+++ b/js/src/jit/arm/MacroAssembler-arm.h
@@ -1451,18 +1451,16 @@ class MacroAssemblerARMCompat : public M
// (On non-simulator builds, does nothing.)
void simulatorStop(const char* msg);
void compareDouble(FloatRegister lhs, FloatRegister rhs);
void branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
Label* label);
void compareFloat(FloatRegister lhs, FloatRegister rhs);
- void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
- Label* label);
void checkStackAlignment();
// If source is a double, load it into dest. If source is int32, convert it
// to double. Else, branch to failure.
void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
void
--- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h
@@ -647,16 +647,39 @@ MacroAssembler::branchPrivatePtr(Conditi
const Register scratch = temps.AcquireX().asUnsized();
if (rhs != scratch)
movePtr(rhs, scratch);
// Instead of unboxing lhs, box rhs and do direct comparison with lhs.
rshiftPtr(Imm32(1), scratch);
branchPtr(cond, lhs, scratch, label);
}
+void
+MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
+ Label* label)
+{
+ compareFloat(cond, lhs, rhs);
+ switch (cond) {
+ case DoubleNotEqual: {
+ Label unordered;
+ // not equal *and* ordered
+ branch(Overflow, &unordered);
+ branch(NotEqual, label);
+ bind(&unordered);
+ break;
+ }
+ case DoubleEqualOrUnordered:
+ branch(Overflow, label);
+ branch(Equal, label);
+ break;
+ default:
+ branch(Condition(cond), label);
+ }
+}
+
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
// x86 prefers |test foo, foo| to |cmp foo, #0|.
// Convert the former to the latter for ARM.
if (lhs == rhs && (cond == Zero || cond == NonZero))
--- a/js/src/jit/arm64/MacroAssembler-arm64.h
+++ b/js/src/jit/arm64/MacroAssembler-arm64.h
@@ -1615,35 +1615,16 @@ class MacroAssemblerCompat : public vixl
default:
branch(Condition(cond), label);
}
}
void compareFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs) {
Fcmp(ARMFPRegister(lhs, 32), ARMFPRegister(rhs, 32));
}
- void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label) {
- compareFloat(cond, lhs, rhs);
- switch (cond) {
- case DoubleNotEqual: {
- Label unordered;
- // not equal *and* ordered
- branch(Overflow, &unordered);
- branch(NotEqual, label);
- bind(&unordered);
- break;
- }
- case DoubleEqualOrUnordered:
- branch(Overflow, label);
- branch(Equal, label);
- break;
- default:
- branch(Condition(cond), label);
- }
- }
void branchNegativeZero(FloatRegister reg, Register scratch, Label* label) {
MOZ_CRASH("branchNegativeZero");
}
void branchNegativeZeroFloat32(FloatRegister reg, Register scratch, Label* label) {
MOZ_CRASH("branchNegativeZeroFloat32");
}
--- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h
+++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h
@@ -340,16 +340,23 @@ MacroAssembler::branchPtr(Condition cond
void
MacroAssembler::branchPtr(Condition cond, wasm::SymbolicAddress lhs, Register rhs, Label* label)
{
loadPtr(lhs, SecondScratchReg);
branchPtr(cond, SecondScratchReg, rhs, label);
}
+void
+MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
+ Label* label)
+{
+ ma_bc1s(lhs, rhs, label, cond);
+}
+
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
if (lhs == rhs) {
ma_b(lhs, rhs, label, cond);
} else {
--- a/js/src/jit/mips32/MacroAssembler-mips32.cpp
+++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp
@@ -1111,23 +1111,16 @@ MacroAssembler::clampDoubleToUint8(Float
void
MacroAssemblerMIPSCompat::branchDouble(DoubleCondition cond, FloatRegister lhs,
FloatRegister rhs, Label* label)
{
ma_bc1d(lhs, rhs, label, cond);
}
-void
-MacroAssemblerMIPSCompat::branchFloat(DoubleCondition cond, FloatRegister lhs,
- FloatRegister rhs, Label* label)
-{
- ma_bc1s(lhs, rhs, label, cond);
-}
-
// higher level tag testing code
Operand
MacroAssemblerMIPSCompat::ToPayload(Operand base)
{
return Operand(Register::FromCode(base.base()), base.disp() + PAYLOAD_OFFSET);
}
Operand
--- a/js/src/jit/mips32/MacroAssembler-mips32.h
+++ b/js/src/jit/mips32/MacroAssembler-mips32.h
@@ -1073,19 +1073,16 @@ class MacroAssemblerMIPSCompat : public
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
void breakpoint();
void branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
Label* label);
- void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
- Label* label);
-
void checkStackAlignment();
void alignStackPointer();
void restoreStackPointer();
static void calculateAlignedStackPointer(void** stackPointer);
// If source is a double, load it into dest. If source is int32,
// convert it to double. Else, branch to failure.
--- a/js/src/jit/mips64/MacroAssembler-mips64.cpp
+++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp
@@ -1252,23 +1252,16 @@ MacroAssembler::clampDoubleToUint8(Float
void
MacroAssemblerMIPS64Compat::branchDouble(DoubleCondition cond, FloatRegister lhs,
FloatRegister rhs, Label* label)
{
ma_bc1d(lhs, rhs, label, cond);
}
void
-MacroAssemblerMIPS64Compat::branchFloat(DoubleCondition cond, FloatRegister lhs,
- FloatRegister rhs, Label* label)
-{
- ma_bc1s(lhs, rhs, label, cond);
-}
-
-void
MacroAssemblerMIPS64Compat::branchTestGCThing(Condition cond, const Address& address, Label* label)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
extractTag(address, SecondScratchReg);
ma_b(SecondScratchReg, ImmTag(JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET), label,
(cond == Equal) ? AboveOrEqual : Below);
}
void
--- a/js/src/jit/mips64/MacroAssembler-mips64.h
+++ b/js/src/jit/mips64/MacroAssembler-mips64.h
@@ -1083,19 +1083,16 @@ class MacroAssemblerMIPS64Compat : publi
void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest);
void breakpoint();
void branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
Label* label);
- void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
- Label* label);
-
void checkStackAlignment();
static void calculateAlignedStackPointer(void** stackPointer);
// If source is a double, load it into dest. If source is int32,
// convert it to double. Else, branch to failure.
void ensureDouble(const ValueOperand& source, FloatRegister dest, Label* failure);
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -242,17 +242,16 @@ class MacroAssemblerNone : public Assemb
void testUndefinedSet(Condition, ValueOperand, Register) { MOZ_CRASH(); }
template <typename T, typename S> void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); }
template <typename T, typename S> void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); }
template <typename T, typename S> void branchAdd32(Condition, T, S, Label*) { MOZ_CRASH(); }
template <typename T, typename S> void branchSub32(Condition, T, S, Label*) { MOZ_CRASH(); }
template <typename T, typename S> void branchDouble(DoubleCondition, T, S, Label*) { MOZ_CRASH(); }
- template <typename T, typename S> void branchFloat(DoubleCondition, T, S, Label*) { MOZ_CRASH(); }
template <typename T, typename S> void decBranchPtr(Condition, T, S, Label*) { MOZ_CRASH(); }
template <typename T, typename S> void mov(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void movq(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void movePtr(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void move32(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void moveFloat32(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void moveDouble(T, S) { MOZ_CRASH(); }
template <typename T, typename S> void move64(T, S) { MOZ_CRASH(); }
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h
@@ -289,16 +289,40 @@ MacroAssembler::branchPtr(Condition cond
}
void
MacroAssembler::branchPtr(Condition cond, const Address& lhs, ImmWord rhs, Label* label)
{
branchPtrImpl(cond, lhs, rhs, label);
}
+void
+MacroAssembler::branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs,
+ Label* label)
+{
+ compareFloat(cond, lhs, rhs);
+
+ if (cond == DoubleEqual) {
+ Label unordered;
+ j(Parity, &unordered);
+ j(Equal, label);
+ bind(&unordered);
+ return;
+ }
+
+ if (cond == DoubleNotEqualOrUnordered) {
+ j(NotEqual, label);
+ j(Parity, label);
+ return;
+ }
+
+ MOZ_ASSERT(!(cond & DoubleConditionBitSpecial));
+ j(ConditionFromDoubleCondition(cond), label);
+}
+
template <class L>
void
MacroAssembler::branchTest32(Condition cond, Register lhs, Register rhs, L label)
{
MOZ_ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == NotSigned);
test32(lhs, rhs);
j(cond, label);
}
--- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h
@@ -131,36 +131,16 @@ class MacroAssemblerX86Shared : public A
}
void compareFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs) {
if (cond & DoubleConditionBitInvert)
vucomiss(lhs, rhs);
else
vucomiss(rhs, lhs);
}
- void branchFloat(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label)
- {
- compareFloat(cond, lhs, rhs);
-
- if (cond == DoubleEqual) {
- Label unordered;
- j(Parity, &unordered);
- j(Equal, label);
- bind(&unordered);
- return;
- }
- if (cond == DoubleNotEqualOrUnordered) {
- j(NotEqual, label);
- j(Parity, label);
- return;
- }
-
- MOZ_ASSERT(!(cond & DoubleConditionBitSpecial));
- j(ConditionFromDoubleCondition(cond), label);
- }
void branchNegativeZero(FloatRegister reg, Register scratch, Label* label, bool maybeNonZero = true);
void branchNegativeZeroFloat32(FloatRegister reg, Register scratch, Label* label);
void move32(Imm32 imm, Register dest) {
// Use the ImmWord version of mov to register, which has special
// optimizations. Casting to uint32_t here ensures that the value
// is zero-extended.