зеркало из https://github.com/mozilla/pjs.git
Bug 525413 - lirasm: avoid operandCount, r=graydon.
--HG-- extra : convert_revision : f35c3aab85189126ca884e976372050c3278324f
This commit is contained in:
Родитель
425771a170
Коммит
f867541f61
|
@ -200,7 +200,7 @@ public:
|
||||||
token.data.clear();
|
token.data.clear();
|
||||||
mLine.clear();
|
mLine.clear();
|
||||||
} else {
|
} else {
|
||||||
cerr << mLineno << ": error: Unrecognized character in file." << endl;
|
cerr << "line " << mLineno << ": error: Unrecognized character in file." << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ public:
|
||||||
bool mVerbose;
|
bool mVerbose;
|
||||||
Fragments mFragments;
|
Fragments mFragments;
|
||||||
Assembler mAssm;
|
Assembler mAssm;
|
||||||
map<string, pair<LOpcode, size_t> > mOpMap;
|
map<string, LOpcode> mOpMap;
|
||||||
|
|
||||||
void bad(const string &msg) {
|
void bad(const string &msg) {
|
||||||
cerr << "error: " << msg << endl;
|
cerr << "error: " << msg << endl;
|
||||||
|
@ -312,11 +312,11 @@ private:
|
||||||
void tokenizeLine(LirTokenStream &in, LirToken &token);
|
void tokenizeLine(LirTokenStream &in, LirToken &token);
|
||||||
void need(size_t);
|
void need(size_t);
|
||||||
LIns *ref(const string &);
|
LIns *ref(const string &);
|
||||||
LIns *assemble_call(const string &);
|
LIns *assemble_jump(bool isCond);
|
||||||
LIns *assemble_general();
|
|
||||||
LIns *assemble_guard();
|
|
||||||
LIns *assemble_jump();
|
|
||||||
LIns *assemble_load();
|
LIns *assemble_load();
|
||||||
|
LIns *assemble_call(const string &);
|
||||||
|
LIns *assemble_ret(ReturnType rt);
|
||||||
|
LIns *assemble_guard(bool isCond);
|
||||||
void bad(const string &msg);
|
void bad(const string &msg);
|
||||||
void nyi(const string &opname);
|
void nyi(const string &opname);
|
||||||
void extract_any_label(string &lab, char lab_delim);
|
void extract_any_label(string &lab, char lab_delim);
|
||||||
|
@ -382,20 +382,21 @@ imm(const string &s)
|
||||||
uint64_t
|
uint64_t
|
||||||
quad(const string &s)
|
quad(const string &s)
|
||||||
{
|
{
|
||||||
stringstream tmp1(s), tmp2(s);
|
stringstream tmp(s);
|
||||||
union {
|
uint64_t ret;
|
||||||
uint64_t u64;
|
|
||||||
double d;
|
|
||||||
} pun;
|
|
||||||
if ((s.find("0x") == 0 || s.find("0X") == 0) &&
|
if ((s.find("0x") == 0 || s.find("0X") == 0) &&
|
||||||
(tmp1 >> hex >> pun.u64 && tmp1.eof()))
|
(tmp >> hex >> ret && tmp.eof())) {
|
||||||
return pun.u64;
|
return ret;
|
||||||
if ((s.find(".") != string::npos) &&
|
}
|
||||||
(tmp2 >> pun.d && tmp2.eof()))
|
|
||||||
return pun.u64;
|
|
||||||
return lexical_cast<uint64_t>(s);
|
return lexical_cast<uint64_t>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
immf(const string &s)
|
||||||
|
{
|
||||||
|
return lexical_cast<double>(s);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename t> t
|
template<typename t> t
|
||||||
pop_front(vector<t> &vec)
|
pop_front(vector<t> &vec)
|
||||||
{
|
{
|
||||||
|
@ -524,7 +525,8 @@ FragmentAssembler::~FragmentAssembler()
|
||||||
void
|
void
|
||||||
FragmentAssembler::bad(const string &msg)
|
FragmentAssembler::bad(const string &msg)
|
||||||
{
|
{
|
||||||
cerr << "instruction " << mLineno << ": " << msg << endl;
|
cerr << "line " << mLineno << ": " << msg << endl;
|
||||||
|
exit(1);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,24 +555,24 @@ FragmentAssembler::ref(const string &lab)
|
||||||
}
|
}
|
||||||
|
|
||||||
LIns *
|
LIns *
|
||||||
FragmentAssembler::assemble_jump()
|
FragmentAssembler::assemble_jump(bool isCond)
|
||||||
{
|
{
|
||||||
LIns *target = NULL;
|
LIns *condition;
|
||||||
LIns *condition = NULL;
|
|
||||||
|
|
||||||
if (mOpcode == LIR_j) {
|
if (isCond) {
|
||||||
need(1);
|
|
||||||
} else {
|
|
||||||
need(2);
|
need(2);
|
||||||
string cond = pop_front(mTokens);
|
string cond = pop_front(mTokens);
|
||||||
condition = ref(cond);
|
condition = ref(cond);
|
||||||
|
} else {
|
||||||
|
need(1);
|
||||||
|
condition = NULL;
|
||||||
}
|
}
|
||||||
string name = pop_front(mTokens);
|
string name = pop_front(mTokens);
|
||||||
if (mLabels.find(name) != mLabels.end()) {
|
if (mLabels.find(name) != mLabels.end()) {
|
||||||
target = ref(name);
|
LIns *target = ref(name);
|
||||||
return mLir->insBranch(mOpcode, condition, target);
|
return mLir->insBranch(mOpcode, condition, target);
|
||||||
} else {
|
} else {
|
||||||
LIns *ins = mLir->insBranch(mOpcode, condition, target);
|
LIns *ins = mLir->insBranch(mOpcode, condition, NULL);
|
||||||
mFwdJumps.insert(make_pair(name, ins));
|
mFwdJumps.insert(make_pair(name, ins));
|
||||||
return ins;
|
return ins;
|
||||||
}
|
}
|
||||||
|
@ -676,6 +678,14 @@ FragmentAssembler::assemble_call(const string &op)
|
||||||
return mLir->insCall(ci, args);
|
return mLir->insCall(ci, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LIns *
|
||||||
|
FragmentAssembler::assemble_ret(ReturnType rt)
|
||||||
|
{
|
||||||
|
need(1);
|
||||||
|
mReturnTypeBits |= rt;
|
||||||
|
return mLir->ins1(mOpcode, ref(mTokens[0]));
|
||||||
|
}
|
||||||
|
|
||||||
LasmSideExit*
|
LasmSideExit*
|
||||||
FragmentAssembler::createSideExit()
|
FragmentAssembler::createSideExit()
|
||||||
{
|
{
|
||||||
|
@ -699,61 +709,27 @@ FragmentAssembler::createGuardRecord(LasmSideExit *exit)
|
||||||
|
|
||||||
|
|
||||||
LIns *
|
LIns *
|
||||||
FragmentAssembler::assemble_guard()
|
FragmentAssembler::assemble_guard(bool isCond)
|
||||||
{
|
{
|
||||||
GuardRecord* guard = createGuardRecord(createSideExit());
|
GuardRecord* guard = createGuardRecord(createSideExit());
|
||||||
|
|
||||||
need(mOpcount);
|
LIns *ins_cond;
|
||||||
|
if (isCond) {
|
||||||
|
need(1);
|
||||||
|
ins_cond = ref(pop_front(mTokens));
|
||||||
|
} else {
|
||||||
|
need(0);
|
||||||
|
ins_cond = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
mReturnTypeBits |= RT_GUARD;
|
mReturnTypeBits |= RT_GUARD;
|
||||||
|
|
||||||
LIns *ins_cond;
|
|
||||||
if (mOpcode == LIR_xt || mOpcode == LIR_xf)
|
|
||||||
ins_cond = ref(pop_front(mTokens));
|
|
||||||
else
|
|
||||||
ins_cond = NULL;
|
|
||||||
|
|
||||||
if (!mTokens.empty())
|
if (!mTokens.empty())
|
||||||
bad("too many arguments");
|
bad("too many arguments");
|
||||||
|
|
||||||
return mLir->insGuard(mOpcode, ins_cond, guard);
|
return mLir->insGuard(mOpcode, ins_cond, guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIns *
|
|
||||||
FragmentAssembler::assemble_general()
|
|
||||||
{
|
|
||||||
if (mOpcount == 0) {
|
|
||||||
// 0-ary ops may, or may not, have an immediate
|
|
||||||
// thing wedged in them; depends on the op. We
|
|
||||||
// are lax and set it if it's provided.
|
|
||||||
LIns *ins = mLir->ins0(mOpcode);
|
|
||||||
if (mTokens.size() > 0) {
|
|
||||||
assert(mTokens.size() == 1);
|
|
||||||
ins->initLInsI(mOpcode, imm(mTokens[0]));
|
|
||||||
}
|
|
||||||
return ins;
|
|
||||||
} else {
|
|
||||||
need(mOpcount);
|
|
||||||
if (mOpcount == 1) {
|
|
||||||
if (mOpcode == LIR_ret)
|
|
||||||
mReturnTypeBits |= RT_INT32;
|
|
||||||
if (mOpcode == LIR_fret)
|
|
||||||
mReturnTypeBits |= RT_FLOAT;
|
|
||||||
|
|
||||||
return mLir->ins1(mOpcode,
|
|
||||||
ref(mTokens[0]));
|
|
||||||
} else if (mOpcount == 2) {
|
|
||||||
return mLir->ins2(mOpcode,
|
|
||||||
ref(mTokens[0]),
|
|
||||||
ref(mTokens[1]));
|
|
||||||
} else {
|
|
||||||
bad("too many operands");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Never get here.
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FragmentAssembler::endFragment()
|
FragmentAssembler::endFragment()
|
||||||
{
|
{
|
||||||
|
@ -885,18 +861,106 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||||
if (mParent.mOpMap.find(op) == mParent.mOpMap.end())
|
if (mParent.mOpMap.find(op) == mParent.mOpMap.end())
|
||||||
bad("unknown instruction '" + op + "'");
|
bad("unknown instruction '" + op + "'");
|
||||||
|
|
||||||
pair<LOpcode, size_t> entry = mParent.mOpMap[op];
|
mOpcode = mParent.mOpMap[op];
|
||||||
mOpcode = entry.first;
|
|
||||||
mOpcount = entry.second;
|
|
||||||
|
|
||||||
switch (mOpcode) {
|
switch (mOpcode) {
|
||||||
// A few special opcode cases.
|
case LIR_start:
|
||||||
|
bad("start instructions cannot be specified explicitly");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_regfence:
|
||||||
|
need(0);
|
||||||
|
ins = mLir->ins0(mOpcode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_live:
|
||||||
|
case LIR_flive:
|
||||||
|
case LIR_neg:
|
||||||
|
case LIR_fneg:
|
||||||
|
case LIR_qlo:
|
||||||
|
case LIR_qhi:
|
||||||
|
case LIR_ov:
|
||||||
|
case LIR_i2q:
|
||||||
|
case LIR_u2q:
|
||||||
|
case LIR_i2f:
|
||||||
|
case LIR_u2f:
|
||||||
|
need(1);
|
||||||
|
ins = mLir->ins1(mOpcode,
|
||||||
|
ref(mTokens[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_iaddp:
|
||||||
|
case LIR_qaddp:
|
||||||
|
case LIR_add:
|
||||||
|
case LIR_sub:
|
||||||
|
case LIR_mul:
|
||||||
|
case LIR_div:
|
||||||
|
case LIR_mod:
|
||||||
|
case LIR_fadd:
|
||||||
|
case LIR_fsub:
|
||||||
|
case LIR_fmul:
|
||||||
|
case LIR_fdiv:
|
||||||
|
case LIR_fmod:
|
||||||
|
case LIR_qiadd:
|
||||||
|
case LIR_and:
|
||||||
|
case LIR_or:
|
||||||
|
case LIR_xor:
|
||||||
|
case LIR_qiand:
|
||||||
|
case LIR_qior:
|
||||||
|
case LIR_qxor:
|
||||||
|
case LIR_not:
|
||||||
|
case LIR_lsh:
|
||||||
|
case LIR_rsh:
|
||||||
|
case LIR_ush:
|
||||||
|
case LIR_qilsh:
|
||||||
|
case LIR_qirsh:
|
||||||
|
case LIR_qursh:
|
||||||
|
case LIR_eq:
|
||||||
|
case LIR_lt:
|
||||||
|
case LIR_gt:
|
||||||
|
case LIR_le:
|
||||||
|
case LIR_ge:
|
||||||
|
case LIR_ult:
|
||||||
|
case LIR_ugt:
|
||||||
|
case LIR_ule:
|
||||||
|
case LIR_uge:
|
||||||
|
case LIR_feq:
|
||||||
|
case LIR_flt:
|
||||||
|
case LIR_fgt:
|
||||||
|
case LIR_fle:
|
||||||
|
case LIR_fge:
|
||||||
|
case LIR_qeq:
|
||||||
|
case LIR_qlt:
|
||||||
|
case LIR_qgt:
|
||||||
|
case LIR_qle:
|
||||||
|
case LIR_qge:
|
||||||
|
case LIR_qult:
|
||||||
|
case LIR_qugt:
|
||||||
|
case LIR_qule:
|
||||||
|
case LIR_quge:
|
||||||
|
case LIR_qjoin:
|
||||||
|
need(2);
|
||||||
|
ins = mLir->ins2(mOpcode,
|
||||||
|
ref(mTokens[0]),
|
||||||
|
ref(mTokens[1]));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_cmov:
|
||||||
|
case LIR_qcmov:
|
||||||
|
need(3);
|
||||||
|
ins = mLir->ins3(mOpcode,
|
||||||
|
ref(mTokens[0]),
|
||||||
|
ref(mTokens[1]),
|
||||||
|
ref(mTokens[2]));
|
||||||
|
break;
|
||||||
|
|
||||||
case LIR_j:
|
case LIR_j:
|
||||||
|
ins = assemble_jump(/*isCond*/false);
|
||||||
|
break;
|
||||||
|
|
||||||
case LIR_jt:
|
case LIR_jt:
|
||||||
case LIR_jf:
|
case LIR_jf:
|
||||||
case LIR_ji:
|
ins = assemble_jump(/*isCond*/true);
|
||||||
ins = assemble_jump();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIR_int:
|
case LIR_int:
|
||||||
|
@ -909,6 +973,11 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||||
ins = mLir->insImmq(quad(mTokens[0]));
|
ins = mLir->insImmq(quad(mTokens[0]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LIR_float:
|
||||||
|
need(1);
|
||||||
|
ins = mLir->insImmf(immf(mTokens[0]));
|
||||||
|
break;
|
||||||
|
|
||||||
case LIR_sti:
|
case LIR_sti:
|
||||||
case LIR_stqi:
|
case LIR_stqi:
|
||||||
need(3);
|
need(3);
|
||||||
|
@ -926,13 +995,19 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||||
ins = assemble_load();
|
ins = assemble_load();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// XXX: insParam gives the one appropriate for the platform. Eg. if
|
||||||
|
// you specify qparam on x86 you'll end up with iparam anyway. Fix
|
||||||
|
// this.
|
||||||
case LIR_iparam:
|
case LIR_iparam:
|
||||||
|
case LIR_qparam:
|
||||||
need(2);
|
need(2);
|
||||||
ins = mLir->insParam(imm(mTokens[0]),
|
ins = mLir->insParam(imm(mTokens[0]),
|
||||||
imm(mTokens[1]));
|
imm(mTokens[1]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// XXX: similar to iparam/qparam above.
|
||||||
case LIR_ialloc:
|
case LIR_ialloc:
|
||||||
|
case LIR_qalloc:
|
||||||
need(1);
|
need(1);
|
||||||
ins = mLir->insAlloc(imm(mTokens[0]));
|
ins = mLir->insAlloc(imm(mTokens[0]));
|
||||||
break;
|
break;
|
||||||
|
@ -941,21 +1016,41 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
||||||
bad("skip instruction is deprecated");
|
bad("skip instruction is deprecated");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIR_xt:
|
|
||||||
case LIR_xf:
|
|
||||||
case LIR_x:
|
case LIR_x:
|
||||||
case LIR_xbarrier:
|
case LIR_xbarrier:
|
||||||
ins = assemble_guard();
|
ins = assemble_guard(/*isCond*/false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_xt:
|
||||||
|
case LIR_xf:
|
||||||
|
ins = assemble_guard(/*isCond*/true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIR_icall:
|
case LIR_icall:
|
||||||
case LIR_callh:
|
case LIR_callh:
|
||||||
case LIR_fcall:
|
case LIR_fcall:
|
||||||
|
case LIR_qcall:
|
||||||
ins = assemble_call(op);
|
ins = assemble_call(op);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LIR_ret:
|
||||||
|
ins = assemble_ret(RT_INT32);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_fret:
|
||||||
|
ins = assemble_ret(RT_FLOAT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIR_label:
|
||||||
|
case LIR_file:
|
||||||
|
case LIR_line:
|
||||||
|
case LIR_xtbl:
|
||||||
|
case LIR_ji:
|
||||||
|
nyi(op);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ins = assemble_general();
|
nyi(op);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1656,9 +1751,9 @@ Lirasm::Lirasm(bool verbose) :
|
||||||
|
|
||||||
// Populate the mOpMap table.
|
// Populate the mOpMap table.
|
||||||
#define OPDEF(op, number, args, repkind) \
|
#define OPDEF(op, number, args, repkind) \
|
||||||
mOpMap[#op] = make_pair(LIR_##op, args);
|
mOpMap[#op] = LIR_##op;
|
||||||
#define OPDEF64(op, number, args, repkind) \
|
#define OPDEF64(op, number, args, repkind) \
|
||||||
mOpMap[#op] = make_pair(LIR_##op, args);
|
mOpMap[#op] = LIR_##op;
|
||||||
#include "nanojit/LIRopcode.tbl"
|
#include "nanojit/LIRopcode.tbl"
|
||||||
#undef OPDEF
|
#undef OPDEF
|
||||||
#undef OPDEF64
|
#undef OPDEF64
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pi = quad 3.14
|
pi = float 3.14
|
||||||
half = quad 0.5
|
half = float 0.5
|
||||||
halfpi = fmul pi half
|
halfpi = fmul pi half
|
||||||
res = fcall sin cdecl halfpi
|
res = fcall sin cdecl halfpi
|
||||||
fret res
|
fret res
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pi = quad 3.14
|
pi = float 3.14
|
||||||
two = quad 2.0
|
two = float 2.0
|
||||||
TwoPi = fmul pi two
|
TwoPi = fmul pi two
|
||||||
fret two
|
fret two
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.begin sinpibytwo
|
.begin sinpibytwo
|
||||||
pi = quad 3.14
|
pi = float 3.14
|
||||||
half = quad 0.5
|
half = float 0.5
|
||||||
halfpi = fmul pi half
|
halfpi = fmul pi half
|
||||||
res = fcall sin cdecl halfpi
|
res = fcall sin cdecl halfpi
|
||||||
fret res
|
fret res
|
||||||
|
@ -8,7 +8,7 @@ fret res
|
||||||
|
|
||||||
.begin main
|
.begin main
|
||||||
aa = fcall sinpibytwo fastcall
|
aa = fcall sinpibytwo fastcall
|
||||||
bb = quad 5.53
|
bb = float 5.53
|
||||||
res = fadd aa bb
|
res = fadd aa bb
|
||||||
fret res
|
fret res
|
||||||
.end
|
.end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче