lots of errors

This commit is contained in:
felsabbagh3
2019-02-09 20:17:17 -05:00
parent 8128d2e250
commit 0c3a73a896
8 changed files with 1676 additions and 1591 deletions

View File

@@ -1,7 +1,7 @@
################################################################################
# HARPtools by Chad D. Kersey, Summer 2011 #
################################################################################
CXXFLAGS ?= -fPIC -O3 # -g -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS
CXXFLAGS ?= -std=c++11 -fPIC -O3 # -g -DUSE_DEBUG=3 -DPRINT_ACTIVE_THREADS
LDLIBS ?= -pthread
PREFIX ?= /usr/local

View File

@@ -28,75 +28,75 @@ static void decodeError(string msg) {
}
void Encoder::encodeChunk(DataChunk &dest, const TextChunk &src) {
typedef vector<Instruction*>::const_iterator vec_it;
const vector<Instruction*> &s(src.instructions);
vector<Byte> &d(dest.contents);
// typedef vector<Instruction*>::const_iterator vec_it;
// const vector<Instruction*> &s(src.instructions);
// vector<Byte> &d(dest.contents);
/* Keep encoding the instructions. */
Size n = 0;
// /* Keep encoding the instructions. */
// Size n = 0;
/* For each instruction. */
for (vec_it i = s.begin(); i != s.end(); i++) {
Ref *ref;
// /* For each instruction. */
// for (vec_it i = s.begin(); i != s.end(); i++) {
// Ref *ref;
/* Perform the encoding. */
n += encode(ref, d, n, **i);
// /* Perform the encoding. */
// n += encode(ref, d, n, **i);
/* Add reference if necessary. */
if (ref != NULL) {
ref->ibase = n;
dest.refs.push_back(ref);
}
}
// /* Add reference if necessary. */
// if (ref != NULL) {
// ref->ibase = n;
// dest.refs.push_back(ref);
// }
// }
dest.alignment = src.alignment;
dest.flags = src.flags;
dest.address = src.address;
dest.bound = src.bound;
if (src.isGlobal()) dest.setGlobal();
// dest.alignment = src.alignment;
// dest.flags = src.flags;
// dest.address = src.address;
// dest.bound = src.bound;
// if (src.isGlobal()) dest.setGlobal();
d.resize(n);
dest.size = n;
// d.resize(n);
// dest.size = n;
}
void Decoder::decodeChunk(TextChunk &dest, const DataChunk &src) {
typedef vector<Instruction*>::const_iterator vec_it;
const vector<Byte> &v(src.contents);
Size n = 0;
// typedef vector<Instruction*>::const_iterator vec_it;
// const vector<Byte> &v(src.contents);
// Size n = 0;
setRefs(src.refs);
// setRefs(src.refs);
while (n < src.contents.size()) {
Instruction *inst = decode(v, n);
if (inst->hasRefLiteral()) {
dest.refs.push_back(inst->getRefLiteral());
}
// while (n < src.contents.size()) {
// Instruction *inst = decode(v, n);
// if (inst->hasRefLiteral()) {
// dest.refs.push_back(inst->getRefLiteral());
// }
dest.instructions.push_back(inst);
}
// dest.instructions.push_back(inst);
// }
dest.alignment = src.alignment;
dest.flags = src.flags;
dest.address = src.address;
dest.bound = src.bound;
if (src.isGlobal()) dest.setGlobal();
// dest.alignment = src.alignment;
// dest.flags = src.flags;
// dest.address = src.address;
// dest.bound = src.bound;
// if (src.isGlobal()) dest.setGlobal();
clearRefs();
}
// clearRefs();
// }
void Decoder::setRefs(const std::vector<Ref*> &refVec) {
haveRefs = true;
// void Decoder::setRefs(const std::vector<Ref*> &refVec) {
// haveRefs = true;
typedef std::vector<Ref*>::const_iterator vec_ci;
// typedef std::vector<Ref*>::const_iterator vec_ci;
for (vec_ci i = refVec.begin(); i != refVec.end(); i++) {
OffsetRef *oref = dynamic_cast<OffsetRef*>(*i);
if (oref) {
refMap[oref->getOffset()] = *i;
} else {
decodeError("Unknown Ref type in Decoder::setRefs");
}
}
// for (vec_ci i = refVec.begin(); i != refVec.end(); i++) {
// OffsetRef *oref = dynamic_cast<OffsetRef*>(*i);
// if (oref) {
// refMap[oref->getOffset()] = *i;
// } else {
// decodeError("Unknown Ref type in Decoder::setRefs");
// }
// }
}
Instruction *ByteDecoder::decode(const vector<Byte> &v, Size &n) {
@@ -242,27 +242,34 @@ static unsigned ceilLog2(RegNum x) {
return z;
}
static Word mask(Size bits) {
return (1ull<<bits)-1;
}
static void getSizes(const ArchDef &arch, Size &n, Size& o, Size &r, Size &p,
Size &i1, Size &i2, Size &i3)
{
n = arch.getWordSize() * 8;
o = 7;
r = ceilLog2(arch.getNRegs());
p = 0;
i1 = n - 1 - p - o;
i2 = i1 - r;
i3 = i2 - r;
}
WordDecoder::WordDecoder(const ArchDef &arch) {
getSizes(arch, n, o, r, p, i1, i2, i3);
if (p > r) r = p;
oMask = mask(o); rMask = mask(r); pMask = mask(p);
i1Mask = mask(i1); i2Mask = mask(i2); i3Mask = mask(i3);
inst_s = arch.getWordSize() * 8;
opcode_s = 7;
reg_s = 5;
func3_s = 3;
shift_opcode = 0;
shift_rd = opcode_s;
shift_func3 = opcode_s + reg_s;
shift_rs1 = opcode_s + reg_s + func3_s;
shift_rs2 = opcode_s + reg_s + func3_s + reg_s;
shift_func7 = opcode_s + reg_s + func3_s + reg_s + reg_s;
shift_j_u_immed = opcode_s + reg_s;
shift_s_b_immed = opcode_s + reg_s + func3_s + reg_s + reg_s;
shift_i_immed = opcode_s + reg_s + func3_s + reg_s;
reg_mask = 0x1f;
func3_mask = 0x7;
func7_mask = 0x7f;
opcode_mask = 0x7f;
i_immed_mask = 0xfff;
s_immed_mask = 0xfff;
b_immed_mask = 0x1fff;
u_immed_mask = 0xfffff;
j_immed_mask = 0xfffff;
}
Word signExt(Word w, Size bit, Word mask) {
@@ -278,69 +285,83 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx) {
bool predicated = false;
if (predicated) { inst.setPred((code>>(n-p-1))&pMask); }
Instruction::Opcode op = (Instruction::Opcode)((code>>i1)&oMask);
Instruction::Opcode op = (Instruction::Opcode)((code>>shift_opcode)&opcode_mask);
inst.setOpcode(op);
bool usedImm(false);
switch(Instruction::instTable[op].argClass) {
case Instruction::AC_NONE:
switch(Instruction::instTable[op].iType)
{
case Instruction::InstType::N_TYPE:
break;
case Instruction::AC_1IMM:
inst.setSrcImm(signExt(code&i1Mask, i1, i1Mask));
case Instruction::InstType::R_TYPE:
inst.setDestReg((code>>shift_rd) & reg_mask);
inst.setSrcReg((code>>shift_rs1) & reg_mask);
inst.setSrcReg((code>>shift_rs2) & reg_mask);
inst.setFunc3 ((code>>shift_func3) & func3_mask);
inst.setFunc7 ((code>>shift_func7) & func7_mask);
break;
case Instruction::InstType::I_TYPE
inst.setDestReg((code>>shift_rd) & reg_mask);
inst.setSrcReg((code>>shift_rs1) & reg_mask);
inst.setFunc3 ((code>>shift_func3) & func3_mask);
inst.setSrcImm(signExt(code>>shift_i_immed, 12, i_immed_mask));
usedImm = true;
break;
case Instruction::AC_2IMM:
inst.setDestReg((code>>i2)&rMask);
inst.setSrcImm(signExt(code&i2Mask, i2, i2Mask));
case Instruction::InstType::S_TYPE:
inst.setSrcReg((code>>shift_rs1) & reg_mask);
inst.setSrcReg((code>>shift_rs2) & reg_mask);
inst.setFunc3 ((code>>shift_func3) & func3_mask);
word dest_bits = (code>>shift_rd) & reg_mask;
Word imm_bits = (code>>shift_s_b_immed & func7_mask);
Word imeed = (imm_bits << reg_s) | dest_bits;
inst.setSrcImm(signExt(imeed, 12, s_immed_mask));
usedImm = true;
break;
case Instruction::AC_3IMM:
inst.setDestReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
inst.setSrcImm(signExt(code&i3Mask, i3, i3Mask));
case Instruction::InstType::B_TYPE:
inst.setSrcReg((code>>shift_rs1) & reg_mask);
inst.setSrcReg((code>>shift_rs2) & reg_mask);
inst.setFunc3 ((code>>shift_func3) & func3_mask);
word dest_bits = (code>>shift_rd) & reg_mask;
Word imm_bits = (code>>shift_s_b_immed & func7_mask);
Word bit_11 = dest_bits & 0x1;
Word bit_4_1 = dest_bits >> 1;
Word bit_10_5 = imm_bits & 0x3f;
Word bit_12 = imm_bits >> 6;
Word imeed = 0 | (bits_4_1 << 1) | (bit_10_5 << 5) | (bit_11 << 11) | (bit_12 << 12);
inst.setSrcImm(signExt(imeed, 13, b_immed_mask));
usedImm = true;
break;
case Instruction::AC_3IMMSRC:
inst.setSrcReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
inst.setSrcImm(signExt(code&i3Mask, i3, i3Mask));
case Instruction::InstType::U_TYPE:
inst.setDestReg((code>>shift_rd) & reg_mask);
inst.setSrcImm(signExt(code>>shift_j_u_immed, 20, u_immed_mask));
usedImm = true;
break;
case Instruction::AC_1REG:
inst.setSrcReg((code>>i2)&rMask);
case Instruction::InstType::J_TYPE:
inst.setDestReg((code>>shift_rd) & reg_mask);
// [20 | 10:1 | 11 | 19:12]
Word unordered = code>>shift_j_u_immed;
Word bits_19_12 = unordered & 0xff;
Word bit_11 = (unordered>>8) & 0x1;
Word bits_10_1 = (unordered >> 9) & 0x3ff;
Word bit_20 = (unordered>>19) & 0x1;
Word imeed = 0 | (bits_10_1 << 1) | (bit_11 << 11) | (bits_19_12 << 12) | (bit20 << 20);
inst.setSrcImm(signExt(imeed, 20, j_immed_mask));
usedImm = true;
break;
case Instruction::AC_2REG:
inst.setDestReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
break;
case Instruction::AC_3REG:
inst.setDestReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
inst.setSrcReg((code>>(i3-r))&rMask);
break;
case Instruction::AC_3REGSRC:
inst.setSrcReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
inst.setSrcReg((code>>(i3-r))&rMask);
break;
case Instruction::AC_PREG_REG:
inst.setDestPReg((code>>i2)&pMask);
inst.setSrcReg((code>>i3)&rMask);
break;
case Instruction::AC_2PREG:
inst.setDestPReg((code>>i2)&pMask);
inst.setSrcPReg((code>>i3)&pMask);
break;
case Instruction::AC_3PREG:
inst.setDestPReg((code>>i2)&pMask);
inst.setSrcPReg((code>>i3)&pMask);
inst.setSrcPReg((code>>(i3-r))&pMask);
break;
case Instruction::AC_2REGSRC:
inst.setSrcReg((code>>i2)&rMask);
inst.setSrcReg((code>>i3)&rMask);
break;
defualt:
defualt:
cout << "Unrecognized argument class in word decoder.\n";
exit(1);
}
@@ -359,120 +380,120 @@ Instruction *WordDecoder::decode(const std::vector<Byte> &v, Size &idx) {
return &inst;
}
WordEncoder::WordEncoder(const ArchDef &arch) {
getSizes(arch, n, o, r, p, i1, i2, i3);
if (p > r) r = p;
oMask = mask(o); rMask = mask(r); pMask = mask(p);
i1Mask = mask(i1); i2Mask = mask(i2); i3Mask = mask(i3);
}
// WordEncoder::WordEncoder(const ArchDef &arch) {
// getSizes(arch, n, o, r, p, i1, i2, i3);
// if (p > r) r = p;
// oMask = mask(o); rMask = mask(r); pMask = mask(p);
// i1Mask = mask(i1); i2Mask = mask(i2); i3Mask = mask(i3);
// }
Size WordEncoder::encode(Ref *&ref, std::vector<Byte> &v,
Size idx, Instruction &i)
{
Word code = 0;
Size bitsWritten = 0;
// Size WordEncoder::encode(Ref *&ref, std::vector<Byte> &v,
// Size idx, Instruction &i)
// {
// Word code = 0;
// Size bitsWritten = 0;
/* Predicate/predicated bit */
if (i.hasPred()) {
code = 1 << p;
code |= (i.getPred()&pMask);
if (i.getPred() > pMask) {
cout << "Predicate in " << i << " does not fit in encoding.\n";
exit(1);
}
}
bitsWritten += (1 + p);
// /* Predicate/predicated bit */
// if (i.hasPred()) {
// code = 1 << p;
// code |= (i.getPred()&pMask);
// if (i.getPred() > pMask) {
// cout << "Predicate in " << i << " does not fit in encoding.\n";
// exit(1);
// }
// }
// bitsWritten += (1 + p);
/* Opcode */
code <<= o;
code |= (i.getOpcode()&oMask);
if (i.getOpcode() > oMask) {
cout << "Opcode in " << i << " does not fit in encoding.\n";
exit(1);
}
bitsWritten += o;
// /* Opcode */
// code <<= o;
// code |= (i.getOpcode()&oMask);
// if (i.getOpcode() > oMask) {
// cout << "Opcode in " << i << " does not fit in encoding.\n";
// exit(1);
// }
// bitsWritten += o;
if (i.hasRDest()) {
code <<= r;
code |= i.getRDest();
bitsWritten += r;
if (i.getRDest() > rMask) {
cout << "Destination register in " << i << " does not fit in encoding.\n";
exit(1);
}
}
// if (i.hasRDest()) {
// code <<= r;
// code |= i.getRDest();
// bitsWritten += r;
// if (i.getRDest() > rMask) {
// cout << "Destination register in " << i << " does not fit in encoding.\n";
// exit(1);
// }
// }
if (i.hasPDest()) {
code <<= r;
code |= i.getPDest();
bitsWritten += r;
if (i.getPDest() > rMask) {
cout << "Destination predicate in " <<i<< " does not fit in encoding.\n";
exit(1);
}
}
// if (i.hasPDest()) {
// code <<= r;
// code |= i.getPDest();
// bitsWritten += r;
// if (i.getPDest() > rMask) {
// cout << "Destination predicate in " <<i<< " does not fit in encoding.\n";
// exit(1);
// }
// }
for (Size j = 0; j < i.getNRSrc(); j++) {
code <<= r;
code |= i.getRSrc(j);
bitsWritten += r;
if (i.getRSrc(j) > rMask) {
cout << "Source register " << j << " in " << i
<< " does not fit in encoding.\n";
exit(1);
}
}
// for (Size j = 0; j < i.getNRSrc(); j++) {
// code <<= r;
// code |= i.getRSrc(j);
// bitsWritten += r;
// if (i.getRSrc(j) > rMask) {
// cout << "Source register " << j << " in " << i
// << " does not fit in encoding.\n";
// exit(1);
// }
// }
for (Size j = 0; j < i.getNPSrc(); j++) {
code <<= r;
code |= i.getPSrc(j);
bitsWritten += r;
if (i.getPSrc(j) > rMask) {
cout << "Source predicate " << j << " in " << i
<< " does not fit in encoding.\n";
exit(1);
}
}
// for (Size j = 0; j < i.getNPSrc(); j++) {
// code <<= r;
// code |= i.getPSrc(j);
// bitsWritten += r;
// if (i.getPSrc(j) > rMask) {
// cout << "Source predicate " << j << " in " << i
// << " does not fit in encoding.\n";
// exit(1);
// }
// }
if (i.hasRefLiteral()) {
Ref *r = i.getRefLiteral();
ref = new OffsetRef(r->name, v, idx, n - bitsWritten, n, i.hasRelImm());
} else {
ref = NULL;
}
// if (i.hasRefLiteral()) {
// Ref *r = i.getRefLiteral();
// ref = new OffsetRef(r->name, v, idx, n - bitsWritten, n, i.hasRelImm());
// } else {
// ref = NULL;
// }
if (i.hasImm()) {
if (bitsWritten == n - i1) {
code <<= i1;
code |= (i.getImm()&i1Mask);
bitsWritten += i1;
Word_s ws(i.getImm());
if ((ws >> i1) != 0 && (ws >> i1) != -1) goto tooBigImm;
} else if (bitsWritten == n - i2) {
code <<= i2;
code |= (i.getImm()&i2Mask);
bitsWritten += i2;
Word_s ws(i.getImm());
if ((ws >> i2) != 0 && (ws >> i2) != -1) goto tooBigImm;
} else if (bitsWritten == n - i3) {
code <<= i3;
code |= (i.getImm()&i3Mask);
bitsWritten += i3;
Word_s ws(i.getImm());
if ((ws >> i3) != 0 && (ws >> i3) != -1) goto tooBigImm;
} else {
cout << "WordEncoder::encode() could not encode: " << i << '\n';
exit(1);
}
}
// if (i.hasImm()) {
// if (bitsWritten == n - i1) {
// code <<= i1;
// code |= (i.getImm()&i1Mask);
// bitsWritten += i1;
// Word_s ws(i.getImm());
// if ((ws >> i1) != 0 && (ws >> i1) != -1) goto tooBigImm;
// } else if (bitsWritten == n - i2) {
// code <<= i2;
// code |= (i.getImm()&i2Mask);
// bitsWritten += i2;
// Word_s ws(i.getImm());
// if ((ws >> i2) != 0 && (ws >> i2) != -1) goto tooBigImm;
// } else if (bitsWritten == n - i3) {
// code <<= i3;
// code |= (i.getImm()&i3Mask);
// bitsWritten += i3;
// Word_s ws(i.getImm());
// if ((ws >> i3) != 0 && (ws >> i3) != -1) goto tooBigImm;
// } else {
// cout << "WordEncoder::encode() could not encode: " << i << '\n';
// exit(1);
// }
// }
if (bitsWritten < n) code <<= (n - bitsWritten);
// if (bitsWritten < n) code <<= (n - bitsWritten);
writeWord(v, idx, n/8, code);
// writeWord(v, idx, n/8, code);
return n/8;
// return n/8;
tooBigImm:
cout << "Immediate in " << i << " too large to encode.\n";
exit(1);
}
// tooBigImm:
// cout << "Immediate in " << i << " too large to encode.\n";
// exit(1);
// }

View File

@@ -50,158 +50,158 @@ HarpToolMode findMode(int argc, char** argv) {
}
int asm_main(int argc, char **argv) {
string archString("8w32/32/8/8"), outFileName("a.out.HOF"),
inFileName(argv[argc-1]);
bool showHelp;
// string archString("8w32/32/8/8"), outFileName("a.out.HOF"),
// inFileName(argv[argc-1]);
// bool showHelp;
/* Get command line arguments. */
CommandLineArgFlag fh("-h", "--help", "", showHelp);
CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
// /* Get command line arguments. */
// CommandLineArgFlag fh("-h", "--help", "", showHelp);
// CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
// CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
CommandLineArg::readArgs(argc-1, argv);
// CommandLineArg::readArgs(argc-1, argv);
if (showHelp || argc == 0) {
cout << Help::asmHelp;
exit(0);
}
// if (showHelp || argc == 0) {
// cout << Help::asmHelp;
// exit(0);
// }
ArchDef arch(archString);
// ArchDef arch(archString);
D(0, "Created ArchDef for " << string(arch));
// D(0, "Created ArchDef for " << string(arch));
/* Create an appropriate encoder. */
Encoder *enc;
switch (arch.getEncChar()) {
case 'b': enc = new ByteEncoder(arch); break;
case 'w': enc = new WordEncoder(arch); break;
defaulet:
cout << "Unknown encoding type, \"" << arch.getEncChar() << "\"\n";
exit(1);
}
// /* Create an appropriate encoder. */
// Encoder *enc;
// switch (arch.getEncChar()) {
// case 'b': enc = new ByteEncoder(arch); break;
// case 'w': enc = new WordEncoder(arch); break;
// defaulet:
// cout << "Unknown encoding type, \"" << arch.getEncChar() << "\"\n";
// exit(1);
// }
/* Open files. */
if (outFileName == "") {
cout << "HARP Assembler: No output filename given.\n";
exit(1);
}
// /* Open files. */
// if (outFileName == "") {
// cout << "HARP Assembler: No output filename given.\n";
// exit(1);
// }
ifstream asmFile(inFileName.c_str());
ofstream outFile(outFileName.c_str());
// ifstream asmFile(inFileName.c_str());
// ofstream outFile(outFileName.c_str());
if (!asmFile) {
cout << "Could not open \"" << inFileName << "\" for reading.\n";
exit(1);
}
// if (!asmFile) {
// cout << "Could not open \"" << inFileName << "\" for reading.\n";
// exit(1);
// }
if (!outFile) {
cout << "Could not open \"" << outFileName << "\" for writing.\n";
exit(1);
}
// if (!outFile) {
// cout << "Could not open \"" << outFileName << "\" for writing.\n";
// exit(1);
// }
/* Read an Obj from the assembly file. */
D(0, "Passing AsmReader ArchDef: " << string(arch));
AsmReader ar(arch);
Obj *o = ar.read(asmFile);
// /* Read an Obj from the assembly file. */
// D(0, "Passing AsmReader ArchDef: " << string(arch));
// AsmReader ar(arch);
// Obj *o = ar.read(asmFile);
/* Encode the text chunks read from the assembly file. */
for (Size j = 0; j < o->chunks.size(); j++) {
Chunk *&c = o->chunks[j];
TextChunk *tc;
DataChunk *dc;
if ((tc = dynamic_cast<TextChunk*>(c)) != NULL) {
/* Encode it. */
dc = new DataChunk(tc->name);
enc->encodeChunk(*dc, *tc);
// /* Encode the text chunks read from the assembly file. */
// for (Size j = 0; j < o->chunks.size(); j++) {
// Chunk *&c = o->chunks[j];
// TextChunk *tc;
// DataChunk *dc;
// if ((tc = dynamic_cast<TextChunk*>(c)) != NULL) {
// /* Encode it. */
// dc = new DataChunk(tc->name);
// enc->encodeChunk(*dc, *tc);
/* Delete the text chunk. */
delete tc;
// /* Delete the text chunk. */
// delete tc;
/* Do the switch. */
c = dc;
}
}
asmFile.close();
delete enc;
// /* Do the switch. */
// c = dc;
// }
// }
// asmFile.close();
// delete enc;
/* Write a HOF binary. */
D(0, "Creating a HOFWriter, passing it ArchDef: " << string(arch));
HOFWriter hw(arch);
hw.write(outFile, *o);
outFile.close();
// /* Write a HOF binary. */
// D(0, "Creating a HOFWriter, passing it ArchDef: " << string(arch));
// HOFWriter hw(arch);
// hw.write(outFile, *o);
// outFile.close();
delete o;
// delete o;
return 0;
}
int disasm_main(int argc, char **argv) {
bool showHelp;
string outFileName("a.out.s"), archString("8w32/32/8/8");
// bool showHelp;
// string outFileName("a.out.s"), archString("8w32/32/8/8");
/* Get command line arguments. */
CommandLineArgFlag fh("-h", "--help", "", showHelp);
CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
// /* Get command line arguments. */
// CommandLineArgFlag fh("-h", "--help", "", showHelp);
// CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
// CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
if (argc != 0) CommandLineArg::readArgs(argc-1, argv);
// if (argc != 0) CommandLineArg::readArgs(argc-1, argv);
if (argc == 0 || showHelp) {
cout << Help::disasmHelp;
exit(0);
}
// if (argc == 0 || showHelp) {
// cout << Help::disasmHelp;
// exit(0);
// }
ifstream objFile(argv[argc-1]);
ofstream outFile(outFileName.c_str());
ArchDef arch(archString);
// ifstream objFile(argv[argc-1]);
// ofstream outFile(outFileName.c_str());
// ArchDef arch(archString);
if (!objFile) {
cout << "Disassembler could not open \"" << argv[argc-1]
<< "\" for reading.\n";
exit(1);
}
// if (!objFile) {
// cout << "Disassembler could not open \"" << argv[argc-1]
// << "\" for reading.\n";
// exit(1);
// }
if (!outFile) {
cout << "Disassembler could not open \"" << outFileName
<< "\" for output.\n";
exit(1);
}
// if (!outFile) {
// cout << "Disassembler could not open \"" << outFileName
// << "\" for output.\n";
// exit(1);
// }
HOFReader hr(arch);
Obj *o = hr.read(objFile);
objFile.close();
Decoder *dec;
// HOFReader hr(arch);
// Obj *o = hr.read(objFile);
// objFile.close();
// Decoder *dec;
switch (arch.getEncChar()) {
case 'b': dec = new ByteDecoder(arch); break;
case 'w': dec = new WordDecoder(arch); break;
default:
cout << "Unrecognized encoding character for disassembler.\n";
exit(1);
}
// switch (arch.getEncChar()) {
// case 'b': dec = new ByteDecoder(arch); break;
// case 'w': dec = new WordDecoder(arch); break;
// default:
// cout << "Unrecognized encoding character for disassembler.\n";
// exit(1);
// }
/* Decode the chunks read from the object. */
for (Size j = 0; j < o->chunks.size(); j++) {
Chunk *&c = o->chunks[j];
if (c->flags & EX_USR) {
TextChunk *tc;
DataChunk *dc;
if ((dc = dynamic_cast<DataChunk*>(c)) != NULL) {
TextChunk *tc = new TextChunk(dc->name);
dec->decodeChunk(*tc, *dc);
delete dc;
c = tc;
}
}
}
delete dec;
// /* Decode the chunks read from the object. */
// for (Size j = 0; j < o->chunks.size(); j++) {
// Chunk *&c = o->chunks[j];
// if (c->flags & EX_USR) {
// TextChunk *tc;
// DataChunk *dc;
// if ((dc = dynamic_cast<DataChunk*>(c)) != NULL) {
// TextChunk *tc = new TextChunk(dc->name);
// dec->decodeChunk(*tc, *dc);
// delete dc;
// c = tc;
// }
// }
// }
// delete dec;
AsmWriter aw(arch);
aw.write(outFile, *o);
outFile.close();
// AsmWriter aw(arch);
// aw.write(outFile, *o);
// outFile.close();
delete o;
// delete o;
return 0;
}
@@ -254,117 +254,117 @@ int emu_main(int argc, char **argv) {
}
int ld_main(int argc, char **argv) {
bool showHelp, mustResolveRefs(true);
string outFileName("a.out.bin"), archString("8w32/32/8/8"),
formatString("bin");
Size nObjects;
Addr binOffset(0);
// bool showHelp, mustResolveRefs(true);
// string outFileName("a.out.bin"), archString("8w32/32/8/8"),
// formatString("bin");
// Size nObjects;
// Addr binOffset(0);
/* Get command line arguments. */
CommandLineArgFlag fh("-h", "--help", "", showHelp);
CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
CommandLineArgSetter<string>ff("-f", "--format", "", formatString);
CommandLineArgSetter<Addr> foffset("--offset", "", binOffset);
CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
// /* Get command line arguments. */
// CommandLineArgFlag fh("-h", "--help", "", showHelp);
// CommandLineArgSetter<string>fa("-a", "--arch", "", archString);
// CommandLineArgSetter<string>ff("-f", "--format", "", formatString);
// CommandLineArgSetter<Addr> foffset("--offset", "", binOffset);
// CommandLineArgSetter<string>fo("-o", "--output", "", outFileName);
int firstInput(0), newArgc;
for (size_t i = 0; i < argc; i++) {
if (*(argv[i]) != '-') { firstInput = i; newArgc = i; break; }
else if (string(argv[i]) == "--") { firstInput = i+1; newArgc = i; break; }
else i++; /* Skip both the switch and its argument. */
}
nObjects = argc - firstInput;
// int firstInput(0), newArgc;
// for (size_t i = 0; i < argc; i++) {
// if (*(argv[i]) != '-') { firstInput = i; newArgc = i; break; }
// else if (string(argv[i]) == "--") { firstInput = i+1; newArgc = i; break; }
// else i++; /* Skip both the switch and its argument. */
// }
// nObjects = argc - firstInput;
if (argc != 0) CommandLineArg::readArgs(newArgc, argv);
// if (argc != 0) CommandLineArg::readArgs(newArgc, argv);
if (argc == 0 || showHelp) {
cout << Help::ldHelp;
exit(0);
}
// if (argc == 0 || showHelp) {
// cout << Help::ldHelp;
// exit(0);
// }
if (firstInput == argc) {
cout << "Linker: no input files given.\n";
exit(1);
}
// if (firstInput == argc) {
// cout << "Linker: no input files given.\n";
// exit(1);
// }
ArchDef arch(archString);
// ArchDef arch(archString);
/* Read all of the objects, assign addresses to their chunks, and place them
in an address map.*/
vector<Obj *> objects(nObjects);
vector<DataChunk*> chunks;
map<string, Addr> gChunkMap;
Addr nextOffset(binOffset);
// /* Read all of the objects, assign addresses to their chunks, and place them
// in an address map.*/
// vector<Obj *> objects(nObjects);
// vector<DataChunk*> chunks;
// map<string, Addr> gChunkMap;
// Addr nextOffset(binOffset);
for (Size i = 0; i < nObjects; i++) {
map <string, Addr> lChunkMap;
// for (Size i = 0; i < nObjects; i++) {
// map <string, Addr> lChunkMap;
/* Read the object. */
HOFReader hr(arch);
ifstream objFile(argv[firstInput + i]);
if (!objFile) {
cout << "Could not open \"" << argv[firstInput + i]
<< "\" for reading.\n";
exit(1);
}
objects[i] = hr.read(objFile);
// /* Read the object. */
// HOFReader hr(arch);
// ifstream objFile(argv[firstInput + i]);
// if (!objFile) {
// cout << "Could not open \"" << argv[firstInput + i]
// << "\" for reading.\n";
// exit(1);
// }
// objects[i] = hr.read(objFile);
/* Assign addresses to chunks. */
Obj &obj = *objects[i];
for (Size j = 0; j < obj.chunks.size(); j++) {
DataChunk *c = dynamic_cast<DataChunk*>(obj.chunks[j]);
if (c->alignment != 0 && nextOffset % c->alignment)
nextOffset += c->alignment - (nextOffset % c->alignment);
c->bind(nextOffset);
chunks.push_back(c);
if (obj.chunks[j]->name != "") {
if (c->isGlobal()) gChunkMap[c->name] = nextOffset;
else lChunkMap[c->name] = nextOffset;
}
nextOffset += (c->size);
}
// /* Assign addresses to chunks. */
// Obj &obj = *objects[i];
// for (Size j = 0; j < obj.chunks.size(); j++) {
// DataChunk *c = dynamic_cast<DataChunk*>(obj.chunks[j]);
// if (c->alignment != 0 && nextOffset % c->alignment)
// nextOffset += c->alignment - (nextOffset % c->alignment);
// c->bind(nextOffset);
// chunks.push_back(c);
// if (obj.chunks[j]->name != "") {
// if (c->isGlobal()) gChunkMap[c->name] = nextOffset;
// else lChunkMap[c->name] = nextOffset;
// }
// nextOffset += (c->size);
// }
/* Resolve local references. */
for (Size i = 0; i < obj.chunks.size(); i++) {
DataChunk *dc = dynamic_cast<DataChunk*>(obj.chunks[i]);
for (Size j = 0; j < dc->refs.size(); j++) {
Ref &ref = *(dc->refs[j]);
if (lChunkMap.find(dc->refs[j]->name) != lChunkMap.end()) {
dc->refs[j]->bind(lChunkMap[dc->refs[j]->name],
dc->address + dc->refs[j]->ibase);
}
}
}
}
// /* Resolve local references. */
// for (Size i = 0; i < obj.chunks.size(); i++) {
// DataChunk *dc = dynamic_cast<DataChunk*>(obj.chunks[i]);
// for (Size j = 0; j < dc->refs.size(); j++) {
// Ref &ref = *(dc->refs[j]);
// if (lChunkMap.find(dc->refs[j]->name) != lChunkMap.end()) {
// dc->refs[j]->bind(lChunkMap[dc->refs[j]->name],
// dc->address + dc->refs[j]->ibase);
// }
// }
// }
// }
/* Resolve references. */
for (Size i = 0; i < chunks.size(); i++) {
DataChunk *dc = chunks[i];
for (Size j = 0; j < dc->refs.size(); j++) {
Ref &ref = *(dc->refs[j]);
if (!ref.bound && (gChunkMap.find(ref.name) != gChunkMap.end())) {
ref.bind(gChunkMap[ref.name], dc->address + ref.ibase);
} else if (!ref.bound && mustResolveRefs) {
cout << "Undefined symbol: \"" << ref.name << "\"\n";
exit(1);
}
}
}
// /* Resolve references. */
// for (Size i = 0; i < chunks.size(); i++) {
// DataChunk *dc = chunks[i];
// for (Size j = 0; j < dc->refs.size(); j++) {
// Ref &ref = *(dc->refs[j]);
// if (!ref.bound && (gChunkMap.find(ref.name) != gChunkMap.end())) {
// ref.bind(gChunkMap[ref.name], dc->address + ref.ibase);
// } else if (!ref.bound && mustResolveRefs) {
// cout << "Undefined symbol: \"" << ref.name << "\"\n";
// exit(1);
// }
// }
// }
/* Write out the chunks. */
ofstream outFile(outFileName.c_str());
for (Size i = 0; i < chunks.size(); i++) {
if (outFile.tellp() > chunks[i]->address - binOffset) {
cout << "Linker internal error. Wrote past next chunk address.\n";
exit(1);
}
while (outFile.tellp() < chunks[i]->address - binOffset) outFile.put('\0');
outFile.seekp(chunks[i]->address - binOffset);
outFile.write((char*)&chunks[i]->contents[0], chunks[i]->contents.size());
}
// /* Write out the chunks. */
// ofstream outFile(outFileName.c_str());
// for (Size i = 0; i < chunks.size(); i++) {
// if (outFile.tellp() > chunks[i]->address - binOffset) {
// cout << "Linker internal error. Wrote past next chunk address.\n";
// exit(1);
// }
// while (outFile.tellp() < chunks[i]->address - binOffset) outFile.put('\0');
// outFile.seekp(chunks[i]->address - binOffset);
// outFile.write((char*)&chunks[i]->contents[0], chunks[i]->contents.size());
// }
/* Clean up. */
for (Size i = 0; i < nObjects; i++) delete objects[i];
// /* Clean up. */
// for (Size i = 0; i < nObjects; i++) delete objects[i];
return 0;
}

View File

@@ -51,6 +51,17 @@ namespace Harp {
private:
Size n, o, r, p, i1, i2, i3;
Word oMask, rMask, pMask, i1Mask, i2Mask, i3Mask;
// FARES
Size inst_s, opcode_s, reg_s, func3_s;
Size shift_opcode, shift_rd, shift_rs1, shift_rs2, shift_func3, shift_func7;
Size shift_j_u_immed, shift_s_b_immed, shift_i_immed;
Word reg_mask, func3_mask, func7_mask, opcode_mask, i_immed_mask,
s_immed_mask, b_immed_mask, u_immed_mask, j_immed_mask;
};
class ByteDecoder : public Decoder {

View File

@@ -4,6 +4,7 @@
#ifndef __INSTRUCTION_H
#define __INSTRUCTION_H
#include <map>
#include <iostream>
#include "types.h"
@@ -24,34 +25,52 @@ namespace Harp {
class Instruction {
public:
enum Opcode { 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, WSPAWN, SPLIT, JOIN, BAR };
enum ArgClass {
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_2REGSRC
};
enum InstType {
ITYPE_NULL, ITYPE_INTBASIC, ITYPE_INTMUL, ITYPE_INTDIV, ITYPE_STACK, ITYPE_BR,
ITYPE_CALL, ITYPE_RET, ITYPE_TRAP, ITYPE_FPBASIC, ITYPE_FPMUL, ITYPE_FPDIV
};
enum Opcode
{
NOP = 0,
R_INST = 51,
L_INST = 3,
I_INST = 19,
S_INST = 35,
B_INST = 99,
LUI_INST = 55,
AUIPC_INST = 23,
JAL_INST = 111,
JALR_INST = 103,
SYS_INST = 115
};
enum InstType { N_TYPE, R_TYPE, I_TYPE, S_TYPE, B_TYPE, U_TYPE, J_TYPE };
// We build a table of instruction information out of this.
static struct InstTableEntry {
struct InstTableEntry_t {
const char *opString;
bool controlFlow, relAddress, allSrcArgs, privileged;
ArgClass argClass;
InstType iType;
} instTable[];
};
Instruction() :
predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false),
rdestPresent(false), pdestPresent(false), refLiteral(NULL) {}
rdestPresent(false), pdestPresent(false), refLiteral(NULL)
{
instTable = std::map<int, struct InstTableEntry_t>
{
{Opcode::NOP, {"nop" , false, false, false, false, InstType::N_TYPE }},
{Opcode::R_INST, {"r_type", false, false, false, false, InstType::R_TYPE }},
{Opcode::L_INST, {"load" , false, false, false, false, InstType::I_TYPE }},
{Opcode::I_INST, {"i_type", false, false, false, false, InstType::I_TYPE }},
{Opcode::S_INST, {"store" , false, false, false, false, InstType::I_TYPE }},
{Opcode::B_INST, {"branch", true , false, false, false, InstType::B_TYPE }},
{Opcode::LUI_INST, {"lui" , false, false, false, false, InstType::U_TYPE }},
{Opcode::AUIPC_INST, {"auipc" , false, false, false, false, InstType::U_TYPE }},
{Opcode::JAL_INST, {"jal" , true , false, false, false, InstType::J_TYPE }},
{Opcode::JALR_INST, {"jalr" , true , false, false, false, InstType::I_TYPE }},
{Opcode::SYS_INST, {"SYS" , true , false, false, false, InstType::I_TYPE }}
};
}
void executeOn(Warp &warp);
friend std::ostream &operator<<(std::ostream &, Instruction &);
@@ -61,6 +80,8 @@ namespace Harp {
void setPred (RegNum pReg) { predicated = true; pred = pReg; }
void setDestReg (RegNum destReg) { rdestPresent = true; rdest = destReg; }
void setSrcReg (RegNum srcReg) { rsrc[nRsrc++] = srcReg; }
void setFunc3 (Word func3) { this->func3 = func3; }
void setFunc7 (Word func7) { this->func7 = func7; }
void setDestPReg(RegNum dPReg) { pdestPresent = true; pdest = dPReg; }
void setSrcPReg (RegNum srcPReg) { psrc[nPsrc++] = srcPReg; }
Word *setSrcImm () { immsrcPresent = true; immsrc = 0xa5; return &immsrc;}
@@ -85,7 +106,7 @@ namespace Harp {
Ref *getRefLiteral() const { return refLiteral; }
/* Getters used as table lookup. */
bool hasRelImm() const { return instTable[op].relAddress; }
bool hasRelImm() const { return (*(instTable.find(op))).second.relAddress; }
private:
bool predicated;
@@ -95,10 +116,22 @@ namespace Harp {
RegNum rsrc[MAX_REG_SOURCES], psrc[MAX_PRED_SOURCES];
bool immsrcPresent;
Word immsrc;
Word func3;
Word func7;
bool rdestPresent, pdestPresent;
RegNum rdest, pdest;
Ref *refLiteral;
public:
static std::map<int, struct InstTableEntry_t> instTable;
};
};
#endif
// static struct InstTableEntry {
// const char *opString;
// bool controlFlow, relAddress, allSrcArgs, privileged;
// InstType iType;
// };

View File

@@ -16,195 +16,195 @@
#include "enc.h"
#include "asm-tokens.h"
namespace Harp {
class Decoder;
class Encoder;
// namespace Harp {
// class Decoder;
// class Encoder;
class Ref {
public:
std::string name;
Ref(const std::string &n, bool r, Size ib = 0):
name(n), bound(false), relative(r), ibase(ib) { }
virtual ~Ref() { }
virtual void bind(Addr addr, Addr base = 0) = 0;
virtual Addr getAddr() const = 0;
// class Ref {
// public:
// std::string name;
// Ref(const std::string &n, bool r, Size ib = 0):
// name(n), bound(false), relative(r), ibase(ib) { }
// virtual ~Ref() { }
// virtual void bind(Addr addr, Addr base = 0) = 0;
// virtual Addr getAddr() const = 0;
bool bound, relative;
Size ibase;
};
// bool bound, relative;
// Size ibase;
// };
/* Used in not-yet-encoded code objects, plain old data. */
class SimpleRef : public Ref {
public:
SimpleRef(const std::string &name, Addr &addr, bool rel = false) :
Ref(name, rel), addr(addr) { }
virtual void bind(Addr addr, Addr base = 0) {
std::cout << "Attempted to bind a SimpleRef.\n";
exit(1);
}
virtual Addr getAddr() const { return this->addr; }
Byte *getAddrPtr() { return (Byte*)&addr; }
// /* Used in not-yet-encoded code objects, plain old data. */
// class SimpleRef : public Ref {
// public:
// SimpleRef(const std::string &name, Addr &addr, bool rel = false) :
// Ref(name, rel), addr(addr) { }
// virtual void bind(Addr addr, Addr base = 0) {
// std::cout << "Attempted to bind a SimpleRef.\n";
// exit(1);
// }
// virtual Addr getAddr() const { return this->addr; }
// Byte *getAddrPtr() { return (Byte*)&addr; }
private:
Addr &addr;
};
// private:
// Addr &addr;
// };
/* Used in already-encoded code objects. */
class OffsetRef : public Ref {
public:
OffsetRef(
const std::string &name, std::vector<Byte> &v, Size offset, Size bits,
Size ws, bool rel = false, Size ibase = 0
) : Ref(name, rel, ibase), data(v), offset(offset), bits(bits), wordSize(ws)
{}
// /* Used in already-encoded code objects. */
// class OffsetRef : public Ref {
// public:
// OffsetRef(
// const std::string &name, std::vector<Byte> &v, Size offset, Size bits,
// Size ws, bool rel = false, Size ibase = 0
// ) : Ref(name, rel, ibase), data(v), offset(offset), bits(bits), wordSize(ws)
// {}
virtual void bind(Addr addr, Addr base = 0) {
Size bytes(bits/8), remainder(bits%8);
// virtual void bind(Addr addr, Addr base = 0) {
// Size bytes(bits/8), remainder(bits%8);
if (relative) {
addr = addr - base;
Word_s addr_s(addr);
if ((addr_s >> bits) != ~0ull && (addr_s >> bits) != 0) goto noFit;
} else {
Addr mask = (1ull<<bits)-1;
if (addr > mask) goto noFit;
}
// if (relative) {
// addr = addr - base;
// Word_s addr_s(addr);
// if ((addr_s >> bits) != ~0ull && (addr_s >> bits) != 0) goto noFit;
// } else {
// Addr mask = (1ull<<bits)-1;
// if (addr > mask) goto noFit;
// }
{ Byte mask((1ull<<remainder) - 1);
Size i;
for (i = 0; i < bytes; i++) {
data[offset+i] = addr & 0xff;
addr >>= 8;
}
data[offset+i] &= ~mask;
data[offset+i] |= (addr&mask);
bound = true;
}
// { Byte mask((1ull<<remainder) - 1);
// Size i;
// for (i = 0; i < bytes; i++) {
// data[offset+i] = addr & 0xff;
// addr >>= 8;
// }
// data[offset+i] &= ~mask;
// data[offset+i] |= (addr&mask);
// bound = true;
// }
return;
noFit:
std::cout << "Attempt to bind a " << bits << "-bit "
<< (relative?"":"non-") << "relative symbol to an address"
" it cannot reach.\n";
exit(1);
}
// return;
// noFit:
// std::cout << "Attempt to bind a " << bits << "-bit "
// << (relative?"":"non-") << "relative symbol to an address"
// " it cannot reach.\n";
// exit(1);
// }
virtual Addr getAddr() const {
Size bytes = bits/8, remainder = bits%8;
Byte mask((1<<remainder)-1);
Addr a(data[offset]&mask);
// virtual Addr getAddr() const {
// Size bytes = bits/8, remainder = bits%8;
// Byte mask((1<<remainder)-1);
// Addr a(data[offset]&mask);
for (Size i = 0; i < bytes-1; i++) {
a |= data[offset + bytes - i - 1];
a <<= 8;
}
return a;
}
// for (Size i = 0; i < bytes-1; i++) {
// a |= data[offset + bytes - i - 1];
// a <<= 8;
// }
// return a;
// }
Size getOffset() const { return offset; }
Size getBits() const { return bits; }
// Size getOffset() const { return offset; }
// Size getBits() const { return bits; }
private:
std::vector<Byte> &data;
Size offset, bits, wordSize;
};
// private:
// std::vector<Byte> &data;
// Size offset, bits, wordSize;
// };
class Chunk {
public:
Chunk(std::string n, Size a = 0, Word f = 0) :
name(n), alignment(a), bound(false), flags(f), global(false) {}
virtual ~Chunk() { for (Size i = 0; i < refs.size(); i++) delete refs[i]; }
void bind(Addr a) { address = a; bound = true; }
void setGlobal() { global = true; }
bool isGlobal() const { return global; }
std::string name;
Size alignment;
bool bound, global;
Addr address;
Word flags;
std::vector<Ref*> refs;
};
// class Chunk {
// public:
// Chunk(std::string n, Size a = 0, Word f = 0) :
// name(n), alignment(a), bound(false), flags(f), global(false) {}
// virtual ~Chunk() { for (Size i = 0; i < refs.size(); i++) delete refs[i]; }
// void bind(Addr a) { address = a; bound = true; }
// void setGlobal() { global = true; }
// bool isGlobal() const { return global; }
// std::string name;
// Size alignment;
// bool bound, global;
// Addr address;
// Word flags;
// std::vector<Ref*> refs;
// };
class TextChunk : public Chunk {
public:
TextChunk(std::string n, Size a = 0, Word f = 0)
: Chunk(n, a, f), instructions() {}
// class TextChunk : public Chunk {
// public:
// TextChunk(std::string n, Size a = 0, Word f = 0)
// : Chunk(n, a, f), instructions() {}
~TextChunk() {
for (Size i = 0; i < instructions.size(); i++) delete instructions[i];
}
// ~TextChunk() {
// for (Size i = 0; i < instructions.size(); i++) delete instructions[i];
// }
std::vector<Instruction*> instructions;
};
// std::vector<Instruction*> instructions;
// };
class DataChunk : public Chunk {
public:
DataChunk(std::string n, Size a = 0, Word f = 0)
: Chunk(n, a, f), size(0), contents() {}
Size size;
std::vector<Byte> contents; /* 0 to size bytes in length. */
};
// class DataChunk : public Chunk {
// public:
// DataChunk(std::string n, Size a = 0, Word f = 0)
// : Chunk(n, a, f), size(0), contents() {}
// Size size;
// std::vector<Byte> contents; /* 0 to size bytes in length. */
// };
class Obj {
public:
~Obj() { for (Size i = 0; i < chunks.size(); i++) delete chunks[i]; }
std::vector<Chunk*> chunks;
Size entry;
};
// class Obj {
// public:
// ~Obj() { for (Size i = 0; i < chunks.size(); i++) delete chunks[i]; }
// std::vector<Chunk*> chunks;
// Size entry;
// };
class DynObj : public Obj {
public:
std::vector<std::string> deps;
};
// class DynObj : public Obj {
// public:
// std::vector<std::string> deps;
// };
class ObjReader {
public:
virtual Obj *read(std::istream &input) = 0;
private:
};
// class ObjReader {
// public:
// virtual Obj *read(std::istream &input) = 0;
// private:
// };
class ObjWriter {
public:
virtual void write(std::ostream &output, const Obj &o) = 0;
private:
};
// class ObjWriter {
// public:
// virtual void write(std::ostream &output, const Obj &o) = 0;
// private:
// };
class AsmReader : public ObjReader {
public:
AsmReader(ArchDef arch) :
wordSize(arch.getWordSize()), nRegs(arch.getNRegs()) {}
virtual Obj *read(std::istream &input);
private:
Size wordSize, nRegs;
// class AsmReader : public ObjReader {
// public:
// AsmReader(ArchDef arch) :
// wordSize(arch.getWordSize()), nRegs(arch.getNRegs()) {}
// virtual Obj *read(std::istream &input);
// private:
// Size wordSize, nRegs;
// Operand type sequences indexed by argument class
enum ArgType {AT_END, AT_REG, AT_PREG, AT_LIT};
static ArgType operandtype_table[][4]; // ArgClass -> ArgType[arg_idx]
};
// // Operand type sequences indexed by argument class
// enum ArgType {AT_END, AT_REG, AT_PREG, AT_LIT};
// static ArgType operandtype_table[][4]; // ArgClass -> ArgType[arg_idx]
// };
class HOFReader : public ObjReader {
public:
HOFReader(ArchDef &arch) : arch(arch) {}
Obj *read(std::istream &input);
private:
const ArchDef &arch;
};
// class HOFReader : public ObjReader {
// public:
// HOFReader(ArchDef &arch) : arch(arch) {}
// Obj *read(std::istream &input);
// private:
// const ArchDef &arch;
// };
class AsmWriter : public ObjWriter {
public:
AsmWriter(ArchDef arch): wordSize(arch.getWordSize()) {}
virtual void write(std::ostream &output, const Obj &obj);
private:
Size wordSize;
};
// class AsmWriter : public ObjWriter {
// public:
// AsmWriter(ArchDef arch): wordSize(arch.getWordSize()) {}
// virtual void write(std::ostream &output, const Obj &obj);
// private:
// Size wordSize;
// };
class HOFWriter : public ObjWriter {
public:
HOFWriter(ArchDef &arch) : arch(arch) {}
virtual void write(std::ostream &output, const Obj &obj);
private:
const ArchDef &arch;
};
};
// class HOFWriter : public ObjWriter {
// public:
// HOFWriter(ArchDef &arch) : arch(arch) {}
// virtual void write(std::ostream &output, const Obj &obj);
// private:
// const ArchDef &arch;
// };
// };
#endif

View File

@@ -20,93 +20,28 @@ using namespace std;
/* It is important that this stays consistent with the Harp::Instruction::Opcode
enum. */
Instruction::InstTableEntry Instruction::instTable[] = {
//str cflow relad allsrc priv argcl itype
{"nop", false, false, false, false, AC_NONE, ITYPE_NULL },
{"di", false, false, false, true, AC_NONE, ITYPE_NULL },
{"ei", false, false, false, true, AC_NONE, ITYPE_NULL },
{"tlbadd", false, false, true, true, AC_3REGSRC, ITYPE_NULL },
{"tlbflush", false, false, false, true, AC_NONE, ITYPE_NULL },
{"neg", false, false, false, false, AC_2REG, ITYPE_INTBASIC},
{"not", false, false, false, false, AC_2REG, ITYPE_INTBASIC},
{"and", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"or", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"xor", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"add", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"sub", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"mul", false, false, false, false, AC_3REG, ITYPE_INTMUL },
{"div", false, false, false, false, AC_3REG, ITYPE_INTDIV },
{"mod", false, false, false, false, AC_3REG, ITYPE_INTDIV },
{"shl", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"shr", false, false, false, false, AC_3REG, ITYPE_INTBASIC},
{"andi", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"ori", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"xori", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"addi", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"subi", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"muli", false, false, false, false, AC_3IMM, ITYPE_INTMUL },
{"divi", false, false, false, false, AC_3IMM, ITYPE_INTDIV },
{"modi", false, false, false, false, AC_3IMM, ITYPE_INTDIV },
{"shli", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"shri", false, false, false, false, AC_3IMM, ITYPE_INTBASIC},
{"jali", true, true, false, false, AC_2IMM, ITYPE_CALL },
{"jalr", true, false, false, false, AC_2REG, ITYPE_CALL },
{"jmpi", true, true, true, false, AC_1IMM, ITYPE_BR },
{"jmpr", true, false, true, false, AC_1REG, ITYPE_RET },
{"clone", true, false, false, false, AC_1REG, ITYPE_NULL },
{"jalis", true, true, false, false, AC_3IMM, ITYPE_CALL },
{"jalrs", true, false, false, false, AC_3REG, ITYPE_CALL },
{"jmprt", true, false, true, false, AC_1REG, ITYPE_RET },
{"ld", false, false, false, false, AC_3IMM, ITYPE_NULL },
{"st", false, false, true, false, AC_3IMMSRC, ITYPE_NULL },
{"ldi", false, false, false, false, AC_2IMM, ITYPE_NULL },
{"rtop", false, false, false, false, AC_PREG_REG, ITYPE_NULL },
{"andp", false, false, false, false, AC_3PREG, ITYPE_INTBASIC},
{"orp", false, false, false, false, AC_3PREG, ITYPE_INTBASIC},
{"xorp", false, false, false, false, AC_3PREG, ITYPE_INTBASIC},
{"notp", false, false, false, false, AC_2PREG, ITYPE_INTBASIC},
{"isneg", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
{"iszero", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
{"halt", false, false, false, false, AC_NONE, ITYPE_NULL },
{"trap", true, false, false, false, AC_NONE, ITYPE_TRAP },
{"jmpru", false, false, false, true, AC_1REG, ITYPE_RET },
{"skep", false, false, false, true, AC_1REG, ITYPE_NULL },
{"reti", true, false, false, true, AC_NONE, ITYPE_RET },
{"tlbrm", false, false, false, true, AC_1REG, ITYPE_NULL },
{"itof", false, false, false, false, AC_2REG, ITYPE_FPBASIC },
{"ftoi", false, false, false, false, AC_2REG, ITYPE_FPBASIC },
{"fadd", false, false, false, false, AC_3REG, ITYPE_FPBASIC },
{"fsub", false, false, false, false, AC_3REG, ITYPE_FPBASIC },
{"fmul", false, false, false, false, AC_3REG, ITYPE_FPMUL },
{"fdiv", false, false, false, false, AC_3REG, ITYPE_FPDIV },
{"fneg", false, false, false, false, AC_2REG, ITYPE_FPBASIC },
{"wspawn", false, false, true, false, AC_3REG, ITYPE_NULL },
{"split", false, false, true, false, AC_NONE, ITYPE_NULL },
{"join", false, false, true, false, AC_NONE, ITYPE_NULL },
{"bar", false, false, true, false, AC_2REGSRC, ITYPE_NULL },
{NULL,false,false,false,false,AC_NONE,ITYPE_NULL}/////// End of table.
};
ostream &Harp::operator<<(ostream& os, Instruction &inst) {
os << dec;
if (inst.predicated) {
os << "@p" << dec << inst.pred << " ? ";
}
// if (inst.predicated) {
// os << "@p" << dec << inst.pred << " ? ";
// }
os << Instruction::instTable[inst.op].opString << ' ';
if (inst.rdestPresent) os << "%r" << dec << inst.rdest << ' ';
if (inst.pdestPresent) os << "@p" << inst.pdest << ' ';
for (int i = 0; i < inst.nRsrc; i++) {
os << "%r" << dec << inst.rsrc[i] << ' ';
}
for (int i = 0; i < inst.nPsrc; i++) {
os << "@p" << dec << inst.psrc[i] << ' ';
}
if (inst.immsrcPresent) {
if (inst.refLiteral) os << inst.refLiteral->name;
else os << "#0x" << hex << inst.immsrc;
}
// os << inst.instTable[inst.op].opString << ' ';
// if (inst.rdestPresent) os << "%r" << dec << inst.rdest << ' ';
// if (inst.pdestPresent) os << "@p" << inst.pdest << ' ';
// for (int i = 0; i < inst.nRsrc; i++) {
// os << "%r" << dec << inst.rsrc[i] << ' ';
// }
// for (int i = 0; i < inst.nPsrc; i++) {
// os << "@p" << dec << inst.psrc[i] << ' ';
// }
// if (inst.immsrcPresent) {
// if (inst.refLiteral) os << inst.refLiteral->name;
// else os << "#0x" << hex << inst.immsrc;
// }
os << inst.instTable[inst.op].opString;
os << ';';
return os;
@@ -134,6 +69,11 @@ bool checkUnanimous(unsigned p, const std::vector<std::vector<Reg<bool> > >& m,
return true;
}
Word signExt(Word w, Size bit, Word mask) {
if (w>>(bit-1)) w |= ~mask;
return w;
}
void Instruction::executeOn(Warp &c) {
D(3, "Begin instruction execute.");
@@ -165,7 +105,7 @@ void Instruction::executeOn(Warp &c) {
// If we have a load, overwriting a register's contents, we have to make sure
// ahead of time it will not fault. Otherwise we may perform an indirect load
// by mistake.
if (op == LD && rdest == rsrc[0]) {
if (op == L_INST && rdest == rsrc[0]) {
for (Size t = 0; t < c.activeThreads; t++) {
if ((!predicated || c.pred[t][pred]) && c.tmask[t]) {
Word memAddr = c.reg[t][rsrc[0]] + immsrc;
@@ -183,261 +123,341 @@ void Instruction::executeOn(Warp &c) {
// If this thread is masked out, don't execute the instruction, unless it's
// a split or join.
if (((predicated && !pReg[pred]) || !c.tmask[t]) &&
op != SPLIT && op != JOIN) continue;
// if (((predicated && !pReg[pred]) || !c.tmask[t]) &&
// op != SPLIT && op != JOIN) continue;
++c.insts;
Word memAddr;
Word memAddr;
Word shift_by;
switch (op) {
case NOP: break;
case DI: c.interruptEnable = false;
break;
case EI: c.interruptEnable = true;
break;
case TLBADD: c.core->mem.tlbAdd(reg[rsrc[0]], reg[rsrc[1]], reg[rsrc[2]]);
break;
case TLBFLUSH: c.core->mem.tlbFlush();
break;
case ADD: reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]];
case R_INST:
switch (func3)
{
case 0:
if (func7)
{
reg[rdest] = reg[rsrc[0]] - reg[rsrc[1]];
reg[rdest].trunc(wordSz);
break;
case SUB: reg[rdest] = reg[rsrc[0]] - reg[rsrc[1]];
}
else
{
reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]];
reg[rdest].trunc(wordSz);
break;
case MUL: reg[rdest] = reg[rsrc[0]] * reg[rsrc[1]];
}
break;
case 1:
reg[rdest] = reg[rsrc[0]] << reg[rsrc[1]];
reg[rdest].trunc(wordSz);
break;
case DIV: if (reg[rsrc[1]] == 0) throw DomainException();
reg[rdest] = reg[rsrc[0]] / reg[rsrc[1]];
break;
case SHL: reg[rdest] = reg[rsrc[0]] << reg[rsrc[1]];
break;
case 2:
if ( Word_s(reg[rsrc[0]]) < Word_s(reg[rsrc[1]]))
{
reg[rdest] = 1;
}
else
{
reg[rdest] = 0;
}
break;
case 3:
if ( Word_u(reg[rsrc[0]]) < Word_u(reg[rsrc[1]]))
{
reg[rdest] = 1;
}
else
{
reg[rdest] = 0;
}
break;
case 4:
reg[rdest] = reg[rsrc[0]] ^ reg[rsrc[1]];
break;
case 5:
if (func7)
{
reg[rdest] = Word_s(reg[rsrc[0]]) >> Word_s(reg[rsrc[1]]);
reg[rdest].trunc(wordSz);
break;
case SHR: reg[rdest] = Word_s(reg[rsrc[0]]) >> reg[rsrc[1]];
}
else
{
reg[rdest] = Word_u(reg[rsrc[0]]) >> Word_u(reg[rsrc[1]]);
reg[rdest].trunc(wordSz);
break;
case MOD: if (reg[rsrc[1]] == 0) throw DomainException();
reg[rdest] = reg[rsrc[0]] % reg[rsrc[1]];
break;
case AND: reg[rdest] = reg[rsrc[0]] & reg[rsrc[1]];
break;
case OR: reg[rdest] = reg[rsrc[0]] | reg[rsrc[1]];
break;
case XOR: reg[rdest] = reg[rsrc[0]] ^ reg[rsrc[1]];
break;
case NEG: reg[rdest] = -(Word_s)reg[rsrc[0]];
reg[rdest].trunc(wordSz);
break;
case NOT: reg[rdest] = ~(Word_s)reg[rsrc[0]];
reg[rdest].trunc(wordSz);
break;
case ADDI: reg[rdest] = reg[rsrc[0]] + immsrc;
reg[rdest].trunc(wordSz);
break;
case SUBI: reg[rdest] = reg[rsrc[0]] - immsrc;
reg[rdest].trunc(wordSz);
break;
case MULI: reg[rdest] = reg[rsrc[0]] * immsrc;
reg[rdest].trunc(wordSz);
break;
case DIVI: if (immsrc == 0) throw DomainException();
reg[rdest] = reg[rsrc[0]] / immsrc;
break;
case MODI: if (immsrc == 0) throw DomainException();
reg[rdest] = reg[rsrc[0]] % immsrc;
break;
case SHRI: reg[rdest] = Word_s(reg[rsrc[0]]) >> immsrc;
break;
case SHLI: reg[rdest] = reg[rsrc[0]] << immsrc;
reg[rdest].trunc(wordSz);
break;
case ANDI: reg[rdest] = reg[rsrc[0]] & immsrc;
break;
case ORI: reg[rdest] = reg[rsrc[0]] | immsrc;
break;
case XORI: reg[rdest] = reg[rsrc[0]] ^ immsrc;
break;
case JMPI: if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALI: reg[rdest] = c.pc;
if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALR: reg[rdest] = c.pc;
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case JMPR: if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case CLONE: c.reg[reg[rsrc[0]]] = reg;
break;
case JALIS: nextActiveThreads = reg[rsrc[0]];
reg[rdest] = c.pc;
if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALRS: nextActiveThreads = reg[rsrc[0]];
reg[rdest] = c.pc;
if (!pcSet) nextPc = reg[rsrc[1]];
pcSet = true;
break;
case JMPRT: nextActiveThreads = 1;
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case LD: ++c.loads;
memAddr = reg[rsrc[0]] + immsrc;
}
break;
case 6:
reg[rdest] = reg[rsrc[0]] | reg[rsrc[1]];
break;
case 7:
reg[rdest] = reg[rsrc[0]] & reg[rsrc[1]];
break;
default:
cout << "ERROR: UNSUPPORTED R INST\n";
exit(1);
}
break;
case L_INST:
memAddr = (reg[rsrc[0]] + immsrc) & 0xFFFFFF00;
shift_by = (reg[rsrc[0]] + immsrc) & 0x000000FF;
#ifdef EMU_INSTRUMENTATION
Harp::OSDomain::osDomain->
do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
Harp::OSDomain::osDomain->
do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
#endif
reg[rdest] = c.core->mem.read(memAddr, c.supervisorMode);
c.memAccesses.push_back(Warp::MemAccess(false, memAddr));
break;
case ST: ++c.stores;
memAddr = reg[rsrc[1]] + immsrc;
c.core->mem.write(memAddr, reg[rsrc[0]], c.supervisorMode);
c.memAccesses.push_back(Warp::MemAccess(true, memAddr));
#ifdef EMU_INSTRUMENTATION
Harp::OSDomain::osDomain->
do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
#endif
break;
case LDI: reg[rdest] = immsrc;
reg[rdest].trunc(wordSz);
break;
case RTOP: pReg[pdest] = reg[rsrc[0]];
break;
case ISZERO: pReg[pdest] = !reg[rsrc[0]];
break;
case NOTP: pReg[pdest] = !(pReg[psrc[0]]);
break;
case ANDP: pReg[pdest] = pReg[psrc[0]] & pReg[psrc[1]];
break;
case ORP: pReg[pdest] = pReg[psrc[0]] | pReg[psrc[1]];
break;
case XORP: pReg[pdest] = pReg[psrc[0]] != pReg[psrc[1]];
break;
case ISNEG: pReg[pdest] = (1ll<<(wordSz*8 - 1))&reg[rsrc[0]];
break;
case HALT: c.activeThreads = 0;
nextActiveThreads = 0;
break;
case TRAP: c.interrupt(0);
break;
case JMPRU: c.supervisorMode = false;
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case SKEP: c.core->interruptEntry = reg[rsrc[0]];
break;
case RETI: if (t == 0) {
c.tmask = c.shadowTmask;
nextActiveThreads = c.shadowActiveThreads;
c.interruptEnable = c.shadowInterruptEnable;
c.supervisorMode = c.shadowSupervisorMode;
for (unsigned i = 0; i < reg.size(); ++i)
reg[i] = c.shadowReg[i];
for (unsigned i = 0; i < pReg.size(); ++i)
pReg[i] = c.shadowPReg[i];
if (!pcSet) { nextPc = c.shadowPc; pcSet = true; }
}
break;
case ITOF: reg[rdest] = Float(double(Word_s(reg[rsrc[0]])), wordSz);
break;
case FTOI: reg[rdest] = Word_s(double(Float(reg[rsrc[0]], wordSz)));
reg[rdest].trunc(wordSz);
break;
case FNEG: reg[rdest] = Float(-double(Float(reg[rsrc[0]],wordSz)),wordSz);
break;
case FADD: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) +
double(Float(reg[rsrc[1]], wordSz)),wordSz);
break;
case FSUB: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) -
double(Float(reg[rsrc[1]], wordSz)),wordSz);
break;
case FMUL: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) *
double(Float(reg[rsrc[1]], wordSz)),wordSz);
break;
case FDIV: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) /
double(Float(reg[rsrc[1]], wordSz)),wordSz);
break;
case SPLIT: if (sjOnce) {
sjOnce = false;
if (checkUnanimous(pred, c.pred, c.tmask)) {
DomStackEntry e(c.tmask);
e.uni = true;
c.domStack.push(e);
break;
}
DomStackEntry e(pred, c.pred, c.tmask, c.pc);
c.domStack.push(c.tmask);
c.domStack.push(e);
for (unsigned i = 0; i < e.tmask.size(); ++i)
c.tmask[i] = !e.tmask[i] && c.tmask[i];
}
break;
case JOIN: if (sjOnce) {
sjOnce = false;
if (!c.domStack.empty() && c.domStack.top().uni) {
D(2, "Uni branch at join");
c.tmask = c.domStack.top().tmask;
c.domStack.pop();
break;
}
if (!c.domStack.top().fallThrough) {
if (!pcSet) nextPc = c.domStack.top().pc;
pcSet = true;
}
c.tmask = c.domStack.top().tmask;
c.domStack.pop();
}
break;
case WSPAWN: if (sjOnce) {
sjOnce = false;
D(0, "Spawning a new warp.");
for (unsigned i = 0; i < c.core->w.size(); ++i) {
Warp &newWarp(c.core->w[i]);
if (newWarp.spawned == false) {
newWarp.pc = reg[rsrc[0]];
newWarp.reg[0][rdest] = reg[rsrc[1]];
newWarp.activeThreads = 1;
newWarp.supervisorMode = false;
newWarp.spawned = true;
break;
}
}
}
break;
case BAR: if (sjOnce) {
sjOnce = false;
Word id(reg[rsrc[0]]), n(reg[rsrc[1]]);
set<Warp*> &b(c.core->b[id]);
// Add current warp to the barrier and halt.
b.insert(&c);
c.shadowActiveThreads = c.activeThreads;
nextActiveThreads = 0;
D(2, "Barrier " << id << ' ' << b.size() << " of " << n);
// If the barrier's full, reactivate warps waiting at it
if (b.size() == n) {
set<Warp*>::iterator it;
for (it = b.begin(); it != b.end(); ++it)
(*it)->activeThreads = (*it)->shadowActiveThreads;
c.core->b.erase(id);
nextActiveThreads = c.shadowActiveThreads;
}
}
break;
switch (func3)
{
case 0:
// LB
reg[rdest] = signExt((c.core->mem.read(memAddr, c.supervisorMode) >> shift_by) & 0xFF, 8, 0xFF);
break;
case 1:
// LH
reg[rdest] = signExt((c.core->mem.read(memAddr, c.supervisorMode) >> shift_by) & 0xFFFF, 16, 0xFF);
break;
case 2:
reg[rdest] = Word_s(c.core->mem.read(memAddr, c.supervisorMode) & 0xFFFFFFFF);
break;
case 4:
// LBU
reg[rdest] = Word_u((c.core->mem.read(memAddr, c.supervisorMode) >> shift_by) & 0xFF);
break;
case 5:
reg[rdest] = Word_s((c.core->mem.read(memAddr, c.supervisorMode) >> shift_by) & 0xFFFF);
default:
cout << "ERROR: UNSUPPORTED L INST\n";
exit(1);
c.memAccesses.push_back(Warp::MemAccess(false, memAddr));
}
break;
case I_INST:
break;
case S_INST:
break;
case B_INST:
break;
case LUI_INST:
break;
case AUIPC_INST:
break;
case JAL_INST:
break;
case JALR_INST:
break;
case SYS_INST:
break;
default:
cout << "ERROR: Unsupported instruction: " << *this << "\n";
exit(1);
// case SHL:
// break;
// case SHR:
// break;
// case ADDI: reg[rdest] = reg[rsrc[0]] + immsrc;
// reg[rdest].trunc(wordSz);
// break;
// case SUBI: reg[rdest] = reg[rsrc[0]] - immsrc;
// reg[rdest].trunc(wordSz);
// break;
// case SHRI: reg[rdest] = Word_s(reg[rsrc[0]]) >> immsrc;
// break;
// case SHLI: reg[rdest] = reg[rsrc[0]] << immsrc;
// reg[rdest].trunc(wordSz);
// break;
// case ANDI: reg[rdest] = reg[rsrc[0]] & immsrc;
// break;
// case ORI: reg[rdest] = reg[rsrc[0]] | immsrc;
// break;
// case XORI: reg[rdest] = reg[rsrc[0]] ^ immsrc;
// break;
// case JMPI: if (!pcSet) nextPc = c.pc + immsrc;
// pcSet = true;
// break;
// case JALI: reg[rdest] = c.pc;
// if (!pcSet) nextPc = c.pc + immsrc;
// pcSet = true;
// break;
// case JALR: reg[rdest] = c.pc;
// if (!pcSet) nextPc = reg[rsrc[0]];
// pcSet = true;
// break;
// case JMPR: if (!pcSet) nextPc = reg[rsrc[0]];
// pcSet = true;
// break;
// case JALIS: nextActiveThreads = reg[rsrc[0]];
// reg[rdest] = c.pc;
// if (!pcSet) nextPc = c.pc + immsrc;
// pcSet = true;
// break;
// case JALRS: nextActiveThreads = reg[rsrc[0]];
// reg[rdest] = c.pc;
// if (!pcSet) nextPc = reg[rsrc[1]];
// pcSet = true;
// break;
// case JMPRT: nextActiveThreads = 1;
// if (!pcSet) nextPc = reg[rsrc[0]];
// pcSet = true;
// break;
// case LD: ++c.loads;
// memAddr = reg[rsrc[0]] + immsrc;
// #ifdef EMU_INSTRUMENTATION
// Harp::OSDomain::osDomain->
// do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
// #endif
// reg[rdest] = c.core->mem.read(memAddr, c.supervisorMode);
// c.memAccesses.push_back(Warp::MemAccess(false, memAddr));
// break;
// case ST: ++c.stores;
// memAddr = reg[rsrc[1]] + immsrc;
// c.core->mem.write(memAddr, reg[rsrc[0]], c.supervisorMode);
// c.memAccesses.push_back(Warp::MemAccess(true, memAddr));
// #ifdef EMU_INSTRUMENTATION
// Harp::OSDomain::osDomain->
// do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true);
// #endif
// break;
// case LDI: reg[rdest] = immsrc;
// reg[rdest].trunc(wordSz);
// break;
// case RTOP: pReg[pdest] = reg[rsrc[0]];
// break;
// case ISZERO: pReg[pdest] = !reg[rsrc[0]];
// break;
// case NOTP: pReg[pdest] = !(pReg[psrc[0]]);
// break;
// case ANDP: pReg[pdest] = pReg[psrc[0]] & pReg[psrc[1]];
// break;
// case ORP: pReg[pdest] = pReg[psrc[0]] | pReg[psrc[1]];
// break;
// case XORP: pReg[pdest] = pReg[psrc[0]] != pReg[psrc[1]];
// break;
// case ISNEG: pReg[pdest] = (1ll<<(wordSz*8 - 1))&reg[rsrc[0]];
// break;
// case HALT: c.activeThreads = 0;
// nextActiveThreads = 0;
// break;
// case TRAP: c.interrupt(0);
// break;
// case JMPRU: c.supervisorMode = false;
// if (!pcSet) nextPc = reg[rsrc[0]];
// pcSet = true;
// break;
// case SKEP: c.core->interruptEntry = reg[rsrc[0]];
// break;
// case RETI: if (t == 0) {
// c.tmask = c.shadowTmask;
// nextActiveThreads = c.shadowActiveThreads;
// c.interruptEnable = c.shadowInterruptEnable;
// c.supervisorMode = c.shadowSupervisorMode;
// for (unsigned i = 0; i < reg.size(); ++i)
// reg[i] = c.shadowReg[i];
// for (unsigned i = 0; i < pReg.size(); ++i)
// pReg[i] = c.shadowPReg[i];
// if (!pcSet) { nextPc = c.shadowPc; pcSet = true; }
// }
// break;
// case ITOF: reg[rdest] = Float(double(Word_s(reg[rsrc[0]])), wordSz);
// break;
// case FTOI: reg[rdest] = Word_s(double(Float(reg[rsrc[0]], wordSz)));
// reg[rdest].trunc(wordSz);
// break;
// case FNEG: reg[rdest] = Float(-double(Float(reg[rsrc[0]],wordSz)),wordSz);
// break;
// case FADD: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) +
// double(Float(reg[rsrc[1]], wordSz)),wordSz);
// break;
// case FSUB: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) -
// double(Float(reg[rsrc[1]], wordSz)),wordSz);
// break;
// case FMUL: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) *
// double(Float(reg[rsrc[1]], wordSz)),wordSz);
// break;
// case FDIV: reg[rdest] = Float(double(Float(reg[rsrc[0]], wordSz)) /
// double(Float(reg[rsrc[1]], wordSz)),wordSz);
// break;
// case SPLIT: if (sjOnce) {
// sjOnce = false;
// if (checkUnanimous(pred, c.pred, c.tmask)) {
// DomStackEntry e(c.tmask);
// e.uni = true;
// c.domStack.push(e);
// break;
// }
// DomStackEntry e(pred, c.pred, c.tmask, c.pc);
// c.domStack.push(c.tmask);
// c.domStack.push(e);
// for (unsigned i = 0; i < e.tmask.size(); ++i)
// c.tmask[i] = !e.tmask[i] && c.tmask[i];
// }
// break;
// case JOIN: if (sjOnce) {
// sjOnce = false;
// if (!c.domStack.empty() && c.domStack.top().uni) {
// D(2, "Uni branch at join");
// c.tmask = c.domStack.top().tmask;
// c.domStack.pop();
// break;
// }
// if (!c.domStack.top().fallThrough) {
// if (!pcSet) nextPc = c.domStack.top().pc;
// pcSet = true;
// }
// c.tmask = c.domStack.top().tmask;
// c.domStack.pop();
// }
// break;
// case WSPAWN: if (sjOnce) {
// sjOnce = false;
// D(0, "Spawning a new warp.");
// for (unsigned i = 0; i < c.core->w.size(); ++i) {
// Warp &newWarp(c.core->w[i]);
// if (newWarp.spawned == false) {
// newWarp.pc = reg[rsrc[0]];
// newWarp.reg[0][rdest] = reg[rsrc[1]];
// newWarp.activeThreads = 1;
// newWarp.supervisorMode = false;
// newWarp.spawned = true;
// break;
// }
// }
// }
// break;
// case BAR: if (sjOnce) {
// sjOnce = false;
// Word id(reg[rsrc[0]]), n(reg[rsrc[1]]);
// set<Warp*> &b(c.core->b[id]);
// // Add current warp to the barrier and halt.
// b.insert(&c);
// c.shadowActiveThreads = c.activeThreads;
// nextActiveThreads = 0;
// D(2, "Barrier " << id << ' ' << b.size() << " of " << n);
// // If the barrier's full, reactivate warps waiting at it
// if (b.size() == n) {
// set<Warp*>::iterator it;
// for (it = b.begin(); it != b.end(); ++it)
// (*it)->activeThreads = (*it)->shadowActiveThreads;
// c.core->b.erase(id);
// nextActiveThreads = c.shadowActiveThreads;
// }
// }
// break;
// default:
// cout << "ERROR: Unsupported instruction: " << *this << "\n";
// exit(1);
}
}

File diff suppressed because it is too large Load Diff