Add unary and binary helpers that automatically demote and promote when dealing with integer operations (not used yet, need loop typemap peeling in place first.)

This commit is contained in:
Andreas Gal 2008-07-06 13:16:34 -07:00
parent 4e1aa1d977
commit d30b7d1c8a
3 changed files with 63 additions and 85 deletions

View File

@ -678,7 +678,7 @@ TraceRecorder::adjustType(jsval& v, int type)
printf("getType(v): %d type: %d\n", getType(v), type); printf("getType(v): %d type: %d\n", getType(v), type);
/* if its an integer now, but we want a double at entry, make it so */ /* if its an integer now, but we want a double at entry, make it so */
if (getType(v) == JSVAL_INT && type == JSVAL_DOUBLE) { if (getType(v) == JSVAL_INT && type == JSVAL_DOUBLE) {
set(&v, i2f(get(&v))); set(&v, lir->ins1(LIR_i2f, get(&v)));
return true; return true;
} }
/* fail, incompatible types */ /* fail, incompatible types */
@ -891,24 +891,6 @@ TraceRecorder::stack(int n, LIns* i)
set(&stackval(n), i); set(&stackval(n), i);
} }
LIns*
TraceRecorder::i2f(LIns* i)
{
return lir->ins1(LIR_i2f, i);
}
LIns*
TraceRecorder::u2f(LIns* u)
{
return lir->ins1(LIR_u2f, u);
}
LIns*
TraceRecorder::f2i(LIns* f)
{
return lir->insCall(F_doubleToInt32, &f);
}
bool TraceRecorder::ifop(bool sense) bool TraceRecorder::ifop(bool sense)
{ {
jsval& v = stackval(-1); jsval& v = stackval(-1);
@ -988,6 +970,46 @@ TraceRecorder::cmp(LOpcode op, bool negate)
return false; return false;
} }
bool
TraceRecorder::unary(LOpcode op)
{
jsval& v = stackval(-1);
bool intop = !(op & LIR64);
if (isNumber(v)) {
LIns* a = get(&v);
if (intop)
a = lir->insCall(F_doubleToInt32, &a);
a = lir->ins1(op, a);
if (intop)
a = lir->ins1(LIR_i2f, a);
set(&v, a);
return true;
}
return false;
}
bool
TraceRecorder::binary(LOpcode op)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
bool intop = !(op & LIR64);
if (isNumber(l) && isNumber(r)) {
LIns* a = get(&l);
LIns* b = get(&r);
if (intop) {
a = lir->insCall(op == LIR_ush ? F_doubleToUint32 : F_doubleToInt32, &a);
b = lir->insCall(F_doubleToInt32, &b);
}
a = lir->ins2(op, a, b);
if (intop)
a = lir->ins1(op == LIR_ush ? LIR_u2f : LIR_i2f, a);
set(&l, a);
return true;
}
return false;
}
bool bool
TraceRecorder::iunary(LOpcode op) TraceRecorder::iunary(LOpcode op)
{ {
@ -1011,48 +1033,6 @@ TraceRecorder::ibinary(LOpcode op)
return false; return false;
} }
bool
TraceRecorder::bbinary(LOpcode op)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
if (JSVAL_IS_BOOLEAN(l) && JSVAL_IS_BOOLEAN(r)) {
LIns* result = lir->ins2(op, get(&l), get(&r));
set(&l, result);
return true;
}
return false;
}
bool
TraceRecorder::dbinary(LOpcode op)
{
jsval& r = stackval(-1);
jsval& l = stackval(-2);
if (isNumber(l) && isNumber(r)) {
/* if we store our operands currently as int, we have to cast them to float */
LIns* l_ins = get(&l);
if (isInt(l))
l_ins = i2f(l_ins);
LIns* r_ins = get(&r);
if (isInt(r))
r_ins = i2f(r_ins);
set(&l, lir->ins2(op, l_ins, r_ins));
return true;
}
return false;
}
void
TraceRecorder::demote(jsval& v, jsdouble result)
{
jsint i;
if (JSDOUBLE_IS_INT(result, i)) {
LIns* v_ins = get(&v);
set(&v, lir->insCall(F_doubleToInt32, &v_ins));
}
}
bool bool
TraceRecorder::map_is_native(JSObjectMap* map, LIns* map_ins) TraceRecorder::map_is_native(JSObjectMap* map, LIns* map_ins)
{ {
@ -1376,34 +1356,18 @@ bool TraceRecorder::JSOP_URSH()
} }
bool TraceRecorder::JSOP_ADD() bool TraceRecorder::JSOP_ADD()
{ {
if (dbinary(LIR_fadd)) {
demote(stackval(-2), asNumber(stackval(-2)) + asNumber(stackval(-1)));
return true;
}
return false; return false;
} }
bool TraceRecorder::JSOP_SUB() bool TraceRecorder::JSOP_SUB()
{ {
if (dbinary(LIR_fsub)) {
demote(stackval(-2), asNumber(stackval(-2)) - asNumber(stackval(-1)));
return true;
}
return false; return false;
} }
bool TraceRecorder::JSOP_MUL() bool TraceRecorder::JSOP_MUL()
{ {
if (dbinary(LIR_fmul)) {
demote(stackval(-2), asNumber(stackval(-2)) - asNumber(stackval(-1)));
return true;
}
return false; return false;
} }
bool TraceRecorder::JSOP_DIV() bool TraceRecorder::JSOP_DIV()
{ {
if (dbinary(LIR_fdiv)) {
demote(stackval(-2), asNumber(stackval(-2)) - asNumber(stackval(-1)));
return true;
}
return false; return false;
} }
bool TraceRecorder::JSOP_MOD() bool TraceRecorder::JSOP_MOD()
@ -1655,11 +1619,25 @@ bool TraceRecorder::JSOP_TRUE()
} }
bool TraceRecorder::JSOP_OR() bool TraceRecorder::JSOP_OR()
{ {
return bbinary(LIR_or); jsval& r = stackval(-1);
jsval& l = stackval(-2);
if (JSVAL_IS_BOOLEAN(l) && JSVAL_IS_BOOLEAN(r)) {
LIns* result = lir->ins2(LIR_or, get(&l), get(&r));
set(&l, result);
return true;
}
return false;
} }
bool TraceRecorder::JSOP_AND() bool TraceRecorder::JSOP_AND()
{ {
return bbinary(LIR_and); jsval& r = stackval(-1);
jsval& l = stackval(-2);
if (JSVAL_IS_BOOLEAN(l) && JSVAL_IS_BOOLEAN(r)) {
LIns* result = lir->ins2(LIR_and, get(&l), get(&r));
set(&l, result);
return true;
}
return false;
} }
bool TraceRecorder::JSOP_TABLESWITCH() bool TraceRecorder::JSOP_TABLESWITCH()
{ {

View File

@ -149,17 +149,16 @@ class TraceRecorder {
nanojit::LIns* stack(int n); nanojit::LIns* stack(int n);
void stack(int n, nanojit::LIns* i); void stack(int n, nanojit::LIns* i);
nanojit::LIns* i2f(nanojit::LIns* i);
nanojit::LIns* u2f(nanojit::LIns* u);
nanojit::LIns* f2i(nanojit::LIns* f);
bool ifop(bool sense); bool ifop(bool sense);
bool inc(jsval& v, jsint incr, bool pre); bool inc(jsval& v, jsint incr, bool pre);
bool cmp(nanojit::LOpcode op, bool negate = false); bool cmp(nanojit::LOpcode op, bool negate = false);
bool unary(nanojit::LOpcode op);
bool binary(nanojit::LOpcode op);
bool ibinary(nanojit::LOpcode op); bool ibinary(nanojit::LOpcode op);
bool iunary(nanojit::LOpcode op); bool iunary(nanojit::LOpcode op);
bool bbinary(nanojit::LOpcode op); bool bbinary(nanojit::LOpcode op);
bool dbinary(nanojit::LOpcode op);
void demote(jsval& v, jsdouble result); void demote(jsval& v, jsdouble result);
bool map_is_native(JSObjectMap* map, nanojit::LIns* map_ins); bool map_is_native(JSObjectMap* map, nanojit::LIns* map_ins);

View File

@ -2,7 +2,8 @@ f = function() {
var q = 1; var q = 1;
//for (var j = 0; j < 500; ++j) //for (var j = 0; j < 500; ++j)
for (var i = 0; i < 5000; ++i) for (var i = 0; i < 5000; ++i)
q += 2.5; //q += 2.5;
++q;
print("q=" + q + " i=" + i); print("q=" + q + " i=" + i);
} }