Replaced instruction information arrays with a table.
git-svn-id: http://www.cdkersey.com/harp/harptool@12 0246edb2-e076-4747-b392-db732a341fa2
This commit is contained in:
@@ -109,7 +109,7 @@ Instruction *ByteDecoder::decode(const vector<Byte> &v, Size &n) {
|
|||||||
|
|
||||||
bool usedImm = false;
|
bool usedImm = false;
|
||||||
|
|
||||||
switch (Instruction::argClasses[op]) {
|
switch (Instruction::instTable[op].argClass) {
|
||||||
case Instruction::AC_NONE:
|
case Instruction::AC_NONE:
|
||||||
break;
|
break;
|
||||||
case Instruction::AC_2REG:
|
case Instruction::AC_2REG:
|
||||||
@@ -276,7 +276,7 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx) {
|
|||||||
inst.setOpcode(op);
|
inst.setOpcode(op);
|
||||||
|
|
||||||
bool usedImm(false);
|
bool usedImm(false);
|
||||||
switch(Instruction::argClasses[op]) {
|
switch(Instruction::instTable[op].argClass) {
|
||||||
case Instruction::AC_NONE:
|
case Instruction::AC_NONE:
|
||||||
break;
|
break;
|
||||||
case Instruction::AC_1IMM:
|
case Instruction::AC_1IMM:
|
||||||
|
|||||||
@@ -35,9 +35,13 @@ namespace Harp {
|
|||||||
AC_NONE, AC_2REG, AC_2IMM, AC_3REG, AC_3PREG, AC_3IMM, AC_3REGSRC,
|
AC_NONE, AC_2REG, AC_2IMM, AC_3REG, AC_3PREG, AC_3IMM, AC_3REGSRC,
|
||||||
AC_1IMM, AC_1REG, AC_3IMMSRC, AC_PREG_REG, AC_2PREG
|
AC_1IMM, AC_1REG, AC_3IMMSRC, AC_PREG_REG, AC_2PREG
|
||||||
};
|
};
|
||||||
static const char *opStrings[];
|
|
||||||
static const bool allSrcArgs[], privileged[], relAddress[], isControlFlow[];
|
// We build a table of instruction information out of this.
|
||||||
static const ArgClass argClasses[];
|
static struct InstTableEntry {
|
||||||
|
const char *opString;
|
||||||
|
bool controlFlow, relAddress, allSrcArgs, privileged;
|
||||||
|
ArgClass argClass;
|
||||||
|
} instTable[];
|
||||||
|
|
||||||
Instruction() :
|
Instruction() :
|
||||||
predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false),
|
predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false),
|
||||||
@@ -75,7 +79,7 @@ namespace Harp {
|
|||||||
Ref *getRefLiteral() const { return refLiteral; }
|
Ref *getRefLiteral() const { return refLiteral; }
|
||||||
|
|
||||||
/* Getters used as table lookup. */
|
/* Getters used as table lookup. */
|
||||||
bool hasRelImm() const { return relAddress[op]; }
|
bool hasRelImm() const { return instTable[op].relAddress; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool predicated;
|
bool predicated;
|
||||||
|
|||||||
@@ -14,68 +14,68 @@ using namespace std;
|
|||||||
|
|
||||||
/* It is important that this stays consistent with the Harp::Instruction::Opcode
|
/* It is important that this stays consistent with the Harp::Instruction::Opcode
|
||||||
enum. */
|
enum. */
|
||||||
const char *Instruction::opStrings[] = {
|
|
||||||
"nop", "di", "ei", "tlbadd", "tlbflush", "neg", "not", "and", "or", "xor",
|
|
||||||
"add", "sub", "mul", "div", "mod", "shl", "shr","andi",
|
|
||||||
"ori", "xori", "addi", "subi", "muli", "divi", "modi", "shli", "shri",
|
|
||||||
"jali", "jalr", "jmpi", "jmpr", "clone", "jalis", "jalrs",
|
|
||||||
"jmprt", "ld", "st", "ldi", "rtop", "andp", "orp", "xorp", "notp",
|
|
||||||
"isneg", "iszero", "halt", "trap", "jmpru", "skep", "reti", "tlbrm",
|
|
||||||
"itof", "ftoi", "fadd", "fsub", "fmul", "fdiv", "fneg", 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const bool Instruction::isControlFlow[] = {
|
Instruction::InstTableEntry Instruction::instTable[] = {
|
||||||
false, false, false, false, false, false, false, false, false, false,
|
//str cflow relad allsrc priv argcl
|
||||||
false, false, false, false, false, false, false, false,
|
{"nop", false, false, false, false, AC_NONE },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"di", false, false, false, true, AC_NONE },
|
||||||
true, true, true, true, true, true, true,
|
{"ei", false, false, false, true, AC_NONE },
|
||||||
true, false, false, false, false, false, false, false, false,
|
{"tlbadd", false, false, true, true, AC_3REGSRC },
|
||||||
false, false, false, false, true, false, true, false,
|
{"tlbflush", false, false, false, true, AC_NONE },
|
||||||
false, false, false, false, false, false, false
|
{"neg", false, false, false, false, AC_2REG },
|
||||||
};
|
{"not", false, false, false, false, AC_2REG },
|
||||||
|
{"and", false, false, false, false, AC_3REG },
|
||||||
const bool Instruction::relAddress[] = {
|
{"or", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false, false, false, false,
|
{"xor", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false, false,
|
{"add", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"sub", false, false, false, false, AC_3REG },
|
||||||
true, false, true, false, false, true, false,
|
{"mul", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"div", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false, false,
|
{"mod", false, false, false, false, AC_3REG },
|
||||||
false, false, false, false, false, false, false
|
{"shl", false, false, false, false, AC_3REG },
|
||||||
};
|
{"shr", false, false, false, false, AC_3REG },
|
||||||
|
{"andi", false, false, false, false, AC_3IMM },
|
||||||
const bool Instruction::allSrcArgs[] = {
|
{"ori", false, false, false, false, AC_3IMM },
|
||||||
false, false, false, true, false, false, false, false, false, false,
|
{"xori", false, false, false, false, AC_3IMM },
|
||||||
false, false, false, false, false, false, false, false,
|
{"addi", false, false, false, false, AC_3IMM },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"subi", false, false, false, false, AC_3IMM },
|
||||||
false, false, true, true, false, false, false,
|
{"muli", false, false, false, false, AC_3IMM },
|
||||||
true, false, true, false, false, false, false, false, false,
|
{"divi", false, false, false, false, AC_3IMM },
|
||||||
false, false, false, false, true, true, false, false,
|
{"modi", false, false, false, false, AC_3IMM },
|
||||||
false, false, false, false, false, false, false
|
{"shli", false, false, false, false, AC_3IMM },
|
||||||
};
|
{"shri", false, false, false, false, AC_3IMM },
|
||||||
|
{"jali", true, true, false, false, AC_2IMM },
|
||||||
const bool Instruction::privileged[] = {
|
{"jalr", true, false, false, false, AC_2REG },
|
||||||
false, true, true, true, true, false, false, false, false, false,
|
{"jmpi", true, true, true, false, AC_1IMM },
|
||||||
false, false, false, false, false, false, false, false,
|
{"jmpr", true, false, true, false, AC_1REG },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"clone", true, false, false, false, AC_1REG },
|
||||||
false, false, false, false, false, false, false,
|
{"jalis", true, true, false, false, AC_3IMM },
|
||||||
false, false, false, false, false, false, false, false, false,
|
{"jalrs", true, false, false, false, AC_3REG },
|
||||||
false, false, true, false, true, true, true, true,
|
{"jmprt", true, false, true, false, AC_1REG },
|
||||||
false, false, false, false, false, false, false
|
{"ld", false, false, false, false, AC_3IMM },
|
||||||
};
|
{"st", false, false, true, false, AC_3IMMSRC },
|
||||||
|
{"ldi", false, false, false, false, AC_2IMM },
|
||||||
const Instruction::ArgClass Instruction::argClasses[] = {
|
{"rtop", false, false, false, false, AC_PREG_REG},
|
||||||
AC_NONE, AC_NONE, AC_NONE, AC_3REGSRC, AC_NONE, AC_2REG, AC_2REG, AC_3REG,
|
{"andp", false, false, false, false, AC_3PREG },
|
||||||
AC_3REG, AC_3REG,
|
{"orp", false, false, false, false, AC_3PREG },
|
||||||
AC_3REG, AC_3REG, AC_3REG, AC_3REG, AC_3REG, AC_3REG, AC_3REG, AC_3IMM,
|
{"xorp", false, false, false, false, AC_3PREG },
|
||||||
AC_3IMM, AC_3IMM, AC_3IMM, AC_3IMM, AC_3IMM, AC_3IMM, AC_3IMM, AC_3IMM,
|
{"notp", false, false, false, false, AC_3PREG },
|
||||||
AC_3IMM,
|
{"isneg", false, false, false, false, AC_PREG_REG},
|
||||||
AC_2IMM, AC_2REG, AC_1IMM, AC_1REG, AC_1REG, AC_3IMM, AC_3REG,
|
{"iszero", false, false, false, false, AC_PREG_REG},
|
||||||
AC_1REG, AC_3IMM, AC_3IMMSRC, AC_2IMM, AC_PREG_REG, AC_3PREG, AC_3PREG,
|
{"halt", false, false, false, true, AC_NONE },
|
||||||
AC_3PREG, AC_2PREG,
|
{"trap", true, false, false, false, AC_NONE },
|
||||||
AC_PREG_REG, AC_PREG_REG, AC_NONE, AC_NONE, AC_1REG, AC_1REG, AC_NONE,
|
{"jmpru", false, false, false, true, AC_1REG },
|
||||||
AC_1REG,
|
{"skep", false, false, false, true, AC_1REG },
|
||||||
AC_2REG, AC_2REG, AC_3REG, AC_3REG, AC_3REG, AC_3REG, AC_2REG
|
{"reti", true, false, false, true, AC_NONE },
|
||||||
|
{"tlbrm", false, false, false, true, AC_1REG },
|
||||||
|
{"itof", false, false, false, false, AC_2REG },
|
||||||
|
{"ftoi", false, false, false, false, AC_2REG },
|
||||||
|
{"fadd", false, false, false, false, AC_3REG },
|
||||||
|
{"fsub", false, false, false, false, AC_3REG },
|
||||||
|
{"fmul", false, false, false, false, AC_3REG },
|
||||||
|
{"fdiv", false, false, false, false, AC_3REG },
|
||||||
|
{"fneg", false, false, false, false, AC_2REG },
|
||||||
|
{NULL,false,false,false,false,AC_NONE}/////////////// End of table.
|
||||||
};
|
};
|
||||||
|
|
||||||
ostream &Harp::operator<<(ostream& os, Instruction &inst) {
|
ostream &Harp::operator<<(ostream& os, Instruction &inst) {
|
||||||
@@ -83,7 +83,7 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) {
|
|||||||
os << "@p" << inst.pred << " ? ";
|
os << "@p" << inst.pred << " ? ";
|
||||||
}
|
}
|
||||||
|
|
||||||
os << Instruction::opStrings[inst.op] << ' ';
|
os << Instruction::instTable[inst.op].opString << ' ';
|
||||||
if (inst.rdestPresent) os << "%r" << inst.rdest << ' ';
|
if (inst.rdestPresent) os << "%r" << inst.rdest << ' ';
|
||||||
if (inst.pdestPresent) os << "@p" << inst.pdest << ' ';
|
if (inst.pdestPresent) os << "@p" << inst.pdest << ' ';
|
||||||
for (int i = 0; i < inst.nRsrc; i++) {
|
for (int i = 0; i < inst.nRsrc; i++) {
|
||||||
@@ -104,12 +104,12 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) {
|
|||||||
void Instruction::executeOn(Core &c) {
|
void Instruction::executeOn(Core &c) {
|
||||||
/* If I try to execute a privileged instruction in user mode, throw an
|
/* If I try to execute a privileged instruction in user mode, throw an
|
||||||
exception 3. */
|
exception 3. */
|
||||||
if (privileged[op] && !c.supervisorMode) {
|
if (instTable[op].privileged && !c.supervisorMode) {
|
||||||
c.interrupt(3);
|
c.interrupt(3);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (predicated && isControlFlow[op]) {
|
if (predicated && instTable[op].controlFlow) {
|
||||||
bool p0 = c.pred[0][pred];
|
bool p0 = c.pred[0][pred];
|
||||||
for (Size t = 1; t < c.activeThreads; t++) {
|
for (Size t = 1; t < c.activeThreads; t++) {
|
||||||
if (c.pred[t][pred] != p0) throw DivergentBranchException();
|
if (c.pred[t][pred] != p0) throw DivergentBranchException();
|
||||||
@@ -244,7 +244,7 @@ void Instruction::executeOn(Core &c) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isControlFlow[op]) break;
|
if (instTable[op].controlFlow) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.activeThreads = nextActiveThreads;
|
c.activeThreads = nextActiveThreads;
|
||||||
|
|||||||
@@ -104,8 +104,9 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
map <string, Instruction::Opcode> opMap;
|
map <string, Instruction::Opcode> opMap;
|
||||||
|
|
||||||
// Build opMap
|
// Build opMap
|
||||||
for (size_t i = 0; Instruction::opStrings[i]; i++)
|
for (size_t i = 0; Instruction::instTable[i].opString; i++)
|
||||||
opMap[std::string(Instruction::opStrings[i])] = Instruction::Opcode(i);
|
opMap[std::string(Instruction::instTable[i].opString)]
|
||||||
|
= Instruction::Opcode(i);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ST_INIT, ST_DEF1, ST_DEF2, ST_PERM, ST_WORD1, ST_WORD2, ST_STRING1,
|
ST_INIT, ST_DEF1, ST_DEF2, ST_PERM, ST_WORD1, ST_WORD2, ST_STRING1,
|
||||||
@@ -316,7 +317,7 @@ Obj *AsmReader::read(std::istream &input) {
|
|||||||
nextPred = false;
|
nextPred = false;
|
||||||
curInst->setPred(nextPredNum);
|
curInst->setPred(nextPredNum);
|
||||||
}
|
}
|
||||||
state = Instruction::allSrcArgs[opc]?ST_INST2:ST_INST1;
|
state = Instruction::instTable[opc].allSrcArgs?ST_INST2:ST_INST1;
|
||||||
} else { asmReaderError(yyline, "Unexpected token"); }
|
} else { asmReaderError(yyline, "Unexpected token"); }
|
||||||
break;
|
break;
|
||||||
case ASM_T_PREG:
|
case ASM_T_PREG:
|
||||||
|
|||||||
Reference in New Issue
Block a user