зеркало из 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();
|
||||
mLine.clear();
|
||||
} else {
|
||||
cerr << mLineno << ": error: Unrecognized character in file." << endl;
|
||||
cerr << "line " << mLineno << ": error: Unrecognized character in file." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ public:
|
|||
bool mVerbose;
|
||||
Fragments mFragments;
|
||||
Assembler mAssm;
|
||||
map<string, pair<LOpcode, size_t> > mOpMap;
|
||||
map<string, LOpcode> mOpMap;
|
||||
|
||||
void bad(const string &msg) {
|
||||
cerr << "error: " << msg << endl;
|
||||
|
@ -312,11 +312,11 @@ private:
|
|||
void tokenizeLine(LirTokenStream &in, LirToken &token);
|
||||
void need(size_t);
|
||||
LIns *ref(const string &);
|
||||
LIns *assemble_call(const string &);
|
||||
LIns *assemble_general();
|
||||
LIns *assemble_guard();
|
||||
LIns *assemble_jump();
|
||||
LIns *assemble_jump(bool isCond);
|
||||
LIns *assemble_load();
|
||||
LIns *assemble_call(const string &);
|
||||
LIns *assemble_ret(ReturnType rt);
|
||||
LIns *assemble_guard(bool isCond);
|
||||
void bad(const string &msg);
|
||||
void nyi(const string &opname);
|
||||
void extract_any_label(string &lab, char lab_delim);
|
||||
|
@ -382,20 +382,21 @@ imm(const string &s)
|
|||
uint64_t
|
||||
quad(const string &s)
|
||||
{
|
||||
stringstream tmp1(s), tmp2(s);
|
||||
union {
|
||||
uint64_t u64;
|
||||
double d;
|
||||
} pun;
|
||||
stringstream tmp(s);
|
||||
uint64_t ret;
|
||||
if ((s.find("0x") == 0 || s.find("0X") == 0) &&
|
||||
(tmp1 >> hex >> pun.u64 && tmp1.eof()))
|
||||
return pun.u64;
|
||||
if ((s.find(".") != string::npos) &&
|
||||
(tmp2 >> pun.d && tmp2.eof()))
|
||||
return pun.u64;
|
||||
(tmp >> hex >> ret && tmp.eof())) {
|
||||
return ret;
|
||||
}
|
||||
return lexical_cast<uint64_t>(s);
|
||||
}
|
||||
|
||||
double
|
||||
immf(const string &s)
|
||||
{
|
||||
return lexical_cast<double>(s);
|
||||
}
|
||||
|
||||
template<typename t> t
|
||||
pop_front(vector<t> &vec)
|
||||
{
|
||||
|
@ -524,7 +525,8 @@ FragmentAssembler::~FragmentAssembler()
|
|||
void
|
||||
FragmentAssembler::bad(const string &msg)
|
||||
{
|
||||
cerr << "instruction " << mLineno << ": " << msg << endl;
|
||||
cerr << "line " << mLineno << ": " << msg << endl;
|
||||
exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -553,24 +555,24 @@ FragmentAssembler::ref(const string &lab)
|
|||
}
|
||||
|
||||
LIns *
|
||||
FragmentAssembler::assemble_jump()
|
||||
FragmentAssembler::assemble_jump(bool isCond)
|
||||
{
|
||||
LIns *target = NULL;
|
||||
LIns *condition = NULL;
|
||||
LIns *condition;
|
||||
|
||||
if (mOpcode == LIR_j) {
|
||||
need(1);
|
||||
} else {
|
||||
if (isCond) {
|
||||
need(2);
|
||||
string cond = pop_front(mTokens);
|
||||
condition = ref(cond);
|
||||
} else {
|
||||
need(1);
|
||||
condition = NULL;
|
||||
}
|
||||
string name = pop_front(mTokens);
|
||||
if (mLabels.find(name) != mLabels.end()) {
|
||||
target = ref(name);
|
||||
LIns *target = ref(name);
|
||||
return mLir->insBranch(mOpcode, condition, target);
|
||||
} else {
|
||||
LIns *ins = mLir->insBranch(mOpcode, condition, target);
|
||||
LIns *ins = mLir->insBranch(mOpcode, condition, NULL);
|
||||
mFwdJumps.insert(make_pair(name, ins));
|
||||
return ins;
|
||||
}
|
||||
|
@ -676,6 +678,14 @@ FragmentAssembler::assemble_call(const string &op)
|
|||
return mLir->insCall(ci, args);
|
||||
}
|
||||
|
||||
LIns *
|
||||
FragmentAssembler::assemble_ret(ReturnType rt)
|
||||
{
|
||||
need(1);
|
||||
mReturnTypeBits |= rt;
|
||||
return mLir->ins1(mOpcode, ref(mTokens[0]));
|
||||
}
|
||||
|
||||
LasmSideExit*
|
||||
FragmentAssembler::createSideExit()
|
||||
{
|
||||
|
@ -699,61 +709,27 @@ FragmentAssembler::createGuardRecord(LasmSideExit *exit)
|
|||
|
||||
|
||||
LIns *
|
||||
FragmentAssembler::assemble_guard()
|
||||
FragmentAssembler::assemble_guard(bool isCond)
|
||||
{
|
||||
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;
|
||||
|
||||
LIns *ins_cond;
|
||||
if (mOpcode == LIR_xt || mOpcode == LIR_xf)
|
||||
ins_cond = ref(pop_front(mTokens));
|
||||
else
|
||||
ins_cond = NULL;
|
||||
|
||||
if (!mTokens.empty())
|
||||
bad("too many arguments");
|
||||
|
||||
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
|
||||
FragmentAssembler::endFragment()
|
||||
{
|
||||
|
@ -885,18 +861,106 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
|||
if (mParent.mOpMap.find(op) == mParent.mOpMap.end())
|
||||
bad("unknown instruction '" + op + "'");
|
||||
|
||||
pair<LOpcode, size_t> entry = mParent.mOpMap[op];
|
||||
mOpcode = entry.first;
|
||||
mOpcount = entry.second;
|
||||
mOpcode = mParent.mOpMap[op];
|
||||
|
||||
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:
|
||||
ins = assemble_jump(/*isCond*/false);
|
||||
break;
|
||||
|
||||
case LIR_jt:
|
||||
case LIR_jf:
|
||||
case LIR_ji:
|
||||
ins = assemble_jump();
|
||||
ins = assemble_jump(/*isCond*/true);
|
||||
break;
|
||||
|
||||
case LIR_int:
|
||||
|
@ -909,6 +973,11 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
|||
ins = mLir->insImmq(quad(mTokens[0]));
|
||||
break;
|
||||
|
||||
case LIR_float:
|
||||
need(1);
|
||||
ins = mLir->insImmf(immf(mTokens[0]));
|
||||
break;
|
||||
|
||||
case LIR_sti:
|
||||
case LIR_stqi:
|
||||
need(3);
|
||||
|
@ -926,13 +995,19 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
|||
ins = assemble_load();
|
||||
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_qparam:
|
||||
need(2);
|
||||
ins = mLir->insParam(imm(mTokens[0]),
|
||||
imm(mTokens[1]));
|
||||
break;
|
||||
|
||||
// XXX: similar to iparam/qparam above.
|
||||
case LIR_ialloc:
|
||||
case LIR_qalloc:
|
||||
need(1);
|
||||
ins = mLir->insAlloc(imm(mTokens[0]));
|
||||
break;
|
||||
|
@ -941,21 +1016,41 @@ FragmentAssembler::assembleFragment(LirTokenStream &in, bool implicitBegin, cons
|
|||
bad("skip instruction is deprecated");
|
||||
break;
|
||||
|
||||
case LIR_xt:
|
||||
case LIR_xf:
|
||||
case LIR_x:
|
||||
case LIR_xbarrier:
|
||||
ins = assemble_guard();
|
||||
ins = assemble_guard(/*isCond*/false);
|
||||
break;
|
||||
|
||||
case LIR_xt:
|
||||
case LIR_xf:
|
||||
ins = assemble_guard(/*isCond*/true);
|
||||
break;
|
||||
|
||||
case LIR_icall:
|
||||
case LIR_callh:
|
||||
case LIR_fcall:
|
||||
case LIR_qcall:
|
||||
ins = assemble_call(op);
|
||||
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:
|
||||
ins = assemble_general();
|
||||
nyi(op);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1656,9 +1751,9 @@ Lirasm::Lirasm(bool verbose) :
|
|||
|
||||
// Populate the mOpMap table.
|
||||
#define OPDEF(op, number, args, repkind) \
|
||||
mOpMap[#op] = make_pair(LIR_##op, args);
|
||||
mOpMap[#op] = LIR_##op;
|
||||
#define OPDEF64(op, number, args, repkind) \
|
||||
mOpMap[#op] = make_pair(LIR_##op, args);
|
||||
mOpMap[#op] = LIR_##op;
|
||||
#include "nanojit/LIRopcode.tbl"
|
||||
#undef OPDEF
|
||||
#undef OPDEF64
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
pi = quad 3.14
|
||||
half = quad 0.5
|
||||
pi = float 3.14
|
||||
half = float 0.5
|
||||
halfpi = fmul pi half
|
||||
res = fcall sin cdecl halfpi
|
||||
fret res
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pi = quad 3.14
|
||||
two = quad 2.0
|
||||
pi = float 3.14
|
||||
two = float 2.0
|
||||
TwoPi = fmul pi two
|
||||
fret two
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
.begin sinpibytwo
|
||||
pi = quad 3.14
|
||||
half = quad 0.5
|
||||
pi = float 3.14
|
||||
half = float 0.5
|
||||
halfpi = fmul pi half
|
||||
res = fcall sin cdecl halfpi
|
||||
fret res
|
||||
|
@ -8,7 +8,7 @@ fret res
|
|||
|
||||
.begin main
|
||||
aa = fcall sinpibytwo fastcall
|
||||
bb = quad 5.53
|
||||
bb = float 5.53
|
||||
res = fadd aa bb
|
||||
fret res
|
||||
.end
|
||||
|
|
Загрузка…
Ссылка в новой задаче