Added LIR_float to distinguish NULL from 0.0 on x64 (bug 513838, r=gal,rreitmai).

This commit is contained in:
David Anderson 2009-09-01 14:26:24 -07:00
parent 84f6367d69
commit 21466cd521
5 changed files with 73 additions and 30 deletions

View File

@ -1000,7 +1000,7 @@ demote(LirWriter *out, LIns* i)
return iu2fArg(i); return iu2fArg(i);
if (i->isconst()) if (i->isconst())
return i; return i;
AvmAssert(i->isconstq()); JS_ASSERT(i->isconstf());
double cf = i->imm64f(); double cf = i->imm64f();
int32_t ci = cf > 0x7fffffff ? uint32_t(cf) : int32_t(cf); int32_t ci = cf > 0x7fffffff ? uint32_t(cf) : int32_t(cf);
return out->insImm(ci); return out->insImm(ci);
@ -1011,7 +1011,7 @@ isPromoteInt(LIns* i)
{ {
if (isi2f(i) || i->isconst()) if (isi2f(i) || i->isconst())
return true; return true;
if (!i->isconstq()) if (!i->isconstf())
return false; return false;
jsdouble d = i->imm64f(); jsdouble d = i->imm64f();
return d == jsdouble(jsint(d)) && !JSDOUBLE_IS_NEGZERO(d); return d == jsdouble(jsint(d)) && !JSDOUBLE_IS_NEGZERO(d);
@ -1022,7 +1022,7 @@ isPromoteUint(LIns* i)
{ {
if (isu2f(i) || i->isconst()) if (isu2f(i) || i->isconst())
return true; return true;
if (!i->isconstq()) if (!i->isconstf())
return false; return false;
jsdouble d = i->imm64f(); jsdouble d = i->imm64f();
return d == jsdouble(jsuint(d)) && !JSDOUBLE_IS_NEGZERO(d); return d == jsdouble(jsuint(d)) && !JSDOUBLE_IS_NEGZERO(d);
@ -1286,13 +1286,13 @@ public:
{ {
if (ci == &js_DoubleToUint32_ci) { if (ci == &js_DoubleToUint32_ci) {
LIns* s0 = args[0]; LIns* s0 = args[0];
if (s0->isconstq()) if (s0->isconstf())
return out->insImm(js_DoubleToECMAUint32(s0->imm64f())); return out->insImm(js_DoubleToECMAUint32(s0->imm64f()));
if (isi2f(s0) || isu2f(s0)) if (isi2f(s0) || isu2f(s0))
return iu2fArg(s0); return iu2fArg(s0);
} else if (ci == &js_DoubleToInt32_ci) { } else if (ci == &js_DoubleToInt32_ci) {
LIns* s0 = args[0]; LIns* s0 = args[0];
if (s0->isconstq()) if (s0->isconstf())
return out->insImm(js_DoubleToECMAInt32(s0->imm64f())); return out->insImm(js_DoubleToECMAInt32(s0->imm64f()));
if (s0->isop(LIR_fadd) || s0->isop(LIR_fsub)) { if (s0->isop(LIR_fadd) || s0->isop(LIR_fsub)) {
LIns* lhs = s0->oprnd1(); 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); return lir->insCall(&js_dmod_ci, args);
} }
LIns* result = lir->ins2(v, s0, s1); 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; return result;
} }
@ -7160,7 +7160,7 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
r = v0 / v1; r = v0 / v1;
break; break;
case LIR_fmod: case LIR_fmod:
if (v0 < 0 || v1 == 0 || (s1->isconstq() && v1 < 0)) if (v0 < 0 || v1 == 0 || (s1->isconstf() && v1 < 0))
goto out; goto out;
r = js_dmod(v0, v1); r = js_dmod(v0, v1);
break; break;
@ -7358,7 +7358,7 @@ TraceRecorder::ifop()
cond = !JSDOUBLE_IS_NaN(d) && d; cond = !JSDOUBLE_IS_NaN(d) && d;
x = lir->ins2(LIR_and, x = lir->ins2(LIR_and,
lir->ins2(LIR_feq, v_ins, v_ins), 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)) { } else if (JSVAL_IS_STRING(v)) {
cond = JSVAL_TO_STRING(v)->length() != 0; cond = JSVAL_TO_STRING(v)->length() != 0;
x = lir->ins2(LIR_piand, x = lir->ins2(LIR_piand,
@ -8981,7 +8981,7 @@ TraceRecorder::record_JSOP_NOT()
} }
if (isNumber(v)) { if (isNumber(v)) {
LIns* v_ins = get(&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)))); lir->ins_eq0(lir->ins2(LIR_feq, v_ins, v_ins))));
return JSRS_CONTINUE; return JSRS_CONTINUE;
} }
@ -9070,7 +9070,7 @@ TraceRecorder::record_JSOP_POS()
return JSRS_CONTINUE; return JSRS_CONTINUE;
if (JSVAL_IS_NULL(v)) { if (JSVAL_IS_NULL(v)) {
set(&v, lir->insImmq(0)); set(&v, lir->insImmf(0));
return JSRS_CONTINUE; return JSRS_CONTINUE;
} }
@ -9306,7 +9306,7 @@ TraceRecorder::emitNativeCall(JSTraceableNative* known, uintN argc, LIns* args[]
break; break;
case FAIL_NEG: case FAIL_NEG:
res_ins = lir->ins1(LIR_i2f, res_ins); 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; break;
case FAIL_VOID: case FAIL_VOID:
guard(false, lir->ins2i(LIR_eq, res_ins, JSVAL_TO_SPECIAL(JSVAL_VOID)), OOM_EXIT); 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) { if (afp) {
uintN int_idx = JSVAL_TO_INT(idx); uintN int_idx = JSVAL_TO_INT(idx);
jsval* vp = &afp->argv[int_idx]; jsval* vp = &afp->argv[int_idx];
if (idx_ins->isconstq()) { if (idx_ins->isconstf()) {
if (int_idx >= 0 && int_idx < afp->argc) if (int_idx >= 0 && int_idx < afp->argc)
v_ins = get(vp); v_ins = get(vp);
else else
@ -11441,7 +11441,7 @@ TraceRecorder::record_JSOP_STRING()
JS_REQUIRES_STACK JSRecordingStatus JS_REQUIRES_STACK JSRecordingStatus
TraceRecorder::record_JSOP_ZERO() TraceRecorder::record_JSOP_ZERO()
{ {
stack(0, lir->insImmq(0)); stack(0, lir->insImmf(0));
return JSRS_CONTINUE; return JSRS_CONTINUE;
} }

View File

@ -929,6 +929,7 @@ namespace nanojit
asm_int(ins); asm_int(ins);
break; break;
} }
case LIR_float:
case LIR_quad: case LIR_quad:
{ {
countlir_imm(); countlir_imm();

View File

@ -302,6 +302,19 @@ namespace nanojit
return ins; 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) LInsp LirBufWriter::insSkip(size_t payload_szB)
{ {
// First, round up payload_szB to a multiple of the word size. To // First, round up payload_szB to a multiple of the word size. To
@ -485,7 +498,12 @@ namespace nanojit
bool LIns::isconstq() const 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 bool LIns::isconstp() const
@ -938,16 +956,6 @@ namespace nanojit
return ins2i(LIR_eq, oprnd1, 0); 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) LIns* LirWriter::qjoin(LInsp lo, LInsp hi)
{ {
return ins2(LIR_qjoin, lo, hi); return ins2(LIR_qjoin, lo, hi);
@ -1184,6 +1192,7 @@ namespace nanojit
switch (op) { switch (op) {
case LIR_int: case LIR_int:
return hashimm(i->imm32()); return hashimm(i->imm32());
case LIR_float:
case LIR_quad: case LIR_quad:
return hashimmq(i->imm64()); return hashimmq(i->imm64());
default: default:
@ -1223,6 +1232,7 @@ namespace nanojit
switch (op) { switch (op) {
case LIR_int: case LIR_int:
return a->imm32() == b->imm32(); return a->imm32() == b->imm32();
case LIR_float:
case LIR_quad: case LIR_quad:
return a->imm64() == b->imm64(); return a->imm64() == b->imm64();
default: default:
@ -1310,7 +1320,7 @@ namespace nanojit
return k; 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; uint32_t cap = m_cap;
const LInsp *list = m_list; const LInsp *list = m_list;
@ -1319,7 +1329,7 @@ namespace nanojit
uint32_t n = 7 << 1; uint32_t n = 7 << 1;
LInsp k; LInsp k;
while ((k = list[hash]) != NULL && while ((k = list[hash]) != NULL &&
(!k->isconstq() || k->imm64() != a)) (k->opcode() != v || k->imm64() != a))
{ {
hash = (hash + (n += 2)) & bitmask; // quadratic probe hash = (hash + (n += 2)) & bitmask; // quadratic probe
} }
@ -1630,6 +1640,9 @@ namespace nanojit
formatImm(ref->imm64_0(), buf); formatImm(ref->imm64_0(), buf);
#endif #endif
} }
else if (ref->isconstf()) {
VMPI_sprintf(buf, "%g", ref->imm64f());
}
else if (ref->isconst()) { else if (ref->isconst()) {
formatImm(ref->imm32(), buf); formatImm(ref->imm32(), buf);
} }
@ -1680,6 +1693,12 @@ namespace nanojit
break; break;
} }
case LIR_float:
{
VMPI_sprintf(s, "%s = %s #%g", formatRef(i), lirNames[op], i->imm64f());
break;
}
case LIR_start: case LIR_start:
VMPI_sprintf(s, "%s", lirNames[op]); VMPI_sprintf(s, "%s", lirNames[op]);
break; break;
@ -1857,12 +1876,26 @@ namespace nanojit
LIns* CseFilter::insImmq(uint64_t q) LIns* CseFilter::insImmq(uint64_t q)
{ {
uint32_t k; uint32_t k;
LInsp found = exprs.find64(q, k); LInsp found = exprs.find64(LIR_quad, q, k);
if (found) if (found)
return found; return found;
return exprs.add(out->insImmq(q), k); 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) LIns* CseFilter::ins0(LOpcode v)
{ {
if (v == LIR_label) if (v == LIR_label)

View File

@ -756,6 +756,8 @@ namespace nanojit
bool isconstq() const; bool isconstq() const;
// True if the instruction is a constant pointer value. // True if the instruction is a constant pointer value.
bool isconstp() const; bool isconstp() const;
// True if the instruction is a constant float value.
bool isconstf() const;
bool isBranch() const { bool isBranch() const {
return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j); return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j);
} }
@ -842,6 +844,9 @@ namespace nanojit
virtual LInsp insImmq(uint64_t imm) { virtual LInsp insImmq(uint64_t imm) {
return out->insImmq(imm); return out->insImmq(imm);
} }
virtual LInsp insImmf(double d) {
return out->insImmf(d);
}
virtual LInsp insLoad(LOpcode op, LIns* base, int32_t d) { virtual LInsp insLoad(LOpcode op, LIns* base, int32_t d) {
return out->insLoad(op, base, d); return out->insLoad(op, base, d);
} }
@ -871,7 +876,6 @@ namespace nanojit
LIns* ins2i(LOpcode op, LIns *oprnd1, int32_t); LIns* ins2i(LOpcode op, LIns *oprnd1, int32_t);
LIns* qjoin(LInsp lo, LInsp hi); LIns* qjoin(LInsp lo, LInsp hi);
LIns* insImmPtr(const void *ptr); LIns* insImmPtr(const void *ptr);
LIns* insImmf(double f);
}; };
@ -1031,6 +1035,9 @@ namespace nanojit
LIns* insImmq(uint64_t imm) { LIns* insImmq(uint64_t imm) {
return add(out->insImmq(imm)); return add(out->insImmq(imm));
} }
LIns* insImmf(double d) {
return add(out->insImmf(d));
}
}; };
#endif #endif
@ -1067,7 +1074,7 @@ namespace nanojit
LInsHashSet(Allocator&); LInsHashSet(Allocator&);
LInsp find32(int32_t a, uint32_t &i); 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 find1(LOpcode v, LInsp a, uint32_t &i);
LInsp find2(LOpcode v, LInsp a, LInsp b, 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); LInsp find3(LOpcode v, LInsp a, LInsp b, LInsp c, uint32_t &i);
@ -1092,6 +1099,7 @@ namespace nanojit
CseFilter(LirWriter *out, Allocator&); CseFilter(LirWriter *out, Allocator&);
LIns* insImm(int32_t imm); LIns* insImm(int32_t imm);
LIns* insImmq(uint64_t q); LIns* insImmq(uint64_t q);
LIns* insImmf(double d);
LIns* ins0(LOpcode v); LIns* ins0(LOpcode v);
LIns* ins1(LOpcode v, LInsp); LIns* ins1(LOpcode v, LInsp);
LIns* ins2(LOpcode v, LInsp, LInsp); LIns* ins2(LOpcode v, LInsp, LInsp);
@ -1172,6 +1180,7 @@ namespace nanojit
LInsp insParam(int32_t i, int32_t kind); LInsp insParam(int32_t i, int32_t kind);
LInsp insImm(int32_t imm); LInsp insImm(int32_t imm);
LInsp insImmq(uint64_t imm); LInsp insImmq(uint64_t imm);
LInsp insImmf(double d);
LInsp insCall(const CallInfo *call, LInsp args[]); LInsp insCall(const CallInfo *call, LInsp args[]);
LInsp insGuard(LOpcode op, LInsp cond, LIns *x); LInsp insGuard(LOpcode op, LInsp cond, LIns *x);
LInsp insBranch(LOpcode v, LInsp condition, LInsp to); LInsp insBranch(LOpcode v, LInsp condition, LInsp to);

View File

@ -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(unused51_64, 51,-1, None)
OPDEF64(unused52_64, 52,-1, None) OPDEF64(unused52_64, 52,-1, None)
OPDEF64(unused53_64, 53,-1, None) OPDEF64(unused53_64, 53,-1, None)
OPDEF64(unused54_64, 54,-1, None) OPDEF64(float, 54, 0, I64)
// 64bit equivalents for integer comparisons // 64bit equivalents for integer comparisons
OPDEF64(qeq, LIR_eq, 2, Op2) // integer equality OPDEF64(qeq, LIR_eq, 2, Op2) // integer equality