Better-working ipdom instructions.

This commit is contained in:
cdkersey 2015-07-30 14:38:15 -06:00
parent 04477a5194
commit 574ffce14b
3 changed files with 34 additions and 22 deletions

View file

@ -48,6 +48,7 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
}
tmask.push_back(true);
shadowTmask.push_back(true);
}
/* Set initial register contents. */
@ -153,11 +154,13 @@ bool Core::interrupt(Word r0) {
#endif
shadowActiveThreads = activeThreads;
shadowTmask = tmask;
shadowInterruptEnable = interruptEnable; /* For traps. */
shadowSupervisorMode = supervisorMode;
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];
for (Word i = 0; i < reg.size(); ++i) tmask[i] = 1;
shadowPc = pc;
activeThreads = 1;

View file

@ -51,15 +51,12 @@ namespace Harp {
// Entry in the IPDOM Stack
struct DomStackEntry {
DomStackEntry(
unsigned p, const std::vector<std::vector<Reg<bool> > >& m, Word pc
unsigned p, const std::vector<std::vector<Reg<bool> > >& m,
std::vector<bool> &tm, Word pc
): pc(pc), fallThrough(false)
{
std::cout << "New DomStackEntry:";
for (unsigned i = 0; i < m.size(); ++i) {
tmask.push_back(!bool(m[i][p]));
std::cout << ' ' << bool(m[i][p]);
}
std::cout << std::endl;
for (unsigned i = 0; i < m.size(); ++i)
tmask.push_back(!bool(m[i][p]) && tm[i]);
}
DomStackEntry(const std::vector<bool> &tmask):
@ -90,7 +87,7 @@ namespace Harp {
std::vector<std::vector<Reg<Word> > > reg;
std::vector<std::vector<Reg<bool> > > pred;
std::vector<bool> tmask;
std::vector<bool> tmask, shadowTmask;
std::stack<DomStackEntry> domStack;
std::vector<Word> shadowReg;

View file

@ -138,7 +138,8 @@ void Instruction::executeOn(Core &c) {
Size wordSz = c.a.getWordSize();
Word nextPc = c.pc;
bool sjOnce(true); // Has split or joined once already
bool sjOnce(true), // Has not yet split or joined once.
pcSet(false); // PC has already been set
for (Size t = 0; t < c.activeThreads; t++) {
vector<Reg<Word> > &reg(c.reg[t]);
vector<Reg<bool> > &pReg(c.pred[t]);
@ -219,28 +220,35 @@ void Instruction::executeOn(Core &c) {
break;
case XORI: reg[rdest] = reg[rsrc[0]] ^ immsrc;
break;
case JMPI: nextPc = c.pc + immsrc;
case JMPI: if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALI: reg[rdest] = c.pc;
nextPc = c.pc + immsrc;
if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALR: reg[rdest] = c.pc;
nextPc = reg[rsrc[0]];
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case JMPR: nextPc = reg[rsrc[0]];
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;
nextPc = c.pc + immsrc;
if (!pcSet) nextPc = c.pc + immsrc;
pcSet = true;
break;
case JALRS: nextActiveThreads = reg[rsrc[0]];
reg[rdest] = c.pc;
nextPc = reg[rsrc[1]];
if (!pcSet) nextPc = reg[rsrc[1]];
pcSet = true;
break;
case JMPRT: nextActiveThreads = 1;
nextPc = reg[rsrc[0]];
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case LD: memAddr = reg[rsrc[0]] + immsrc;
#ifdef EMU_INSTRUMENTATION
@ -279,11 +287,13 @@ void Instruction::executeOn(Core &c) {
case TRAP: c.interrupt(0);
break;
case JMPRU: c.supervisorMode = false;
nextPc = reg[rsrc[0]];
if (!pcSet) nextPc = reg[rsrc[0]];
pcSet = true;
break;
case SKEP: c.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;
@ -291,7 +301,7 @@ void Instruction::executeOn(Core &c) {
reg[i] = c.shadowReg[i];
for (unsigned i = 0; i < pReg.size(); ++i)
pReg[i] = c.shadowPReg[i];
nextPc = c.shadowPc;
if (!pcSet) nextPc = c.shadowPc;
}
break;
case ITOF: reg[rdest] = Float(double(Word_s(reg[rsrc[0]])), wordSz);
@ -316,18 +326,20 @@ void Instruction::executeOn(Core &c) {
case SPLIT: if (sjOnce) {
sjOnce = false;
// TODO: if mask becomes all-zero, fall through
DomStackEntry e(pred, c.pred, c.pc);
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] = !e.tmask[i] && c.tmask[i];
}
break;
case JOIN: if (sjOnce) {
sjOnce = false;
// TODO: if mask becomes all-zero, fall through
if (!c.domStack.top().fallThrough)
nextPc = c.domStack.top().pc;
if (!c.domStack.top().fallThrough) {
if (!pcSet) nextPc = c.domStack.top().pc;
pcSet = true;
}
c.tmask = c.domStack.top().tmask;
c.domStack.pop();
}