diff --git a/src/core.cpp b/src/core.cpp index 833a08b2..cfccb716 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -16,11 +16,24 @@ using namespace std; Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) : a(a), iDec(d), mem(mem), pc(0), interruptEnable(false), supervisorMode(true), - activeThreads(1), - reg(a.getNThds(), vector(a.getNRegs())), - pred(a.getNThds(), vector(a.getNPRegs())), - shadowReg(), shadowPReg(), interruptEntry(0), id(id) -{ reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id; } + activeThreads(1), reg(0), pred(0), shadowReg(a.getNRegs()), shadowPReg(a.getNPRegs()o), + interruptEntry(0), id(id) +{ + /* Build the register file. */ + Word regNum(0); + for (Word j = 0; j < a.getNThds(); ++j) { + reg.push_back(vector >(0)); + for (Word i = 0; i < a.getNRegs(); ++i) + reg[j].push_back(Reg(id, regNum++)); + + pred.push_back(vector >(0)); + for (Word i = 0; i < a.getNPRegs(); ++i) + pred[j].push_back(Reg(id, regNum++)); + } + + /* Set initial register contents. */ + reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id; +} void Core::step() { Size fetchPos(0), decPos, wordSize(a.getWordSize()); @@ -82,8 +95,10 @@ bool Core::interrupt(Word r0) { shadowActiveThreads = activeThreads; shadowInterruptEnable = interruptEnable; /* For traps. */ 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; activeThreads = 1; interruptEnable = false; diff --git a/src/include/core.h b/src/include/core.h index 1e23d206..5045f571 100644 --- a/src/include/core.h +++ b/src/include/core.h @@ -13,6 +13,26 @@ #include "mem.h" namespace Harp { + template 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 { public: Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0); @@ -27,8 +47,8 @@ namespace Harp { Word pc, interruptEntry, shadowPc, id; Size activeThreads, shadowActiveThreads; - std::vector > reg; - std::vector > pred; + std::vector > > reg; + std::vector > > pred; std::vector shadowReg; std::vector shadowPReg; diff --git a/src/instruction.cpp b/src/instruction.cpp index a9f17a51..9fd87ef5 100644 --- a/src/instruction.cpp +++ b/src/instruction.cpp @@ -53,7 +53,7 @@ Instruction::InstTableEntry Instruction::instTable[] = { {"jalrs", true, false, false, false, AC_3REG }, {"jmprt", true, false, true, false, AC_1REG }, {"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 }, {"rtop", false, false, false, false, AC_PREG_REG}, {"andp", false, false, false, false, AC_3PREG }, @@ -109,6 +109,7 @@ void Instruction::executeOn(Core &c) { return; } + /* Also throw exceptions on divergent branches. */ if (predicated && instTable[op].controlFlow) { bool p0 = c.pred[0][pred]; for (Size t = 1; t < c.activeThreads; t++) { @@ -120,8 +121,8 @@ void Instruction::executeOn(Core &c) { Size wordSz = c.a.getWordSize(); for (Size t = 0; t < c.activeThreads; t++) { - vector ®(c.reg[t]); - vector &pReg(c.pred[t]); + vector > ®(c.reg[t]); + vector > &pReg(c.pred[t]); if (predicated && !pReg[pred]) continue; @@ -216,8 +217,10 @@ void Instruction::executeOn(Core &c) { nextActiveThreads = c.shadowActiveThreads; c.interruptEnable = c.shadowInterruptEnable; c.supervisorMode = c.shadowSupervisorMode; - reg = c.shadowReg; - pReg = c.shadowPReg; + 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]; c.pc = c.shadowPc; } break;