diff --git a/src/emucore/CortexM0.cxx b/src/emucore/CortexM0.cxx index 272050b2f..d2d7523e6 100644 --- a/src/emucore/CortexM0.cxx +++ b/src/emucore/CortexM0.cxx @@ -2250,12 +2250,10 @@ CortexM0::err_t CortexM0::execute(uInt16 inst, uInt8 op) return ERR_NONE; } -#ifndef UNSAFE_OPTIMIZATIONS //SETEND case Op::setend: { return errIntrinsic(ERR_UNIMPLEMENTED_INST, read_register(15) - 4); } -#endif //STMIA case Op::stmia: { diff --git a/src/emucore/Thumbulator.cxx b/src/emucore/Thumbulator.cxx index 4570b9d18..2978bbc1b 100644 --- a/src/emucore/Thumbulator.cxx +++ b/src/emucore/Thumbulator.cxx @@ -154,9 +154,7 @@ Thumbulator::Thumbulator(const uInt16* rom_ptr, uInt16* ram_ptr, uInt32 rom_size decodedRom[i] = decodeInstructionWord(CONV_RAMROM(rom[i]), i * 2); setConsoleTiming(ConsoleTiming::ntsc); -#ifndef UNSAFE_OPTIMIZATIONS trapFatalErrors(traponfatal); -#endif #ifdef DEBUGGER_SUPPORT cycleFactor(cyclefactor); #endif @@ -171,10 +169,8 @@ string Thumbulator::doRun(uInt32& cycles, bool irqDrivenAudio) for(;;) { if(execute()) break; -#ifndef UNSAFE_OPTIMIZATIONS if(_stats.instructions > 500000) // way more than would otherwise be possible throw runtime_error("instructions > 500000"); -#endif } #ifdef THUMB_CYCLE_COUNT _totalCycles *= _armCyclesFactor; @@ -241,7 +237,6 @@ string Thumbulator::run(uInt32& cycles, bool irqDrivenAudio) return doRun(cycles, irqDrivenAudio); } -#ifndef UNSAFE_OPTIMIZATIONS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - int Thumbulator::fatalError(string_view opcode, uInt32 v1, string_view msg) { @@ -293,12 +288,10 @@ void Thumbulator::dump_regs() << "LR = " << Base::HEX8 << reg_norm[14] << " " << "PC = " << Base::HEX8 << reg_norm[15] << '\n'; } -#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FORCE_INLINE uInt32 Thumbulator::fetch16(uInt32 addr) { -#ifndef UNSAFE_OPTIMIZATIONS uInt32 data = 0; #ifdef THUMB_CYCLE_COUNT @@ -355,42 +348,32 @@ FORCE_INLINE uInt32 Thumbulator::fetch16(uInt32 addr) break; } return fatalError("fetch16", addr, "abort"); -#else - addr &= ROMADDMASK; - addr >>= 1; - return CONV_RAMROM(rom[addr]); -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Thumbulator::write16(uInt32 addr, uInt32 data) { -#ifndef UNSAFE_OPTIMIZATIONS if(addr & 1) fatalError("write16", addr, "abort - misaligned"); -#endif + THUMB_STAT(_stats.writes) DO_DBUG(statusMsg << "write16(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")\n"); - switch(addr & 0xF0000000) // NOLINT (missing default for UNSAFE_OPTIMIZATIONS) + switch(addr & 0xF0000000) { case 0x40000000: //RAM -#ifndef UNSAFE_OPTIMIZATIONS if(isInvalidRAM(addr)) fatalError("write16", addr, "abort - out of range"); if(isProtectedRAM(addr)) fatalError("write16", addr, "to driver area"); -#endif + addr &= RAMADDMASK; addr >>= 1; ram[addr] = CONV_DATA(data); return; -#ifndef UNSAFE_OPTIMIZATIONS case 0xE0000000: //MAMCR -#else default: -#endif if(addr == 0xE01FC000) { DO_DBUG(statusMsg << "write16(" << Base::HEX8 << "MAMCR" << "," << Base::HEX8 << data << ") *\n"); @@ -399,36 +382,29 @@ void Thumbulator::write16(uInt32 addr, uInt32 data) return; } } -#ifndef UNSAFE_OPTIMIZATIONS fatalError("write16", addr, data, "abort"); -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Thumbulator::write32(uInt32 addr, uInt32 data) { -#ifndef UNSAFE_OPTIMIZATIONS if(addr & 3) fatalError("write32", addr, "abort - misaligned"); -#endif + DO_DBUG(statusMsg << "write32(" << Base::HEX8 << addr << "," << Base::HEX8 << data << ")\n"); - switch(addr & 0xF0000000) // NOLINT (missing default for UNSAFE_OPTIMIZATIONS) + switch(addr & 0xF0000000) { -#ifndef UNSAFE_OPTIMIZATIONS case 0xF0000000: //halt dump_counters(); throw runtime_error("HALT"); -#endif case 0xE0000000: //periph switch(addr) { -#ifndef UNSAFE_OPTIMIZATIONS case 0xE0000000: DO_DISS(statusMsg << "uart: [" << char(data&0xFF) << "]\n"); break; -#endif #ifdef TIMER_0 case 0xE0004004: // T0TCR - Timer 0 Control Register #ifdef THUMB_CYCLE_COUNT @@ -516,7 +492,6 @@ void Thumbulator::write32(uInt32 addr, uInt32 data) return; case 0xD0000000: //debug -#ifndef UNSAFE_OPTIMIZATIONS switch(addr & 0xFF) { case 0x00: @@ -535,24 +510,17 @@ void Thumbulator::write32(uInt32 addr, uInt32 data) default: break; } -#endif return; -#ifndef UNSAFE_OPTIMIZATIONS case 0x40000000: //RAM -#else default: -#endif write16(addr+0, (data >> 0) & 0xFFFF); write16(addr+2, (data >> 16) & 0xFFFF); return; } -#ifndef UNSAFE_OPTIMIZATIONS fatalError("write32", addr, data, "abort"); -#endif } -#ifndef UNSAFE_OPTIMIZATIONS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FORCE_INLINE bool Thumbulator::isInvalidROM(uInt32 addr) const { @@ -613,25 +581,21 @@ FORCE_INLINE bool Thumbulator::isProtectedRAM(uInt32 addr) return false; } -#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Thumbulator::read16(uInt32 addr) { uInt32 data = 0; -#ifndef UNSAFE_OPTIMIZATIONS if(addr & 1) fatalError("read16", addr, "abort - misaligned"); -#endif THUMB_STAT(_stats.reads) - switch(addr & 0xF0000000) // NOLINT (missing default for UNSAFE_OPTIMIZATIONS) + switch(addr & 0xF0000000) { case 0x00000000: //ROM -#ifndef UNSAFE_OPTIMIZATIONS if(isInvalidROM(addr)) fatalError("read16", addr, "abort - out of range"); -#endif + addr &= ROMADDMASK; addr >>= 1; data = CONV_RAMROM(rom[addr]); @@ -639,10 +603,9 @@ uInt32 Thumbulator::read16(uInt32 addr) return data; case 0x40000000: //RAM -#ifndef UNSAFE_OPTIMIZATIONS if(isInvalidRAM(addr)) fatalError("read16", addr, "abort - out of range"); -#endif + addr &= RAMADDMASK; addr >>= 1; data = CONV_RAMROM(ram[addr]); @@ -661,49 +624,40 @@ uInt32 Thumbulator::read16(uInt32 addr) return data; } } -#ifndef UNSAFE_OPTIMIZATIONS return fatalError("read16", addr, "abort"); -#endif } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - uInt32 Thumbulator::read32(uInt32 addr) { -#ifndef UNSAFE_OPTIMIZATIONS if(addr & 3) fatalError("read32", addr, "abort - misaligned"); -#endif uInt32 data = 0; - switch(addr & 0xF0000000) // NOLINT (missing default for UNSAFE_OPTIMIZATIONS) + switch(addr & 0xF0000000) { case 0x00000000: //ROM -#ifndef UNSAFE_OPTIMIZATIONS if(isInvalidROM(addr)) fatalError("read32", addr, "abort - out of range"); -#endif + data = read16(addr+0); data |= read16(addr+2) << 16; DO_DBUG(statusMsg << "read32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << '\n'); return data; case 0x40000000: //RAM -#ifndef UNSAFE_OPTIMIZATIONS if(isInvalidRAM(addr)) fatalError("read32", addr, "abort - out of range"); -#endif + data = read16(addr+0); data |= read16(addr+2) << 16; DO_DBUG(statusMsg << "read32(" << Base::HEX8 << addr << ")=" << Base::HEX8 << data << '\n'); return data; -#ifndef UNSAFE_OPTIMIZATIONS case 0xE0000000: -#else default: -#endif { - switch(addr) // NOLINT (FIXME: missing default) + switch(addr) { #ifdef THUMB_CYCLE_COUNT case 0xE01FC000: //MAMCR @@ -765,22 +719,16 @@ uInt32 Thumbulator::read32(uInt32 addr) return 1; // random value #endif -#ifndef UNSAFE_OPTIMIZATIONS case 0xE000E01C: -#else default: -#endif data = systick_calibrate; return data; } } } -#ifndef UNSAFE_OPTIMIZATIONS return fatalError("read32", addr, "abort"); -#endif } -#ifndef UNSAFE_OPTIMIZATIONS // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FORCE_INLINE uInt32 Thumbulator::read_register(uInt32 reg) { @@ -818,10 +766,6 @@ FORCE_INLINE void Thumbulator::write_register(uInt32 reg, uInt32 data, bool isFl } reg_norm[reg] = data; } -#else - #define read_register(reg) reg_norm[reg] - #define write_register(reg, data) reg_norm[reg]=(data) -#endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Thumbulator::do_cvflag(uInt32 a, uInt32 b, uInt32 c) @@ -1145,37 +1089,23 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) { uInt32 sp, inst, ra, rb, rc, rm, rd, rn, rs; // NOLINT -#ifndef UNSAFE_OPTIMIZATIONS uInt32 pc = read_register(15); -#else - uInt32 pc = read_register(15) & ~1; // not checked and corrected in read_register -#endif const uInt32 instructionPtr = pc - 2; const uInt32 instructionPtr2 = instructionPtr >> 1; inst = fetch16(instructionPtr); pc += 2; -#ifndef UNSAFE_OPTIMIZATIONS write_register(15, pc, false); -#else - write_register(15, pc); -#endif DO_DISS(statusMsg << Base::HEX8 << (pc-5) << ": " << Base::HEX4 << inst << " "); -#ifndef UNSAFE_OPTIMIZATIONS ++_stats.instructions; -#endif Op decodedOp{}; -#ifndef UNSAFE_OPTIMIZATIONS if ((instructionPtr & 0xF0000000) == 0 && instructionPtr < romSize) decodedOp = decodedRom[instructionPtr2]; else decodedOp = decodeInstructionWord(CONV_RAMROM(rom[instructionPtr2]), instructionPtr); -#else - decodedOp = decodedRom[(instructionPtr & ROMADDMASK) >> 1]; -#endif #ifdef COUNT_OPS ++opCount[static_cast(decodedOp)]; @@ -1265,10 +1195,9 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) rc = ra + rb; if(rd == 15) { -#ifndef UNSAFE_OPTIMIZATIONS if((rc & 1) == 0) fatalError("add pc", pc, rc, " produced an arm address"); -#endif + //rc &= ~1; //write_register may f this as well rc += 2; //The program counter is special } @@ -1526,14 +1455,12 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) return 0; } -#ifndef UNSAFE_OPTIMIZATIONS //BKPT case Op::bkpt: { rb = (inst >> 0) & 0xFF; statusMsg << "bkpt 0x" << Base::HEX2 << rb << '\n'; return 1; } -#endif //BL/BLX(1) variants // (bl, blx_thumb, blx_arm) @@ -1584,9 +1511,6 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) if(rc & 1) { write_register(14, (pc-2) | 1); -#ifdef UNSAFE_OPTIMIZATIONS - rc &= ~1; // not checked and corrected in write_register -#endif write_register(15, rc); return 0; } @@ -1906,13 +1830,11 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) return 0; } -#ifndef UNSAFE_OPTIMIZATIONS //CPS case Op::cps: { DO_DISS(statusMsg << "cps TODO\n"); return 1; } -#endif //CPY copy high register case Op::cpy: { @@ -2047,11 +1969,7 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) rb = (inst >> 6) & 0x1F; DO_DISS(statusMsg << "ldrb r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX2 << rb << "]\n"); rb = read_register(rn) + rb; -#ifndef UNSAFE_OPTIMIZATIONS rc = read16(rb & (~1U)); -#else - rc = read16(rb); -#endif if(rb & 1) { rc >>= 8; @@ -2071,11 +1989,7 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) rm = (inst >> 6) & 0x7; DO_DISS(statusMsg << "ldrb r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]\n"); rb = read_register(rn) + read_register(rm); -#ifndef UNSAFE_OPTIMIZATIONS rc = read16(rb & (~1U)); -#else - rc = read16(rb); -#endif if(rb & 1) { rc >>= 8; @@ -2119,11 +2033,7 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) rm = (inst >> 6) & 0x7; DO_DISS(statusMsg << "ldrsb r" << dec << rd << ",[r" << dec << rn << ",r" << dec << rm << "]\n"); rb = read_register(rn) + read_register(rm); -#ifndef UNSAFE_OPTIMIZATIONS rc = read16(rb & (~1U)); -#else - rc = read16(rb); -#endif if(rb & 1) { rc >>= 8; @@ -2603,13 +2513,11 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) return 0; } -#ifndef UNSAFE_OPTIMIZATIONS //SETEND case Op::setend: { statusMsg << "setend not implemented\n"; return 1; } -#endif //STMIA case Op::stmia: { @@ -2701,11 +2609,7 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) DO_DISS(statusMsg << "strb r" << dec << rd << ",[r" << dec << rn << ",#0x" << Base::HEX8 << rb << "]\n"); rb = read_register(rn) + rb; rc = read_register(rd); -#ifndef UNSAFE_OPTIMIZATIONS ra = read16(rb & (~1U)); -#else - ra = read16(rb); -#endif if(rb & 1) { ra &= 0x00FF; @@ -2729,11 +2633,7 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) DO_DISS(statusMsg << "strb r" << dec << rd << ",[r" << dec << rn << ",r" << rm << "]\n"); rb = read_register(rn) + read_register(rm); rc = read_register(rd); -#ifndef UNSAFE_OPTIMIZATIONS ra = read16(rb & (~1U)); -#else - ra = read16(rb); -#endif if(rb & 1) { ra &= 0x00FF; @@ -2912,19 +2812,13 @@ FORCE_INLINE int Thumbulator::execute() // NOLINT (readability-function-size) case Op::numOps: break; -#ifndef UNSAFE_OPTIMIZATIONS case Op::invalid: - break; -#else default: break; -#endif } -#ifndef UNSAFE_OPTIMIZATIONS statusMsg << "invalid instruction " << Base::HEX8 << pc << " " << Base::HEX4 << inst << '\n'; -#endif return 1; } @@ -2946,10 +2840,8 @@ int Thumbulator::reset() systick_calibrate = 0x00ABCDEF; // fxq: don't care about below so much (maybe to guess timing???) -#ifndef UNSAFE_OPTIMIZATIONS _stats.instructions = 0; statusMsg.str(""); -#endif #ifdef THUMB_STATS _stats.reads = _stats.writes = _stats.nCycles = _stats.nCycles = _stats.iCycles diff --git a/src/emucore/Thumbulator.hxx b/src/emucore/Thumbulator.hxx index e8b6971b7..49996d20b 100644 --- a/src/emucore/Thumbulator.hxx +++ b/src/emucore/Thumbulator.hxx @@ -30,8 +30,6 @@ class Cartridge; #include "bspf.hxx" #include "Console.hxx" -//#define UNSAFE_OPTIMIZATIONS - #ifdef DEBUGGER_SUPPORT #define THUMB_CYCLE_COUNT //#define COUNT_OPS @@ -117,7 +115,6 @@ class Thumbulator double cycleFactor() const { return 1.0; } #endif - #ifndef UNSAFE_OPTIMIZATIONS /** Normally when a fatal error is encountered, the ARM emulation immediately throws an exception and exits. This method allows execution @@ -131,7 +128,6 @@ class Thumbulator @param enable Enable (the default) or disable exceptions on fatal errors */ void trapFatalErrors(bool enable) { trapOnFatal = enable; } - #endif /** Inform the Thumbulator class about the console currently in use, @@ -215,18 +211,14 @@ class Thumbulator private: string doRun(uInt32& cycles, bool irqDrivenAudio); -#ifndef UNSAFE_OPTIMIZATIONS uInt32 read_register(uInt32 reg); void write_register(uInt32 reg, uInt32 data, bool isFlowBreak = true); -#endif uInt32 fetch16(uInt32 addr); uInt32 read16(uInt32 addr); uInt32 read32(uInt32 addr); - #ifndef UNSAFE_OPTIMIZATIONS bool isInvalidROM(uInt32 addr) const; bool isInvalidRAM(uInt32 addr) const; bool isProtectedRAM(uInt32 addr); - #endif void write16(uInt32 addr, uInt32 data); void write32(uInt32 addr, uInt32 data); void updateTimer(uInt32 cycles); @@ -235,7 +227,6 @@ class Thumbulator void do_cvflag(uInt32 a, uInt32 b, uInt32 c); - #ifndef UNSAFE_OPTIMIZATIONS // Throw a runtime_error exception containing an error referencing the // given message and variables // Note that the return value is never used in these methods @@ -244,7 +235,6 @@ class Thumbulator void dump_counters() const; void dump_regs(); - #endif int execute(); int reset(); @@ -299,10 +289,8 @@ class Thumbulator uInt32 tim1Total{0}; // total cycles of Timer 1 double timing_factor{0.0}; - #ifndef UNSAFE_OPTIMIZATIONS ostringstream statusMsg; bool trapOnFatal{true}; - #endif bool _countCycles{false}; bool _lockMamcr{false};