Better-working ipdom instructions.
This commit is contained in:
@@ -48,6 +48,7 @@ Core::Core(const ArchDef &a, Decoder &d, MemoryUnit &mem, Word id) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
tmask.push_back(true);
|
tmask.push_back(true);
|
||||||
|
shadowTmask.push_back(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set initial register contents. */
|
/* Set initial register contents. */
|
||||||
@@ -153,11 +154,13 @@ bool Core::interrupt(Word r0) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
shadowActiveThreads = activeThreads;
|
shadowActiveThreads = activeThreads;
|
||||||
|
shadowTmask = tmask;
|
||||||
shadowInterruptEnable = interruptEnable; /* For traps. */
|
shadowInterruptEnable = interruptEnable; /* For traps. */
|
||||||
shadowSupervisorMode = supervisorMode;
|
shadowSupervisorMode = supervisorMode;
|
||||||
|
|
||||||
for (Word i = 0; i < reg[0].size(); ++i) shadowReg[i] = reg[0][i];
|
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 < pred[0].size(); ++i) shadowPReg[i] = pred[0][i];
|
||||||
|
for (Word i = 0; i < reg.size(); ++i) tmask[i] = 1;
|
||||||
|
|
||||||
shadowPc = pc;
|
shadowPc = pc;
|
||||||
activeThreads = 1;
|
activeThreads = 1;
|
||||||
|
|||||||
@@ -51,15 +51,12 @@ namespace Harp {
|
|||||||
// Entry in the IPDOM Stack
|
// Entry in the IPDOM Stack
|
||||||
struct DomStackEntry {
|
struct DomStackEntry {
|
||||||
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)
|
): pc(pc), fallThrough(false)
|
||||||
{
|
{
|
||||||
std::cout << "New DomStackEntry:";
|
for (unsigned i = 0; i < m.size(); ++i)
|
||||||
for (unsigned i = 0; i < m.size(); ++i) {
|
tmask.push_back(!bool(m[i][p]) && tm[i]);
|
||||||
tmask.push_back(!bool(m[i][p]));
|
|
||||||
std::cout << ' ' << bool(m[i][p]);
|
|
||||||
}
|
|
||||||
std::cout << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DomStackEntry(const std::vector<bool> &tmask):
|
DomStackEntry(const std::vector<bool> &tmask):
|
||||||
@@ -90,7 +87,7 @@ namespace Harp {
|
|||||||
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;
|
||||||
|
|
||||||
std::vector<bool> tmask;
|
std::vector<bool> tmask, shadowTmask;
|
||||||
std::stack<DomStackEntry> domStack;
|
std::stack<DomStackEntry> domStack;
|
||||||
|
|
||||||
std::vector<Word> shadowReg;
|
std::vector<Word> shadowReg;
|
||||||
|
|||||||
@@ -138,7 +138,8 @@ void Instruction::executeOn(Core &c) {
|
|||||||
Size wordSz = c.a.getWordSize();
|
Size wordSz = c.a.getWordSize();
|
||||||
Word nextPc = c.pc;
|
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++) {
|
for (Size t = 0; t < c.activeThreads; t++) {
|
||||||
vector<Reg<Word> > ®(c.reg[t]);
|
vector<Reg<Word> > ®(c.reg[t]);
|
||||||
vector<Reg<bool> > &pReg(c.pred[t]);
|
vector<Reg<bool> > &pReg(c.pred[t]);
|
||||||
@@ -219,28 +220,35 @@ void Instruction::executeOn(Core &c) {
|
|||||||
break;
|
break;
|
||||||
case XORI: reg[rdest] = reg[rsrc[0]] ^ immsrc;
|
case XORI: reg[rdest] = reg[rsrc[0]] ^ immsrc;
|
||||||
break;
|
break;
|
||||||
case JMPI: nextPc = c.pc + immsrc;
|
case JMPI: if (!pcSet) nextPc = c.pc + immsrc;
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case JALI: reg[rdest] = c.pc;
|
case JALI: reg[rdest] = c.pc;
|
||||||
nextPc = c.pc + immsrc;
|
if (!pcSet) nextPc = c.pc + immsrc;
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case JALR: reg[rdest] = c.pc;
|
case JALR: reg[rdest] = c.pc;
|
||||||
nextPc = reg[rsrc[0]];
|
if (!pcSet) nextPc = reg[rsrc[0]];
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case JMPR: nextPc = reg[rsrc[0]];
|
case JMPR: if (!pcSet) nextPc = reg[rsrc[0]];
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case CLONE: c.reg[reg[rsrc[0]]] = reg;
|
case CLONE: c.reg[reg[rsrc[0]]] = reg;
|
||||||
break;
|
break;
|
||||||
case JALIS: nextActiveThreads = reg[rsrc[0]];
|
case JALIS: nextActiveThreads = reg[rsrc[0]];
|
||||||
reg[rdest] = c.pc;
|
reg[rdest] = c.pc;
|
||||||
nextPc = c.pc + immsrc;
|
if (!pcSet) nextPc = c.pc + immsrc;
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case JALRS: nextActiveThreads = reg[rsrc[0]];
|
case JALRS: nextActiveThreads = reg[rsrc[0]];
|
||||||
reg[rdest] = c.pc;
|
reg[rdest] = c.pc;
|
||||||
nextPc = reg[rsrc[1]];
|
if (!pcSet) nextPc = reg[rsrc[1]];
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case JMPRT: nextActiveThreads = 1;
|
case JMPRT: nextActiveThreads = 1;
|
||||||
nextPc = reg[rsrc[0]];
|
if (!pcSet) nextPc = reg[rsrc[0]];
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case LD: memAddr = reg[rsrc[0]] + immsrc;
|
case LD: memAddr = reg[rsrc[0]] + immsrc;
|
||||||
#ifdef EMU_INSTRUMENTATION
|
#ifdef EMU_INSTRUMENTATION
|
||||||
@@ -279,11 +287,13 @@ void Instruction::executeOn(Core &c) {
|
|||||||
case TRAP: c.interrupt(0);
|
case TRAP: c.interrupt(0);
|
||||||
break;
|
break;
|
||||||
case JMPRU: c.supervisorMode = false;
|
case JMPRU: c.supervisorMode = false;
|
||||||
nextPc = reg[rsrc[0]];
|
if (!pcSet) nextPc = reg[rsrc[0]];
|
||||||
|
pcSet = true;
|
||||||
break;
|
break;
|
||||||
case SKEP: c.interruptEntry = reg[rsrc[0]];
|
case SKEP: c.interruptEntry = reg[rsrc[0]];
|
||||||
break;
|
break;
|
||||||
case RETI: if (t == 0) {
|
case RETI: if (t == 0) {
|
||||||
|
c.tmask = c.shadowTmask;
|
||||||
nextActiveThreads = c.shadowActiveThreads;
|
nextActiveThreads = c.shadowActiveThreads;
|
||||||
c.interruptEnable = c.shadowInterruptEnable;
|
c.interruptEnable = c.shadowInterruptEnable;
|
||||||
c.supervisorMode = c.shadowSupervisorMode;
|
c.supervisorMode = c.shadowSupervisorMode;
|
||||||
@@ -291,7 +301,7 @@ void Instruction::executeOn(Core &c) {
|
|||||||
reg[i] = c.shadowReg[i];
|
reg[i] = c.shadowReg[i];
|
||||||
for (unsigned i = 0; i < pReg.size(); ++i)
|
for (unsigned i = 0; i < pReg.size(); ++i)
|
||||||
pReg[i] = c.shadowPReg[i];
|
pReg[i] = c.shadowPReg[i];
|
||||||
nextPc = c.shadowPc;
|
if (!pcSet) nextPc = c.shadowPc;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ITOF: reg[rdest] = Float(double(Word_s(reg[rsrc[0]])), wordSz);
|
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) {
|
case SPLIT: if (sjOnce) {
|
||||||
sjOnce = false;
|
sjOnce = false;
|
||||||
// TODO: if mask becomes all-zero, fall through
|
// 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(c.tmask);
|
||||||
c.domStack.push(e);
|
c.domStack.push(e);
|
||||||
for (unsigned i = 0; i < e.tmask.size(); ++i)
|
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;
|
break;
|
||||||
case JOIN: if (sjOnce) {
|
case JOIN: if (sjOnce) {
|
||||||
sjOnce = false;
|
sjOnce = false;
|
||||||
// TODO: if mask becomes all-zero, fall through
|
// TODO: if mask becomes all-zero, fall through
|
||||||
if (!c.domStack.top().fallThrough)
|
if (!c.domStack.top().fallThrough) {
|
||||||
nextPc = c.domStack.top().pc;
|
if (!pcSet) nextPc = c.domStack.top().pc;
|
||||||
|
pcSet = true;
|
||||||
|
}
|
||||||
c.tmask = c.domStack.top().tmask;
|
c.tmask = c.domStack.top().tmask;
|
||||||
c.domStack.pop();
|
c.domStack.pop();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user