diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 4f70abf7d8a..5d57999fe26 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -1000,7 +1000,7 @@ demote(LirWriter *out, LIns* i) return iu2fArg(i); if (i->isconst()) return i; - AvmAssert(i->isconstq()); + JS_ASSERT(i->isconstf()); double cf = i->imm64f(); int32_t ci = cf > 0x7fffffff ? uint32_t(cf) : int32_t(cf); return out->insImm(ci); @@ -1011,7 +1011,7 @@ isPromoteInt(LIns* i) { if (isi2f(i) || i->isconst()) return true; - if (!i->isconstq()) + if (!i->isconstf()) return false; jsdouble d = i->imm64f(); return d == jsdouble(jsint(d)) && !JSDOUBLE_IS_NEGZERO(d); @@ -1022,7 +1022,7 @@ isPromoteUint(LIns* i) { if (isu2f(i) || i->isconst()) return true; - if (!i->isconstq()) + if (!i->isconstf()) return false; jsdouble d = i->imm64f(); return d == jsdouble(jsuint(d)) && !JSDOUBLE_IS_NEGZERO(d); @@ -1286,13 +1286,13 @@ public: { if (ci == &js_DoubleToUint32_ci) { LIns* s0 = args[0]; - if (s0->isconstq()) + if (s0->isconstf()) return out->insImm(js_DoubleToECMAUint32(s0->imm64f())); if (isi2f(s0) || isu2f(s0)) return iu2fArg(s0); } else if (ci == &js_DoubleToInt32_ci) { LIns* s0 = args[0]; - if (s0->isconstq()) + if (s0->isconstf()) return out->insImm(js_DoubleToECMAInt32(s0->imm64f())); if (s0->isop(LIR_fadd) || s0->isop(LIR_fsub)) { LIns* lhs = s0->oprnd1(); @@ -7136,7 +7136,7 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1) return lir->insCall(&js_dmod_ci, args); } LIns* result = lir->ins2(v, s0, s1); - JS_ASSERT_IF(s0->isconstq() && s1->isconstq(), result->isconstq()); + JS_ASSERT_IF(s0->isconstf() && s1->isconstf(), result->isconstf()); return result; } @@ -7160,7 +7160,7 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1) r = v0 / v1; break; case LIR_fmod: - if (v0 < 0 || v1 == 0 || (s1->isconstq() && v1 < 0)) + if (v0 < 0 || v1 == 0 || (s1->isconstf() && v1 < 0)) goto out; r = js_dmod(v0, v1); break; @@ -7358,7 +7358,7 @@ TraceRecorder::ifop() cond = !JSDOUBLE_IS_NaN(d) && d; x = lir->ins2(LIR_and, lir->ins2(LIR_feq, v_ins, v_ins), - lir->ins_eq0(lir->ins2(LIR_feq, v_ins, lir->insImmq(0)))); + lir->ins_eq0(lir->ins2(LIR_feq, v_ins, lir->insImmf(0)))); } else if (JSVAL_IS_STRING(v)) { cond = JSVAL_TO_STRING(v)->length() != 0; x = lir->ins2(LIR_piand, @@ -8981,7 +8981,7 @@ TraceRecorder::record_JSOP_NOT() } if (isNumber(v)) { LIns* v_ins = get(&v); - set(&v, lir->ins2(LIR_or, lir->ins2(LIR_feq, v_ins, lir->insImmq(0)), + set(&v, lir->ins2(LIR_or, lir->ins2(LIR_feq, v_ins, lir->insImmf(0)), lir->ins_eq0(lir->ins2(LIR_feq, v_ins, v_ins)))); return JSRS_CONTINUE; } @@ -9070,7 +9070,7 @@ TraceRecorder::record_JSOP_POS() return JSRS_CONTINUE; if (JSVAL_IS_NULL(v)) { - set(&v, lir->insImmq(0)); + set(&v, lir->insImmf(0)); return JSRS_CONTINUE; } @@ -9306,7 +9306,7 @@ TraceRecorder::emitNativeCall(JSTraceableNative* known, uintN argc, LIns* args[] break; case FAIL_NEG: res_ins = lir->ins1(LIR_i2f, res_ins); - guard(false, lir->ins2(LIR_flt, res_ins, lir->insImmq(0)), OOM_EXIT); + guard(false, lir->ins2(LIR_flt, res_ins, lir->insImmf(0)), OOM_EXIT); break; case FAIL_VOID: guard(false, lir->ins2i(LIR_eq, res_ins, JSVAL_TO_SPECIAL(JSVAL_VOID)), OOM_EXIT); @@ -10354,7 +10354,7 @@ TraceRecorder::record_JSOP_GETELEM() if (afp) { uintN int_idx = JSVAL_TO_INT(idx); jsval* vp = &afp->argv[int_idx]; - if (idx_ins->isconstq()) { + if (idx_ins->isconstf()) { if (int_idx >= 0 && int_idx < afp->argc) v_ins = get(vp); else @@ -11441,7 +11441,7 @@ TraceRecorder::record_JSOP_STRING() JS_REQUIRES_STACK JSRecordingStatus TraceRecorder::record_JSOP_ZERO() { - stack(0, lir->insImmq(0)); + stack(0, lir->insImmf(0)); return JSRS_CONTINUE; } diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index 35dc2e1c9e6..769ad9a4455 100644 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -929,6 +929,7 @@ namespace nanojit asm_int(ins); break; } + case LIR_float: case LIR_quad: { countlir_imm(); diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index 92e4ebc4fb4..ea9b13d29df 100644 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -302,6 +302,19 @@ namespace nanojit return ins; } + LInsp LirBufWriter::insImmf(double d) + { + LInsI64* insI64 = (LInsI64*)_buf->makeRoom(sizeof(LInsI64)); + LIns* ins = insI64->getLIns(); + union { + double d; + uint64_t q; + } u; + u.d = d; + ins->initLInsI64(LIR_float, u.q); + return ins; + } + LInsp LirBufWriter::insSkip(size_t payload_szB) { // First, round up payload_szB to a multiple of the word size. To @@ -485,7 +498,12 @@ namespace nanojit bool LIns::isconstq() const { - return opcode() == LIR_quad; + return opcode() == LIR_quad || opcode() == LIR_float; + } + + bool LIns::isconstf() const + { + return opcode() == LIR_float; } bool LIns::isconstp() const @@ -938,16 +956,6 @@ namespace nanojit return ins2i(LIR_eq, oprnd1, 0); } - LIns* LirWriter::insImmf(double f) - { - union { - double f; - uint64_t q; - } u; - u.f = f; - return insImmq(u.q); - } - LIns* LirWriter::qjoin(LInsp lo, LInsp hi) { return ins2(LIR_qjoin, lo, hi); @@ -1184,6 +1192,7 @@ namespace nanojit switch (op) { case LIR_int: return hashimm(i->imm32()); + case LIR_float: case LIR_quad: return hashimmq(i->imm64()); default: @@ -1223,6 +1232,7 @@ namespace nanojit switch (op) { case LIR_int: return a->imm32() == b->imm32(); + case LIR_float: case LIR_quad: return a->imm64() == b->imm64(); default: @@ -1310,7 +1320,7 @@ namespace nanojit return k; } - LInsp LInsHashSet::find64(uint64_t a, uint32_t &i) + LInsp LInsHashSet::find64(LOpcode v, uint64_t a, uint32_t &i) { uint32_t cap = m_cap; const LInsp *list = m_list; @@ -1319,7 +1329,7 @@ namespace nanojit uint32_t n = 7 << 1; LInsp k; while ((k = list[hash]) != NULL && - (!k->isconstq() || k->imm64() != a)) + (k->opcode() != v || k->imm64() != a)) { hash = (hash + (n += 2)) & bitmask; // quadratic probe } @@ -1630,6 +1640,9 @@ namespace nanojit formatImm(ref->imm64_0(), buf); #endif } + else if (ref->isconstf()) { + VMPI_sprintf(buf, "%g", ref->imm64f()); + } else if (ref->isconst()) { formatImm(ref->imm32(), buf); } @@ -1680,6 +1693,12 @@ namespace nanojit break; } + case LIR_float: + { + VMPI_sprintf(s, "%s = %s #%g", formatRef(i), lirNames[op], i->imm64f()); + break; + } + case LIR_start: VMPI_sprintf(s, "%s", lirNames[op]); break; @@ -1857,12 +1876,26 @@ namespace nanojit LIns* CseFilter::insImmq(uint64_t q) { uint32_t k; - LInsp found = exprs.find64(q, k); + LInsp found = exprs.find64(LIR_quad, q, k); if (found) return found; return exprs.add(out->insImmq(q), k); } + LIns* CseFilter::insImmf(double d) + { + uint32_t k; + union { + double d; + uint64_t u64; + } u; + u.d = d; + LInsp found = exprs.find64(LIR_float, u.u64, k); + if (found) + return found; + return exprs.add(out->insImmf(d), k); + } + LIns* CseFilter::ins0(LOpcode v) { if (v == LIR_label) diff --git a/js/src/nanojit/LIR.h b/js/src/nanojit/LIR.h index 81c6fd69590..004b6b4d921 100644 --- a/js/src/nanojit/LIR.h +++ b/js/src/nanojit/LIR.h @@ -756,6 +756,8 @@ namespace nanojit bool isconstq() const; // True if the instruction is a constant pointer value. bool isconstp() const; + // True if the instruction is a constant float value. + bool isconstf() const; bool isBranch() const { return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j); } @@ -842,6 +844,9 @@ namespace nanojit virtual LInsp insImmq(uint64_t imm) { return out->insImmq(imm); } + virtual LInsp insImmf(double d) { + return out->insImmf(d); + } virtual LInsp insLoad(LOpcode op, LIns* base, int32_t d) { return out->insLoad(op, base, d); } @@ -871,7 +876,6 @@ namespace nanojit LIns* ins2i(LOpcode op, LIns *oprnd1, int32_t); LIns* qjoin(LInsp lo, LInsp hi); LIns* insImmPtr(const void *ptr); - LIns* insImmf(double f); }; @@ -1031,6 +1035,9 @@ namespace nanojit LIns* insImmq(uint64_t imm) { return add(out->insImmq(imm)); } + LIns* insImmf(double d) { + return add(out->insImmf(d)); + } }; #endif @@ -1067,7 +1074,7 @@ namespace nanojit LInsHashSet(Allocator&); LInsp find32(int32_t a, uint32_t &i); - LInsp find64(uint64_t a, uint32_t &i); + LInsp find64(LOpcode v, uint64_t a, uint32_t &i); LInsp find1(LOpcode v, LInsp a, uint32_t &i); LInsp find2(LOpcode v, LInsp a, LInsp b, uint32_t &i); LInsp find3(LOpcode v, LInsp a, LInsp b, LInsp c, uint32_t &i); @@ -1092,6 +1099,7 @@ namespace nanojit CseFilter(LirWriter *out, Allocator&); LIns* insImm(int32_t imm); LIns* insImmq(uint64_t q); + LIns* insImmf(double d); LIns* ins0(LOpcode v); LIns* ins1(LOpcode v, LInsp); LIns* ins2(LOpcode v, LInsp, LInsp); @@ -1172,6 +1180,7 @@ namespace nanojit LInsp insParam(int32_t i, int32_t kind); LInsp insImm(int32_t imm); LInsp insImmq(uint64_t imm); + LInsp insImmf(double d); LInsp insCall(const CallInfo *call, LInsp args[]); LInsp insGuard(LOpcode op, LInsp cond, LIns *x); LInsp insBranch(LOpcode v, LInsp condition, LInsp to); diff --git a/js/src/nanojit/LIRopcode.tbl b/js/src/nanojit/LIRopcode.tbl index e31607cdbb3..e667ab8be06 100644 --- a/js/src/nanojit/LIRopcode.tbl +++ b/js/src/nanojit/LIRopcode.tbl @@ -250,7 +250,7 @@ OPDEF64(qjoin, 50, 2, Op2) // join two 32-bit values (1st arg is low bi OPDEF64(unused51_64, 51,-1, None) OPDEF64(unused52_64, 52,-1, None) OPDEF64(unused53_64, 53,-1, None) -OPDEF64(unused54_64, 54,-1, None) +OPDEF64(float, 54, 0, I64) // 64bit equivalents for integer comparisons OPDEF64(qeq, LIR_eq, 2, Op2) // integer equality