diff --git a/CMakeLists.txt b/CMakeLists.txt index de350b96f..988b87544 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -884,6 +884,8 @@ target_sources(${PROJECT_NAME} PRIVATE core/hw/sh4/modules/ubc.cpp core/hw/sh4/modules/wince.h core/hw/sh4/sh4_cache.h + core/hw/sh4/sh4_cycles.cpp + core/hw/sh4/sh4_cycles.h core/hw/sh4/sh4_core.h core/hw/sh4/sh4_core_regs.cpp core/hw/sh4/sh4_if.h diff --git a/core/cfg/option.cpp b/core/cfg/option.cpp index dc4ca3337..7a57c4a21 100644 --- a/core/cfg/option.cpp +++ b/core/cfg/option.cpp @@ -25,7 +25,6 @@ namespace config { // Dynarec Option DynarecEnabled("Dynarec.Enabled", true); -Option DynarecIdleSkip("Dynarec.idleskip", true); // General diff --git a/core/cfg/option.h b/core/cfg/option.h index 9c5e3cbde..c27410c45 100644 --- a/core/cfg/option.h +++ b/core/cfg/option.h @@ -356,8 +356,6 @@ using OptionString = Option; // Dynarec extern Option DynarecEnabled; -extern Option DynarecIdleSkip; -constexpr bool DynarecSafeMode = false; // General diff --git a/core/hw/pvr/spg.cpp b/core/hw/pvr/spg.cpp index 54f6d2f52..e5e101ce3 100755 --- a/core/hw/pvr/spg.cpp +++ b/core/hw/pvr/spg.cpp @@ -286,7 +286,7 @@ void scheduleRenderDone(TA_context *cntx) int size = 0; for (TA_context *c = cntx; c != nullptr; c = c->nextContext) size += c->tad.thd_data - c->tad.thd_root; - cycles = std::min(550000 + size * 100, 1500000); + cycles = std::min(450000 + size * 100, 1500000); } } sh4_sched_request(render_end_schid, cycles); diff --git a/core/hw/sh4/dyna/blockmanager.cpp b/core/hw/sh4/dyna/blockmanager.cpp index 5c97bd63d..92f929b80 100644 --- a/core/hw/sh4/dyna/blockmanager.cpp +++ b/core/hw/sh4/dyna/blockmanager.cpp @@ -67,6 +67,7 @@ DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) // This should make this syscall faster r[0] = sh4_sched_now64() * 1000 / SH4_MAIN_CLOCK; next_pc = pr; + Sh4cntx.cycle_counter -= 100; break; case 0xfffffd05: // QueryPerformanceCounter(u64 *) @@ -79,6 +80,7 @@ DynarecCodeEntryPtr DYNACALL bm_GetCodeByVAddr(u32 addr) *ptr = sh4_sched_now64() >> 4; r[0] = 1; next_pc = pr; + Sh4cntx.cycle_counter -= 100; } else { @@ -570,11 +572,8 @@ void bm_RamWriteAccess(u32 addr) { addr &= RAM_MASK; if (unprotected_pages[addr / PAGE_SIZE]) - { - //ERROR_LOG(DYNAREC, "Page %08x already unprotected", addr); - //die("Fatal error"); return; - } + unprotected_pages[addr / PAGE_SIZE] = true; bm_UnlockPage(addr); std::set& block_list = blocks_per_page[addr / PAGE_SIZE]; @@ -585,9 +584,7 @@ void bm_RamWriteAccess(u32 addr) if (!list_copy.empty()) DEBUG_LOG(DYNAREC, "bm_RamWriteAccess write access to %08x pc %08x", addr, next_pc); for (auto& block : list_copy) - { bm_DiscardBlock(block); - } verify(block_list.empty()); } } @@ -665,8 +662,6 @@ void print_blocks() fprintf(f,"block: %p\n",blk.get()); fprintf(f,"vaddr: %08X\n",blk->vaddr); fprintf(f,"paddr: %08X\n",blk->addr); - fprintf(f,"hash: %s\n",blk->hash()); - fprintf(f,"hash_rloc: %s\n",blk->hash()); fprintf(f,"code: %p\n",blk->code); fprintf(f,"runs: %d\n",blk->runs); fprintf(f,"BlockType: %d\n",blk->BlockType); diff --git a/core/hw/sh4/dyna/blockmanager.h b/core/hw/sh4/dyna/blockmanager.h index 375d876ad..6e506ae5d 100644 --- a/core/hw/sh4/dyna/blockmanager.h +++ b/core/hw/sh4/dyna/blockmanager.h @@ -10,18 +10,13 @@ typedef void (*DynarecCodeEntryPtr)(); struct RuntimeBlockInfo; typedef std::shared_ptr RuntimeBlockInfoPtr; -struct RuntimeBlockInfo_Core +struct RuntimeBlockInfo { + bool Setup(u32 pc,fpscr_t fpu_cfg); + u32 addr; DynarecCodeEntryPtr code; u32 lookups; -}; - -struct RuntimeBlockInfo: RuntimeBlockInfo_Core -{ - bool Setup(u32 pc,fpscr_t fpu_cfg); - const char* hash(); - u32 vaddr; u32 host_code_size; //in bytes diff --git a/core/hw/sh4/dyna/decoder.cpp b/core/hw/sh4/dyna/decoder.cpp index 62f908dd7..2884c8e54 100644 --- a/core/hw/sh4/dyna/decoder.cpp +++ b/core/hw/sh4/dyna/decoder.cpp @@ -14,6 +14,7 @@ #include "hw/sh4/sh4_core.h" #include "hw/sh4/sh4_interrupts.h" #include "hw/sh4/sh4_mem.h" +#include "hw/sh4/sh4_cycles.h" #include "hw/sh4/modules/mmu.h" #include "decoder_opcodes.h" #include "cfg/option.h" @@ -22,30 +23,7 @@ #define BLOCK_MAX_SH_OPS_HARD 511 static RuntimeBlockInfo* blk; - -static const char idle_hash[] = - //BIOS - ">:1:05:13B23363" - ">:1:04:2E23A33B" - ">:1:04:FB498832" - ">:1:0A:50A249F9" - - //SC - ">:1:0A:B4E90338" - ">:1:04:11578A16" - ">:1:04:C281CC52" - - //HH - ">:1:07:0757DC10" - ">:1:04:1476CC5E" - - //these look very suspicious, but I'm not sure about any of them - //cross testing w/ IKA makes them more suspects than not - ">:1:0D:8C2921FF" - ">:1:04:B806EEE4" - - // Dead or Alive 2 - ">:1:08:0A37187A"; +static Sh4Cycles cycleCounter; static inline shil_param mk_imm(u32 immv) { @@ -635,9 +613,6 @@ static u32 MatchDiv32(u32 pc , Sh4RegType ®1,Sh4RegType ®2 , Sh4RegType &r static bool MatchDiv32u(u32 op,u32 pc) { - if (config::DynarecSafeMode) - return false; - div_som_reg1 = NoReg; div_som_reg2 = NoReg; div_som_reg3 = NoReg; @@ -649,9 +624,6 @@ static bool MatchDiv32u(u32 op,u32 pc) static bool MatchDiv32s(u32 op,u32 pc) { - if (config::DynarecSafeMode) - return false; - u32 n = GetN(op); u32 m = GetM(op); @@ -866,9 +838,13 @@ static bool dec_generic(u32 op) Emit(shop_div32p2, mk_reg(div_som_reg3), mk_reg(div_som_reg3), mk_reg(div_som_reg2), 0, mk_reg(reg_sr_T)); + for (int i = 1; i <= 64; i++) + { + u16 op = IReadMem16(state.cpu.rpc + i * 2); + blk->guest_cycles += cycleCounter.countCycles(op); + } //skip the aggregated opcodes state.cpu.rpc += 128; - blk->guest_cycles += 64; } else { @@ -898,9 +874,13 @@ static bool dec_generic(u32 op) Emit(shop_and, mk_reg(reg_sr_T), mk_reg(reg_sr_T), mk_imm(1)); // clean up T + for (int i = 1; i <= 64; i++) + { + u16 op = IReadMem16(state.cpu.rpc + i * 2); + blk->guest_cycles += cycleCounter.countCycles(op); + } //skip the aggregated opcodes - state.cpu.rpc+=128; - blk->guest_cycles += 64; + state.cpu.rpc += 128; } else { @@ -964,15 +944,7 @@ static void state_Setup(u32 rpc,fpscr_t fpu_cfg) void dec_updateBlockCycles(RuntimeBlockInfo *block, u16 op) { - if (!mmu_enabled()) - { - if (op < 0xF000) - block->guest_cycles++; - } - else - { - block->guest_cycles += std::max((int)OpDesc[op]->LatencyCycles, 1); - } + block->guest_cycles += cycleCounter.countCycles(op); } bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) @@ -980,7 +952,8 @@ bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles) blk=rbi; state_Setup(blk->vaddr, blk->fpu_cfg); - blk->guest_opcodes=0; + blk->guest_opcodes = 0; + cycleCounter.reset(); // If full MMU, don't allow the block to extend past the end of the current 4K page u32 max_pc = mmu_enabled() ? ((state.cpu.rpc >> 12) + 1) << 12 : 0xFFFFFFFF; @@ -1084,75 +1057,11 @@ _end: verify(blk->oplist.size() <= BLOCK_MAX_SH_OPS_HARD); -#if 0 - switch(rbi->addr) - { - case 0x8C09ED16: - case 0x8C0BA50E: - case 0x8C0BA506: - case 0x8C0BA526: - case 0x8C224800: - INFO_LOG(DYNAREC, "HASH: %08X reloc %s", blk->addr, blk->hash()); - break; - } -#endif - - //cycle tricks - if (config::DynarecIdleSkip) - { - //Experimental hash-id based idle skip - if (!mmu_enabled() && strstr(idle_hash, blk->hash())) - { - DEBUG_LOG(DYNAREC, "IDLESKIP: %08X reloc match %s", blk->addr, blk->hash()); - blk->guest_cycles = max_cycles; - } - else - { - //Small-n-simple idle loop detector :p - if (state.info.has_readm && !state.info.has_writem && !state.info.has_fpu && blk->guest_opcodes<6) - { - if (blk->BlockType==BET_Cond_0 || (blk->BlockType==BET_Cond_1 && blk->BranchBlock<=blk->vaddr)) - { - blk->guest_cycles*=3; - } - - if (blk->BranchBlock==blk->vaddr) - { - blk->guest_cycles*=10; - } - } - - //if in syscalls area (ip.bin etc) skip fast :p - if ((blk->addr&0x1FFF0000)==0x0C000000) - { - if (blk->addr&0x8000) - { - //ip.bin (boot loader/img etc) - blk->guest_cycles*=15; - } - else - { - //syscalls - blk->guest_cycles*=5; - } - } - - //blk->guest_cycles=5; - } - } - else - { - blk->guest_cycles*=1.5; - } - // Win CE boost - if (mmu_enabled()) - blk->guest_cycles *= 1.5f; - //make sure we don't use wayy-too-many cycles blk->guest_cycles = std::min(blk->guest_cycles, max_cycles); //make sure we don't use wayy-too-few cycles blk->guest_cycles = std::max(1U, blk->guest_cycles); - blk=0; + blk = nullptr; return true; } diff --git a/core/hw/sh4/dyna/driver.cpp b/core/hw/sh4/dyna/driver.cpp index 9d0df0ee1..f127b9e74 100644 --- a/core/hw/sh4/dyna/driver.cpp +++ b/core/hw/sh4/dyna/driver.cpp @@ -15,8 +15,6 @@ #include "decoder.h" #include "oslib/virtmem.h" -#include - #if FEAT_SHREC != DYNAREC_NONE #if defined(_WIN32) || FEAT_SHREC != DYNAREC_JIT || defined(TARGET_IPHONE) || defined(TARGET_ARM_MAC) @@ -96,34 +94,6 @@ u32 emit_FreeSpace() void AnalyseBlock(RuntimeBlockInfo* blk); -const char* RuntimeBlockInfo::hash() -{ - XXH32_hash_t hash = 0; - - u8* ptr = GetMemPtr(this->addr, this->sh4_code_size); - - if (ptr) - { - XXH32_state_t *state = XXH32_createState(); - XXH32_reset(state, 7); - for (u32 i = 0; i < this->guest_opcodes; i++) - { - u16 data = ptr[i]; - //Do not count PC relative loads (relocated code) - if ((data >> 12) == 0xD) - data = 0xD000; - - XXH32_update(state, &data, 2); - } - hash = XXH32_digest(state); - XXH32_freeState(state); - } - static char block_hash[20]; - sprintf(block_hash, ">:1:%02X:%08X", this->guest_opcodes, hash); - - return block_hash; -} - bool RuntimeBlockInfo::Setup(u32 rpc,fpscr_t rfpu_cfg) { staging_runs=addr=lookups=runs=host_code_size=0; diff --git a/core/hw/sh4/interpr/sh4_interpreter.cpp b/core/hw/sh4/interpr/sh4_interpreter.cpp index 0664a634d..6bd3d4970 100644 --- a/core/hw/sh4/interpr/sh4_interpreter.cpp +++ b/core/hw/sh4/interpr/sh4_interpreter.cpp @@ -12,22 +12,33 @@ #include "../sh4_sched.h" #include "../sh4_cache.h" #include "debug/gdb_server.h" +#include "../sh4_cycles.h" -#define CPU_RATIO (8) +// SH4 underclock factor when using the interpreter so that it's somewhat usable +#ifdef STRICT_MODE +constexpr int CPU_RATIO = 1; +#else +constexpr int CPU_RATIO = 8; +#endif -sh4_icache icache; -sh4_ocache ocache; +Sh4ICache icache; +Sh4OCache ocache; +Sh4Cycles sh4cycles(CPU_RATIO); static void ExecuteOpcode(u16 op) { if (sr.FD == 1 && OpDesc[op]->IsFloatingPoint()) RaiseFPUDisableException(); OpPtr[op](op); - p_sh4rcb->cntx.cycle_counter -= CPU_RATIO; + sh4cycles.executeCycles(op); } static u16 ReadNexOp() { + if (!mmu_enabled() && (next_pc & 1)) + // address error + throw SH4ThrownException(next_pc, Sh4Ex_AddressErrorRead); + u32 addr = next_pc; next_pc += 2; @@ -53,7 +64,8 @@ static void Sh4_int_Run() UpdateSystem_INTC(); } catch (const SH4ThrownException& ex) { Do_Exception(ex.epc, ex.expEvn); - p_sh4rcb->cntx.cycle_counter -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles + // an exception requires the instruction pipeline to drain, so approx 5 cycles + sh4cycles.addCycles(5 * CPU_RATIO); } } while (sh4_int_bCpuRun); } catch (const debugger::Stop&) { @@ -77,7 +89,8 @@ static void Sh4_int_Step() ExecuteOpcode(op); } catch (const SH4ThrownException& ex) { Do_Exception(ex.epc, ex.expEvn); - p_sh4rcb->cntx.cycle_counter -= CPU_RATIO * 5; // an exception requires the instruction pipeline to drain, so approx 5 cycles + // an exception requires the instruction pipeline to drain, so approx 5 cycles + sh4cycles.addCycles(5 * CPU_RATIO); } catch (const debugger::Stop&) { } } @@ -109,6 +122,7 @@ static void Sh4_int_Reset(bool hard) UpdateFPSCR(); icache.Reset(hard); ocache.Reset(hard); + sh4cycles.reset(); p_sh4rcb->cntx.cycle_counter = SH4_TIMESLICE; INFO_LOG(INTERPRETER, "Sh4 Reset"); diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index 3098fd674..5f3a1787d 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -256,6 +256,8 @@ MmuError mmu_full_lookup(u32 va, const TLB_Entry** tlb_entry_ret, u32& rv) cache_entry(entry); + p_sh4rcb->cntx.cycle_counter -= 164; + return MmuError::NONE; } #endif diff --git a/core/hw/sh4/sh4_cache.h b/core/hw/sh4/sh4_cache.h index d94b02e9e..5f9ba26e8 100644 --- a/core/hw/sh4/sh4_cache.h +++ b/core/hw/sh4/sh4_cache.h @@ -23,6 +23,7 @@ #include "modules/mmu.h" #include "hw/sh4/sh4_core.h" #include "serialize.h" +#include "sh4_cycles.h" static bool cachedArea(u32 area) { @@ -51,7 +52,7 @@ static bool translatedArea(u32 area) // // SH4 instruction cache // -class sh4_icache +class Sh4ICache { public: u16 ReadMem(u32 address) @@ -61,9 +62,10 @@ public: MmuError err = translateAddress(address, physAddr, cacheOn); if (err != MmuError::NONE) mmu_raise_exception(err, address, MMU_TT_IREAD); - - if (!cacheOn) + if (!cacheOn) { + sh4cycles.addReadAccessCycles(physAddr, 2); return addrspace::readt(physAddr); + } const u32 index = CCN_CCR.IIX ? ((address >> 5) & 0x7f) | ((address >> (25 - 7)) & 0x80) @@ -85,6 +87,7 @@ public: for (int i = 0; i < 32; i += 4) *p++ = addrspace::read32(line_addr + i); } + sh4cycles.addReadAccessCycles(physAddr, 32); } return *(u16*)&line.data[physAddr & 0x1f]; @@ -179,9 +182,8 @@ private: if (userMode) { // kernel mem protected in user mode - // FIXME this makes WinCE fail - //if (address & 0x80000000) - // return MmuError::BADADDR; + if (address & 0x80000000) + return MmuError::BADADDR; } else { @@ -221,12 +223,12 @@ private: std::array lines; }; -extern sh4_icache icache; +extern Sh4ICache icache; // // SH4 operand cache // -class sh4_ocache +class Sh4OCache { public: template @@ -239,8 +241,10 @@ public: if (err != MmuError::NONE) mmu_raise_exception(err, address, MMU_TT_DREAD); - if (!cacheOn) + if (!cacheOn) { + sh4cycles.addReadAccessCycles(physAddr, sizeof(T)); return addrspace::readt(physAddr); + } const u32 index = lineIndex(address); cache_line& line = lines[index]; @@ -270,6 +274,7 @@ public: if (!cacheOn) { + addWriteThroughCycles(physAddr, sizeof(T)); addrspace::writet(physAddr, data); return; } @@ -304,6 +309,7 @@ public: { // write-through => update main ram addrspace::writet(physAddr, data); + addWriteThroughCycles(physAddr, sizeof(T)); } } @@ -472,6 +478,7 @@ private: for (int i = 0; i < 32; i += 4) *p++ = addrspace::read32(line_addr + i); } + sh4cycles.addReadAccessCycles(address, 32); } void doWriteBack(u32 index, cache_line& line) @@ -488,6 +495,7 @@ private: for (int i = 0; i < 32; i += 4) addrspace::write32(line_addr + i, *p++); } + addWriteBackCycles(line_addr); } template @@ -558,10 +566,32 @@ private: return MmuError::NONE; } + void addWriteBackCycles(u32 addr) + { + u64 now = sh4cycles.now(); + if (writeBackBufferCycles > now) + sh4cycles.addCycles(writeBackBufferCycles - now); + writeBackBufferCycles = now + sh4cycles.writeAccessCycles(addr, 32); + } + + void addWriteThroughCycles(u32 addr, int size) + { + u64 now = sh4cycles.now(); + if (writeThroughBufferCycles > now) + sh4cycles.addCycles(writeThroughBufferCycles - now); + int cycles = sh4cycles.writeAccessCycles(addr, std::min(size, 8)); + if (size == 32) + sh4cycles.addCycles(cycles * 3); + writeThroughBufferCycles = now + cycles; + } + std::array lines; + // TODO serialize + u64 writeBackBufferCycles = 0; + u64 writeThroughBufferCycles = 0; }; -extern sh4_ocache ocache; +extern Sh4OCache ocache; template T ReadCachedMem(u32 address) diff --git a/core/hw/sh4/sh4_cycles.cpp b/core/hw/sh4/sh4_cycles.cpp new file mode 100644 index 000000000..5588c9d6a --- /dev/null +++ b/core/hw/sh4/sh4_cycles.cpp @@ -0,0 +1,458 @@ +/* + Copyright 2023 flyinghead + + This file is part of Flycast. + + Flycast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Flycast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Flycast. If not, see . +*/ +#include "sh4_cycles.h" + +// TODO additional wait cycles depending on area?: +// Area Wait cycles (not including external wait) +// 0 3 +// 1 VRAM 3 +// 2 reserved 3 +// 3 SDRAM 0 CAS latency 3 +// 4 TA,YUV 1 +// 5 G2 ext 3 +// 6 reserved 3 + +int Sh4Cycles::readExternalAccessCycles(u32 addr, u32 size) +{ + if ((addr & 0xfc000000) == 0xe0000000) + // store queues + return 0; + + addr &= 0x1fffffff; + switch (addr >> 26) + { + case 0: + if (!settings.platform.isAtomiswave()) + { + // Dreamcast, Naomi + if (addr < 0x00200000) + { + // system rom + switch (size) + { + case 1: + return 44; + case 2: + return 63; + case 4: + return 99; + case 32: + default: + return 618; + } + } + if (addr < 0x00200000 + settings.platform.flash_size) + { + // flash + switch (size) + { + case 1: + return 41; + case 2: + return 55; + case 4: + return 83; + case 32: + default: + return 489; + } + } + } + else + { + // Atomiswave + if (addr < 0x00020000 || (addr >= 0x00200000 && addr < 0x00200000 + settings.platform.flash_size)) + { + // flash + switch (size) + { + case 1: + return 41; + case 2: + return 55; + case 4: + return 83; + case 32: + default: + return 489; + } + } + } + addr &= 0x01ffffff; + if (addr >= 0x005f6800 && addr <= 0x005f69ff) + { + // holly system control regs + if (size != 4) + INFO_LOG(SH4, "holly system reg: Invalid read size %d @ %07x", size, addr); + return 5; + } + if (addr >= 0x005f6c00 && addr <= 0x005f6cff) + { + // maple regs + if (size != 4) + INFO_LOG(SH4, "maple reg: Invalid read size %d @ %07x", size, addr); + return 22; + } + if (addr >= 0x005f7000 && addr <= 0x005f70ff) + { + if (settings.platform.isArcade()) + // naomi/aw cart + return 20; // ??? + else + { + // gd-rom + if (size > 2) + INFO_LOG(SH4, "gd-rom: Invalid read size %d @ %07x", size, addr); + return 39; + } + } + if (addr >= 0x005f7400 && addr <= 0x005f74ff) + { + // G1 I/F control regs + if (settings.platform.isConsole()) + { + if (size != 4) // unknown for aw/naomi + INFO_LOG(SH4, "G1 I/F: Invalid read size %d @ %07x", size, addr); + } + else + { + // unknown for aw/naomi. seeing size 1 and 4 at least + } + return 24; + } + if (addr >= 0x005f7800 && addr <= 0x005f78ff) + { + // G2 I/F control regs + if (size != 4) + INFO_LOG(SH4, "G2 I/F: Invalid read size %d @ %07x", size, addr); + return 38; + } + if (addr >= 0x005f7c00 && addr <= 0x005f7cff) + { + // PVR I/F control regs + if (size != 4) + INFO_LOG(SH4, "PVR I/F: Invalid read size %d @ %07x", size, addr); + return 24; + } + if (addr >= 0x005f8000 && addr <= 0x005f9fff) + { + // TA/PVR core control regs, Palette RAM, fog table + if (size != 4) + // TODO 32-byte access allowed for palette and fog tables? + INFO_LOG(SH4, "PVR/TA core: Invalid read size %d @ %07x", size, addr); + return 34; + } + if (addr >= 0x00600000 && addr <= 0x006007ff) + { + if (settings.platform.isConsole()) + // AW registers + return 20; // ??? + else + { + // modem + if (size != 1) + INFO_LOG(SH4, "modem: Invalid read size %d @ %07x", size, addr); + return 67; + } + } + if (addr >= 0x00700000 && addr <= 0x00ffffff) + { + // aica regs and ram + if (size < 4) + INFO_LOG(SH4, "aica: Invalid read size %d @ %07x", size, addr); + return 40 * size / 4; // undocumented + } + if (addr >= 0x01000000 && addr <= 0x01ffffff) + { + // G2 external area + switch (size) + { + case 1: + case 2: + return 56; + case 4: + return 60; + case 32: + default: + return 84; + } + } + break; + + case 1: + // VRAM + switch (size) + { + case 1: + INFO_LOG(SH4, "vram: Invalid read size 1 @ %07x", addr); + return 41; + case 2: + case 4: + return 41; + case 32: + default: + return 61; + } + + case 2: + // Area 2 + INFO_LOG(SH4, "Invalid read from area 2 @ %07x", addr); + return 60; + + case 3: + // System RAM + return 7; // or 12 if row miss TODO average? + + case 4: + // TA FIFO + if (size != 32) + INFO_LOG(SH4, "Invalid read size %d from area 4 (TA FIFO) @ %07x", size, addr); + if ((addr >= 0x11000000 && addr <= 0x11ffffff) || (addr >= 0x13000000 && addr <= 0x13ffffff)) + // VRAM (64 bits) + return 61; // undocumented + break; + + case 5: + // Ext device + switch (size) + { + case 1: + case 2: + return 56; + case 4: + return 60; + case 32: + default: + return 84; + } + + case 6: + // Area 6 + INFO_LOG(SH4, "Invalid read from area 6 @ %07x", addr); + return 60; + + case 7: + // SH4 registers + return 0; + } + + INFO_LOG(SH4, "Unmapped read @ %08x", addr); + return 60; +} + + +int Sh4Cycles::writeExternalAccessCycles(u32 addr, u32 size) +{ + if ((addr & 0xfc000000) == 0xe0000000) + // store queues + return 0; + + addr &= 0x1fffffff; + switch (addr >> 26) + { + case 0: + if (!settings.platform.isAtomiswave()) + { + if (addr < 0x00200000) + { + // system rom + INFO_LOG(SH4, "Invalid write to rom @ %07x", addr); + return 99; + } + if (addr < 0x00200000 + settings.platform.flash_size) + { + // flash + if (size != 1) + INFO_LOG(SH4, "flashrom: Invalid write size %d @ %07x", size, addr); + return 28; + } + } + else + { + if (addr < 0x00020000) + { + // flash + if (size != 1) + INFO_LOG(SH4, "flashrom: Invalid write size %d @ %07x", size, addr); + return 28; + } + if (addr >= 0x00200000 && addr < 0x00200000 + settings.platform.flash_size) + { + // nvmem + return 14; // ???? + } + } + addr &= 0x01ffffff; + if (addr >= 0x005f6800 && addr <= 0x005f69ff) + { + // holly system control regs + if (size != 4) + INFO_LOG(SH4, "holly system reg: Invalid write size %d @ %07x", size, addr); + return 5; + } + if (addr >= 0x005f6c00 && addr <= 0x005f6cff) + { + // maple regs + if (size != 4) + INFO_LOG(SH4, "maple reg: Invalid write size %d @ %07x", size, addr); + return 12; + } + if (addr >= 0x005f7000 && addr <= 0x005f70ff) + { + if (settings.platform.isArcade()) + // naomi/aw cart + return 14; // ??? + else + { + // gd-rom + if (size > 2) + INFO_LOG(SH4, "gd-rom: Invalid write size %d @ %07x", size, addr); + return 28; + } + } + if (addr >= 0x005f7400 && addr <= 0x005f74ff) + { + // G1 I/F control regs + if (size != 4) + INFO_LOG(SH4, "G1 I/F: Invalid write size %d @ %07x", size, addr); + return 12; + } + if (addr >= 0x005f7800 && addr <= 0x005f78ff) + { + // G2 I/F control regs + if (size != 4) + INFO_LOG(SH4, "G2 I/F: Invalid write size %d @ %07x", size, addr); + return 12; + } + if (addr >= 0x005f7c00 && addr <= 0x005f7cff) + { + // PVR I/F control regs + if (size != 4) + INFO_LOG(SH4, "PVR I/F: Invalid write size %d @ %07x", size, addr); + return 12; + } + if (addr >= 0x005f8000 && addr <= 0x005f9fff) + { + // TA/PVR core control regs, Palette RAM, fog table + if (size != 4) + // TODO 32-byte access allowed for palette and fog tables? + INFO_LOG(SH4, "PVR/TA core: Invalid write size %d @ %07x", size, addr); + return 14; + } + if (addr >= 0x00600000 && addr <= 0x006007ff) + { + if (settings.platform.isAtomiswave()) + // AW registers + return 14; // ??? + else + { + // modem + if (size != 1) + INFO_LOG(SH4, "modem: Invalid write size %d @ %07x", size, addr); + return 44; + } + } + if (addr >= 0x00700000 && addr <= 0x00ffffff) + { + // aica regs and ram + if (size < 4) + INFO_LOG(SH4, "aica: Invalid read size %d @ %07x", size, addr); + return 12 * size / 4; // undocumented + } + if (addr >= 0x01000000 && addr <= 0x01ffffff) + { + // G2 external area + switch (size) + { + case 1: + case 2: + case 4: + return 28; + case 32: + default: + return 52; + } + } + break; + + case 1: + // VRAM + switch (size) + { + case 1: + INFO_LOG(SH4, "vram: Invalid write size 1 @ %07x", addr); + return 12; + case 2: + case 4: + return 12; + case 32: + default: + return 38; + } + + case 2: + // Area 2 + INFO_LOG(SH4, "Invalid read to area 2 @ %07x", addr); + return 12; + + case 3: + // System RAM + return 4; // or 9 if row miss TODO average? + + case 4: + // TA FIFO + if (size != 32) + INFO_LOG(SH4, "Invalid write size %d to area 4 (TA FIFO) @ %07x", size, addr); + if ((addr >= 0x10000000 && addr <= 0x107fffff) || (addr >= 0x12000000 && addr <= 0x127fffff)) + // TA polygon data + return 7; // undocumented + if ((addr >= 0x10800000 && addr <= 0x10ffffff) || (addr >= 0x12800000 && addr <= 0x12ffffff)) + // YUV converter + return 9; // 858 cycles for 3072 bytes (YUV420) + if ((addr >= 0x11000000 && addr <= 0x11ffffff) || (addr >= 0x13000000 && addr <= 0x13ffffff)) + // VRAM (64 bits) + return 5; // 8 for 32-bit access (LMMODE0/1) + break; + + case 5: + // Ext device + switch (size) + { + case 1: + case 2: + case 4: + return 28; + case 32: + default: + return 52; + } + + case 6: + // Area 6 + INFO_LOG(SH4, "Invalid write to area 6 @ %07x", addr); + return 14; + + case 7: + // SH4 registers + return 0; + } + + INFO_LOG(SH4, "Unmapped read @ %08x", addr); + return 14; +} diff --git a/core/hw/sh4/sh4_cycles.h b/core/hw/sh4/sh4_cycles.h new file mode 100644 index 000000000..46354980f --- /dev/null +++ b/core/hw/sh4/sh4_cycles.h @@ -0,0 +1,113 @@ +/* + Copyright 2023 flyinghead + + This file is part of Flycast. + + Flycast is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + Flycast is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Flycast. If not, see . +*/ +#pragma once +#include "types.h" +#include "sh4_opcode_list.h" +#include "sh4_if.h" +#include "sh4_sched.h" +#include "modules/mmu.h" + +class Sh4Cycles +{ +public: + Sh4Cycles(int cpuRatio = 1) : cpuRatio(cpuRatio) {} + + void executeCycles(u16 op) + { + Sh4cntx.cycle_counter -= countCycles(op); + } + + void addCycles(int cycles) const + { + Sh4cntx.cycle_counter -= cycles; + } + + void addReadAccessCycles(u32 addr, u32 size) const + { + Sh4cntx.cycle_counter -= readAccessCycles(addr, size); + } + + void addWriteAccessCycles(u32 addr, u32 size) const + { + Sh4cntx.cycle_counter -= writeAccessCycles(addr, size); + } + + int countCycles(u16 op) + { + sh4_opcodelistentry *opcode = OpDesc[op]; + int cycles = 0; +#ifndef STRICT_MODE + if (opcode->ex_type == 2 || opcode->ex_type == 3 + || opcode->ex_type == 5 || opcode->ex_type == 6 || opcode->ex_type == 7 + // cache mgmt || opcode->ex_type == 10 || opcode->ex_type == 11 + || opcode->ex_type == 12 + || opcode->ex_type == 17 || opcode->ex_type == 18 || opcode->ex_type == 19 + || opcode->ex_type == 22 || opcode->ex_type == 23 || opcode->ex_type == 25 + || opcode->ex_type == 27 || opcode->ex_type == 29 || opcode->ex_type == 31 + || opcode->ex_type == 33 || opcode->ex_type == 35) + { + cycles = mmu_enabled() ? 5 : 2; + } + // TODO only for mem read? +#endif + + if (lastUnit == CO + || opcode->unit == CO + || (lastUnit == opcode->unit && lastUnit != MT)) + { + // cannot run in parallel + lastUnit = opcode->unit; + cycles += opcode->IssueCycles; + } + else + { + // can run in parallel + lastUnit = CO; + } + return cycles * cpuRatio; + } + + void reset() + { + lastUnit = CO; + } + + static u64 now() { + return sh4_sched_now64() + SH4_TIMESLICE - Sh4cntx.cycle_counter; + } + + int readAccessCycles(u32 addr, u32 size) const { + return readExternalAccessCycles(addr, size) * 2 * cpuRatio; + } + + int writeAccessCycles(u32 addr, u32 size) const { + return writeExternalAccessCycles(addr, size) * 2 * cpuRatio; + } + +private: + // Returns the number of external cycles (100 MHz) needed for a sized read at the given address + static int readExternalAccessCycles(u32 addr, u32 size); + // Returns the number of external cycles (100 MHz) needed for a sized write at the given address + static int writeExternalAccessCycles(u32 addr, u32 size); + + sh4_eu lastUnit = CO; + const int cpuRatio; +}; + +extern Sh4Cycles sh4cycles; diff --git a/core/hw/sh4/sh4_opcode_list.cpp b/core/hw/sh4/sh4_opcode_list.cpp index 8f7f946e7..9fe9f007e 100644 --- a/core/hw/sh4/sh4_opcode_list.cpp +++ b/core/hw/sh4/sh4_opcode_list.cpp @@ -80,263 +80,263 @@ static u64 dec_MRd(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_ReadM,d,s, //d= reg to read from static u64 dec_MWt(DecParam d,DecParam s,u32 sz) { return dec_Fill(DM_WriteM,d,s,shop_writem,sz); } -sh4_opcodelistentry missing_opcode = {dec_illegalOp, iNotImplemented, 0, 0, ReadWritePC, "missing", 0, 0, CO, fix_none }; +sh4_opcodelistentry missing_opcode = {dec_illegalOp, iNotImplemented, 0, 0, ReadWritePC, "missing", 0, 0, CO, 1 }; sh4_opcodelistentry opcodes[]= { //HLE - {0, reios_trap, Mask_none, REIOS_OPCODE, Branch_dir, "reios_trap", 100, 100, CO, fix_none }, + {0, reios_trap, Mask_none, REIOS_OPCODE, Branch_dir, "reios_trap", 100, 100, CO, 1 }, //CPU - {dec_i0000_nnnn_0010_0011 ,i0000_nnnn_0010_0011 ,Mask_n ,0x0023 ,Branch_rel_d ,"braf " ,2,3,CO,fix_none}, //braf - {dec_i0000_nnnn_0000_0011 ,i0000_nnnn_0000_0011 ,Mask_n ,0x0003 ,Branch_rel_d ,"bsrf " ,2,3,CO,fix_none}, //bsrf - {0 ,i0000_nnnn_1100_0011 ,Mask_n ,0x00C3 ,Normal ,"movca.l R0, @" ,2,4,MA,fix_none ,dec_MWt(PRM_RN,PRM_R0,4)}, //movca.l R0, @ - {dec_i0000_0000_0000_1001 ,i0000_nnnn_1001_0011 ,Mask_n ,0x0093 ,Normal ,"ocbi @" ,1,2,MA,fix_none}, //ocbi @ - {dec_i0000_0000_0000_1001 ,i0000_nnnn_1010_0011 ,Mask_n ,0x00A3 ,Normal ,"ocbp @" ,1,2,MA,fix_none}, //ocbp @ - {dec_i0000_0000_0000_1001 ,i0000_nnnn_1011_0011 ,Mask_n ,0x00B3 ,Normal ,"ocbwb @" ,1,2,MA,fix_none}, //ocbwb @ - {0 ,i0000_nnnn_1000_0011 ,Mask_n ,0x0083 ,Normal ,"pref @" ,1,2,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_ONE,shop_pref,1)}, //pref @ - {0 ,i0000_nnnn_mmmm_0111 ,Mask_n_m ,0x0007 ,Normal ,"mul.l ," ,2,4,CO,fix_none ,dec_mul(-32)}, //mul.l , - {0 ,i0000_0000_0010_1000 ,Mask_none ,0x0028 ,Normal ,"clrmac" ,1,3,LS,fix_none}, //clrmac - {0 ,i0000_0000_0100_1000 ,Mask_none ,0x0048 ,Normal ,"clrs" ,1,1,CO,fix_none ,dec_Fill(DM_BinaryOp, PRM_SR_STATUS, PRM_TWO_INV, shop_and, 1) }, //clrs - {0 ,i0000_0000_0000_1000 ,Mask_none ,0x0008 ,Normal ,"clrt" ,1,1,MT,fix_none ,dec_Fill(DM_UnaryOp,PRM_SR_T,PRM_ZERO,shop_mov32)}, //clrt - {0 ,i0000_0000_0011_1000 ,Mask_none ,0x0038 ,Normal ,"ldtlb" ,1,1,CO,fix_none} ,//ldtlb - {0 ,i0000_0000_0101_1000 ,Mask_none ,0x0058 ,Normal ,"sets" ,1,1,CO,fix_none ,dec_Fill(DM_BinaryOp, PRM_SR_STATUS, PRM_TWO, shop_or, 1) }, //sets - {0 ,i0000_0000_0001_1000 ,Mask_none ,0x0018 ,Normal ,"sett" ,1,1,MT,fix_none ,dec_Fill(DM_UnaryOp,PRM_SR_T,PRM_ONE,shop_mov32)}, //sett - {0 ,i0000_0000_0001_1001 ,Mask_none ,0x0019 ,Normal ,"div0u" ,1,1,EX,fix_none ,dec_Fill(DM_DIV0,PRM_RN,PRM_RM,shop_or,1)},//div0u - {0 ,i0000_nnnn_0010_1001 ,Mask_n ,0x0029 ,Normal ,"movt " ,1,1,EX,fix_none ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_SR_T,shop_mov32)}, //movt - {dec_i0000_0000_0000_1001 ,i0000_0000_0000_1001 ,Mask_none ,0x0009 ,Normal ,"nop" ,1,0,MT,fix_none} ,//nop - {dec_i0000_0000_0000_1001 ,i0000_0000_0000_1001 ,Mask_none ,0x0000 ,Normal ,"nop0" ,1,0,MT,fix_none} ,//nop0 Looney Tunes: Space Race, Samba de Amigo 2000 + {dec_i0000_nnnn_0010_0011 ,i0000_nnnn_0010_0011 ,Mask_n ,0x0023 ,Branch_rel_d ,"braf " ,2,3,CO,4}, //braf + {dec_i0000_nnnn_0000_0011 ,i0000_nnnn_0000_0011 ,Mask_n ,0x0003 ,Branch_rel_d ,"bsrf " ,2,3,CO,24}, //bsrf + {0 ,i0000_nnnn_1100_0011 ,Mask_n ,0x00C3 ,Normal ,"movca.l R0, @" ,1,4,LS,12 ,dec_MWt(PRM_RN,PRM_R0,4)}, //movca.l R0, @ + {dec_i0000_0000_0000_1001 ,i0000_nnnn_1001_0011 ,Mask_n ,0x0093 ,Normal ,"ocbi @" ,1,2,LS,10}, //ocbi @ + {dec_i0000_0000_0000_1001 ,i0000_nnnn_1010_0011 ,Mask_n ,0x00A3 ,Normal ,"ocbp @" ,1,3,LS,11}, //ocbp @ + {dec_i0000_0000_0000_1001 ,i0000_nnnn_1011_0011 ,Mask_n ,0x00B3 ,Normal ,"ocbwb @" ,1,3,LS,11}, //ocbwb @ + {0 ,i0000_nnnn_1000_0011 ,Mask_n ,0x0083 ,Normal ,"pref @" ,1,1,LS,2 ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_ONE,shop_pref,1)}, //pref @ + {0 ,i0000_nnnn_mmmm_0111 ,Mask_n_m ,0x0007 ,Normal ,"mul.l ," ,2,4,CO,34 ,dec_mul(-32)}, //mul.l , + {0 ,i0000_0000_0010_1000 ,Mask_none ,0x0028 ,Normal ,"clrmac" ,1,3,CO,28}, //clrmac + {0 ,i0000_0000_0100_1000 ,Mask_none ,0x0048 ,Normal ,"clrs" ,1,1,CO,1 ,dec_Fill(DM_BinaryOp, PRM_SR_STATUS, PRM_TWO_INV, shop_and, 1) }, //clrs + {0 ,i0000_0000_0000_1000 ,Mask_none ,0x0008 ,Normal ,"clrt" ,1,1,MT,1 ,dec_Fill(DM_UnaryOp,PRM_SR_T,PRM_ZERO,shop_mov32)}, //clrt + {0 ,i0000_0000_0011_1000 ,Mask_none ,0x0038 ,Normal ,"ldtlb" ,1,1,CO,2} ,//ldtlb + {0 ,i0000_0000_0101_1000 ,Mask_none ,0x0058 ,Normal ,"sets" ,1,1,CO,1 ,dec_Fill(DM_BinaryOp, PRM_SR_STATUS, PRM_TWO, shop_or, 1) }, //sets + {0 ,i0000_0000_0001_1000 ,Mask_none ,0x0018 ,Normal ,"sett" ,1,1,MT,1 ,dec_Fill(DM_UnaryOp,PRM_SR_T,PRM_ONE,shop_mov32)}, //sett + {0 ,i0000_0000_0001_1001 ,Mask_none ,0x0019 ,Normal ,"div0u" ,1,1,EX,1 ,dec_Fill(DM_DIV0,PRM_RN,PRM_RM,shop_or,1)},//div0u + {0 ,i0000_nnnn_0010_1001 ,Mask_n ,0x0029 ,Normal ,"movt " ,1,1,EX,1 ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_SR_T,shop_mov32)}, //movt + {dec_i0000_0000_0000_1001 ,i0000_0000_0000_1001 ,Mask_none ,0x0009 ,Normal ,"nop" ,1,0,MT,1} ,//nop + {dec_i0000_0000_0000_1001 ,i0000_0000_0000_1001 ,Mask_none ,0x0000 ,Normal ,"nop0" ,1,0,MT,1} ,//nop0 Looney Tunes: Space Race, Samba de Amigo 2000 - {dec_i0000_0000_0010_1011 ,i0000_0000_0010_1011 ,Mask_none ,0x002B ,Branch_dir_d ,"rte" ,5,5,CO,fix_none}, //rte - {dec_i0000_0000_0000_1011 ,i0000_0000_0000_1011 ,Mask_none ,0x000B ,Branch_dir_d ,"rts" ,2,3,CO,fix_none}, //rts - {dec_i0000_0000_0001_1011 ,i0000_0000_0001_1011 ,Mask_none ,0x001B ,ReadWritePC ,"sleep" ,4,4,CO,fix_none}, //sleep + {dec_i0000_0000_0010_1011 ,i0000_0000_0010_1011 ,Mask_none ,0x002B ,Branch_dir_d ,"rte" ,5,5,CO,8}, //rte + {dec_i0000_0000_0000_1011 ,i0000_0000_0000_1011 ,Mask_none ,0x000B ,Branch_dir_d ,"rts" ,2,3,CO,4}, //rts + {dec_i0000_0000_0001_1011 ,i0000_0000_0001_1011 ,Mask_none ,0x001B ,ReadWritePC ,"sleep" ,4,4,CO,9}, //sleep - {0 ,i0000_nnnn_mmmm_1111 ,Mask_n_m ,0x000F ,Normal ,"mac.l @+,@+" ,2,3,CO,fix_none}, //mac.l @+,@+ + {0 ,i0000_nnnn_mmmm_1111 ,Mask_n_m ,0x000F ,Normal ,"mac.l @+,@+" ,2,4,CO,35}, //mac.l @+,@+ - {0 ,i0010_nnnn_mmmm_0111 ,Mask_n_m ,0x2007 ,Normal ,"div0s ," ,1,1,EX,fix_none ,dec_Fill(DM_DIV0,PRM_RN,PRM_RM,shop_or,-1)}, // div0s , - {0 ,i0010_nnnn_mmmm_1000 ,Mask_n_m ,0x2008 ,Normal ,"tst ," ,1,1,MT,fix_none ,dec_cmp(shop_test,PRM_RN,PRM_RM)}, // tst , - {0 ,i0010_nnnn_mmmm_1001 ,Mask_n_m ,0x2009 ,Normal ,"and ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_and)}, //and , - {0 ,i0010_nnnn_mmmm_1010 ,Mask_n_m ,0x200A ,Normal ,"xor ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xor)}, //xor , - {0 ,i0010_nnnn_mmmm_1011 ,Mask_n_m ,0x200B ,Normal ,"or ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_or)}, //or , - {0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal ,"cmp/str ," ,1,1,MT,fix_none ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str , - {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal ,"xtrct ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_xtrct)}, //xtrct , - {0 ,i0010_nnnn_mmmm_1110 ,Mask_n_m ,0x200E ,Normal ,"mulu.w ," ,1,4,CO,fix_none ,dec_mul(16)}, //mulu.w , - {0 ,i0010_nnnn_mmmm_1111 ,Mask_n_m ,0x200F ,Normal ,"muls.w ," ,1,4,CO,fix_none ,dec_mul(-16)}, //muls.w , - {0 ,i0011_nnnn_mmmm_0000 ,Mask_n_m ,0x3000 ,Normal ,"cmp/eq ," ,1,1,MT,fix_none ,dec_cmp(shop_seteq,PRM_RN,PRM_RM)}, // cmp/eq , - {0 ,i0011_nnnn_mmmm_0010 ,Mask_n_m ,0x3002 ,Normal ,"cmp/hs ," ,1,1,MT,fix_none ,dec_cmp(shop_setae,PRM_RN,PRM_RM)}, // cmp/hs , - {0 ,i0011_nnnn_mmmm_0011 ,Mask_n_m ,0x3003 ,Normal ,"cmp/ge ," ,1,1,MT,fix_none ,dec_cmp(shop_setge,PRM_RN,PRM_RM)}, //cmp/ge , - {0 ,i0011_nnnn_mmmm_0100 ,Mask_n_m ,0x3004 ,Normal ,"div1 ," ,1,1,EX,fix_none ,dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_div1,0)}, //div1 , - {0 ,i0011_nnnn_mmmm_0101 ,Mask_n_m ,0x3005 ,Normal ,"dmulu.l ," ,2,4,CO,fix_none ,dec_mul(64)}, //dmulu.l , - {0 ,i0011_nnnn_mmmm_0110 ,Mask_n_m ,0x3006 ,Normal ,"cmp/hi ," ,1,1,MT,fix_none ,dec_cmp(shop_setab,PRM_RN,PRM_RM)}, // cmp/hi , - {0 ,i0011_nnnn_mmmm_0111 ,Mask_n_m ,0x3007 ,Normal ,"cmp/gt ," ,1,1,MT,fix_none ,dec_cmp(shop_setgt,PRM_RN,PRM_RM)}, //cmp/gt , - {0 ,i0011_nnnn_mmmm_1000 ,Mask_n_m ,0x3008 ,Normal ,"sub ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_sub)}, // sub , - {0 ,i0011_nnnn_mmmm_1010 ,Mask_n_m ,0x300A ,Normal ,"subc ," ,1,1,EX,fix_none, dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_sbc,-1)}, //subc , - {0 ,i0011_nnnn_mmmm_1011 ,Mask_n_m ,0x300B ,Normal ,"subv ," ,1,1,EX,fix_none}, //subv , - {0 ,i0011_nnnn_mmmm_1100 ,Mask_n_m ,0x300C ,Normal ,"add ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_add)}, //add , - {0 ,i0011_nnnn_mmmm_1101 ,Mask_n_m ,0x300D ,Normal ,"dmuls.l ," ,1,4,CO,fix_none ,dec_mul(-64)}, //dmuls.l , - {0 ,i0011_nnnn_mmmm_1110 ,Mask_n_m ,0x300E ,Normal ,"addc ," ,1,1,EX,fix_none, dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_adc,-1)}, //addc , - {0 ,i0011_nnnn_mmmm_1111 ,Mask_n_m ,0x300F ,Normal ,"addv ," ,1,1,EX,fix_none}, // addv , + {0 ,i0010_nnnn_mmmm_0111 ,Mask_n_m ,0x2007 ,Normal ,"div0s ," ,1,1,EX,1 ,dec_Fill(DM_DIV0,PRM_RN,PRM_RM,shop_or,-1)}, // div0s , + {0 ,i0010_nnnn_mmmm_1000 ,Mask_n_m ,0x2008 ,Normal ,"tst ," ,1,1,MT,1 ,dec_cmp(shop_test,PRM_RN,PRM_RM)}, // tst , + {0 ,i0010_nnnn_mmmm_1001 ,Mask_n_m ,0x2009 ,Normal ,"and ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_and)}, //and , + {0 ,i0010_nnnn_mmmm_1010 ,Mask_n_m ,0x200A ,Normal ,"xor ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_xor)}, //xor , + {0 ,i0010_nnnn_mmmm_1011 ,Mask_n_m ,0x200B ,Normal ,"or ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_or)}, //or , + {0 ,i0010_nnnn_mmmm_1100 ,Mask_n_m ,0x200C ,Normal ,"cmp/str ," ,1,1,MT,1 ,dec_cmp(shop_setpeq,PRM_RN,PRM_RM)}, //cmp/str , + {0 ,i0010_nnnn_mmmm_1101 ,Mask_n_m ,0x200D ,Normal ,"xtrct ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_xtrct)}, //xtrct , + {0 ,i0010_nnnn_mmmm_1110 ,Mask_n_m ,0x200E ,Normal ,"mulu.w ," ,2,4,CO,34 ,dec_mul(16)}, //mulu.w , + {0 ,i0010_nnnn_mmmm_1111 ,Mask_n_m ,0x200F ,Normal ,"muls.w ," ,2,4,CO,34 ,dec_mul(-16)}, //muls.w , + {0 ,i0011_nnnn_mmmm_0000 ,Mask_n_m ,0x3000 ,Normal ,"cmp/eq ," ,1,1,MT,1 ,dec_cmp(shop_seteq,PRM_RN,PRM_RM)}, // cmp/eq , + {0 ,i0011_nnnn_mmmm_0010 ,Mask_n_m ,0x3002 ,Normal ,"cmp/hs ," ,1,1,MT,1 ,dec_cmp(shop_setae,PRM_RN,PRM_RM)}, // cmp/hs , + {0 ,i0011_nnnn_mmmm_0011 ,Mask_n_m ,0x3003 ,Normal ,"cmp/ge ," ,1,1,MT,1 ,dec_cmp(shop_setge,PRM_RN,PRM_RM)}, //cmp/ge , + {0 ,i0011_nnnn_mmmm_0100 ,Mask_n_m ,0x3004 ,Normal ,"div1 ," ,1,1,EX,1 ,dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_div1,0)}, //div1 , + {0 ,i0011_nnnn_mmmm_0101 ,Mask_n_m ,0x3005 ,Normal ,"dmulu.l ," ,2,4,CO,34 ,dec_mul(64)}, //dmulu.l , + {0 ,i0011_nnnn_mmmm_0110 ,Mask_n_m ,0x3006 ,Normal ,"cmp/hi ," ,1,1,MT,1 ,dec_cmp(shop_setab,PRM_RN,PRM_RM)}, // cmp/hi , + {0 ,i0011_nnnn_mmmm_0111 ,Mask_n_m ,0x3007 ,Normal ,"cmp/gt ," ,1,1,MT,1 ,dec_cmp(shop_setgt,PRM_RN,PRM_RM)}, //cmp/gt , + {0 ,i0011_nnnn_mmmm_1000 ,Mask_n_m ,0x3008 ,Normal ,"sub ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_sub)}, // sub , + {0 ,i0011_nnnn_mmmm_1010 ,Mask_n_m ,0x300A ,Normal ,"subc ," ,1,1,EX,1, dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_sbc,-1)}, //subc , + {0 ,i0011_nnnn_mmmm_1011 ,Mask_n_m ,0x300B ,Normal ,"subv ," ,1,1,EX,1}, //subv , + {0 ,i0011_nnnn_mmmm_1100 ,Mask_n_m ,0x300C ,Normal ,"add ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_add)}, //add , + {0 ,i0011_nnnn_mmmm_1101 ,Mask_n_m ,0x300D ,Normal ,"dmuls.l ," ,2,4,CO,34 ,dec_mul(-64)}, //dmuls.l , + {0 ,i0011_nnnn_mmmm_1110 ,Mask_n_m ,0x300E ,Normal ,"addc ," ,1,1,EX,1, dec_Fill(DM_ADC,PRM_RN,PRM_RM,shop_adc,-1)}, //addc , + {0 ,i0011_nnnn_mmmm_1111 ,Mask_n_m ,0x300F ,Normal ,"addv ," ,1,1,EX,1}, // addv , //Normal readm/writem - {0 ,i0000_nnnn_mmmm_0100 ,Mask_n_m ,0x0004 ,Normal ,"mov.b ,@(R0,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RN_R0,PRM_RM,1)}, //mov.b ,@(R0,) - {0 ,i0000_nnnn_mmmm_0101 ,Mask_n_m ,0x0005 ,Normal ,"mov.w ,@(R0,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RN_R0,PRM_RM,2)}, //mov.w ,@(R0,) - {0 ,i0000_nnnn_mmmm_0110 ,Mask_n_m ,0x0006 ,Normal ,"mov.l ,@(R0,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RN_R0,PRM_RM,4)}, //mov.l ,@(R0,) - {0 ,i0000_nnnn_mmmm_1100 ,Mask_n_m ,0x000C ,Normal ,"mov.b @(R0,)," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM_R0,1)}, //mov.b @(R0,), - {0 ,i0000_nnnn_mmmm_1101 ,Mask_n_m ,0x000D ,Normal ,"mov.w @(R0,)," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM_R0,2)}, //mov.w @(R0,), - {0 ,i0000_nnnn_mmmm_1110 ,Mask_n_m ,0x000E ,Normal ,"mov.l @(R0,)," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM_R0,4)}, //mov.l @(R0,), - {0 ,i0001_nnnn_mmmm_iiii ,Mask_n_imm8 ,0x1000 ,Normal ,"mov.l ,@(,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RN_D4_x4,PRM_RM,4)}, //mov.l ,@(,) - {0 ,i0101_nnnn_mmmm_iiii ,Mask_n_m_imm4 ,0x5000,Normal ,"mov.l @(,)," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM_D4_x4,4)}, //mov.l @(,), + {0 ,i0000_nnnn_mmmm_0100 ,Mask_n_m ,0x0004 ,Normal ,"mov.b ,@(R0,)" ,1,1,LS,2 ,dec_MWt(PRM_RN_R0,PRM_RM,1)}, //mov.b ,@(R0,) + {0 ,i0000_nnnn_mmmm_0101 ,Mask_n_m ,0x0005 ,Normal ,"mov.w ,@(R0,)" ,1,1,LS,2 ,dec_MWt(PRM_RN_R0,PRM_RM,2)}, //mov.w ,@(R0,) + {0 ,i0000_nnnn_mmmm_0110 ,Mask_n_m ,0x0006 ,Normal ,"mov.l ,@(R0,)" ,1,1,LS,2 ,dec_MWt(PRM_RN_R0,PRM_RM,4)}, //mov.l ,@(R0,) + {0 ,i0000_nnnn_mmmm_1100 ,Mask_n_m ,0x000C ,Normal ,"mov.b @(R0,)," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM_R0,1)}, //mov.b @(R0,), + {0 ,i0000_nnnn_mmmm_1101 ,Mask_n_m ,0x000D ,Normal ,"mov.w @(R0,)," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM_R0,2)}, //mov.w @(R0,), + {0 ,i0000_nnnn_mmmm_1110 ,Mask_n_m ,0x000E ,Normal ,"mov.l @(R0,)," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM_R0,4)}, //mov.l @(R0,), + {0 ,i0001_nnnn_mmmm_iiii ,Mask_n_imm8 ,0x1000 ,Normal ,"mov.l ,@(,)" ,1,1,LS,2 ,dec_MWt(PRM_RN_D4_x4,PRM_RM,4)}, //mov.l ,@(,) + {0 ,i0101_nnnn_mmmm_iiii ,Mask_n_m_imm4 ,0x5000,Normal ,"mov.l @(,)," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM_D4_x4,4)}, //mov.l @(,), - {0 ,i0010_nnnn_mmmm_0000 ,Mask_n_m ,0x2000 ,Normal ,"mov.b ,@" ,1,1,LS,fix_none ,dec_MWt(PRM_RN,PRM_RM,1)}, //mov.b ,@ - {0 ,i0010_nnnn_mmmm_0001 ,Mask_n_m ,0x2001 ,Normal ,"mov.w ,@" ,1,1,LS,fix_none ,dec_MWt(PRM_RN,PRM_RM,2)}, // mov.w ,@ - {0 ,i0010_nnnn_mmmm_0010 ,Mask_n_m ,0x2002 ,Normal ,"mov.l ,@" ,1,1,LS,fix_none ,dec_MWt(PRM_RN,PRM_RM,4)}, // mov.l ,@ - {0 ,i0110_nnnn_mmmm_0000 ,Mask_n_m ,0x6000 ,Normal ,"mov.b @," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,1)}, //mov.b @, - {0 ,i0110_nnnn_mmmm_0001 ,Mask_n_m ,0x6001 ,Normal ,"mov.w @," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,2)}, //mov.w @, - {0 ,i0110_nnnn_mmmm_0010 ,Mask_n_m ,0x6002 ,Normal ,"mov.l @," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,4)}, //mov.l @, + {0 ,i0010_nnnn_mmmm_0000 ,Mask_n_m ,0x2000 ,Normal ,"mov.b ,@" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,1)}, //mov.b ,@ + {0 ,i0010_nnnn_mmmm_0001 ,Mask_n_m ,0x2001 ,Normal ,"mov.w ,@" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,2)}, // mov.w ,@ + {0 ,i0010_nnnn_mmmm_0010 ,Mask_n_m ,0x2002 ,Normal ,"mov.l ,@" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,4)}, // mov.l ,@ + {0 ,i0110_nnnn_mmmm_0000 ,Mask_n_m ,0x6000 ,Normal ,"mov.b @," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,1)}, //mov.b @, + {0 ,i0110_nnnn_mmmm_0001 ,Mask_n_m ,0x6001 ,Normal ,"mov.w @," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,2)}, //mov.w @, + {0 ,i0110_nnnn_mmmm_0010 ,Mask_n_m ,0x6002 ,Normal ,"mov.l @," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,4)}, //mov.l @, - {0 ,i0010_nnnn_mmmm_0100 ,Mask_n_m ,0x2004 ,Normal ,"mov.b ,@-" ,1,1,LS,rn_opt_1 ,dec_MWt(PRM_RN,PRM_RM,-1)}, // mov.b ,@- - {0 ,i0010_nnnn_mmmm_0101 ,Mask_n_m ,0x2005 ,Normal ,"mov.w ,@-" ,1,1,LS,rn_opt_2 ,dec_MWt(PRM_RN,PRM_RM,-2)}, //mov.w ,@- - {0 ,i0010_nnnn_mmmm_0110 ,Mask_n_m ,0x2006 ,Normal ,"mov.l ,@-" ,1,1,LS,rn_opt_4 ,dec_MWt(PRM_RN,PRM_RM,-4)}, //mov.l ,@- - {0 ,i0110_nnnn_mmmm_0100 ,Mask_n_m ,0x6004 ,Normal ,"mov.b @+," ,1,1,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,-1)}, //mov.b @+, - {0 ,i0110_nnnn_mmmm_0101 ,Mask_n_m ,0x6005 ,Normal ,"mov.w @+," ,1,1,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,-2)}, //mov.w @+, - {0 ,i0110_nnnn_mmmm_0110 ,Mask_n_m ,0x6006 ,Normal ,"mov.l @+," ,1,1,LS,fix_none ,dec_MRd(PRM_RN,PRM_RM,-4)}, //mov.l @+, + {0 ,i0010_nnnn_mmmm_0100 ,Mask_n_m ,0x2004 ,Normal ,"mov.b ,@-" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,-1)}, // mov.b ,@- + {0 ,i0010_nnnn_mmmm_0101 ,Mask_n_m ,0x2005 ,Normal ,"mov.w ,@-" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,-2)}, //mov.w ,@- + {0 ,i0010_nnnn_mmmm_0110 ,Mask_n_m ,0x2006 ,Normal ,"mov.l ,@-" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_RM,-4)}, //mov.l ,@- + {0 ,i0110_nnnn_mmmm_0100 ,Mask_n_m ,0x6004 ,Normal ,"mov.b @+," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,-1)}, //mov.b @+, + {0 ,i0110_nnnn_mmmm_0101 ,Mask_n_m ,0x6005 ,Normal ,"mov.w @+," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,-2)}, //mov.w @+, + {0 ,i0110_nnnn_mmmm_0110 ,Mask_n_m ,0x6006 ,Normal ,"mov.l @+," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_RM,-4)}, //mov.l @+, - {0 ,i1000_0000_mmmm_iiii ,Mask_imm8 ,0x8000 ,Normal ,"mov.b R0,@(,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RM_D4_x1,PRM_R0,1)}, // mov.b R0,@(,) - {0 ,i1000_0001_mmmm_iiii ,Mask_imm8 ,0x8100 ,Normal ,"mov.w R0,@(,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RM_D4_x2,PRM_R0,2)}, // mov.w R0,@(,) - {0 ,i1000_0100_mmmm_iiii ,Mask_imm8 ,0x8400 ,Normal ,"mov.b @(,),R0" ,1,2,LS,fix_none ,dec_MRd(PRM_R0,PRM_RM_D4_x1,1)}, // mov.b @(,),R0 - {0 ,i1000_0101_mmmm_iiii ,Mask_imm8 ,0x8500 ,Normal ,"mov.w @(,),R0" ,1,2,LS,fix_none ,dec_MRd(PRM_R0,PRM_RM_D4_x2,2)}, // mov.w @(,),R0 - {0 ,i1001_nnnn_iiii_iiii ,Mask_n_imm8 ,0x9000 ,ReadsPC ,"mov.w @()," ,1,2,LS,fix_none ,dec_MRd(PRM_RN,PRM_PC_D8_x2,2)}, // mov.w @(,PC), - {0 ,i1100_0000_iiii_iiii ,Mask_imm8 ,0xC000 ,Normal ,"mov.b R0,@(,GBR)" ,1,1,LS,fix_none ,dec_MWt(PRM_GBR_D8_x1,PRM_R0,1)}, // mov.b R0,@(,GBR) - {0 ,i1100_0001_iiii_iiii ,Mask_imm8 ,0xC100 ,Normal ,"mov.w R0,@(,GBR)" ,1,1,LS,fix_none ,dec_MWt(PRM_GBR_D8_x2,PRM_R0,2)}, // mov.w R0,@(,GBR) - {0 ,i1100_0010_iiii_iiii ,Mask_imm8 ,0xC200 ,Normal ,"mov.l R0,@(,GBR)" ,1,1,LS,fix_none ,dec_MWt(PRM_GBR_D8_x4,PRM_R0,4)}, // mov.l R0,@(,GBR) - {0 ,i1100_0100_iiii_iiii ,Mask_imm8 ,0xC400 ,Normal ,"mov.b @(),R0" ,1,2,LS,fix_none ,dec_MRd(PRM_R0,PRM_GBR_D8_x1,1)}, // mov.b @(,GBR),R0 - {0 ,i1100_0101_iiii_iiii ,Mask_imm8 ,0xC500 ,Normal ,"mov.w @(),R0" ,1,2,LS,fix_none ,dec_MRd(PRM_R0,PRM_GBR_D8_x2,2)}, // mov.w @(,GBR),R0 - {0 ,i1100_0110_iiii_iiii ,Mask_imm8 ,0xC600 ,Normal ,"mov.l @(),R0" ,1,2,LS,fix_none ,dec_MRd(PRM_R0,PRM_GBR_D8_x4,4)}, // mov.l @(,GBR),R0 - {0 ,i1101_nnnn_iiii_iiii ,Mask_n_imm8 ,0xD000 ,ReadsPC ,"mov.l @()," ,1,2,CO,fix_none ,dec_MRd(PRM_RN,PRM_PC_D8_x4,4)}, // mov.l @(,PC), + {0 ,i1000_0000_mmmm_iiii ,Mask_imm8 ,0x8000 ,Normal ,"mov.b R0,@(,)" ,1,1,LS,2 ,dec_MWt(PRM_RM_D4_x1,PRM_R0,1)}, // mov.b R0,@(,) + {0 ,i1000_0001_mmmm_iiii ,Mask_imm8 ,0x8100 ,Normal ,"mov.w R0,@(,)" ,1,1,LS,2 ,dec_MWt(PRM_RM_D4_x2,PRM_R0,2)}, // mov.w R0,@(,) + {0 ,i1000_0100_mmmm_iiii ,Mask_imm8 ,0x8400 ,Normal ,"mov.b @(,),R0" ,1,2,LS,2 ,dec_MRd(PRM_R0,PRM_RM_D4_x1,1)}, // mov.b @(,),R0 + {0 ,i1000_0101_mmmm_iiii ,Mask_imm8 ,0x8500 ,Normal ,"mov.w @(,),R0" ,1,2,LS,2 ,dec_MRd(PRM_R0,PRM_RM_D4_x2,2)}, // mov.w @(,),R0 + {0 ,i1001_nnnn_iiii_iiii ,Mask_n_imm8 ,0x9000 ,ReadsPC ,"mov.w @()," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_PC_D8_x2,2)}, // mov.w @(,PC), + {0 ,i1100_0000_iiii_iiii ,Mask_imm8 ,0xC000 ,Normal ,"mov.b R0,@(,GBR)" ,1,1,LS,3 ,dec_MWt(PRM_GBR_D8_x1,PRM_R0,1)}, // mov.b R0,@(,GBR) + {0 ,i1100_0001_iiii_iiii ,Mask_imm8 ,0xC100 ,Normal ,"mov.w R0,@(,GBR)" ,1,1,LS,3 ,dec_MWt(PRM_GBR_D8_x2,PRM_R0,2)}, // mov.w R0,@(,GBR) + {0 ,i1100_0010_iiii_iiii ,Mask_imm8 ,0xC200 ,Normal ,"mov.l R0,@(,GBR)" ,1,1,LS,3 ,dec_MWt(PRM_GBR_D8_x4,PRM_R0,4)}, // mov.l R0,@(,GBR) + {0 ,i1100_0100_iiii_iiii ,Mask_imm8 ,0xC400 ,Normal ,"mov.b @(),R0" ,1,2,LS,3 ,dec_MRd(PRM_R0,PRM_GBR_D8_x1,1)}, // mov.b @(,GBR),R0 + {0 ,i1100_0101_iiii_iiii ,Mask_imm8 ,0xC500 ,Normal ,"mov.w @(),R0" ,1,2,LS,3 ,dec_MRd(PRM_R0,PRM_GBR_D8_x2,2)}, // mov.w @(,GBR),R0 + {0 ,i1100_0110_iiii_iiii ,Mask_imm8 ,0xC600 ,Normal ,"mov.l @(),R0" ,1,2,LS,3 ,dec_MRd(PRM_R0,PRM_GBR_D8_x4,4)}, // mov.l @(,GBR),R0 + {0 ,i1101_nnnn_iiii_iiii ,Mask_n_imm8 ,0xD000 ,ReadsPC ,"mov.l @()," ,1,2,LS,2 ,dec_MRd(PRM_RN,PRM_PC_D8_x4,4)}, // mov.l @(,PC), //normal mov - {0 ,i0110_nnnn_mmmm_0011 ,Mask_n_m ,0x6003 ,Normal ,"mov ," ,1,0,MT,fix_none ,dec_Un_rNrM(shop_mov32)}, //mov , - {0 ,i1100_0111_iiii_iiii ,Mask_imm8 ,0xC700 ,ReadsPC ,"mova @(),R0" ,1,1,EX,fix_none ,dec_Fill(DM_UnaryOp,PRM_R0,PRM_PC_D8_x4,shop_mov32)}, // mova @(,PC),R0 - {0 ,i1110_nnnn_iiii_iiii ,Mask_n_imm8 ,0xE000 ,Normal ,"mov #," ,1,1,EX,fix_none ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_SIMM8,shop_mov32)}, // mov #, + {0 ,i0110_nnnn_mmmm_0011 ,Mask_n_m ,0x6003 ,Normal ,"mov ," ,1,0,MT,1 ,dec_Un_rNrM(shop_mov32)}, //mov , + {0 ,i1100_0111_iiii_iiii ,Mask_imm8 ,0xC700 ,ReadsPC ,"mova @(),R0" ,1,1,EX,1 ,dec_Fill(DM_UnaryOp,PRM_R0,PRM_PC_D8_x4,shop_mov32)}, // mova @(,PC),R0 + {0 ,i1110_nnnn_iiii_iiii ,Mask_n_imm8 ,0xE000 ,Normal ,"mov #," ,1,1,EX,1 ,dec_Fill(DM_UnaryOp,PRM_RN,PRM_SIMM8,shop_mov32)}, // mov #, //Special register readm/writem/movs //sts : @-rn - {0 ,i0100_nnnn_0101_0010 ,Mask_n ,0x4052 ,UsesFPU ,"sts.l FPUL,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l FPUL,@- - {0 ,i0100_nnnn_0110_0010 ,Mask_n ,0x4062 ,UsesFPU ,"sts.l FPSCR,@-" ,1,2,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l FPSCR,@- - {0 ,i0100_nnnn_0000_0010 ,Mask_n ,0x4002 ,Normal ,"sts.l MACH,@-" ,1,3,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l MACH,@- - {0 ,i0100_nnnn_0001_0010 ,Mask_n ,0x4012 ,Normal ,"sts.l MACL,@-" ,1,3,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l MACL,@- - {0 ,i0100_nnnn_0010_0010 ,Mask_n ,0x4022 ,Normal ,"sts.l PR,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l PR,@- - {0 ,i0100_nnnn_1111_0010 ,Mask_n ,0x40F2 ,Normal ,"stc.l DBR,@-" ,2,2,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l DBR,@- - {0 ,i0100_nnnn_0011_0010 ,Mask_n ,0x4032 ,Normal ,"stc.l SGR,@-" ,3,3,CO,rn_4 ,dec_STM(PRM_SREG)}, //sts.l SGR,@- + {0 ,i0100_nnnn_0101_0010 ,Mask_n ,0x4052 ,UsesFPU ,"sts.l FPUL,@-" ,1,1,CO,2 ,dec_STM(PRM_SREG)}, //sts.l FPUL,@- + {0 ,i0100_nnnn_0110_0010 ,Mask_n ,0x4062 ,UsesFPU ,"sts.l FPSCR,@-" ,1,1,CO,2 ,dec_STM(PRM_SREG)}, //sts.l FPSCR,@- + {0 ,i0100_nnnn_0000_0010 ,Mask_n ,0x4002 ,Normal ,"sts.l MACH,@-" ,1,1,CO,31 ,dec_STM(PRM_SREG)}, //sts.l MACH,@- + {0 ,i0100_nnnn_0001_0010 ,Mask_n ,0x4012 ,Normal ,"sts.l MACL,@-" ,1,1,CO,31 ,dec_STM(PRM_SREG)}, //sts.l MACL,@- + {0 ,i0100_nnnn_0010_0010 ,Mask_n ,0x4022 ,Normal ,"sts.l PR,@-" ,2,2,CO,27 ,dec_STM(PRM_SREG)}, //sts.l PR,@- + {0 ,i0100_nnnn_1111_0010 ,Mask_n ,0x40F2 ,Normal ,"stc.l DBR,@-" ,2,2,CO,22 ,dec_STM(PRM_SREG)}, //sts.l DBR,@- + {0 ,i0100_nnnn_0011_0010 ,Mask_n ,0x4032 ,Normal ,"stc.l SGR,@-" ,3,3,CO,23 ,dec_STM(PRM_SREG)}, //sts.l SGR,@- //stc : @-rn - {dec_i0100_nnnn_0000_0011 ,i0100_nnnn_0000_0011 ,Mask_n ,0x4003 ,Normal ,"stc.l SR,@-" ,1,1,CO,rn_4}, //stc.l SR,@- - {0 ,i0100_nnnn_0001_0011 ,Mask_n ,0x4013 ,Normal ,"stc.l GBR,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l GBR,@- - {0 ,i0100_nnnn_0010_0011 ,Mask_n ,0x4023 ,Normal ,"stc.l VBR,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l VBR,@- - {0 ,i0100_nnnn_0011_0011 ,Mask_n ,0x4033 ,Normal ,"stc.l SSR,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l SSR,@- - {0 ,i0100_nnnn_0100_0011 ,Mask_n ,0x4043 ,Normal ,"stc.l SPC,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc.l SPC,@- - {0 ,i0100_nnnn_1mmm_0011 ,Mask_n_ml3bit ,0x4083,Normal ,"stc ,@-" ,1,1,CO,rn_4 ,dec_STM(PRM_CREG)}, //stc RM_BANK,@- + {dec_i0100_nnnn_0000_0011 ,i0100_nnnn_0000_0011 ,Mask_n ,0x4003 ,Normal ,"stc.l SR,@-" ,2,2,CO,22}, //stc.l SR,@- + {0 ,i0100_nnnn_0001_0011 ,Mask_n ,0x4013 ,Normal ,"stc.l GBR,@-" ,2,2,CO,22 ,dec_STM(PRM_CREG)}, //stc.l GBR,@- + {0 ,i0100_nnnn_0010_0011 ,Mask_n ,0x4023 ,Normal ,"stc.l VBR,@-" ,2,2,CO,22 ,dec_STM(PRM_CREG)}, //stc.l VBR,@- + {0 ,i0100_nnnn_0011_0011 ,Mask_n ,0x4033 ,Normal ,"stc.l SSR,@-" ,2,2,CO,22 ,dec_STM(PRM_CREG)}, //stc.l SSR,@- + {0 ,i0100_nnnn_0100_0011 ,Mask_n ,0x4043 ,Normal ,"stc.l SPC,@-" ,2,2,CO,22 ,dec_STM(PRM_CREG)}, //stc.l SPC,@- + {0 ,i0100_nnnn_1mmm_0011 ,Mask_n_ml3bit ,0x4083,Normal ,"stc ,@-" ,2,2,CO,22 ,dec_STM(PRM_CREG)}, //stc RM_BANK,@- //lds : @rn+ - {0 ,i0100_nnnn_0000_0110 ,Mask_n ,0x4006 ,Normal ,"lds.l @+,MACH" ,1,1,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,MACH - {0 ,i0100_nnnn_0001_0110 ,Mask_n ,0x4016 ,Normal ,"lds.l @+,MAC" ,1,1,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,MACL - {0 ,i0100_nnnn_0010_0110 ,Mask_n ,0x4026 ,Normal ,"lds.l @+,PR" ,1,2,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,PR - {0 ,i0100_nnnn_0011_0110 ,Mask_n ,0x4036 ,Normal ,"ldc.l @+,SGR" ,3,3,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,SGR - {0 ,i0100_nnnn_0101_0110 ,Mask_n ,0x4056 ,UsesFPU ,"lds.l @+,FPUL" ,1,1,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,FPUL - {dec_i0100_nnnn_0110_0110 ,i0100_nnnn_0110_0110 ,Mask_n ,0x4066 ,FWritesFPSCR ,"lds.l @+,FPSCR" ,1,1,CO,fix_none}, //lds.l @+,FPSCR - {0 ,i0100_nnnn_1111_0110 ,Mask_n ,0x40F6 ,Normal ,"ldc.l @+,DBR" ,1,3,CO,fix_none ,dec_LDM(PRM_SREG)}, //lds.l @+,DBR + {0 ,i0100_nnnn_0000_0110 ,Mask_n ,0x4006 ,Normal ,"lds.l @+,MACH" ,1,3,CO,29 ,dec_LDM(PRM_SREG)}, //lds.l @+,MACH + {0 ,i0100_nnnn_0001_0110 ,Mask_n ,0x4016 ,Normal ,"lds.l @+,MAC" ,1,3,CO,29 ,dec_LDM(PRM_SREG)}, //lds.l @+,MACL + {0 ,i0100_nnnn_0010_0110 ,Mask_n ,0x4026 ,Normal ,"lds.l @+,PR" ,2,3,CO,25 ,dec_LDM(PRM_SREG)}, //lds.l @+,PR + {0 ,i0100_nnnn_0011_0110 ,Mask_n ,0x4036 ,Normal ,"ldc.l @+,SGR" ,3,3,CO,18 ,dec_LDM(PRM_SREG)}, //lds.l @+,SGR + {0 ,i0100_nnnn_0101_0110 ,Mask_n ,0x4056 ,UsesFPU ,"lds.l @+,FPUL" ,1,2,CO,2 ,dec_LDM(PRM_SREG)}, //lds.l @+,FPUL + {dec_i0100_nnnn_0110_0110 ,i0100_nnnn_0110_0110 ,Mask_n ,0x4066 ,FWritesFPSCR ,"lds.l @+,FPSCR" ,1,4,CO,33}, //lds.l @+,FPSCR + {0 ,i0100_nnnn_1111_0110 ,Mask_n ,0x40F6 ,Normal ,"ldc.l @+,DBR" ,1,3,CO,17 ,dec_LDM(PRM_SREG)}, //lds.l @+,DBR //ldc : @rn+ - {dec_i0100_nnnn_0000_0111 ,i0100_nnnn_0000_0111 ,Mask_n ,0x4007 ,WritesSRRWPC ,"ldc.l @+,SR" ,1,1,CO,fix_none}, //ldc.l @+,SR - {0 ,i0100_nnnn_0001_0111 ,Mask_n ,0x4017 ,Normal ,"ldc.l @+,GBR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @+,GBR - {0 ,i0100_nnnn_0010_0111 ,Mask_n ,0x4027 ,Normal ,"ldc.l @+,VBR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @+,VBR - {0 ,i0100_nnnn_0011_0111 ,Mask_n ,0x4037 ,Normal ,"ldc.l @+,SSR" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @+,SSR - {0 ,i0100_nnnn_0100_0111 ,Mask_n ,0x4047 ,Normal ,"ldc.l @+,SPC" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @+,SPC - {0 ,i0100_nnnn_1mmm_0111 ,Mask_n_ml3bit ,0x4087 ,Normal ,"ldc.l @+,RM_BANK" ,1,1,CO,fix_none ,dec_LDM(PRM_CREG)}, //ldc.l @+,RM_BANK + {dec_i0100_nnnn_0000_0111 ,i0100_nnnn_0000_0111 ,Mask_n ,0x4007 ,WritesSRRWPC ,"ldc.l @+,SR" ,4,4,CO,19}, //ldc.l @+,SR + {0 ,i0100_nnnn_0001_0111 ,Mask_n ,0x4017 ,Normal ,"ldc.l @+,GBR" ,3,3,CO,18 ,dec_LDM(PRM_CREG)}, //ldc.l @+,GBR + {0 ,i0100_nnnn_0010_0111 ,Mask_n ,0x4027 ,Normal ,"ldc.l @+,VBR" ,1,3,CO,17 ,dec_LDM(PRM_CREG)}, //ldc.l @+,VBR + {0 ,i0100_nnnn_0011_0111 ,Mask_n ,0x4037 ,Normal ,"ldc.l @+,SSR" ,1,3,CO,17 ,dec_LDM(PRM_CREG)}, //ldc.l @+,SSR + {0 ,i0100_nnnn_0100_0111 ,Mask_n ,0x4047 ,Normal ,"ldc.l @+,SPC" ,1,3,CO,17 ,dec_LDM(PRM_CREG)}, //ldc.l @+,SPC + {0 ,i0100_nnnn_1mmm_0111 ,Mask_n_ml3bit ,0x4087 ,Normal ,"ldc.l @+,RM_BANK" ,1,3,CO,17 ,dec_LDM(PRM_CREG)}, //ldc.l @+,RM_BANK //sts : rn - {0 ,i0000_nnnn_0000_0010 ,Mask_n ,0x0002 ,Normal ,"stc SR," ,2,2,CO,fix_none ,dec_STSRF(PRM_CREG)}, //stc SR, - {0 ,i0000_nnnn_0001_0010 ,Mask_n ,0x0012 ,Normal ,"stc GBR," ,2,2,CO,fix_none ,dec_ST(PRM_CREG)}, //stc GBR, - {0 ,i0000_nnnn_0010_0010 ,Mask_n ,0x0022 ,Normal ,"stc VBR," ,2,2,CO,fix_none ,dec_ST(PRM_CREG)}, //stc VBR, - {0 ,i0000_nnnn_0011_0010 ,Mask_n ,0x0032 ,Normal ,"stc SSR," ,2,2,CO,fix_none ,dec_ST(PRM_CREG)}, //stc SSR, - {0 ,i0000_nnnn_0100_0010 ,Mask_n ,0x0042 ,Normal ,"stc SPC," ,2,2,CO,fix_none ,dec_ST(PRM_CREG)}, //stc SPC, - {0 ,i0000_nnnn_1mmm_0010 ,Mask_n_ml3bit ,0x0082 ,Normal ,"stc RM_BANK," ,2,2,CO,fix_none ,dec_ST(PRM_CREG)}, //stc RM_BANK, + {0 ,i0000_nnnn_0000_0010 ,Mask_n ,0x0002 ,Normal ,"stc SR," ,2,2,CO,20 ,dec_STSRF(PRM_CREG)}, //stc SR, + {0 ,i0000_nnnn_0001_0010 ,Mask_n ,0x0012 ,Normal ,"stc GBR," ,2,2,CO,20 ,dec_ST(PRM_CREG)}, //stc GBR, + {0 ,i0000_nnnn_0010_0010 ,Mask_n ,0x0022 ,Normal ,"stc VBR," ,2,2,CO,20 ,dec_ST(PRM_CREG)}, //stc VBR, + {0 ,i0000_nnnn_0011_0010 ,Mask_n ,0x0032 ,Normal ,"stc SSR," ,2,2,CO,20 ,dec_ST(PRM_CREG)}, //stc SSR, + {0 ,i0000_nnnn_0100_0010 ,Mask_n ,0x0042 ,Normal ,"stc SPC," ,2,2,CO,20 ,dec_ST(PRM_CREG)}, //stc SPC, + {0 ,i0000_nnnn_1mmm_0010 ,Mask_n_ml3bit ,0x0082 ,Normal ,"stc RM_BANK," ,2,2,CO,20 ,dec_ST(PRM_CREG)}, //stc RM_BANK, //stc : rn - {0 ,i0000_nnnn_0000_1010 ,Mask_n ,0x000A ,Normal ,"sts MACH," ,1,3,CO,fix_none ,dec_ST(PRM_SREG)}, //sts MACH, - {0 ,i0000_nnnn_0001_1010 ,Mask_n ,0x001A ,Normal ,"sts MACL," ,1,3,CO,fix_none ,dec_ST(PRM_SREG)}, //sts MACL, - {0 ,i0000_nnnn_0010_1010 ,Mask_n ,0x002A ,Normal ,"sts PR," ,2,2,CO,fix_none ,dec_ST(PRM_SREG)}, //sts PR, - {0 ,i0000_nnnn_0011_1010 ,Mask_n ,0x003A ,Normal ,"sts SGR," ,3,3,CO,fix_none ,dec_ST(PRM_SREG)}, //sts SGR, - {0 ,i0000_nnnn_0101_1010 ,Mask_n ,0x005A ,UsesFPU ,"sts FPUL," ,1,3,LS,fix_none ,dec_ST(PRM_SREG)}, //sts FPUL, - {0 ,i0000_nnnn_0110_1010 ,Mask_n ,0x006A ,UsesFPU ,"sts FPSCR," ,1,3,CO,fix_none ,dec_ST(PRM_SREG)}, //sts FPSCR, - {0 ,i0000_nnnn_1111_1010 ,Mask_n ,0x00FA ,Normal ,"sts DBR," ,1,2,CO,fix_none ,dec_ST(PRM_SREG)}, //sts DBR, + {0 ,i0000_nnnn_0000_1010 ,Mask_n ,0x000A ,Normal ,"sts MACH," ,1,3,CO,30 ,dec_ST(PRM_SREG)}, //sts MACH, + {0 ,i0000_nnnn_0001_1010 ,Mask_n ,0x001A ,Normal ,"sts MACL," ,1,3,CO,30 ,dec_ST(PRM_SREG)}, //sts MACL, + {0 ,i0000_nnnn_0010_1010 ,Mask_n ,0x002A ,Normal ,"sts PR," ,2,2,CO,26 ,dec_ST(PRM_SREG)}, //sts PR, + {0 ,i0000_nnnn_0011_1010 ,Mask_n ,0x003A ,Normal ,"sts SGR," ,3,3,CO,21 ,dec_ST(PRM_SREG)}, //sts SGR, + {0 ,i0000_nnnn_0101_1010 ,Mask_n ,0x005A ,UsesFPU ,"sts FPUL," ,1,3,LS,1 ,dec_ST(PRM_SREG)}, //sts FPUL, + {0 ,i0000_nnnn_0110_1010 ,Mask_n ,0x006A ,UsesFPU ,"sts FPSCR," ,1,3,CO,1 ,dec_ST(PRM_SREG)}, //sts FPSCR, + {0 ,i0000_nnnn_1111_1010 ,Mask_n ,0x00FA ,Normal ,"sts DBR," ,2,2,CO,20 ,dec_ST(PRM_SREG)}, //sts DBR, //lds : rn - {0 ,i0100_nnnn_0000_1010 ,Mask_n ,0x400A ,Normal ,"lds ,MACH" ,1,3,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,MACH - {0 ,i0100_nnnn_0001_1010 ,Mask_n ,0x401A ,Normal ,"lds ,MAC" ,1,3,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,MACL - {0 ,i0100_nnnn_0010_1010 ,Mask_n ,0x402A ,Normal ,"lds ,PR" ,1,2,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,PR - {0 ,i0100_nnnn_0011_1010 ,Mask_n ,0x403A ,Normal ,"ldc ,SGR" ,3,3,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,SGR - {0 ,i0100_nnnn_0101_1010 ,Mask_n ,0x405A ,UsesFPU ,"lds ,FPUL" ,1,1,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,FPUL - {dec_i0100_nnnn_0110_1010 ,i0100_nnnn_0110_1010 ,Mask_n ,0x406A ,FWritesFPSCR ,"lds ,FPSCR" ,1,1,CO,fix_none}, //lds ,FPSCR - {0 ,i0100_nnnn_1111_1010 ,Mask_n ,0x40FA ,Normal ,"ldc ,DBR" ,1,1,CO,fix_none ,dec_LD(PRM_SREG)}, //lds ,DBR + {0 ,i0100_nnnn_0000_1010 ,Mask_n ,0x400A ,Normal ,"lds ,MACH" ,1,3,CO,28 ,dec_LD(PRM_SREG)}, //lds ,MACH + {0 ,i0100_nnnn_0001_1010 ,Mask_n ,0x401A ,Normal ,"lds ,MAC" ,1,3,CO,28 ,dec_LD(PRM_SREG)}, //lds ,MACL + {0 ,i0100_nnnn_0010_1010 ,Mask_n ,0x402A ,Normal ,"lds ,PR" ,2,3,CO,24 ,dec_LD(PRM_SREG)}, //lds ,PR + {0 ,i0100_nnnn_0011_1010 ,Mask_n ,0x403A ,Normal ,"ldc ,SGR" ,3,3,CO,15 ,dec_LD(PRM_SREG)}, //lds ,SGR + {0 ,i0100_nnnn_0101_1010 ,Mask_n ,0x405A ,UsesFPU ,"lds ,FPUL" ,1,1,LS,1 ,dec_LD(PRM_SREG)}, //lds ,FPUL + {dec_i0100_nnnn_0110_1010 ,i0100_nnnn_0110_1010 ,Mask_n ,0x406A ,FWritesFPSCR ,"lds ,FPSCR" ,1,4,CO,32}, //lds ,FPSCR + {0 ,i0100_nnnn_1111_1010 ,Mask_n ,0x40FA ,Normal ,"ldc ,DBR" ,1,3,CO,14 ,dec_LD(PRM_SREG)}, //lds ,DBR //ldc : rn - {dec_i0100_nnnn_0000_1110 ,i0100_nnnn_0000_1110 ,Mask_n ,0x400E ,WritesSRRWPC ,"ldc ,SR" ,1,1,CO,fix_none}, //ldc ,SR - {0 ,i0100_nnnn_0001_1110 ,Mask_n ,0x401E ,Normal ,"ldc ,GBR" ,1,1,CO,fix_none ,dec_LD(PRM_CREG)}, //ldc ,GBR - {0 ,i0100_nnnn_0010_1110 ,Mask_n ,0x402E ,Normal ,"ldc ,VBR" ,1,1,CO,fix_none ,dec_LD(PRM_CREG)}, //ldc ,VBR - {0 ,i0100_nnnn_0011_1110 ,Mask_n ,0x403E ,Normal ,"ldc ,SSR" ,1,1,CO,fix_none ,dec_LD(PRM_CREG)}, //ldc ,SSR - {0 ,i0100_nnnn_0100_1110 ,Mask_n ,0x404E ,Normal ,"ldc ,SPC" ,1,1,CO,fix_none ,dec_LD(PRM_CREG)}, //ldc ,SPC - {0 ,i0100_nnnn_1mmm_1110 ,Mask_n_ml3bit ,0x408E ,Normal ,"ldc ," ,1,1,CO,fix_none ,dec_LD(PRM_CREG)}, //ldc , + {dec_i0100_nnnn_0000_1110 ,i0100_nnnn_0000_1110 ,Mask_n ,0x400E ,WritesSRRWPC ,"ldc ,SR" ,4,4,CO,16}, //ldc ,SR + {0 ,i0100_nnnn_0001_1110 ,Mask_n ,0x401E ,Normal ,"ldc ,GBR" ,3,3,CO,15 ,dec_LD(PRM_CREG)}, //ldc ,GBR + {0 ,i0100_nnnn_0010_1110 ,Mask_n ,0x402E ,Normal ,"ldc ,VBR" ,1,3,CO,14 ,dec_LD(PRM_CREG)}, //ldc ,VBR + {0 ,i0100_nnnn_0011_1110 ,Mask_n ,0x403E ,Normal ,"ldc ,SSR" ,1,3,CO,14 ,dec_LD(PRM_CREG)}, //ldc ,SSR + {0 ,i0100_nnnn_0100_1110 ,Mask_n ,0x404E ,Normal ,"ldc ,SPC" ,1,3,CO,14 ,dec_LD(PRM_CREG)}, //ldc ,SPC + {0 ,i0100_nnnn_1mmm_1110 ,Mask_n_ml3bit ,0x408E ,Normal ,"ldc ," ,1,3,CO,14 ,dec_LD(PRM_CREG)}, //ldc , // - {0 ,i0100_nnnn_0000_0000 ,Mask_n ,0x4000 ,Normal ,"shll " ,1,1,EX,fix_none ,dec_shft(1,false)}, //shll - {0 ,i0100_nnnn_0001_0000 ,Mask_n ,0x4010 ,Normal ,"dt " ,1,1,EX,fix_none ,dec_Fill(DM_DT,PRM_RN,PRM_ONE,shop_sub)}, //dt - {0 ,i0100_nnnn_0010_0000 ,Mask_n ,0x4020 ,Normal ,"shal " ,1,1,EX,fix_none ,dec_shft(1,true)}, //shal - {0 ,i0100_nnnn_0000_0001 ,Mask_n ,0x4001 ,Normal ,"shlr " ,1,1,EX,fix_none ,dec_shft(-1,false)}, //shlr - {0 ,i0100_nnnn_0001_0001 ,Mask_n ,0x4011 ,Normal ,"cmp/pz " ,1,1,MT,fix_none ,dec_cmp(shop_setge,PRM_RN,PRM_ZERO)}, //cmp/pz - {0 ,i0100_nnnn_0010_0001 ,Mask_n ,0x4021 ,Normal ,"shar " ,1,1,EX,fix_none ,dec_shft(-1,true)}, //shar - {dec_i0100_nnnn_0010_0100 ,i0100_nnnn_0010_0100 ,Mask_n ,0x4024 ,Normal ,"rotcl " ,1,1,EX,fix_none}, //rotcl - {0 ,i0100_nnnn_0000_0100 ,Mask_n ,0x4004 ,Normal ,"rotl " ,1,1,EX,fix_none ,dec_Fill(DM_Rot,PRM_RN,PRM_RN,shop_ror,-31)}, //rotl - {0 ,i0100_nnnn_0001_0101 ,Mask_n ,0x4015 ,Normal ,"cmp/pl " ,1,1,MT,fix_none ,dec_cmp(shop_setgt,PRM_RN,PRM_ZERO)}, //cmp/pl - {dec_i0100_nnnn_0010_0101 ,i0100_nnnn_0010_0101 ,Mask_n ,0x4025 ,Normal ,"rotcr " ,1,1,EX,fix_none}, //rotcr - {0 ,i0100_nnnn_0000_0101 ,Mask_n ,0x4005 ,Normal ,"rotr " ,1,1,EX,fix_none ,dec_Fill(DM_Rot,PRM_RN,PRM_RN,shop_ror,1)}, //rotr - {0 ,i0100_nnnn_0000_1000 ,Mask_n ,0x4008 ,Normal ,"shll2 " ,1,1,EX,fix_none ,dec_shft(2,false)}, //shll2 - {0 ,i0100_nnnn_0001_1000 ,Mask_n ,0x4018 ,Normal ,"shll8 " ,1,1,EX,fix_none ,dec_shft(8,false)}, //shll8 - {0 ,i0100_nnnn_0010_1000 ,Mask_n ,0x4028 ,Normal ,"shll16 " ,1,1,EX,fix_none ,dec_shft(16,false)}, //shll16 - {0 ,i0100_nnnn_0000_1001 ,Mask_n ,0x4009 ,Normal ,"shlr2 " ,1,1,EX,fix_none ,dec_shft(-2,false)}, //shlr2 - {0 ,i0100_nnnn_0001_1001 ,Mask_n ,0x4019 ,Normal ,"shlr8 " ,1,1,EX,fix_none ,dec_shft(-8,false)}, //shlr8 - {0 ,i0100_nnnn_0010_1001 ,Mask_n ,0x4029 ,Normal ,"shlr16 " ,1,1,EX,fix_none ,dec_shft(-16,false)}, //shlr16 - {dec_i0100_nnnn_0010_1011 ,i0100_nnnn_0010_1011 ,Mask_n ,0x402B ,Branch_dir_d ,"jmp @" ,2,3,CO,fix_none}, //jmp @ - {dec_i0100_nnnn_0000_1011 ,i0100_nnnn_0000_1011 ,Mask_n ,0x400B ,Branch_dir_d ,"jsr @" ,2,3,CO,fix_none}, //jsr @ - {dec_i0100_nnnn_0001_1011 ,i0100_nnnn_0001_1011 ,Mask_n ,0x401B ,Normal ,"tas.b @" ,5,5,CO,fix_none}, //tas.b @ - {0 ,i0100_nnnn_mmmm_1100 ,Mask_n_m ,0x400C ,Normal ,"shad ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_shad)}, //shad , - {0 ,i0100_nnnn_mmmm_1101 ,Mask_n_m ,0x400D ,Normal ,"shld ," ,1,1,EX,fix_none ,dec_Bin_rNrM(shop_shld)}, //shld , - {0 ,i0100_nnnn_mmmm_1111 ,Mask_n_m ,0x400F ,Normal ,"mac.w @+,@+" ,2,3,CO,fix_none}, //mac.w @+,@+ - {0 ,i0110_nnnn_mmmm_0111 ,Mask_n_m ,0x6007 ,Normal ,"not ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_not)}, //not , - {0 ,i0110_nnnn_mmmm_1000 ,Mask_n_m ,0x6008 ,Normal ,"swap.b ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_swaplb)}, //swap.b , - {0 ,i0110_nnnn_mmmm_1001 ,Mask_n_m ,0x6009 ,Normal ,"swap.w ," ,1,1,EX,fix_none ,dec_Fill(DM_Rot,PRM_RN,PRM_RM,shop_ror,16|0x1000)}, //swap.w , - {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,fix_none ,dec_Fill(DM_NEGC,PRM_RN,PRM_RM,shop_negc)}, //negc , - {0 ,i0110_nnnn_mmmm_1011 ,Mask_n_m ,0x600B ,Normal ,"neg ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_neg)}, //neg , - {0 ,i0110_nnnn_mmmm_1100 ,Mask_n_m ,0x600C ,Normal ,"extu.b ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,1)}, //extu.b , - {0 ,i0110_nnnn_mmmm_1101 ,Mask_n_m ,0x600D ,Normal ,"extu.w ," ,1,1,EX,fix_none ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,2)}, //extu.w , - {0 ,i0110_nnnn_mmmm_1110 ,Mask_n_m ,0x600E ,Normal ,"exts.b ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_ext_s8)}, //exts.b , - {0 ,i0110_nnnn_mmmm_1111 ,Mask_n_m ,0x600F ,Normal ,"exts.w ," ,1,1,EX,fix_none ,dec_Un_rNrM(shop_ext_s16)},//exts.w , - {0 ,i0111_nnnn_iiii_iiii ,Mask_n_imm8 ,0x7000 ,Normal ,"add #," ,1,1,EX,fix_none ,dec_Bin_S8R(shop_add)}, //add #, - {dec_i1000_1011_iiii_iiii ,i1000_1011_iiii_iiii ,Mask_imm8 ,0x8B00 ,Branch_rel ,"bf " ,1,1,BR,fix_none}, // bf - {dec_i1000_1111_iiii_iiii ,i1000_1111_iiii_iiii ,Mask_imm8 ,0x8F00 ,Branch_rel_d ,"bf.s " ,1,1,BR,fix_none}, // bf.s - {dec_i1000_1001_iiii_iiii ,i1000_1001_iiii_iiii ,Mask_imm8 ,0x8900 ,Branch_rel ,"bt " ,1,1,BR,fix_none}, // bt - {dec_i1000_1101_iiii_iiii ,i1000_1101_iiii_iiii ,Mask_imm8 ,0x8D00 ,Branch_rel_d ,"bt.s " ,1,1,BR,fix_none}, // bt.s - {0 ,i1000_1000_iiii_iiii ,Mask_imm8 ,0x8800 ,Normal ,"cmp/eq #,R0" ,1,1,MT,fix_none ,dec_cmp(shop_seteq,PRM_R0,PRM_SIMM8)}, // cmp/eq #,R0 - {dec_i1010_iiii_iiii_iiii ,i1010_iiii_iiii_iiii ,Mask_n_imm8 ,0xA000 ,Branch_rel_d ,"bra " ,1,2,BR,fix_none}, // bra - {dec_i1011_iiii_iiii_iiii ,i1011_iiii_iiii_iiii ,Mask_n_imm8 ,0xB000 ,Branch_rel_d ,"bsr " ,1,2,BR,fix_none}, // bsr + {0 ,i0100_nnnn_0000_0000 ,Mask_n ,0x4000 ,Normal ,"shll " ,1,1,EX,1 ,dec_shft(1,false)}, //shll + {0 ,i0100_nnnn_0001_0000 ,Mask_n ,0x4010 ,Normal ,"dt " ,1,1,EX,1 ,dec_Fill(DM_DT,PRM_RN,PRM_ONE,shop_sub)}, //dt + {0 ,i0100_nnnn_0010_0000 ,Mask_n ,0x4020 ,Normal ,"shal " ,1,1,EX,1 ,dec_shft(1,true)}, //shal + {0 ,i0100_nnnn_0000_0001 ,Mask_n ,0x4001 ,Normal ,"shlr " ,1,1,EX,1 ,dec_shft(-1,false)}, //shlr + {0 ,i0100_nnnn_0001_0001 ,Mask_n ,0x4011 ,Normal ,"cmp/pz " ,1,1,MT,1 ,dec_cmp(shop_setge,PRM_RN,PRM_ZERO)}, //cmp/pz + {0 ,i0100_nnnn_0010_0001 ,Mask_n ,0x4021 ,Normal ,"shar " ,1,1,EX,1 ,dec_shft(-1,true)}, //shar + {dec_i0100_nnnn_0010_0100 ,i0100_nnnn_0010_0100 ,Mask_n ,0x4024 ,Normal ,"rotcl " ,1,1,EX,1}, //rotcl + {0 ,i0100_nnnn_0000_0100 ,Mask_n ,0x4004 ,Normal ,"rotl " ,1,1,EX,1 ,dec_Fill(DM_Rot,PRM_RN,PRM_RN,shop_ror,-31)}, //rotl + {0 ,i0100_nnnn_0001_0101 ,Mask_n ,0x4015 ,Normal ,"cmp/pl " ,1,1,MT,1 ,dec_cmp(shop_setgt,PRM_RN,PRM_ZERO)}, //cmp/pl + {dec_i0100_nnnn_0010_0101 ,i0100_nnnn_0010_0101 ,Mask_n ,0x4025 ,Normal ,"rotcr " ,1,1,EX,1}, //rotcr + {0 ,i0100_nnnn_0000_0101 ,Mask_n ,0x4005 ,Normal ,"rotr " ,1,1,EX,1 ,dec_Fill(DM_Rot,PRM_RN,PRM_RN,shop_ror,1)}, //rotr + {0 ,i0100_nnnn_0000_1000 ,Mask_n ,0x4008 ,Normal ,"shll2 " ,1,1,EX,1 ,dec_shft(2,false)}, //shll2 + {0 ,i0100_nnnn_0001_1000 ,Mask_n ,0x4018 ,Normal ,"shll8 " ,1,1,EX,1 ,dec_shft(8,false)}, //shll8 + {0 ,i0100_nnnn_0010_1000 ,Mask_n ,0x4028 ,Normal ,"shll16 " ,1,1,EX,1 ,dec_shft(16,false)}, //shll16 + {0 ,i0100_nnnn_0000_1001 ,Mask_n ,0x4009 ,Normal ,"shlr2 " ,1,1,EX,1 ,dec_shft(-2,false)}, //shlr2 + {0 ,i0100_nnnn_0001_1001 ,Mask_n ,0x4019 ,Normal ,"shlr8 " ,1,1,EX,1 ,dec_shft(-8,false)}, //shlr8 + {0 ,i0100_nnnn_0010_1001 ,Mask_n ,0x4029 ,Normal ,"shlr16 " ,1,1,EX,1 ,dec_shft(-16,false)}, //shlr16 + {dec_i0100_nnnn_0010_1011 ,i0100_nnnn_0010_1011 ,Mask_n ,0x402B ,Branch_dir_d ,"jmp @" ,2,3,CO,4}, //jmp @ + {dec_i0100_nnnn_0000_1011 ,i0100_nnnn_0000_1011 ,Mask_n ,0x400B ,Branch_dir_d ,"jsr @" ,2,3,CO,24}, //jsr @ + {dec_i0100_nnnn_0001_1011 ,i0100_nnnn_0001_1011 ,Mask_n ,0x401B ,Normal ,"tas.b @" ,5,5,CO,7}, //tas.b @ + {0 ,i0100_nnnn_mmmm_1100 ,Mask_n_m ,0x400C ,Normal ,"shad ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_shad)}, //shad , + {0 ,i0100_nnnn_mmmm_1101 ,Mask_n_m ,0x400D ,Normal ,"shld ," ,1,1,EX,1 ,dec_Bin_rNrM(shop_shld)}, //shld , + {0 ,i0100_nnnn_mmmm_1111 ,Mask_n_m ,0x400F ,Normal ,"mac.w @+,@+" ,2,4,CO,35}, //mac.w @+,@+ + {0 ,i0110_nnnn_mmmm_0111 ,Mask_n_m ,0x6007 ,Normal ,"not ," ,1,1,EX,1 ,dec_Un_rNrM(shop_not)}, //not , + {0 ,i0110_nnnn_mmmm_1000 ,Mask_n_m ,0x6008 ,Normal ,"swap.b ," ,1,1,EX,1 ,dec_Un_rNrM(shop_swaplb)}, //swap.b , + {0 ,i0110_nnnn_mmmm_1001 ,Mask_n_m ,0x6009 ,Normal ,"swap.w ," ,1,1,EX,1 ,dec_Fill(DM_Rot,PRM_RN,PRM_RM,shop_ror,16|0x1000)}, //swap.w , + {0 ,i0110_nnnn_mmmm_1010 ,Mask_n_m ,0x600A ,Normal ,"negc ," ,1,1,EX,1 ,dec_Fill(DM_NEGC,PRM_RN,PRM_RM,shop_negc)}, //negc , + {0 ,i0110_nnnn_mmmm_1011 ,Mask_n_m ,0x600B ,Normal ,"neg ," ,1,1,EX,1 ,dec_Un_rNrM(shop_neg)}, //neg , + {0 ,i0110_nnnn_mmmm_1100 ,Mask_n_m ,0x600C ,Normal ,"extu.b ," ,1,1,EX,1 ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,1)}, //extu.b , + {0 ,i0110_nnnn_mmmm_1101 ,Mask_n_m ,0x600D ,Normal ,"extu.w ," ,1,1,EX,1 ,dec_Fill(DM_EXTOP,PRM_RN,PRM_RM,shop_and,2)}, //extu.w , + {0 ,i0110_nnnn_mmmm_1110 ,Mask_n_m ,0x600E ,Normal ,"exts.b ," ,1,1,EX,1 ,dec_Un_rNrM(shop_ext_s8)}, //exts.b , + {0 ,i0110_nnnn_mmmm_1111 ,Mask_n_m ,0x600F ,Normal ,"exts.w ," ,1,1,EX,1 ,dec_Un_rNrM(shop_ext_s16)},//exts.w , + {0 ,i0111_nnnn_iiii_iiii ,Mask_n_imm8 ,0x7000 ,Normal ,"add #," ,1,1,EX,1 ,dec_Bin_S8R(shop_add)}, //add #, + {dec_i1000_1011_iiii_iiii ,i1000_1011_iiii_iiii ,Mask_imm8 ,0x8B00 ,Branch_rel ,"bf " ,1,2,BR,1}, // bf + {dec_i1000_1111_iiii_iiii ,i1000_1111_iiii_iiii ,Mask_imm8 ,0x8F00 ,Branch_rel_d ,"bf.s " ,1,2,BR,1}, // bf.s + {dec_i1000_1001_iiii_iiii ,i1000_1001_iiii_iiii ,Mask_imm8 ,0x8900 ,Branch_rel ,"bt " ,1,2,BR,1}, // bt + {dec_i1000_1101_iiii_iiii ,i1000_1101_iiii_iiii ,Mask_imm8 ,0x8D00 ,Branch_rel_d ,"bt.s " ,1,2,BR,1}, // bt.s + {0 ,i1000_1000_iiii_iiii ,Mask_imm8 ,0x8800 ,Normal ,"cmp/eq #,R0" ,1,1,MT,1 ,dec_cmp(shop_seteq,PRM_R0,PRM_SIMM8)}, // cmp/eq #,R0 + {dec_i1010_iiii_iiii_iiii ,i1010_iiii_iiii_iiii ,Mask_n_imm8 ,0xA000 ,Branch_rel_d ,"bra " ,1,2,BR,1}, // bra + {dec_i1011_iiii_iiii_iiii ,i1011_iiii_iiii_iiii ,Mask_n_imm8 ,0xB000 ,Branch_rel_d ,"bsr " ,1,2,BR,14}, // bsr - {dec_i1100_0011_iiii_iiii ,i1100_0011_iiii_iiii ,Mask_imm8 ,0xC300 ,ReadWritePC ,"trapa #" ,7,7,CO,fix_none}, // trapa # + {dec_i1100_0011_iiii_iiii ,i1100_0011_iiii_iiii ,Mask_imm8 ,0xC300 ,ReadWritePC ,"trapa #" ,7,7,CO,13}, // trapa # - {0 ,i1100_1000_iiii_iiii ,Mask_imm8 ,0xC800 ,Normal ,"tst #,R0" ,1,1,MT,fix_none ,dec_cmp(shop_test,PRM_R0,PRM_UIMM8)}, // tst #,R0 - {0 ,i1100_1001_iiii_iiii ,Mask_imm8 ,0xC900 ,Normal ,"and #,R0" ,1,1,EX,fix_none ,dec_Bin_r0u8(shop_and)}, // and #,R0 - {0 ,i1100_1010_iiii_iiii ,Mask_imm8 ,0xCA00 ,Normal ,"xor #,R0" ,1,1,EX,fix_none ,dec_Bin_r0u8(shop_xor)}, // xor #,R0 - {0 ,i1100_1011_iiii_iiii ,Mask_imm8 ,0xCB00 ,Normal ,"or #,R0" ,1,1,EX,fix_none ,dec_Bin_r0u8(shop_or)}, // or #,R0 + {0 ,i1100_1000_iiii_iiii ,Mask_imm8 ,0xC800 ,Normal ,"tst #,R0" ,1,1,MT,1 ,dec_cmp(shop_test,PRM_R0,PRM_UIMM8)}, // tst #,R0 + {0 ,i1100_1001_iiii_iiii ,Mask_imm8 ,0xC900 ,Normal ,"and #,R0" ,1,1,EX,1 ,dec_Bin_r0u8(shop_and)}, // and #,R0 + {0 ,i1100_1010_iiii_iiii ,Mask_imm8 ,0xCA00 ,Normal ,"xor #,R0" ,1,1,EX,1 ,dec_Bin_r0u8(shop_xor)}, // xor #,R0 + {0 ,i1100_1011_iiii_iiii ,Mask_imm8 ,0xCB00 ,Normal ,"or #,R0" ,1,1,EX,1 ,dec_Bin_r0u8(shop_or)}, // or #,R0 - {0 ,i1100_1100_iiii_iiii ,Mask_imm8 ,0xCC00 ,Normal ,"tst.b #,@(R0,GBR)" ,3,3,CO,fix_none}, // tst.b #,@(R0,GBR) - {0 ,i1100_1101_iiii_iiii ,Mask_imm8 ,0xCD00 ,Normal ,"and.b #,@(R0,GBR)" ,4,4,CO,fix_none}, // and.b #,@(R0,GBR) - {0 ,i1100_1110_iiii_iiii ,Mask_imm8 ,0xCE00 ,Normal ,"xor.b #,@(R0,GBR)" ,4,4,CO,fix_none}, // xor.b #,@(R0,GBR) - {0 ,i1100_1111_iiii_iiii ,Mask_imm8 ,0xCF00 ,Normal ,"or.b #,@(R0,GBR)" ,4,4,CO,fix_none}, // or.b #,@(R0,GBR) + {0 ,i1100_1100_iiii_iiii ,Mask_imm8 ,0xCC00 ,Normal ,"tst.b #,@(R0,GBR)" ,3,3,CO,5}, // tst.b #,@(R0,GBR) + {0 ,i1100_1101_iiii_iiii ,Mask_imm8 ,0xCD00 ,Normal ,"and.b #,@(R0,GBR)" ,4,4,CO,6}, // and.b #,@(R0,GBR) + {0 ,i1100_1110_iiii_iiii ,Mask_imm8 ,0xCE00 ,Normal ,"xor.b #,@(R0,GBR)" ,4,4,CO,6}, // xor.b #,@(R0,GBR) + {0 ,i1100_1111_iiii_iiii ,Mask_imm8 ,0xCF00 ,Normal ,"or.b #,@(R0,GBR)" ,4,4,CO,6}, // or.b #,@(R0,GBR) //and here are the new ones :D - {0 ,i1111_nnnn_mmmm_0000 ,Mask_n_m ,0xF000,UsesFPU ,"fadd ," ,1,3,FE,fix_none ,dec_Bin_frNfrM(shop_fadd)}, //fadd , - {0 ,i1111_nnnn_mmmm_0001 ,Mask_n_m ,0xF001,UsesFPU ,"fsub ," ,1,3,FE,fix_none ,dec_Bin_frNfrM(shop_fsub)}, //fsub , - {0 ,i1111_nnnn_mmmm_0010 ,Mask_n_m ,0xF002,UsesFPU ,"fmul ," ,1,3,FE,fix_none ,dec_Bin_frNfrM(shop_fmul)}, //fmul , - {0 ,i1111_nnnn_mmmm_0011 ,Mask_n_m ,0xF003,UsesFPU ,"fdiv ," ,1,12,FE,fix_none ,dec_Bin_frNfrM(shop_fdiv)},//fdiv , - {0 ,i1111_nnnn_mmmm_0100 ,Mask_n_m ,0xF004,UsesFPU ,"fcmp/eq ," ,1,4,FE,fix_none ,dec_cmp(shop_fseteq,PRM_FRN,PRM_FRM)}, //fcmp/eq , - {0 ,i1111_nnnn_mmmm_0101 ,Mask_n_m ,0xF005,UsesFPU ,"fcmp/gt ," ,1,4,FE,fix_none ,dec_cmp(shop_fsetgt,PRM_FRN,PRM_FRM)}, //fcmp/gt , - {0 ,i1111_nnnn_mmmm_0110 ,Mask_n_m ,0xF006,UsesFPU ,"fmov.s @(R0,)," ,1,2,LS,fix_none ,dec_MRd(PRM_FRN_SZ,PRM_RM_R0,4)}, //fmov.s @(R0,), - {0 ,i1111_nnnn_mmmm_0111 ,Mask_n_m ,0xF007,UsesFPU ,"fmov.s ,@(R0,)" ,1,1,LS,fix_none ,dec_MWt(PRM_RN_R0,PRM_FRM_SZ,4)}, //fmov.s ,@(R0,) - {0 ,i1111_nnnn_mmmm_1000 ,Mask_n_m ,0xF008,UsesFPU ,"fmov.s @," ,1,2,LS,fix_none ,dec_MRd(PRM_FRN_SZ,PRM_RM,4)}, //fmov.s @, - {0 ,i1111_nnnn_mmmm_1001 ,Mask_n_m ,0xF009,UsesFPU ,"fmov.s @+," ,1,2,LS,fix_none ,dec_MRd(PRM_FRN_SZ,PRM_RM,-4)}, //fmov.s @+, - {0 ,i1111_nnnn_mmmm_1010 ,Mask_n_m ,0xF00A,UsesFPU ,"fmov.s ,@" ,1,1,LS,fix_none ,dec_MWt(PRM_RN,PRM_FRM_SZ,4)}, //fmov.s ,@ - {0 ,i1111_nnnn_mmmm_1011 ,Mask_n_m ,0xF00B,UsesFPU ,"fmov.s ,@-" ,1,1,LS,rn_fpu_4 ,dec_MWt(PRM_RN,PRM_FRM_SZ,-4)}, //fmov.s ,@- - {0 ,i1111_nnnn_mmmm_1100 ,Mask_n_m ,0xF00C,UsesFPU ,"fmov ," ,1,0,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_FRN_SZ,PRM_FRM_SZ,shop_mov32)}, //fmov , - {0 ,i1111_nnnn_0101_1101 ,Mask_n ,0xF05D,UsesFPU ,"fabs " ,1,0,LS,fix_none ,dec_Un_frNfrN(shop_fabs)}, //fabs - {0 ,i1111_nnn0_1111_1101 ,Mask_nh3bit ,0xF0FD,UsesFPU ,"FSCA FPUL, " ,1,4,FE,fix_none ,dec_Fill(DM_UnaryOp,PRM_FPN,PRM_FPUL,shop_fsca)}, //FSCA FPUL, DRn//F0FD//1111_nnnn_1111_1101 - {0 ,i1111_nnnn_1011_1101 ,Mask_n ,0xF0BD,UsesFPU ,"fcnvds ,FPUL" ,1,4,FE,fix_none}, //fcnvds ,FPUL - {0 ,i1111_nnnn_1010_1101 ,Mask_n ,0xF0AD,UsesFPU ,"fcnvsd FPUL," ,1,4,FE,fix_none}, //fcnvsd FPUL, - {0 ,i1111_nnmm_1110_1101 ,Mask_n ,0xF0ED,UsesFPU ,"fipr ," ,1,4,FE,fix_none ,dec_Fill(DM_fiprOp,PRM_FVN,PRM_FVM,shop_fipr)}, //fipr , - {0 ,i1111_nnnn_1000_1101 ,Mask_n ,0xF08D,UsesFPU ,"fldi0 " ,1,0,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_ZERO,shop_mov32)}, //fldi0 - {0 ,i1111_nnnn_1001_1101 ,Mask_n ,0xF09D,UsesFPU ,"fldi1 " ,1,0,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_ONE_F32,shop_mov32)}, //fldi1 - {0 ,i1111_nnnn_0001_1101 ,Mask_n ,0xF01D,UsesFPU ,"flds ,FPUL" ,1,0,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_mov32)}, //flds ,FPUL - {0 ,i1111_nnnn_0010_1101 ,Mask_n ,0xF02D,UsesFPU ,"float FPUL," ,1,3,FE,fix_none ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FPUL,shop_cvt_i2f_n)}, //float FPUL, - {0 ,i1111_nnnn_0100_1101 ,Mask_n ,0xF04D,UsesFPU ,"fneg " ,1,0,LS,fix_none ,dec_Un_frNfrN(shop_fneg)}, //fneg - {dec_i1111_1011_1111_1101 ,i1111_1011_1111_1101 ,Mask_none ,0xFBFD,FWritesFPSCR ,"frchg" ,1,2,FE,fix_none}, //frchg - {dec_i1111_0011_1111_1101 ,i1111_0011_1111_1101 ,Mask_none ,0xF3FD,FWritesFPSCR ,"fschg" ,1,2,FE,fix_none}, //fschg - {0 ,i1111_nnnn_0110_1101 ,Mask_n ,0xF06D,UsesFPU ,"fsqrt " ,1,12,FE,fix_none ,dec_Un_frNfrN(shop_fsqrt)},//fsqrt - {0 ,i1111_nnnn_0011_1101 ,Mask_n ,0xF03D,UsesFPU ,"ftrc , FPUL" ,1,4,FE,fix_none ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_cvt_f2i_t)}, //ftrc , FPUL // ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_cvt) - {0 ,i1111_nnnn_0000_1101 ,Mask_n ,0xF00D,UsesFPU ,"fsts FPUL," ,1,0,LS,fix_none ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FPUL,shop_mov32)}, //fsts FPUL, - {0 ,i1111_nn01_1111_1101 ,Mask_nh2bit ,0xF1FD,UsesFPU ,"ftrv xmtrx," ,1,6,FE,fix_none ,dec_Fill(DM_BinaryOp,PRM_FVN,PRM_XMTRX,shop_ftrv,1)}, //ftrv xmtrx, - {0 ,i1111_nnnn_mmmm_1110 ,Mask_n_m ,0xF00E,UsesFPU ,"fmac ,," ,1,4,FE,fix_none ,dec_Fill(DM_BinaryOp,PRM_FRN,PRM_FRM_FR0,shop_fmac,1)}, //fmac ,, - {0 ,i1111_nnnn_0111_1101 ,Mask_n ,0xF07D,UsesFPU ,"FSRRA " ,1,4,FE,fix_none ,dec_Un_frNfrN(shop_fsrra)}, //FSRRA (1111nnnn 01111101) + {0 ,i1111_nnnn_mmmm_0000 ,Mask_n_m ,0xF000,UsesFPU ,"fadd ," ,1,4,FE,36 ,dec_Bin_frNfrM(shop_fadd)}, //fadd , + {0 ,i1111_nnnn_mmmm_0001 ,Mask_n_m ,0xF001,UsesFPU ,"fsub ," ,1,4,FE,36 ,dec_Bin_frNfrM(shop_fsub)}, //fsub , + {0 ,i1111_nnnn_mmmm_0010 ,Mask_n_m ,0xF002,UsesFPU ,"fmul ," ,1,4,FE,36 ,dec_Bin_frNfrM(shop_fmul)}, //fmul , + {0 ,i1111_nnnn_mmmm_0011 ,Mask_n_m ,0xF003,UsesFPU ,"fdiv ," ,1,13,FE,37 ,dec_Bin_frNfrM(shop_fdiv)},//fdiv , + {0 ,i1111_nnnn_mmmm_0100 ,Mask_n_m ,0xF004,UsesFPU ,"fcmp/eq ," ,1,4,FE,36 ,dec_cmp(shop_fseteq,PRM_FRN,PRM_FRM)}, //fcmp/eq , + {0 ,i1111_nnnn_mmmm_0101 ,Mask_n_m ,0xF005,UsesFPU ,"fcmp/gt ," ,1,4,FE,36 ,dec_cmp(shop_fsetgt,PRM_FRN,PRM_FRM)}, //fcmp/gt , + {0 ,i1111_nnnn_mmmm_0110 ,Mask_n_m ,0xF006,UsesFPU ,"fmov.s @(R0,)," ,1,2,LS,2 ,dec_MRd(PRM_FRN_SZ,PRM_RM_R0,4)}, //fmov.s @(R0,), + {0 ,i1111_nnnn_mmmm_0111 ,Mask_n_m ,0xF007,UsesFPU ,"fmov.s ,@(R0,)" ,1,1,LS,2 ,dec_MWt(PRM_RN_R0,PRM_FRM_SZ,4)}, //fmov.s ,@(R0,) + {0 ,i1111_nnnn_mmmm_1000 ,Mask_n_m ,0xF008,UsesFPU ,"fmov.s @," ,1,2,LS,2 ,dec_MRd(PRM_FRN_SZ,PRM_RM,4)}, //fmov.s @, + {0 ,i1111_nnnn_mmmm_1001 ,Mask_n_m ,0xF009,UsesFPU ,"fmov.s @+," ,1,2,LS,2 ,dec_MRd(PRM_FRN_SZ,PRM_RM,-4)}, //fmov.s @+, + {0 ,i1111_nnnn_mmmm_1010 ,Mask_n_m ,0xF00A,UsesFPU ,"fmov.s ,@" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_FRM_SZ,4)}, //fmov.s ,@ + {0 ,i1111_nnnn_mmmm_1011 ,Mask_n_m ,0xF00B,UsesFPU ,"fmov.s ,@-" ,1,1,LS,2 ,dec_MWt(PRM_RN,PRM_FRM_SZ,-4)}, //fmov.s ,@- + {0 ,i1111_nnnn_mmmm_1100 ,Mask_n_m ,0xF00C,UsesFPU ,"fmov ," ,1,0,LS,1 ,dec_Fill(DM_UnaryOp,PRM_FRN_SZ,PRM_FRM_SZ,shop_mov32)}, //fmov , + {0 ,i1111_nnnn_0101_1101 ,Mask_n ,0xF05D,UsesFPU ,"fabs " ,1,0,LS,1 ,dec_Un_frNfrN(shop_fabs)}, //fabs + {0 ,i1111_nnn0_1111_1101 ,Mask_nh3bit ,0xF0FD,UsesFPU ,"FSCA FPUL, " ,1,3,FE,44 ,dec_Fill(DM_UnaryOp,PRM_FPN,PRM_FPUL,shop_fsca)}, //FSCA FPUL, DRn//F0FD//1111_nnnn_1111_1101 + {0 ,i1111_nnnn_1011_1101 ,Mask_n ,0xF0BD,UsesFPU ,"fcnvds ,FPUL" ,1,4,FE,38}, //fcnvds ,FPUL + {0 ,i1111_nnnn_1010_1101 ,Mask_n ,0xF0AD,UsesFPU ,"fcnvsd FPUL," ,1,4,FE,38}, //fcnvsd FPUL, + {0 ,i1111_nnmm_1110_1101 ,Mask_n ,0xF0ED,UsesFPU ,"fipr ," ,1,5,FE,42 ,dec_Fill(DM_fiprOp,PRM_FVN,PRM_FVM,shop_fipr)}, //fipr , + {0 ,i1111_nnnn_1000_1101 ,Mask_n ,0xF08D,UsesFPU ,"fldi0 " ,1,0,LS,1 ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_ZERO,shop_mov32)}, //fldi0 + {0 ,i1111_nnnn_1001_1101 ,Mask_n ,0xF09D,UsesFPU ,"fldi1 " ,1,0,LS,1 ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_ONE_F32,shop_mov32)}, //fldi1 + {0 ,i1111_nnnn_0001_1101 ,Mask_n ,0xF01D,UsesFPU ,"flds ,FPUL" ,1,0,LS,1 ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_mov32)}, //flds ,FPUL + {0 ,i1111_nnnn_0010_1101 ,Mask_n ,0xF02D,UsesFPU ,"float FPUL," ,1,4,FE,36 ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FPUL,shop_cvt_i2f_n)}, //float FPUL, + {0 ,i1111_nnnn_0100_1101 ,Mask_n ,0xF04D,UsesFPU ,"fneg " ,1,0,LS,1 ,dec_Un_frNfrN(shop_fneg)}, //fneg + {dec_i1111_1011_1111_1101 ,i1111_1011_1111_1101 ,Mask_none ,0xFBFD,FWritesFPSCR ,"frchg" ,1,4,FE,36}, //frchg + {dec_i1111_0011_1111_1101 ,i1111_0011_1111_1101 ,Mask_none ,0xF3FD,FWritesFPSCR ,"fschg" ,1,4,FE,36}, //fschg + {0 ,i1111_nnnn_0110_1101 ,Mask_n ,0xF06D,UsesFPU ,"fsqrt " ,1,23,FE,41 ,dec_Un_frNfrN(shop_fsqrt)},//fsqrt + {0 ,i1111_nnnn_0011_1101 ,Mask_n ,0xF03D,UsesFPU ,"ftrc , FPUL" ,1,4,FE,38 ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_cvt_f2i_t)}, //ftrc , FPUL // ,dec_Fill(DM_UnaryOp,PRM_FPUL,PRM_FRN,shop_cvt) + {0 ,i1111_nnnn_0000_1101 ,Mask_n ,0xF00D,UsesFPU ,"fsts FPUL," ,1,0,LS,1 ,dec_Fill(DM_UnaryOp,PRM_FRN,PRM_FPUL,shop_mov32)}, //fsts FPUL, + {0 ,i1111_nn01_1111_1101 ,Mask_nh2bit ,0xF1FD,UsesFPU ,"ftrv xmtrx," ,1,8,FE,43 ,dec_Fill(DM_BinaryOp,PRM_FVN,PRM_XMTRX,shop_ftrv,1)}, //ftrv xmtrx, + {0 ,i1111_nnnn_mmmm_1110 ,Mask_n_m ,0xF00E,UsesFPU ,"fmac ,," ,1,4,FE,36 ,dec_Fill(DM_BinaryOp,PRM_FRN,PRM_FRM_FR0,shop_fmac,1)}, //fmac ,, + {0 ,i1111_nnnn_0111_1101 ,Mask_n ,0xF07D,UsesFPU ,"FSRRA " ,1,4,FE,36 ,dec_Un_frNfrN(shop_fsrra)}, //FSRRA (1111nnnn 01111101) //HLE ops diff --git a/core/hw/sh4/sh4_opcode_list.h b/core/hw/sh4/sh4_opcode_list.h index e2c215954..7f4ce3719 100644 --- a/core/hw/sh4/sh4_opcode_list.h +++ b/core/hw/sh4/sh4_opcode_list.h @@ -14,22 +14,10 @@ enum sh4_eu LS, FE, CO, - MA, - sh4_eu_max }; std::string disassemble_op(const char* tx1, u32 pc, u16 opcode); -//exception fixup needed , added it to fix exception on opcodes that modify before exept :) -enum sh4_exept_fixup -{ - fix_none, - rn_opt_1, //1 if n!=m - rn_opt_2, //2 if n!=m - rn_opt_4, //4 if n!=m - rn_4, //Always 4 from rn - rn_fpu_4, //4 or 8, according to FPU size -}; typedef void ( RecOpCallFP) (u32 op); struct sh4_opcodelistentry { @@ -42,12 +30,20 @@ struct sh4_opcodelistentry u8 IssueCycles; u8 LatencyCycles; sh4_eu unit; - sh4_exept_fixup ex_fixup; + u8 ex_type; u64 decode; - u64 fallbacks; + void Disassemble(char* strout, u32 pc, u16 op) const { - std::string text = disassemble_op(diss, pc, op); + const char *disOp = diss; + if (!strcmp(disOp, "missing")) + { + static char tmp[6]; + sprintf(tmp, "?%04X", op); + disOp = tmp; + } + + std::string text = disassemble_op(disOp, pc, op); strcpy(strout, text.c_str()); } diff --git a/core/lua/lua.cpp b/core/lua/lua.cpp index 87ae893ba..7ddcd2b1b 100644 --- a/core/lua/lua.cpp +++ b/core/lua/lua.cpp @@ -177,7 +177,6 @@ CONFIG_ACCESSORS(AudioVolume) // Advanced CONFIG_ACCESSORS(DynarecEnabled) -CONFIG_ACCESSORS(DynarecIdleSkip) CONFIG_ACCESSORS(SerialConsole) CONFIG_ACCESSORS(SerialPTY) CONFIG_ACCESSORS(UseReios) @@ -501,7 +500,6 @@ static void luaRegister(lua_State *L) .beginNamespace("advanced") CONFIG_PROPERTY(DynarecEnabled, bool) - CONFIG_PROPERTY(DynarecIdleSkip, bool) CONFIG_PROPERTY(SerialConsole, bool) CONFIG_PROPERTY(SerialPTY, bool) CONFIG_PROPERTY(UseReios, bool) diff --git a/core/profiler/dc_profiler.cpp b/core/profiler/dc_profiler.cpp index b9d0d1df1..44da9d245 100644 --- a/core/profiler/dc_profiler.cpp +++ b/core/profiler/dc_profiler.cpp @@ -30,14 +30,6 @@ struct regacc #include "hw/sh4/sh4_opcode_list.h" -int stuffcmp(const void* p1,const void* p2) -{ - sh4_opcodelistentry* a=(sh4_opcodelistentry*)p1; - sh4_opcodelistentry* b=(sh4_opcodelistentry*)p2; - - return b->fallbacks-a->fallbacks; -} - extern u32 ret_hit,ret_all,ret_stc; extern u32 bm_gc_luc,bm_gcf_luc,cvld; @@ -173,28 +165,6 @@ void dc_prof_periodical() dc_prof.counters.print(); } - printf("opcode fallbacks:\n"); - vector stuff; - for (u32 i=0;opcodes[i].oph;i++) - { - if (opcodes[i].fallbacks) - stuff.push_back(opcodes[i]); - } - - if (stuff.size()) - { - qsort(&stuff[0],stuff.size(),sizeof(stuff[0]),stuffcmp); - for (u32 i=0;i<10 && i DynarecEnabled("", true); -Option DynarecIdleSkip("", true); // General