Added capability for instrumentation on all register accesses.
git-svn-id: http://www.cdkersey.com/harp/harptool@30 0246edb2-e076-4747-b392-db732a341fa2
This commit is contained in:
29
src/core.cpp
29
src/core.cpp
@@ -16,11 +16,24 @@ using namespace std;
|
|||||||
|
|
||||||
Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
|
Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
|
||||||
a(a), iDec(d), mem(mem), pc(0), interruptEnable(false), supervisorMode(true),
|
a(a), iDec(d), mem(mem), pc(0), interruptEnable(false), supervisorMode(true),
|
||||||
activeThreads(1),
|
activeThreads(1), reg(0), pred(0), shadowReg(a.getNRegs()), shadowPReg(a.getNPRegs()o),
|
||||||
reg(a.getNThds(), vector<Word>(a.getNRegs())),
|
interruptEntry(0), id(id)
|
||||||
pred(a.getNThds(), vector<bool>(a.getNPRegs())),
|
{
|
||||||
shadowReg(), shadowPReg(), interruptEntry(0), id(id)
|
/* Build the register file. */
|
||||||
{ reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id; }
|
Word regNum(0);
|
||||||
|
for (Word j = 0; j < a.getNThds(); ++j) {
|
||||||
|
reg.push_back(vector<Reg<Word> >(0));
|
||||||
|
for (Word i = 0; i < a.getNRegs(); ++i)
|
||||||
|
reg[j].push_back(Reg<Word>(id, regNum++));
|
||||||
|
|
||||||
|
pred.push_back(vector<Reg<bool> >(0));
|
||||||
|
for (Word i = 0; i < a.getNPRegs(); ++i)
|
||||||
|
pred[j].push_back(Reg<bool>(id, regNum++));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set initial register contents. */
|
||||||
|
reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id;
|
||||||
|
}
|
||||||
|
|
||||||
void Core::step() {
|
void Core::step() {
|
||||||
Size fetchPos(0), decPos, wordSize(a.getWordSize());
|
Size fetchPos(0), decPos, wordSize(a.getWordSize());
|
||||||
@@ -82,8 +95,10 @@ bool Core::interrupt(Word r0) {
|
|||||||
shadowActiveThreads = activeThreads;
|
shadowActiveThreads = activeThreads;
|
||||||
shadowInterruptEnable = interruptEnable; /* For traps. */
|
shadowInterruptEnable = interruptEnable; /* For traps. */
|
||||||
shadowSupervisorMode = supervisorMode;
|
shadowSupervisorMode = supervisorMode;
|
||||||
shadowReg = reg[0];
|
|
||||||
shadowPReg = pred[0];
|
for (Word i = 0; i < reg[0].size(); ++i) shadowReg[i] = reg[0][i];
|
||||||
|
for (Word i = 0; i < pred[0].size(); ++i) shadowPReg[i] = pred[0][i];
|
||||||
|
|
||||||
shadowPc = pc;
|
shadowPc = pc;
|
||||||
activeThreads = 1;
|
activeThreads = 1;
|
||||||
interruptEnable = false;
|
interruptEnable = false;
|
||||||
|
|||||||
@@ -13,6 +13,26 @@
|
|||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
namespace Harp {
|
namespace Harp {
|
||||||
|
template <typename T> class Reg {
|
||||||
|
public:
|
||||||
|
Reg(): cpuId(0), regNum(0) {}
|
||||||
|
Reg(Word c, Word n): cpuId(c), regNum(n) {}
|
||||||
|
|
||||||
|
Reg &operator=(T r) { val = r; doWrite(); return *this; }
|
||||||
|
operator T() { doRead(); return val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Word cpuId, regNum;
|
||||||
|
T val;
|
||||||
|
|
||||||
|
#ifdef EMU_INSTRUMENTATION
|
||||||
|
#error TODO: instrument Harp::Reg.
|
||||||
|
#else
|
||||||
|
void doWrite() {}
|
||||||
|
void doRead() {}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
class Core {
|
class Core {
|
||||||
public:
|
public:
|
||||||
Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0);
|
Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0);
|
||||||
@@ -27,8 +47,8 @@ namespace Harp {
|
|||||||
|
|
||||||
Word pc, interruptEntry, shadowPc, id;
|
Word pc, interruptEntry, shadowPc, id;
|
||||||
Size activeThreads, shadowActiveThreads;
|
Size activeThreads, shadowActiveThreads;
|
||||||
std::vector<std::vector<Word> > reg;
|
std::vector<std::vector<Reg<Word> > > reg;
|
||||||
std::vector<std::vector<bool> > pred;
|
std::vector<std::vector<Reg<bool> > > pred;
|
||||||
|
|
||||||
std::vector<Word> shadowReg;
|
std::vector<Word> shadowReg;
|
||||||
std::vector<bool> shadowPReg;
|
std::vector<bool> shadowPReg;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ Instruction::InstTableEntry Instruction::instTable[] = {
|
|||||||
{"jalrs", true, false, false, false, AC_3REG },
|
{"jalrs", true, false, false, false, AC_3REG },
|
||||||
{"jmprt", true, false, true, false, AC_1REG },
|
{"jmprt", true, false, true, false, AC_1REG },
|
||||||
{"ld", false, false, false, false, AC_3IMM },
|
{"ld", false, false, false, false, AC_3IMM },
|
||||||
{"st", false, false, true, false, AC_3IMMSRC },
|
{"st", false, false, true, false, AC_3IMMSRC },
|
||||||
{"ldi", false, false, false, false, AC_2IMM },
|
{"ldi", false, false, false, false, AC_2IMM },
|
||||||
{"rtop", false, false, false, false, AC_PREG_REG},
|
{"rtop", false, false, false, false, AC_PREG_REG},
|
||||||
{"andp", false, false, false, false, AC_3PREG },
|
{"andp", false, false, false, false, AC_3PREG },
|
||||||
@@ -109,6 +109,7 @@ void Instruction::executeOn(Core &c) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Also throw exceptions on divergent branches. */
|
||||||
if (predicated && instTable[op].controlFlow) {
|
if (predicated && instTable[op].controlFlow) {
|
||||||
bool p0 = c.pred[0][pred];
|
bool p0 = c.pred[0][pred];
|
||||||
for (Size t = 1; t < c.activeThreads; t++) {
|
for (Size t = 1; t < c.activeThreads; t++) {
|
||||||
@@ -120,8 +121,8 @@ void Instruction::executeOn(Core &c) {
|
|||||||
Size wordSz = c.a.getWordSize();
|
Size wordSz = c.a.getWordSize();
|
||||||
|
|
||||||
for (Size t = 0; t < c.activeThreads; t++) {
|
for (Size t = 0; t < c.activeThreads; t++) {
|
||||||
vector<Word> ®(c.reg[t]);
|
vector<Reg<Word> > ®(c.reg[t]);
|
||||||
vector<bool> &pReg(c.pred[t]);
|
vector<Reg<bool> > &pReg(c.pred[t]);
|
||||||
|
|
||||||
if (predicated && !pReg[pred]) continue;
|
if (predicated && !pReg[pred]) continue;
|
||||||
|
|
||||||
@@ -216,8 +217,10 @@ void Instruction::executeOn(Core &c) {
|
|||||||
nextActiveThreads = c.shadowActiveThreads;
|
nextActiveThreads = c.shadowActiveThreads;
|
||||||
c.interruptEnable = c.shadowInterruptEnable;
|
c.interruptEnable = c.shadowInterruptEnable;
|
||||||
c.supervisorMode = c.shadowSupervisorMode;
|
c.supervisorMode = c.shadowSupervisorMode;
|
||||||
reg = c.shadowReg;
|
for (unsigned i = 0; i < reg.size(); ++i)
|
||||||
pReg = c.shadowPReg;
|
reg[i] = c.shadowReg[i];
|
||||||
|
for (unsigned i = 0; i < pReg.size(); ++i)
|
||||||
|
pReg[i] = c.shadowPReg[i];
|
||||||
c.pc = c.shadowPc;
|
c.pc = c.shadowPc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user