lots of errors
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
471
src/enc.cpp
471
src/enc.cpp
@@ -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);
|
||||
// }
|
||||
|
||||
432
src/harptool.cpp
432
src/harptool.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
// };
|
||||
@@ -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
|
||||
|
||||
@@ -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))®[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))®[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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1284
src/obj.cpp
1284
src/obj.cpp
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user