fixed ARM branch cycles (not taken = 1)

added cycle change tracking
This commit is contained in:
Thomas Jentzsch 2021-06-16 12:39:58 +02:00
parent b07c74d5e5
commit b1e9572186
3 changed files with 75 additions and 6 deletions

View File

@ -46,7 +46,7 @@ void CartridgeARMWidget::addCycleWidgets(int xpos, int ypos)
myCycleFactor = new SliderWidget(_boss, _font, myIncCycles->getRight() + _fontWidth * 2, ypos - 1,
_fontWidth * 10, _lineHeight, "Factor ", _fontWidth * 7,
kFactorChanged, _fontWidth * 4, "%");
myCycleFactor->setMinValue(100); myCycleFactor->setMaxValue(200);
myCycleFactor->setMinValue(90); myCycleFactor->setMaxValue(110);
myCycleFactor->setTickmarkIntervals(4);
myCycleFactor->setToolTip("Multiply approximated ARM cycles by factor.");
myCycleFactor->setTarget(this);

View File

@ -53,9 +53,11 @@ bool CartridgeARM::save(Serializer& out) const
{
try
{
out.putInt(myPrevStats.cycles);
out.putInt(myPrevStats.fetches);
out.putInt(myPrevStats.reads);
out.putInt(myPrevStats.writes);
out.putInt(myStats.cycles);
out.putInt(myStats.fetches);
out.putInt(myStats.reads);
out.putInt(myStats.writes);
@ -73,9 +75,11 @@ bool CartridgeARM::load(Serializer& in)
{
try
{
myPrevStats.cycles = in.getInt();
myPrevStats.fetches = in.getInt();
myPrevStats.reads = in.getInt();
myPrevStats.writes = in.getInt();
myStats.cycles = in.getInt();
myStats.fetches = in.getInt();
myStats.reads = in.getInt();
myStats.writes = in.getInt();

View File

@ -1126,9 +1126,6 @@ int Thumbulator::execute()
//B(1) conditional branch
case Op::b1: {
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
rb = (inst >> 0) & 0xFF;
if(rb & 0x80)
rb |= (~0U) << 8;
@ -1141,75 +1138,133 @@ int Thumbulator::execute()
case 0x0: //b eq z set
DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
if(cpsr & CPSR_Z)
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x1: //b ne z clear
DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
if(!(cpsr & CPSR_Z))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x2: //b cs c set
DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
if(cpsr & CPSR_C)
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x3: //b cc c clear
DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
if(!(cpsr & CPSR_C))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x4: //b mi n set
DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
if(cpsr & CPSR_N)
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x5: //b pl n clear
DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
if(!(cpsr & CPSR_N))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x6: //b vs v set
DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
if(cpsr & CPSR_V)
write_register(15,rb);
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x7: //b vc v clear
DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
if(!(cpsr & CPSR_V))
{
write_register(15, rb);
}
return 0;
case 0x8: //b hi c set z clear
DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
if((cpsr & CPSR_C) && (!(cpsr & CPSR_Z)))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0x9: //b ls c clear or z set
DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
if((cpsr & CPSR_Z) || (!(cpsr & CPSR_C)))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0xA: //b ge N == V
DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0xB: //b lt N != V
DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
if((!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0xC: //b gt Z==0 and N == V
@ -1218,7 +1273,12 @@ int Thumbulator::execute()
{
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
}
return 0;
@ -1227,7 +1287,12 @@ int Thumbulator::execute()
if((cpsr & CPSR_Z) ||
(!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
write_register(15, rb);
{
#ifndef NO_THUMB_STATS
++_stats.cycles;
#endif
write_register(15, rb);
}
return 0;
case 0xE: