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);
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;
}

View File

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

View File

@ -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)

View File

@ -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);

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(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