wspawn instruction support.
This commit is contained in:
25
src/core.cpp
25
src/core.cpp
@@ -32,9 +32,10 @@ void Harp::reg_doWrite(Word cpuId, Word regNum) {
|
|||||||
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)
|
a(a), iDec(d), mem(mem)
|
||||||
{
|
{
|
||||||
w.push_back(Warp(this));
|
for (unsigned i = 0; i < 8; ++i)
|
||||||
|
w.push_back(Warp(this));
|
||||||
|
|
||||||
// TODO: core-level initialization
|
w[0].activeThreads = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::interrupt(Word r0) {
|
bool Core::interrupt(Word r0) {
|
||||||
@@ -42,21 +43,25 @@ bool Core::interrupt(Word r0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Core::step() {
|
void Core::step() {
|
||||||
for (unsigned i = 0; i < w.size(); ++i)
|
for (unsigned i = 0; i < w.size(); ++i) {
|
||||||
w[i].step();
|
if (w[i].activeThreads) {
|
||||||
|
D(3, "Core step stepping warp " << i << '[' << w[i].activeThreads << ']');
|
||||||
|
w[i].step();
|
||||||
|
D(3, "Now " << w[i].activeThreads << " active threads in " << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::running() const {
|
bool Core::running() const {
|
||||||
for (unsigned i = 0; i < w.size(); ++i)
|
for (unsigned i = 0; i < w.size(); ++i)
|
||||||
if (!w[i].running()) return false;
|
if (w[i].running()) return true;
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Warp::Warp(Core *c, Word id) :
|
Warp::Warp(Core *c, Word id) :
|
||||||
core(c), pc(0), interruptEnable(false),
|
core(c), pc(0), interruptEnable(false),
|
||||||
supervisorMode(true), activeThreads(1), reg(0), pred(0),
|
supervisorMode(true), activeThreads(0), reg(0), pred(0),
|
||||||
shadowReg(core->a.getNRegs()), shadowPReg(core->a.getNPRegs()),
|
shadowReg(core->a.getNRegs()), shadowPReg(core->a.getNPRegs()), id(id)
|
||||||
interruptEntry(0), id(id)
|
|
||||||
{
|
{
|
||||||
/* Build the register file. */
|
/* Build the register file. */
|
||||||
Word regNum(0);
|
Word regNum(0);
|
||||||
@@ -191,7 +196,7 @@ bool Warp::interrupt(Word r0) {
|
|||||||
interruptEnable = false;
|
interruptEnable = false;
|
||||||
supervisorMode = true;
|
supervisorMode = true;
|
||||||
reg[0][0] = r0;
|
reg[0][0] = r0;
|
||||||
pc = interruptEntry;
|
pc = core->interruptEntry;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ namespace Harp {
|
|||||||
Decoder &iDec;
|
Decoder &iDec;
|
||||||
MemoryUnit &mem;
|
MemoryUnit &mem;
|
||||||
|
|
||||||
|
Word interruptEntry;
|
||||||
|
|
||||||
std::vector<Warp> w;
|
std::vector<Warp> w;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,7 +100,7 @@ namespace Harp {
|
|||||||
// private:
|
// private:
|
||||||
Core *core;
|
Core *core;
|
||||||
|
|
||||||
Word pc, interruptEntry, shadowPc, id;
|
Word pc, shadowPc, id;
|
||||||
Size activeThreads, shadowActiveThreads;
|
Size activeThreads, shadowActiveThreads;
|
||||||
std::vector<std::vector<Reg<Word> > > reg;
|
std::vector<std::vector<Reg<Word> > > reg;
|
||||||
std::vector<std::vector<Reg<bool> > > pred;
|
std::vector<std::vector<Reg<bool> > > pred;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Instruction::InstTableEntry Instruction::instTable[] = {
|
|||||||
{"notp", false, false, false, false, AC_2PREG, ITYPE_INTBASIC},
|
{"notp", false, false, false, false, AC_2PREG, ITYPE_INTBASIC},
|
||||||
{"isneg", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
|
{"isneg", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
|
||||||
{"iszero", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
|
{"iszero", false, false, false, false, AC_PREG_REG, ITYPE_INTBASIC},
|
||||||
{"halt", false, false, false, true, AC_NONE, ITYPE_NULL },
|
{"halt", false, false, false, false, AC_NONE, ITYPE_NULL },
|
||||||
{"trap", true, false, false, false, AC_NONE, ITYPE_TRAP },
|
{"trap", true, false, false, false, AC_NONE, ITYPE_TRAP },
|
||||||
{"jmpru", false, false, false, true, AC_1REG, ITYPE_RET },
|
{"jmpru", false, false, false, true, AC_1REG, ITYPE_RET },
|
||||||
{"skep", false, false, false, true, AC_1REG, ITYPE_NULL },
|
{"skep", false, false, false, true, AC_1REG, ITYPE_NULL },
|
||||||
@@ -281,7 +281,8 @@ void Instruction::executeOn(Warp &c) {
|
|||||||
break;
|
break;
|
||||||
case ISNEG: pReg[pdest] = (1ll<<(wordSz*8 - 1))®[rsrc[0]];
|
case ISNEG: pReg[pdest] = (1ll<<(wordSz*8 - 1))®[rsrc[0]];
|
||||||
break;
|
break;
|
||||||
case HALT: c.activeThreads = 0;
|
case HALT: D(3, "=== EXECUTING halt ===");
|
||||||
|
c.activeThreads = 0;
|
||||||
nextActiveThreads = 0;
|
nextActiveThreads = 0;
|
||||||
break;
|
break;
|
||||||
case TRAP: c.interrupt(0);
|
case TRAP: c.interrupt(0);
|
||||||
@@ -290,7 +291,7 @@ void Instruction::executeOn(Warp &c) {
|
|||||||
if (!pcSet) nextPc = reg[rsrc[0]];
|
if (!pcSet) nextPc = reg[rsrc[0]];
|
||||||
pcSet = true;
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case SKEP: c.interruptEntry = reg[rsrc[0]];
|
case SKEP: c.core->interruptEntry = reg[rsrc[0]];
|
||||||
break;
|
break;
|
||||||
case RETI: if (t == 0) {
|
case RETI: if (t == 0) {
|
||||||
c.tmask = c.shadowTmask;
|
c.tmask = c.shadowTmask;
|
||||||
@@ -344,6 +345,21 @@ void Instruction::executeOn(Warp &c) {
|
|||||||
c.domStack.pop();
|
c.domStack.pop();
|
||||||
}
|
}
|
||||||
break;
|
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.activeThreads == 0) {
|
||||||
|
newWarp.pc = reg[rsrc[0]];
|
||||||
|
newWarp.reg[0][rdest] = reg[rsrc[1]];
|
||||||
|
newWarp.activeThreads = 1;
|
||||||
|
newWarp.supervisorMode = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cout << "ERROR: Unsupported instruction: " << *this << "\n";
|
cout << "ERROR: Unsupported instruction: " << *this << "\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user