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:
chad
2011-07-24 10:07:09 +00:00
parent 600d27ec60
commit f758375767
4 changed files with 79 additions and 74 deletions

View File

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

View File

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

View File

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

View File

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