diff --git a/src/core.cpp b/src/core.cpp index 340416e3..c0fce13e 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -29,21 +29,45 @@ void Harp::reg_doWrite(Word cpuId, Word regNum) { } #endif -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(0), pred(0), shadowReg(a.getNRegs()), - shadowPReg(a.getNPRegs()), interruptEntry(0), id(id) +Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id): + a(a), iDec(d), mem(mem) +{ + w.push_back(Warp(this)); + + // TODO: core-level initialization +} + +bool Core::interrupt(Word r0) { + w[0].interrupt(r0); +} + +void Core::step() { + for (unsigned i = 0; i < w.size(); ++i) + w[i].step(); +} + +bool Core::running() const { + for (unsigned i = 0; i < w.size(); ++i) + if (!w[i].running()) return false; + return true; +} + +Warp::Warp(Core *c, Word id) : + core(c), pc(0), interruptEnable(false), + supervisorMode(true), activeThreads(1), reg(0), pred(0), + shadowReg(core->a.getNRegs()), shadowPReg(core->a.getNPRegs()), + interruptEntry(0), id(id) { /* Build the register file. */ Word regNum(0); - for (Word j = 0; j < a.getNThds(); ++j) { + for (Word j = 0; j < core->a.getNThds(); ++j) { reg.push_back(vector >(0)); - for (Word i = 0; i < a.getNRegs(); ++i) { + for (Word i = 0; i < core->a.getNRegs(); ++i) { reg[j].push_back(Reg(id, regNum++)); } pred.push_back(vector >(0)); - for (Word i = 0; i < a.getNPRegs(); ++i) { + for (Word i = 0; i < core->a.getNPRegs(); ++i) { pred[j].push_back(Reg(id, regNum++)); } @@ -52,11 +76,11 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) : } /* Set initial register contents. */ - reg[0][0] = (a.getNThds()<<(a.getWordSize()*8 / 2)) | id; + reg[0][0] = (core->a.getNThds()<<(core->a.getWordSize()*8 / 2)) | id; } -void Core::step() { - Size fetchPos(0), decPos, wordSize(a.getWordSize()); +void Warp::step() { + Size fetchPos(0), decPos, wordSize(core->a.getWordSize()); vector fetchBuffer(wordSize); if (activeThreads == 0) return; @@ -73,10 +97,10 @@ void Core::step() { fetchMore = false; unsigned fetchSize(wordSize - (pc+fetchPos)%wordSize); fetchBuffer.resize(fetchPos + fetchSize); - Word fetched = mem.fetch(pc + fetchPos, supervisorMode); + Word fetched = core->mem.fetch(pc + fetchPos, supervisorMode); writeWord(fetchBuffer, fetchPos, fetchSize, fetched); decPos = 0; - inst = iDec.decode(fetchBuffer, decPos); + inst = core->iDec.decode(fetchBuffer, decPos); } catch (OutOfBytes o) { D(3, "Caught OutOfBytes. Fetching more."); fetchMore = true; @@ -91,9 +115,9 @@ void Core::step() { D(3, "0x" << hex << pc << ": " << *inst); #ifdef EMU_INSTRUMENTATION - { Addr pcPhys(mem.virtToPhys(pc)); + { Addr pcPhys(core->mem.virtToPhys(pc)); Harp::OSDomain::osDomain-> - do_inst(0, pc, pcPhys, decPos, mem.getPtr(pcPhys, decPos), + do_inst(0, pc, pcPhys, decPos, core->mem.getPtr(pcPhys, decPos), (enum inst_type)inst->instTable[inst->getOpcode()].iType); } #endif @@ -146,7 +170,7 @@ void Core::step() { delete inst; } -bool Core::interrupt(Word r0) { +bool Warp::interrupt(Word r0) { if (!interruptEnable) return false; #ifdef EMU_INSTRUMENTATION diff --git a/src/include/core.h b/src/include/core.h index 46e9e791..dc7e05b4 100644 --- a/src/include/core.h +++ b/src/include/core.h @@ -67,9 +67,27 @@ namespace Harp { Word pc; }; + class Warp; + class Core { public: Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id=0); + + bool interrupt(Word r0); + bool running() const; + void step(); + + const ArchDef &a; + Decoder &iDec; + MemoryUnit &mem; + + std::vector w; + }; + + class Warp { + public: + Warp(Core *c, Word id=0); + void step(); bool interrupt(Word r0); bool running() const { return activeThreads; } @@ -78,9 +96,7 @@ namespace Harp { #endif // private: - const ArchDef a; - Decoder &iDec; - MemoryUnit &mem; + Core *core; Word pc, interruptEntry, shadowPc, id; Size activeThreads, shadowActiveThreads; diff --git a/src/include/instruction.h b/src/include/instruction.h index d421cd6a..26b5725f 100644 --- a/src/include/instruction.h +++ b/src/include/instruction.h @@ -9,7 +9,7 @@ #include "types.h" namespace Harp { - class Core; + class Warp; class Ref; static const Size MAX_REG_SOURCES(3); @@ -53,7 +53,7 @@ namespace Harp { predicated(false), nRsrc(0), nPsrc(0), immsrcPresent(false), rdestPresent(false), pdestPresent(false), refLiteral(NULL) {} - void executeOn(Core &core); + void executeOn(Warp &warp); friend std::ostream &operator<<(std::ostream &, Instruction &); /* Setters used to "craft" the instruction. */ diff --git a/src/instruction.cpp b/src/instruction.cpp index 8195b220..4382956e 100644 --- a/src/instruction.cpp +++ b/src/instruction.cpp @@ -112,7 +112,7 @@ ostream &Harp::operator<<(ostream& os, Instruction &inst) { return os; } -void Instruction::executeOn(Core &c) { +void Instruction::executeOn(Warp &c) { D(3, "Begin instruction execute."); /* If I try to execute a privileged instruction in user mode, throw an @@ -135,7 +135,7 @@ void Instruction::executeOn(Core &c) { } Size nextActiveThreads = c.activeThreads; - Size wordSz = c.a.getWordSize(); + Size wordSz = c.core->a.getWordSize(); Word nextPc = c.pc; bool sjOnce(true), // Has not yet split or joined once. @@ -157,9 +157,9 @@ void Instruction::executeOn(Core &c) { break; case EI: c.interruptEnable = true; break; - case TLBADD: c.mem.tlbAdd(reg[rsrc[0]], reg[rsrc[1]], reg[rsrc[2]]); + case TLBADD: c.core->mem.tlbAdd(reg[rsrc[0]], reg[rsrc[1]], reg[rsrc[2]]); break; - case TLBFLUSH: c.mem.tlbFlush(); + case TLBFLUSH: c.core->mem.tlbFlush(); break; case ADD: reg[rdest] = reg[rsrc[0]] + reg[rsrc[1]]; reg[rdest].trunc(wordSz); @@ -253,15 +253,15 @@ void Instruction::executeOn(Core &c) { case LD: memAddr = reg[rsrc[0]] + immsrc; #ifdef EMU_INSTRUMENTATION Harp::OSDomain::osDomain-> - do_mem(0, memAddr, c.mem.virtToPhys(memAddr), 8, true); + do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true); #endif - reg[rdest] = c.mem.read(memAddr, c.supervisorMode); + reg[rdest] = c.core->mem.read(memAddr, c.supervisorMode); break; case ST: memAddr = reg[rsrc[1]] + immsrc; - c.mem.write(memAddr, reg[rsrc[0]], c.supervisorMode); + c.core->mem.write(memAddr, reg[rsrc[0]], c.supervisorMode); #ifdef EMU_INSTRUMENTATION Harp::OSDomain::osDomain-> - do_mem(0, memAddr, c.mem.virtToPhys(memAddr), 8, true); + do_mem(0, memAddr, c.core->mem.virtToPhys(memAddr), 8, true); #endif break; case LDI: reg[rdest] = immsrc;