mirror of https://github.com/stella-emu/stella.git
optimized thumb flags handling
This commit is contained in:
parent
4802981a3a
commit
866ee840de
|
@ -123,6 +123,10 @@ using Common::Base;
|
||||||
#define INC_ARM_CYCLES(m)
|
#define INC_ARM_CYCLES(m)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define do_znflags(x) znFlags=(x)
|
||||||
|
#define do_cflag_bit(x) cFlag = (x)
|
||||||
|
#define do_vflag_bit(x) vFlag = (x);
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size,
|
||||||
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
const uInt32 c_base, const uInt32 c_start, const uInt32 c_stack,
|
||||||
|
@ -819,52 +823,17 @@ void Thumbulator::write_register(uInt32 reg, uInt32 data, bool isFlowBreak)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Thumbulator::do_zflag(uInt32 x)
|
void Thumbulator::do_cvflag(uInt32 a, uInt32 b, uInt32 c)
|
||||||
{
|
|
||||||
if(x == 0) cpsr |= CPSR_Z; else cpsr &= ~CPSR_Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Thumbulator::do_nflag(uInt32 x)
|
|
||||||
{
|
|
||||||
if(x & 0x80000000) cpsr |= CPSR_N; else cpsr &= ~CPSR_N;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Thumbulator::do_cflag(uInt32 a, uInt32 b, uInt32 c)
|
|
||||||
{
|
|
||||||
uInt32 rc = (a & 0x7FFFFFFF) + (b & 0x7FFFFFFF) + c; //carry in
|
|
||||||
rc = (rc >> 31) + (a >> 31) + (b >> 31); //carry out
|
|
||||||
if(rc & 2)
|
|
||||||
cpsr |= CPSR_C;
|
|
||||||
else
|
|
||||||
cpsr &= ~CPSR_C;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void Thumbulator::do_vflag(uInt32 a, uInt32 b, uInt32 c)
|
|
||||||
{
|
{
|
||||||
uInt32 rc = (a & 0x7FFFFFFF) + (b & 0x7FFFFFFF) + c; //carry in
|
uInt32 rc = (a & 0x7FFFFFFF) + (b & 0x7FFFFFFF) + c; //carry in
|
||||||
rc >>= 31; //carry in in lsbit
|
rc >>= 31; //carry in in lsbit
|
||||||
uInt32 rd = (rc & 1) + ((a >> 31) & 1) + ((b >> 31) & 1); //carry out
|
uInt32 rd = (rc & 1) + ((a >> 31) & 1) + ((b >> 31) & 1); //carry out
|
||||||
rd >>= 1; //carry out in lsbit
|
rd >>= 1; //carry out in lsbit
|
||||||
rc = (rc^rd) & 1; //if carry in != carry out then signed overflow
|
|
||||||
if(rc)
|
|
||||||
cpsr |= CPSR_V;
|
|
||||||
else
|
|
||||||
cpsr &= ~CPSR_V;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
vFlag = (rc ^ rd) & 1; //if carry in != carry out then signed overflow
|
||||||
void Thumbulator::do_cflag_bit(uInt32 x)
|
|
||||||
{
|
|
||||||
if(x) cpsr |= CPSR_C; else cpsr &= ~CPSR_C;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
rc += (a >> 31) + (b >> 31); //carry out
|
||||||
void Thumbulator::do_vflag_bit(uInt32 x)
|
cFlag = rc & 2;
|
||||||
{
|
|
||||||
if(x) cpsr |= CPSR_V; else cpsr &= ~CPSR_V;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -1208,13 +1177,12 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rd);
|
ra = read_register(rd);
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
if(cpsr & CPSR_C)
|
if(cFlag)
|
||||||
++rc;
|
++rc;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
if(cFlag) do_cvflag(ra, rb, 1);
|
||||||
if(cpsr & CPSR_C) { do_cflag(ra, rb, 1); do_vflag(ra, rb, 1); }
|
else do_cvflag(ra, rb, 0);
|
||||||
else { do_cflag(ra, rb, 0); do_vflag(ra, rb, 0); }
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,10 +1199,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
//fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
|
//fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, rb, 0);
|
||||||
do_cflag(ra, rb, 0);
|
|
||||||
do_vflag(ra, rb, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1252,10 +1218,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rd);
|
ra = read_register(rd);
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, rb, 0);
|
||||||
do_cflag(ra, rb, 0);
|
|
||||||
do_vflag(ra, rb, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1269,10 +1233,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, rb, 0);
|
||||||
do_cflag(ra, rb, 0);
|
|
||||||
do_vflag(ra, rb, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1295,7 +1257,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
if((rc & 1) == 0)
|
if((rc & 1) == 0)
|
||||||
fatalError("add pc", pc, rc, " produced an arm address");
|
fatalError("add pc", pc, rc, " produced an arm address");
|
||||||
#endif
|
#endif
|
||||||
//rc &= ~1; //write_register may do this as well
|
//rc &= ~1; //write_register may f this as well
|
||||||
rc += 2; //The program counter is special
|
rc += 2; //The program counter is special
|
||||||
}
|
}
|
||||||
//fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
|
//fprintf(stderr,"0x%08X = 0x%08X + 0x%08X\n",rc,ra,rb);
|
||||||
|
@ -1347,8 +1309,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra & rb;
|
rc = ra & rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1381,8 +1342,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc |= (~0U) << (32-rb);
|
rc |= (~0U) << (32-rb);
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1422,8 +1382,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1436,7 +1395,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "beq 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_Z)
|
if(!znFlags)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1447,7 +1406,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bne 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_Z))
|
if(znFlags)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1458,7 +1417,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bcs 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_C)
|
if(cFlag)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1469,7 +1428,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bcc 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_C))
|
if(!cFlag)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1480,7 +1439,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bmi 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_N)
|
if(znFlags & 0x80000000)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1491,7 +1450,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bpl 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_N))
|
if(!(znFlags & 0x80000000))
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1502,7 +1461,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bvs 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(cpsr & CPSR_V)
|
if(vFlag)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1513,7 +1472,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bvc 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_V))
|
if(!vFlag)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1524,7 +1483,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bhi 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((cpsr & CPSR_C) && (!(cpsr & CPSR_Z)))
|
if(cFlag && znFlags)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1535,7 +1494,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bls 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((cpsr & CPSR_Z) || (!(cpsr & CPSR_C)))
|
if(!znFlags || !cFlag)
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1546,8 +1505,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bge 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if(((znFlags & 0x80000000) && vFlag) ||
|
||||||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
((!(znFlags & 0x80000000)) && !vFlag))
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1558,8 +1517,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "blt 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if((!(znFlags & 0x80000000) && vFlag) ||
|
||||||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
(((znFlags & 0x80000000)) && !vFlag))
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1570,10 +1529,10 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "bgt 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "bgt 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if(!(cpsr & CPSR_Z))
|
if(znFlags)
|
||||||
{
|
{
|
||||||
if(((cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
if(((znFlags & 0x80000000) && vFlag) ||
|
||||||
((!(cpsr & CPSR_N)) && (!(cpsr & CPSR_V))))
|
((!(znFlags & 0x80000000)) && !vFlag))
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1585,9 +1544,9 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rb = decodedParam[instructionPtr >> 1];
|
rb = decodedParam[instructionPtr >> 1];
|
||||||
DO_DISS(statusMsg << "ble 0x" << Base::HEX8 << (rb-3) << endl);
|
DO_DISS(statusMsg << "ble 0x" << Base::HEX8 << (rb-3) << endl);
|
||||||
if((cpsr & CPSR_Z) ||
|
if(!znFlags ||
|
||||||
(!(cpsr & CPSR_N) && (cpsr & CPSR_V)) ||
|
(!(znFlags & 0x80000000) && vFlag) ||
|
||||||
(((cpsr & CPSR_N)) && !(cpsr & CPSR_V)))
|
(((znFlags & 0x80000000)) && !vFlag))
|
||||||
write_register(15, rb);
|
write_register(15, rb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1612,8 +1571,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra & (~rb);
|
rc = ra & (~rb);
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1938,10 +1896,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rn);
|
ra = read_register(rn);
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra + rb;
|
rc = ra + rb;
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, rb, 0);
|
||||||
do_cflag(ra, rb, 0);
|
|
||||||
do_vflag(ra, rb, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1953,10 +1909,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rn);
|
ra = read_register(rn);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
//fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
|
//fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1969,10 +1923,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
//fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
|
//fprintf(stderr,"0x%08X 0x%08X\n",ra,rb);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1993,10 +1945,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rn);
|
ra = read_register(rn);
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2029,8 +1979,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra ^ rb;
|
rc = ra ^ rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2267,8 +2216,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc <<= rb;
|
rc <<= rb;
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2300,8 +2248,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2324,8 +2271,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc >>= rb;
|
rc >>= rb;
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2357,8 +2303,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2369,8 +2314,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rd = (inst >> 8) & 0x07;
|
rd = (inst >> 8) & 0x07;
|
||||||
DO_DISS(statusMsg << "movs r" << dec << rd << ",#0x" << Base::HEX2 << rb << endl);
|
DO_DISS(statusMsg << "movs r" << dec << rd << ",#0x" << Base::HEX2 << rb << endl);
|
||||||
write_register(rd, rb);
|
write_register(rd, rb);
|
||||||
do_nflag(rb);
|
do_znflags(rb);
|
||||||
do_zflag(rb);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2382,8 +2326,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rc = read_register(rn);
|
rc = read_register(rn);
|
||||||
//fprintf(stderr,"0x%08X\n",rc);
|
//fprintf(stderr,"0x%08X\n",rc);
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
do_cflag_bit(0);
|
do_cflag_bit(0);
|
||||||
do_vflag_bit(0);
|
do_vflag_bit(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2437,8 +2380,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
#endif
|
#endif
|
||||||
rc = ra * rb;
|
rc = ra * rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2450,8 +2392,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rm);
|
ra = read_register(rm);
|
||||||
rc = (~ra);
|
rc = (~ra);
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2463,10 +2404,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rm);
|
ra = read_register(rm);
|
||||||
rc = 0 - ra;
|
rc = 0 - ra;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(0, ~ra, 1);
|
||||||
do_cflag(0, ~ra, 1);
|
|
||||||
do_vflag(0, ~ra, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2479,8 +2418,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra | rb;
|
rc = ra | rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2688,8 +2626,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
INC_SHIFT_CYCLES;
|
INC_SHIFT_CYCLES;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2702,20 +2639,11 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rd);
|
ra = read_register(rd);
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
if(!(cpsr & CPSR_C)) --rc;
|
if(!cFlag) --rc;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
if(cFlag) do_cvflag(ra, ~rb, 1);
|
||||||
if(cpsr & CPSR_C)
|
else do_cvflag(ra, ~rb, 0);
|
||||||
{
|
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do_cflag(ra, ~rb, 0);
|
|
||||||
do_vflag(ra, ~rb, 0);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,10 +2829,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rn);
|
ra = read_register(rn);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2916,10 +2842,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rd);
|
ra = read_register(rd);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2933,10 +2857,8 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra - rb;
|
rc = ra - rb;
|
||||||
write_register(rd, rc);
|
write_register(rd, rc);
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
do_cvflag(ra, ~rb, 1);
|
||||||
do_cflag(ra, ~rb, 1);
|
|
||||||
do_vflag(ra, ~rb, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2952,16 +2874,16 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
}
|
}
|
||||||
|
|
||||||
//SWI
|
//SWI
|
||||||
case Op::swi: {
|
case Op::swi: { // never used
|
||||||
rb = inst & 0xFF;
|
rb = inst & 0xFF;
|
||||||
DO_DISS(statusMsg << "swi 0x" << Base::HEX2 << rb << endl);
|
DO_DISS(statusMsg << "swi 0x" << Base::HEX2 << rb << endl);
|
||||||
|
|
||||||
if(rb == 0xCC)
|
//if(rb == 0xCC)
|
||||||
{
|
//{
|
||||||
write_register(0, cpsr);
|
// write_register(0, cpsr);
|
||||||
return 0;
|
// return 0;
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
{
|
||||||
#if defined(THUMB_DISS)
|
#if defined(THUMB_DISS)
|
||||||
statusMsg << endl << endl << "swi 0x" << Base::HEX2 << rb << endl;
|
statusMsg << endl << endl << "swi 0x" << Base::HEX2 << rb << endl;
|
||||||
|
@ -3004,8 +2926,7 @@ inline int Thumbulator::execute() // NOLINT (readability-function-size)
|
||||||
ra = read_register(rn);
|
ra = read_register(rn);
|
||||||
rb = read_register(rm);
|
rb = read_register(rm);
|
||||||
rc = ra & rb;
|
rc = ra & rb;
|
||||||
do_nflag(rc);
|
do_znflags(rc);
|
||||||
do_zflag(rc);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3059,7 +2980,7 @@ int Thumbulator::reset()
|
||||||
reg_norm[14] = cBase; // LR
|
reg_norm[14] = cBase; // LR
|
||||||
reg_norm[15] = (cStart + 2) | 1; // PC (+2 for pipeline, lower bit for THUMB)
|
reg_norm[15] = (cStart + 2) | 1; // PC (+2 for pipeline, lower bit for THUMB)
|
||||||
|
|
||||||
cpsr = 0;
|
znFlags = cFlag = vFlag = 0;
|
||||||
handler_mode = false;
|
handler_mode = false;
|
||||||
|
|
||||||
systick_ctrl = 0x00000004;
|
systick_ctrl = 0x00000004;
|
||||||
|
|
|
@ -242,12 +242,7 @@ class Thumbulator
|
||||||
|
|
||||||
Op decodeInstructionWord(uint16_t inst, uInt32 pc);
|
Op decodeInstructionWord(uint16_t inst, uInt32 pc);
|
||||||
|
|
||||||
void do_zflag(uInt32 x);
|
void do_cvflag(uInt32 a, uInt32 b, uInt32 c);
|
||||||
void do_nflag(uInt32 x);
|
|
||||||
void do_cflag(uInt32 a, uInt32 b, uInt32 c);
|
|
||||||
void do_vflag(uInt32 a, uInt32 b, uInt32 c);
|
|
||||||
void do_cflag_bit(uInt32 x);
|
|
||||||
void do_vflag_bit(uInt32 x);
|
|
||||||
|
|
||||||
#ifndef UNSAFE_OPTIMIZATIONS
|
#ifndef UNSAFE_OPTIMIZATIONS
|
||||||
// Throw a runtime_error exception containing an error referencing the
|
// Throw a runtime_error exception containing an error referencing the
|
||||||
|
@ -281,7 +276,9 @@ class Thumbulator
|
||||||
const unique_ptr<uInt32[]> decodedParam; // NOLINT
|
const unique_ptr<uInt32[]> decodedParam; // NOLINT
|
||||||
uInt16* ram{nullptr};
|
uInt16* ram{nullptr};
|
||||||
std::array<uInt32, 16> reg_norm; // normal execution mode, do not have a thread mode
|
std::array<uInt32, 16> reg_norm; // normal execution mode, do not have a thread mode
|
||||||
uInt32 cpsr{0};
|
uInt32 znFlags{0};
|
||||||
|
uInt32 cFlag{0};
|
||||||
|
uInt32 vFlag{0};
|
||||||
MamModeType mamcr{MamModeType::mode0};
|
MamModeType mamcr{MamModeType::mode0};
|
||||||
bool handler_mode{false};
|
bool handler_mode{false};
|
||||||
uInt32 systick_ctrl{0}, systick_reload{0}, systick_count{0}, systick_calibrate{0};
|
uInt32 systick_ctrl{0}, systick_reload{0}, systick_count{0}, systick_calibrate{0};
|
||||||
|
|
Loading…
Reference in New Issue