From 64630ea06bdbe8b34933ff2c7221d18a6c3848a5 Mon Sep 17 00:00:00 2001 From: CocoSimone Date: Wed, 4 Jan 2023 16:50:33 +0100 Subject: [PATCH] No more segfault in JIT. Keeps executing the same blocks over and over though... --- external/parallel-rdp/ParallelRDPWrapper.cpp | 12 +- src/CMakeLists.txt | 12 +- src/Discord.hpp | 2 +- src/backend/Core.hpp | 5 +- src/backend/MupenMovie.cpp | 50 +- src/backend/RomHelpers.hpp | 2 +- src/backend/Scheduler.cpp | 2 +- src/backend/core/Audio.cpp | 4 +- src/backend/core/Dynarec.cpp | 30 +- src/backend/core/Dynarec.hpp | 7 +- src/backend/core/MMIO.cpp | 4 +- src/backend/core/Mem.cpp | 112 +- src/backend/core/Mem.hpp | 8 +- src/backend/core/RDP.cpp | 80 +- src/backend/core/RSP.cpp | 28 +- src/backend/core/dynarec/cop/cop0decode.cpp | 9 +- .../core/dynarec/cop/cop0instructions.cpp | 4 +- src/backend/core/dynarec/cop/cop1decode.cpp | 44 +- .../core/dynarec/cop/cop1instructions.cpp | 4 +- src/backend/core/dynarec/decode.cpp | 1080 ++++++++--------- .../core/interpreter/cop/cop0instructions.cpp | 4 +- .../core/interpreter/cop/cop1instructions.cpp | 4 +- src/backend/core/interpreter/decode.cpp | 6 +- src/backend/core/mmio/AI.cpp | 4 +- src/backend/core/mmio/MI.cpp | 4 +- src/backend/core/mmio/PI.cpp | 8 +- src/backend/core/mmio/PIF.cpp | 2 +- src/backend/core/mmio/RI.cpp | 4 +- src/backend/core/mmio/SI.cpp | 8 +- src/backend/core/mmio/VI.cpp | 4 +- src/backend/core/registers/Cop0.cpp | 20 +- src/backend/core/registers/Cop1.cpp | 12 +- src/backend/core/rsp/decode.cpp | 34 +- src/backend/core/rsp/instructions.cpp | 8 +- src/frontend/App.cpp | 2 +- src/frontend/App.hpp | 2 +- src/frontend/imgui/GameList.cpp | 16 +- src/frontend/imgui/GameList.hpp | 9 + src/frontend/imgui/Settings.cpp | 2 +- src/frontend/imgui/Window.cpp | 14 +- src/utils/File.hpp | 2 +- src/utils/MemoryHelpers.hpp | 2 +- src/utils/log.hpp | 2 +- 43 files changed, 823 insertions(+), 849 deletions(-) diff --git a/external/parallel-rdp/ParallelRDPWrapper.cpp b/external/parallel-rdp/ParallelRDPWrapper.cpp index eb14ffdb..45ea0cc6 100644 --- a/external/parallel-rdp/ParallelRDPWrapper.cpp +++ b/external/parallel-rdp/ParallelRDPWrapper.cpp @@ -79,7 +79,7 @@ public: unsigned int num_extensions = 64; if (!SDL_Vulkan_GetInstanceExtensions(g_Window, &num_extensions, extensions)) { - util::panic("SDL_Vulkan_GetInstanceExtensions failed: {}", SDL_GetError()); + Util::panic("SDL_Vulkan_GetInstanceExtensions failed: {}", SDL_GetError()); } auto vec = std::vector(); @@ -93,7 +93,7 @@ public: VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice gpu) override { VkSurfaceKHR vk_surface; if (!SDL_Vulkan_CreateSurface(g_Window, instance, &vk_surface)) { - util::panic("Failed to create Vulkan window surface: {}", SDL_GetError()); + Util::panic("Failed to create Vulkan window surface: {}", SDL_GetError()); } return vk_surface; } @@ -133,7 +133,7 @@ WSI* LoadWSIPlatform(Vulkan::WSIPlatform* wsi_platform, std::unique_ptrset_present_mode(PresentMode::SyncToVBlank); Context::SystemHandles handles; if (!wsi->init_simple(1, handles)) { - util::panic("Failed to initialize WSI!"); + Util::panic("Failed to initialize WSI!"); } windowInfo = std::move(newWindowInfo); @@ -157,8 +157,8 @@ void LoadParallelRDP(const u8* rdram, SDL_Window* window) { fragLayout.sets[0].array_size[0] = 1; u32* fullscreenQuadVert, *fullscreenQuadFrag; - auto sizeVert = util::ReadFileBinary("resources/vert.spv", &fullscreenQuadVert); - auto sizeFrag = util::ReadFileBinary("resources/frag.spv", &fullscreenQuadFrag); + auto sizeVert = Util::ReadFileBinary("resources/vert.spv", &fullscreenQuadVert); + auto sizeFrag = Util::ReadFileBinary("resources/frag.spv", &fullscreenQuadFrag); fullscreen_quad_program = wsi->get_device().request_program(fullscreenQuadVert, sizeVert, fullscreenQuadFrag, sizeFrag, &vertLayout, &fragLayout); @@ -178,7 +178,7 @@ void LoadParallelRDP(const u8* rdram, SDL_Window* window) { offset, 8 * 1024 * 1024, 4 * 1024 * 1024, flags); if (!command_processor->device_is_supported()) { - util::panic("This device probably does not support 8/16-bit storage. Make sure you're using up-to-date drivers!"); + Util::panic("This device probably does not support 8/16-bit storage. Make sure you're using up-to-date drivers!"); } } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 24ce44f0..ec9909ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -68,17 +68,17 @@ endif() if(${CMAKE_BUILD_TYPE} MATCHES Release) set_property(TARGET gadolinium PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE) if(WIN32) - add_compile_options(/O2) + target_compile_options(gadolinium PRIVATE /O2) else() - add_compile_options(-O3) + target_compile_options(gadolinium PRIVATE -O3) endif() else() if(WIN32) - add_compile_options(/Od) + target_compile_options(gadolinium PRIVATE /Od) else() - add_compile_options(-fsanitize=address) - add_link_options(-fsanitize=address) - add_compile_options(-g) + target_compile_options(gadolinium PRIVATE -fsanitize=address) + target_link_options(gadolinium PRIVATE -fsanitize=address) + target_compile_options(gadolinium PRIVATE -g) endif() endif() diff --git a/src/Discord.hpp b/src/Discord.hpp index 820dab89..c6c0aa7d 100644 --- a/src/Discord.hpp +++ b/src/Discord.hpp @@ -3,7 +3,7 @@ #include #include -namespace util { +namespace Util { enum State { Idling, Playing, diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index 44f1ecf1..6597f113 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -24,10 +24,7 @@ struct Core { VI& GetVI() { return mem.mmio.vi; } void CpuReset() { - switch(cpuType) { - case CpuType::Dynarec: break; - case CpuType::Interpreter: break; - } + regs.Reset(); } int CpuStep() { diff --git a/src/backend/MupenMovie.cpp b/src/backend/MupenMovie.cpp index 9e3156a5..0093ea33 100644 --- a/src/backend/MupenMovie.cpp +++ b/src/backend/MupenMovie.cpp @@ -71,7 +71,7 @@ void LoadTAS(const char* filename) { FILE *fp = fopen(filename, "rb"); if (!fp) { - util::panic("Error opening the movie file {}! Are you sure it's a valid movie and that it exists?", filename); + Util::panic("Error opening the movie file {}! Are you sure it's a valid movie and that it exists?", filename); } fseek(fp, 0, SEEK_END); @@ -85,31 +85,31 @@ void LoadTAS(const char* filename) { loaded_tas_movie_size = size; if (!loaded_tas_movie) { - util::panic("Error loading movie!"); + Util::panic("Error loading movie!"); } memcpy(&loaded_tas_movie_header, buf, sizeof(TASMovieHeader)); if (loaded_tas_movie_header.signature[0] != 0x4D || loaded_tas_movie_header.signature[1] != 0x36 || loaded_tas_movie_header.signature[2] != 0x34 || loaded_tas_movie_header.signature[3] != 0x1A) { - util::panic("Failed to load movie: incorrect signature. Are you sure this is a valid movie?"); + Util::panic("Failed to load movie: incorrect signature. Are you sure this is a valid movie?"); } if (loaded_tas_movie_header.version != 3) { - util::panic("This movie is version {}: only version 3 is supported.", loaded_tas_movie_header.version); + Util::panic("This movie is version {}: only version 3 is supported.", loaded_tas_movie_header.version); } if (loaded_tas_movie_header.startType != 2) { - util::panic("Movie start type is {} - only movies with a start type of 2 are supported (start at power on)", loaded_tas_movie_header.startType); + Util::panic("Movie start type is {} - only movies with a start type of 2 are supported (start at power on)", loaded_tas_movie_header.startType); } // TODO: check ROM CRC32 here - util::print("Loaded movie '{}' ", loaded_tas_movie_header.movie_description); - util::print("by {}\n", loaded_tas_movie_header.author_name); - util::print("{} controller(s) connected\n", loaded_tas_movie_header.numControllers); + Util::print("Loaded movie '{}' ", loaded_tas_movie_header.movie_description); + Util::print("by {}\n", loaded_tas_movie_header.author_name); + Util::print("{} controller(s) connected\n", loaded_tas_movie_header.numControllers); if (loaded_tas_movie_header.numControllers != 1) { - util::panic("Currently, only movies with 1 controller connected are supported.\n"); + Util::panic("Currently, only movies with 1 controller connected are supported.\n"); } loaded_tas_movie_index = sizeof(TASMovieHeader) - 4; // skip header @@ -120,22 +120,22 @@ bool tas_movie_loaded() { } inline void LogController(const n64::Controller& controller) { - util::print("c_right: {}\n", controller.c_right); - util::print("c_left: {}\n", controller.c_left); - util::print("c_down: {}\n", controller.c_down); - util::print("c_up: {}\n", controller.c_up); - util::print("r: {}\n", controller.r); - util::print("l: {}\n", controller.l); - util::print("dp_right: {}\n", controller.dp_right); - util::print("dp_left: {}\n", controller.dp_left); - util::print("dp_down: {}\n", controller.dp_down); - util::print("dp_up: {}\n", controller.dp_up); - util::print("z: {}\n", controller.z); - util::print("b: {}\n", controller.b); - util::print("a: {}\n", controller.a); - util::print("start: {}\n", controller.start); - util::print("joy_x: {}\n", controller.joy_x); - util::print("joy_y: {}\n\n", controller.joy_y); + Util::print("c_right: {}\n", controller.c_right); + Util::print("c_left: {}\n", controller.c_left); + Util::print("c_down: {}\n", controller.c_down); + Util::print("c_up: {}\n", controller.c_up); + Util::print("r: {}\n", controller.r); + Util::print("l: {}\n", controller.l); + Util::print("dp_right: {}\n", controller.dp_right); + Util::print("dp_left: {}\n", controller.dp_left); + Util::print("dp_down: {}\n", controller.dp_down); + Util::print("dp_up: {}\n", controller.dp_up); + Util::print("z: {}\n", controller.z); + Util::print("b: {}\n", controller.b); + Util::print("a: {}\n", controller.a); + Util::print("start: {}\n", controller.start); + Util::print("joy_x: {}\n", controller.joy_x); + Util::print("joy_y: {}\n\n", controller.joy_y); } n64::Controller tas_next_inputs() { diff --git a/src/backend/RomHelpers.hpp b/src/backend/RomHelpers.hpp index 482ff476..0129846c 100644 --- a/src/backend/RomHelpers.hpp +++ b/src/backend/RomHelpers.hpp @@ -2,7 +2,7 @@ #include #include -namespace util { +namespace Util { enum RomTypes { Z64 = 0x80371240, N64 = 0x40123780, diff --git a/src/backend/Scheduler.cpp b/src/backend/Scheduler.cpp index 6775ea83..ce245f74 100644 --- a/src/backend/Scheduler.cpp +++ b/src/backend/Scheduler.cpp @@ -6,7 +6,7 @@ Scheduler scheduler; Scheduler::Scheduler() { events.push({UINT64_MAX, [](n64::Mem&, n64::Registers&){ - util::panic("How the fuck did we get here?!\n"); + Util::panic("How the fuck did we get here?!\n"); }}); } diff --git a/src/backend/core/Audio.cpp b/src/backend/core/Audio.cpp index 904cfefd..54c81ef5 100644 --- a/src/backend/core/Audio.cpp +++ b/src/backend/core/Audio.cpp @@ -53,7 +53,7 @@ void InitAudio() { } if(!audioDev) { - util::panic("Failed to initialize SDL Audio: {}", SDL_GetError()); + Util::panic("Failed to initialize SDL Audio: {}", SDL_GetError()); } SDL_PauseAudioDevice(audioDev, false); @@ -61,7 +61,7 @@ void InitAudio() { audioStreamMutex = SDL_CreateMutex(); if(!audioStreamMutex) { - util::panic("Unable to initialize audio mutex: {}", SDL_GetError()); + Util::panic("Unable to initialize audio mutex: {}", SDL_GetError()); } } diff --git a/src/backend/core/Dynarec.cpp b/src/backend/core/Dynarec.cpp index ccfd2601..6bfaecb8 100644 --- a/src/backend/core/Dynarec.cpp +++ b/src/backend/core/Dynarec.cpp @@ -1,28 +1,46 @@ #include #include +#include namespace n64::JIT { -Dynarec::Dynarec() : code(Xbyak::DEFAULT_MAX_CODE_SIZE, Xbyak::AutoGrow) {} +namespace fs = std::filesystem; + +Dynarec::~Dynarec() { + dumpCode.close(); +} + +Dynarec::Dynarec() : code(DEFAULT_MAX_CODE_SIZE, AutoGrow) { + if(fs::exists("jit.dump")) { + fs::remove("jit.dump"); + } + + dumpCode.open("jit.dump", std::ios::app | std::ios::binary); + code.setProtectMode(CodeGenerator::PROTECT_RWE); +} void Dynarec::Recompile(Registers& regs, Mem& mem) { bool branch = false, prevBranch = false; u32 start_addr = regs.pc; Fn block = code.getCurr(); + code.sub(code.rsp, 8); + while(!prevBranch) { instrInBlock++; prevBranch = branch; - u32 instr = mem.Read32(regs, regs.pc, regs.pc); + u32 instr = mem.Read32(regs, start_addr, start_addr); - regs.oldPC = regs.pc; - regs.pc = regs.nextPC; - regs.nextPC += 4; + start_addr += 4; + code.mov(code.rdi, (u64)®s); branch = Exec(regs, mem, instr); } + code.add(code.rsp, 8); code.ret(); - codeCache[start_addr >> 20][start_addr & 0xFFF] = block; + dumpCode.write(code.getCode(), code.getSize()); + u32 pc = regs.pc & 0xffffffff; + codeCache[pc >> 20][pc & 0xFFF] = block; block(); } diff --git a/src/backend/core/Dynarec.hpp b/src/backend/core/Dynarec.hpp index 57ce1392..6e3672cc 100644 --- a/src/backend/core/Dynarec.hpp +++ b/src/backend/core/Dynarec.hpp @@ -1,22 +1,27 @@ #pragma once #include #include +#include namespace n64::JIT { +using namespace Xbyak; +using namespace Xbyak::util; using Fn = void (*)(); struct Dynarec { Dynarec(); + ~Dynarec(); int Step(Mem&, n64::Registers&); void Reset() { code.reset(); } u64 cop2Latch{}; - Xbyak::CodeGenerator code; + CodeGenerator code; private: friend struct Cop1; Fn* codeCache[0x80000]{}; int instrInBlock = 0; + std::ofstream dumpCode; void Recompile(n64::Registers&, Mem&); void AllocateOuter(n64::Registers&); diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index 9b0fcec9..620731cd 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -30,7 +30,7 @@ u32 MMIO::Read(u32 addr) { case 0x04700000 ... 0x047FFFFF: return ri.Read(addr); case 0x04800000 ... 0x048FFFFF: return si.Read(mi, addr); default: - util::panic("Unhandled mmio read at addr {:08X}\n", addr); + Util::panic("Unhandled mmio read at addr {:08X}\n", addr); } } @@ -45,7 +45,7 @@ void MMIO::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { case 0x04700000 ... 0x047FFFFF: ri.Write(addr, val); break; case 0x04800000 ... 0x048FFFFF: si.Write(mem, regs, addr, val); break; default: - util::panic("Unhandled mmio write at addr {:08X} with val {:08X}\n", addr, val); + Util::panic("Unhandled mmio write at addr {:08X} with val {:08X}\n", addr, val); } } } diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index 643bebc0..03489461 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -41,12 +41,12 @@ CartInfo Mem::LoadROM(const std::string& filename) { file.unsetf(std::ios::skipws); if(!file.is_open()) { - util::panic("Unable to open {}!", filename); + Util::panic("Unable to open {}!", filename); } file.seekg(0, std::ios::end); auto size = file.tellg(); - auto sizeAdjusted = util::NextPow2(size); + auto sizeAdjusted = Util::NextPow2(size); romMask = sizeAdjusted - 1; file.seekg(0, std::ios::beg); @@ -59,7 +59,7 @@ CartInfo Mem::LoadROM(const std::string& filename) { CartInfo result{}; u32 cicChecksum; - util::SwapN64Rom(sizeAdjusted, cart.data(), result.crc, cicChecksum); + Util::SwapN64Rom(sizeAdjusted, cart.data(), result.crc, cicChecksum); memcpy(mmio.rsp.dmem, cart.data(), 0x1000); SetCICType(result.cicType, cicChecksum); @@ -77,9 +77,9 @@ bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) case 0 ... 3: case 7: return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); case 4 ... 5: return true; - case 6: util::panic("Unimplemented virtual mapping in KSSEG! ({:08X})\n", vaddr); + case 6: Util::panic("Unimplemented virtual mapping in KSSEG! ({:08X})\n", vaddr); default: - util::panic("Should never end up in default case in map_vaddr! ({:08X})\n", vaddr); + Util::panic("Should never end up in default case in map_vaddr! ({:08X})\n", vaddr); } return false; @@ -134,7 +134,7 @@ u8 Mem::Read8(n64::Registers ®s, u64 vaddr, s64 pc) { case 0x1FC00800 ... 0xFFFFFFFF: return 0; default: - util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); + Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); } } } @@ -152,16 +152,16 @@ u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) { const auto pointer = readPages[page]; if(pointer) { - return util::ReadAccess((u8*)pointer, HALF_ADDRESS(offset)); + return Util::ReadAccess((u8*)pointer, HALF_ADDRESS(offset)); } else { switch (paddr) { case 0x00000000 ... 0x007FFFFF: - return util::ReadAccess(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr)); + return Util::ReadAccess(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr)); case 0x04000000 ... 0x0403FFFF: if ((paddr >> 12) & 1) - return util::ReadAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.imem, HALF_ADDRESS(paddr) & IMEM_DSIZE); else - return util::ReadAccess(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.dmem, HALF_ADDRESS(paddr) & DMEM_DSIZE); case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: @@ -169,18 +169,18 @@ u16 Mem::Read16(n64::Registers ®s, u64 vaddr, s64 pc) { return mmio.Read(paddr); case 0x10000000 ... 0x1FBFFFFF: paddr = (paddr + 2) & ~3; - return util::ReadAccess(cart.data(), HALF_ADDRESS(paddr) & romMask); + return Util::ReadAccess(cart.data(), HALF_ADDRESS(paddr) & romMask); case 0x1FC00000 ... 0x1FC007BF: - return util::ReadAccess(pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000); + return Util::ReadAccess(pifBootrom, HALF_ADDRESS(paddr) - 0x1FC00000); case 0x1FC007C0 ... 0x1FC007FF: - return be16toh(util::ReadAccess(pifRam, paddr - 0x1FC007C0)); + return be16toh(Util::ReadAccess(pifRam, paddr - 0x1FC007C0)); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; default: - util::panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); + Util::panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); } } } @@ -198,29 +198,29 @@ u32 Mem::Read32(n64::Registers ®s, u64 vaddr, s64 pc) { const auto pointer = readPages[page]; if(pointer) { - return util::ReadAccess((u8*)pointer, offset); + return Util::ReadAccess((u8*)pointer, offset); } else { switch(paddr) { case 0x00000000 ... 0x007FFFFF: - return util::ReadAccess(mmio.rdp.rdram.data(), paddr); + return Util::ReadAccess(mmio.rdp.rdram.data(), paddr); case 0x04000000 ... 0x0403FFFF: if((paddr >> 12) & 1) - return util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); else - return util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); case 0x10000000 ... 0x1FBFFFFF: - return util::ReadAccess(cart.data(), paddr & romMask); + return Util::ReadAccess(cart.data(), paddr & romMask); case 0x1FC00000 ... 0x1FC007BF: - return util::ReadAccess(pifBootrom, paddr - 0x1FC00000); + return Util::ReadAccess(pifBootrom, paddr - 0x1FC00000); case 0x1FC007C0 ... 0x1FC007FF: - return be32toh(util::ReadAccess(pifRam, paddr - 0x1FC007C0)); + return be32toh(Util::ReadAccess(pifRam, paddr - 0x1FC007C0)); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; default: - util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); + Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); } } } @@ -238,34 +238,34 @@ u64 Mem::Read64(n64::Registers ®s, u64 vaddr, s64 pc) { const auto pointer = readPages[page]; if(pointer) { - return util::ReadAccess((u8*)pointer, offset); + return Util::ReadAccess((u8*)pointer, offset); } else { switch (paddr) { case 0x00000000 ... 0x007FFFFF: - return util::ReadAccess(mmio.rdp.rdram.data(), paddr); + return Util::ReadAccess(mmio.rdp.rdram.data(), paddr); case 0x04000000 ... 0x0403FFFF: if ((paddr >> 12) & 1) - return util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.imem, paddr & IMEM_DSIZE); else - return util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); + return Util::ReadAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE); case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); case 0x10000000 ... 0x1FBFFFFF: - return util::ReadAccess(cart.data(), paddr & romMask); + return Util::ReadAccess(cart.data(), paddr & romMask); case 0x1FC00000 ... 0x1FC007BF: - return util::ReadAccess(pifBootrom, paddr - 0x1FC00000); + return Util::ReadAccess(pifBootrom, paddr - 0x1FC00000); case 0x1FC007C0 ... 0x1FC007FF: - return be64toh(util::ReadAccess(pifRam, paddr - 0x1FC007C0)); + return be64toh(Util::ReadAccess(pifRam, paddr - 0x1FC007C0)); case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x04900000 ... 0x0FFFFFFF: case 0x1FC00800 ... 0xFFFFFFFF: return 0; default: - util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); + Util::panic("Unimplemented 32-bit read at address {:08X} (PC = {:016X})\n", paddr, (u64) regs.pc); } } } @@ -307,21 +307,21 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { val = val << (8 * (3 - (paddr & 3))); paddr = (paddr & DMEM_DSIZE) & ~3; if (paddr & 0x1000) - util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); else - util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: - util::panic("MMIO Write8!\n"); + Util::panic("MMIO Write8!\n"); case 0x10000000 ... 0x13FFFFFF: break; case 0x1FC007C0 ... 0x1FC007FF: val = val << (8 * (3 - (paddr & 3))); paddr = (paddr - 0x1FC007C0) & ~3; - util::WriteAccess(pifRam, paddr, htobe32(val)); + Util::WriteAccess(pifRam, paddr, htobe32(val)); ProcessPIFCommands(pifRam, mmio.si.controller, *this); break; case 0x00800000 ... 0x03FFFFFF: @@ -332,7 +332,7 @@ void Mem::Write8(Registers& regs, u64 vaddr, u32 val, s64 pc) { case 0x80000000 ... 0xFFFFFFFF: break; default: - util::panic("Unimplemented 8-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, + Util::panic("Unimplemented 8-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64) regs.pc); } } @@ -356,31 +356,31 @@ void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) { offset &= ~3; } - util::WriteAccess((u8*)pointer, HALF_ADDRESS(offset), val); + Util::WriteAccess((u8*)pointer, HALF_ADDRESS(offset), val); } else { switch (paddr) { case 0x00000000 ... 0x007FFFFF: - util::WriteAccess(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr), val); + Util::WriteAccess(mmio.rdp.rdram.data(), HALF_ADDRESS(paddr), val); break; case 0x04000000 ... 0x0403FFFF: val = val << (16 * !(paddr & 2)); paddr &= ~3; if (paddr & 0x1000) - util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); else - util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: - util::panic("MMIO Write16!\n"); + Util::panic("MMIO Write16!\n"); case 0x10000000 ... 0x13FFFFFF: break; case 0x1FC007C0 ... 0x1FC007FF: val = val << (16 * !(paddr & 2)); paddr &= ~3; - util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe32(val)); + Util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe32(val)); ProcessPIFCommands(pifRam, mmio.si.controller, *this); break; case 0x00800000 ... 0x03FFFFFF: @@ -391,7 +391,7 @@ void Mem::Write16(Registers& regs, u64 vaddr, u32 val, s64 pc) { case 0x80000000 ... 0xFFFFFFFF: break; default: - util::panic("Unimplemented 16-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, + Util::panic("Unimplemented 16-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64) regs.pc); } } @@ -410,17 +410,17 @@ void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) { const auto pointer = readPages[page]; if(pointer) { - util::WriteAccess((u8*)pointer, offset, val); + Util::WriteAccess((u8*)pointer, offset, val); } else { switch(paddr) { case 0x00000000 ... 0x007FFFFF: - util::WriteAccess(mmio.rdp.rdram.data(), paddr, val); + Util::WriteAccess(mmio.rdp.rdram.data(), paddr, val); break; case 0x04000000 ... 0x0403FFFF: if(paddr & 0x1000) - util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); else - util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: mmio.Write(*this, regs, paddr, val); break; @@ -434,16 +434,16 @@ void Mem::Write32(Registers& regs, u64 vaddr, u32 val, s64 pc) { } } break; case 0x13FF0020 ... 0x13FFFFFF: - util::WriteAccess(isviewer, paddr - 0x13FF0020, htobe32(val)); + Util::WriteAccess(isviewer, paddr - 0x13FF0020, htobe32(val)); break; case 0x1FC007C0 ... 0x1FC007FF: - util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe32(val)); + Util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe32(val)); ProcessPIFCommands(pifRam, mmio.si.controller, *this); break; case 0x00800000 ... 0x03FFFFFF: case 0x04200000 ... 0x042FFFFF: case 0x08000000 ... 0x0FFFFFFF: case 0x04900000 ... 0x07FFFFFF: case 0x1FC00800 ... 0x7FFFFFFF: case 0x80000000 ... 0xFFFFFFFF: break; - default: util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc); + default: Util::panic("Unimplemented 32-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64)regs.pc); } } } @@ -464,28 +464,28 @@ void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) { if(paddr >= 0x04000000 && paddr <= 0x0403FFFF) { val >>= 32; } - util::WriteAccess((u8*)pointer, offset, val); + Util::WriteAccess((u8*)pointer, offset, val); } else { switch (paddr) { case 0x00000000 ... 0x007FFFFF: - util::WriteAccess(mmio.rdp.rdram.data(), paddr, val); + Util::WriteAccess(mmio.rdp.rdram.data(), paddr, val); break; case 0x04000000 ... 0x0403FFFF: val >>= 32; if (paddr & 0x1000) - util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.imem, paddr & IMEM_DSIZE, val); else - util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); + Util::WriteAccess(mmio.rsp.dmem, paddr & DMEM_DSIZE, val); break; case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: - util::panic("MMIO Write64!\n"); + Util::panic("MMIO Write64!\n"); case 0x10000000 ... 0x13FFFFFF: break; case 0x1FC007C0 ... 0x1FC007FF: - util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe64(val)); + Util::WriteAccess(pifRam, paddr - 0x1FC007C0, htobe64(val)); ProcessPIFCommands(pifRam, mmio.si.controller, *this); break; case 0x00800000 ... 0x03FFFFFF: @@ -496,7 +496,7 @@ void Mem::Write64(Registers& regs, u64 vaddr, u64 val, s64 pc) { case 0x80000000 ... 0xFFFFFFFF: break; default: - util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, + Util::panic("Unimplemented 64-bit write at address {:08X} with value {:0X} (PC = {:016X})\n", paddr, val, (u64) regs.pc); } } diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 008c3de9..fea7ca7c 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -48,7 +48,7 @@ struct Mem { FILE *fp = fopen("rdram.dump", "wb"); u8 *temp = (u8*)calloc(RDRAM_SIZE, 1); memcpy(temp, mmio.rdp.rdram.data(), RDRAM_SIZE); - util::SwapBuffer32(RDRAM_SIZE, temp); + Util::SwapBuffer32(RDRAM_SIZE, temp); fwrite(temp, 1, RDRAM_SIZE, fp); free(temp); fclose(fp); @@ -58,7 +58,7 @@ struct Mem { FILE *fp = fopen("imem.bin", "wb"); u8 *temp = (u8*)calloc(IMEM_SIZE, 1); memcpy(temp, mmio.rsp.imem, IMEM_SIZE); - util::SwapBuffer32(IMEM_SIZE, temp); + Util::SwapBuffer32(IMEM_SIZE, temp); fwrite(temp, 1, IMEM_SIZE, fp); free(temp); fclose(fp); @@ -68,7 +68,7 @@ struct Mem { FILE *fp = fopen("dmem.dump", "wb"); u8 *temp = (u8*)calloc(DMEM_SIZE, 1); memcpy(temp, mmio.rsp.dmem, DMEM_SIZE); - util::SwapBuffer32(DMEM_SIZE, temp); + Util::SwapBuffer32(DMEM_SIZE, temp); fwrite(temp, 1, DMEM_SIZE, fp); free(temp); fclose(fp); @@ -107,7 +107,7 @@ private: cicType = CIC_NUS_6106_7106; break; default: - util::warn("Could not determine CIC TYPE! Checksum: {:08X} is unknown!\n", checksum); + Util::warn("Could not determine CIC TYPE! Checksum: {:08X} is unknown!\n", checksum); cicType = UNKNOWN_CIC_TYPE; break; } diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index 2e2f39c6..bc0d18e7 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -35,7 +35,7 @@ auto RDP::Read(u32 addr) const -> u32 { case 0x04100018: return dpc.status.pipeBusy; case 0x0410001C: return dpc.tmem; default: - util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr); + Util::panic("Unhandled DP Command Registers read (addr: {:08X})\n", addr); } } @@ -45,7 +45,7 @@ void RDP::Write(MI& mi, Registers& regs, RSP& rsp, u32 addr, u32 val) { case 0x04100004: WriteEnd(mi, regs, rsp, val); break; case 0x0410000C: WriteStatus(mi, regs, rsp, val); break; default: - util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})\n", addr, val); + Util::panic("Unhandled DP Command Registers write (addr: {:08X}, val: {:08X})\n", addr, val); } } @@ -74,41 +74,41 @@ void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) { inline void logCommand(u8 cmd) { switch(cmd) { - case 0x08: util::print("Fill triangle\n"); break; - case 0x09: util::print("Fill, zbuf triangle\n"); break; - case 0x0a: util::print("Texture triangle\n"); break; - case 0x0b: util::print("Texture, zbuf triangle\n"); break; - case 0x0c: util::print("Shade triangle\n"); break; - case 0x0d: util::print("Shade, zbuf triangle\n"); break; - case 0x0e: util::print("Shade, texture triangle\n"); break; - case 0x0f: util::print("Shade, texture, zbuf triangle\n"); break; - case 0x24: util::print("Texture rectangle\n"); break; - case 0x25: util::print("Texture rectangle flip\n"); break; - case 0x26: util::print("Sync load\n"); break; - case 0x27: util::print("Sync pipe\n"); break; - case 0x28: util::print("Sync tile\n"); break; - case 0x29: util::print("Sync full\n"); break; - case 0x2a: util::print("Set key gb\n"); break; - case 0x2b: util::print("Set key r\n"); break; - case 0x2c: util::print("Set convert\n"); break; - case 0x2d: util::print("Set scissor\n"); break; - case 0x2e: util::print("Set prim depth\n"); break; - case 0x2f: util::print("Set other modes\n"); break; - case 0x30: util::print("Load TLUT\n"); break; - case 0x32: util::print("Set tile size\n"); break; - case 0x33: util::print("Load block\n"); break; - case 0x34: util::print("Load tile\n"); break; - case 0x35: util::print("Set tile\n"); break; - case 0x36: util::print("Fill rectangle\n"); break; - case 0x37: util::print("Set fill color\n"); break; - case 0x38: util::print("Set fog color\n"); break; - case 0x39: util::print("Set blend color\n"); break; - case 0x3a: util::print("Set prim color\n"); break; - case 0x3b: util::print("Set env color\n"); break; - case 0x3c: util::print("Set combine\n"); break; - case 0x3d: util::print("Set texture image\n"); break; - case 0x3e: util::print("Set mask image\n"); break; - case 0x3f: util::print("Set color image\n"); break; + case 0x08: Util::print("Fill triangle\n"); break; + case 0x09: Util::print("Fill, zbuf triangle\n"); break; + case 0x0a: Util::print("Texture triangle\n"); break; + case 0x0b: Util::print("Texture, zbuf triangle\n"); break; + case 0x0c: Util::print("Shade triangle\n"); break; + case 0x0d: Util::print("Shade, zbuf triangle\n"); break; + case 0x0e: Util::print("Shade, texture triangle\n"); break; + case 0x0f: Util::print("Shade, texture, zbuf triangle\n"); break; + case 0x24: Util::print("Texture rectangle\n"); break; + case 0x25: Util::print("Texture rectangle flip\n"); break; + case 0x26: Util::print("Sync load\n"); break; + case 0x27: Util::print("Sync pipe\n"); break; + case 0x28: Util::print("Sync tile\n"); break; + case 0x29: Util::print("Sync full\n"); break; + case 0x2a: Util::print("Set key gb\n"); break; + case 0x2b: Util::print("Set key r\n"); break; + case 0x2c: Util::print("Set convert\n"); break; + case 0x2d: Util::print("Set scissor\n"); break; + case 0x2e: Util::print("Set prim depth\n"); break; + case 0x2f: Util::print("Set other modes\n"); break; + case 0x30: Util::print("Load TLUT\n"); break; + case 0x32: Util::print("Set tile size\n"); break; + case 0x33: Util::print("Load block\n"); break; + case 0x34: Util::print("Load tile\n"); break; + case 0x35: Util::print("Set tile\n"); break; + case 0x36: Util::print("Fill rectangle\n"); break; + case 0x37: Util::print("Set fill color\n"); break; + case 0x38: Util::print("Set fog color\n"); break; + case 0x39: Util::print("Set blend color\n"); break; + case 0x3a: Util::print("Set prim color\n"); break; + case 0x3b: Util::print("Set env color\n"); break; + case 0x3c: Util::print("Set combine\n"); break; + case 0x3d: Util::print("Set texture image\n"); break; + case 0x3e: Util::print("Set mask image\n"); break; + case 0x3f: Util::print("Set color image\n"); break; } } @@ -130,13 +130,13 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) { if (len <= 0) return; if (len + (remaining_cmds * 4) > 0xFFFFF) { - util::panic("Too many RDP commands\n"); + Util::panic("Too many RDP commands\n"); return; } if (dpc.status.xbusDmemDma) { for (int i = 0; i < len; i += 4) { - u32 cmd = util::ReadAccess(rsp.dmem, (current + i) & 0xFFF); + u32 cmd = Util::ReadAccess(rsp.dmem, (current + i) & 0xFFF); cmd_buf[remaining_cmds + (i >> 2)] = cmd; } } else { @@ -144,7 +144,7 @@ void RDP::RunCommand(MI& mi, Registers& regs, RSP& rsp) { return; } for (int i = 0; i < len; i += 4) { - u32 cmd = util::ReadAccess(rdram.data(), current + i); + u32 cmd = Util::ReadAccess(rdram.data(), current + i); cmd_buf[remaining_cmds + (i >> 2)] = cmd; } } diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 1967b1ad..51b1378a 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -32,39 +32,39 @@ void RSP::Reset() { } inline void logRSP(const RSP& rsp, const u32 instr) { - util::print("{:04X} {:08X} ", rsp.oldPC, instr); + Util::print("{:04X} {:08X} ", rsp.oldPC, instr); for (int i = 0; i < 32; i++) { - util::print("{:08X} ", (u32)rsp.gpr[i]); + Util::print("{:08X} ", (u32)rsp.gpr[i]); } for (int i = 0; i < 32; i++) { for (int e = 0; e < 8; e++) { - util::print("{:04X}", rsp.vpr[i].element[e]); + Util::print("{:04X}", rsp.vpr[i].element[e]); } - util::print(" "); + Util::print(" "); } for (int e = 0; e < 8; e++) { - util::print("{:04X}", rsp.acc.h.element[e]); + Util::print("{:04X}", rsp.acc.h.element[e]); } - util::print(" "); + Util::print(" "); for (int e = 0; e < 8; e++) { - util::print("{:04X}", rsp.acc.m.element[e]); + Util::print("{:04X}", rsp.acc.m.element[e]); } - util::print(" "); + Util::print(" "); for (int e = 0; e < 8; e++) { - util::print("{:04X}", rsp.acc.l.element[e]); + Util::print("{:04X}", rsp.acc.l.element[e]); } - util::print(" {:04X} {:04X} {:02X}\n", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE()); - util::print("DMEM: {:02X}{:02X}\n", rsp.dmem[0x3c4], rsp.dmem[0x3c5]); + Util::print(" {:04X} {:04X} {:02X}\n", rsp.GetVCC(), rsp.GetVCO(), rsp.GetVCE()); + Util::print("DMEM: {:02X}{:02X}\n", rsp.dmem[0x3c4], rsp.dmem[0x3c5]); } void RSP::Step(Registers& regs, Mem& mem) { gpr[0] = 0; - u32 instr = util::ReadAccess(imem, pc & IMEM_DSIZE); + u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); oldPC = pc & 0xFFC; pc = nextPC & 0xFFC; nextPC += 4; @@ -87,7 +87,7 @@ auto RSP::Read(u32 addr) -> u32{ return AcquireSemaphore(); case 0x04080000: return pc & 0xFFC; default: - util::panic("Unimplemented SP register read {:08X}\n", addr); + Util::panic("Unimplemented SP register read {:08X}\n", addr); } } @@ -137,7 +137,7 @@ void RSP::Write(Mem& mem, Registers& regs, u32 addr, u32 value) { SetPC(value); } break; default: - util::panic("Unimplemented SP register write {:08X}, val: {:08X}\n", addr, value); + Util::panic("Unimplemented SP register write {:08X}, val: {:08X}\n", addr, value); } } } diff --git a/src/backend/core/dynarec/cop/cop0decode.cpp b/src/backend/core/dynarec/cop/cop0decode.cpp index b83bb9c8..8dedc1a9 100644 --- a/src/backend/core/dynarec/cop/cop0decode.cpp +++ b/src/backend/core/dynarec/cop/cop0decode.cpp @@ -36,9 +36,8 @@ void cop0Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x02: - code.mov(code.rbp, (u64)®s.cop0.index); - code.and_(code.dword[code.rbp], 0x3F); - code.mov(code.rsi, code.dword[code.rbp]); + code.and_(code.dword[code.rdi + offsetof(n64::Registers, cop0.index)], 0x3F); + code.mov(code.rsi, code.dword[code.rdi]); code.mov(code.rax, (u64)tlbw); code.call(code.rax); break; @@ -57,10 +56,10 @@ void cop0Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.mov(code.rax, (u64)eret); code.call(code.rax); break; - default: util::panic("Unimplemented COP0 function {} {} ({:08X}) ({:016lX})", mask_cop2 >> 3, mask_cop2 & 7, instr, regs.oldPC); + default: Util::panic("Unimplemented COP0 function {} {} ({:08X}) ({:016lX})", mask_cop2 >> 3, mask_cop2 & 7, instr, regs.oldPC); } break; - default: util::panic("Unimplemented COP0 instruction {} {}", mask_cop >> 4, mask_cop & 7); + default: Util::panic("Unimplemented COP0 instruction {} {}", mask_cop >> 4, mask_cop & 7); } } } \ No newline at end of file diff --git a/src/backend/core/dynarec/cop/cop0instructions.cpp b/src/backend/core/dynarec/cop/cop0instructions.cpp index 99d9778d..76c20f75 100644 --- a/src/backend/core/dynarec/cop/cop0instructions.cpp +++ b/src/backend/core/dynarec/cop/cop0instructions.cpp @@ -34,7 +34,7 @@ void eret(n64::Registers& regs) { void tlbr(n64::Registers& regs) { u8 Index = regs.cop0.index & 0b111111; if (Index >= 32) { - util::panic("TLBR with TLB index {}", Index); + Util::panic("TLBR with TLB index {}", Index); } TLBEntry entry = regs.cop0.tlb[Index]; @@ -54,7 +54,7 @@ void tlbw(n64::Registers& regs, int index_) { page_mask.mask = top | (top >> 1); if(index_ >= 32) { - util::panic("TLBWI with TLB index {}", index_); + Util::panic("TLBWI with TLB index {}", index_); } regs.cop0.tlb[index_].entryHi.raw = regs.cop0.entryHi.raw; diff --git a/src/backend/core/dynarec/cop/cop1decode.cpp b/src/backend/core/dynarec/cop/cop1decode.cpp index 9ec45eb4..10db3816 100644 --- a/src/backend/core/dynarec/cop/cop1decode.cpp +++ b/src/backend/core/dynarec/cop/cop1decode.cpp @@ -5,24 +5,6 @@ namespace n64::JIT { bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { Xbyak::CodeGenerator& code = cpu.code; - code.push(code.rbp); - code.mov(code.rbp, (u64)®s.cop0.status.raw); - code.mov(code.eax, code.dword[code.rbp]); - code.pop(code.rbp); - code.and_(code.eax, 0x20000000); - code.cmp(code.eax, 1); - code.je("NoException1"); - - code.mov(code.rdi, (u64)®s); - code.mov(code.rsi, (u64)ExceptionCode::CoprocessorUnusable); - code.mov(code.rdx, 1); - code.mov(code.rcx, 1); - code.mov(code.rax, (u64) FireException); - code.call(code.rax); - code.xor_(code.rax, code.rax); - code.ret(); - - code.L("NoException1"); u8 mask_sub = (instr >> 21) & 0x1F; u8 mask_fun = instr & 0x3F; @@ -46,7 +28,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x03: - util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); case 0x04: code.mov(code.rax, (u64)mtc1); code.call(code.rax); @@ -60,7 +42,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x07: - util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); case 0x08: switch(mask_branch) { case 0: @@ -83,7 +65,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.mov(code.rax, (u64)bl); code.call(code.rax); return true; - default: util::panic("Undefined BC COP1 {:02X}\n", mask_branch); + default: Util::panic("Undefined BC COP1 {:02X}\n", mask_branch); } break; case 0x10: // s @@ -153,7 +135,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x20: - util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); case 0x21: code.mov(code.rax, (u64)cvtds); code.call(code.rax); @@ -246,7 +228,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.mov(code.rdx, NGT); code.call(code.rax); break; - default: util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x11: // d @@ -320,7 +302,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x21: - util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU Reserved instruction exception!\n"); case 0x24: code.mov(code.rax, (u64)cvtwd); code.call(code.rax); @@ -409,7 +391,7 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.mov(code.rdx, NGT); code.call(code.rax); break; - default: util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x14: // w @@ -439,8 +421,8 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x24: - util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); - default: util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + default: Util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x15: // l @@ -470,13 +452,13 @@ bool cop1Decode(n64::Registers& regs, u32 instr, Dynarec& cpu) { code.call(code.rax); break; case 0x24: - util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); case 0x25: - util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); - default: util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + Util::panic("[RECOMPILER] FPU reserved instruction exception!\n"); + default: Util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; - default: util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7); + default: Util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7); } return false; diff --git a/src/backend/core/dynarec/cop/cop1instructions.cpp b/src/backend/core/dynarec/cop/cop1instructions.cpp index fe6d4caa..d3a4bf4e 100644 --- a/src/backend/core/dynarec/cop/cop1instructions.cpp +++ b/src/backend/core/dynarec/cop/cop1instructions.cpp @@ -120,7 +120,7 @@ void cfc1(n64::Registers& regs, u32 instr) { switch(fd) { case 0: val = regs.cop1.fcr0; break; case 31: val = regs.cop1.fcr31.raw; break; - default: util::panic("Undefined CFC1 with rd != 0 or 31\n"); + default: Util::panic("Undefined CFC1 with rd != 0 or 31\n"); } regs.gpr[RT(instr)] = val; } @@ -134,7 +134,7 @@ void ctc1(n64::Registers& regs, u32 instr) { val &= 0x183ffff; regs.cop1.fcr31.raw = val; } break; - default: util::panic("Undefined CTC1 with rd != 0 or 31\n"); + default: Util::panic("Undefined CTC1 with rd != 0 or 31\n"); } } diff --git a/src/backend/core/dynarec/decode.cpp b/src/backend/core/dynarec/decode.cpp index 5a124998..34647a22 100644 --- a/src/backend/core/dynarec/decode.cpp +++ b/src/backend/core/dynarec/decode.cpp @@ -4,48 +4,33 @@ #include namespace n64::JIT { +#define GPR_OFFSET(x) ((uintptr_t)®s.gpr[(x)] - (uintptr_t)®s) + void Dynarec::cop2Decode(n64::Registers& regs, u32 instr) { - code.mov(code.rbp, (u64)®s.cop0.status.raw); - code.mov(code.eax, code.dword[code.rbp]); - code.pop(code.rbp); - code.and_(code.eax, 0x40000000); - code.cmp(code.eax, 1); - code.je("NoException2"); - - code.mov(code.rsi, (u64)ExceptionCode::CoprocessorUnusable); - code.mov(code.rdx, 2); - code.mov(code.rcx, 1); - code.mov(code.rax, (u64) FireException); - code.call(code.rax); - code.xor_(code.eax, code.eax); - code.ret(); - - code.L("NoException2"); - - code.mov(code.rdi, (u64)this); - code.mov(code.rsi, (u64)®s); - code.mov(code.rdx, (u64)instr); + code.mov(rdi, (u64)this); + code.mov(rsi, (u64)®s); + code.mov(rdx, (u64)instr); switch(RS(instr)) { case 0x00: - code.mov(code.rax, (u64)mfc2); - code.call(code.rax); + code.mov(rax, (u64)mfc2); + code.call(rax); break; case 0x01: - code.mov(code.rax, (u64)dmfc2); - code.call(code.rax); + code.mov(rax, (u64)dmfc2); + code.call(rax); break; - case 0x02: case 0x06: code.nop(); break; + case 0x02: case 0x06: break; case 0x04: - code.mov(code.rax, (u64)mtc2); - code.call(code.rax); + code.mov(rax, (u64)mtc2); + code.call(rax); break; case 0x05: - code.mov(code.rax, (u64)dmtc2); - code.call(code.rax); + code.mov(rax, (u64)dmtc2); + code.call(rax); break; default: - util::panic("[RECOMPILER] Unhandled reserved instruction exception {:016X}\n", (u64)regs.pc); + Util::panic("[RECOMPILER] Unhandled reserved instruction exception {:016X}\n", (u64)regs.pc); } } @@ -56,297 +41,295 @@ bool Dynarec::special(n64::Registers& regs, u32 instr) { // 00rr_rccc switch (mask) { // TODO: named constants for clearer code case 0: - if (instr == 0) { - code.nop(); - } else { - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sll); - code.call(code.rax); + if (instr != 0) { + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sll); + code.call(rax); } break; case 0x02: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)srl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)srl); + code.call(rax); break; case 0x03: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sra); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sra); + code.call(rax); break; case 0x04: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sllv); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sllv); + code.call(rax); break; case 0x06: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)srlv); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)srlv); + code.call(rax); break; case 0x07: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)srav); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)srav); + code.call(rax); break; case 0x08: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)jr); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)jr); + code.call(rax); res = true; break; case 0x09: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)jalr); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)jalr); + code.call(rax); res = true; break; - case 0x0C: util::panic("[RECOMPILER] Unhandled syscall instruction {:016X}\n", (u64)regs.pc); - case 0x0D: util::panic("[RECOMPILER] Unhandled break instruction {:016X}\n", (u64)regs.pc); - case 0x0F: code.nop(); break; // SYNC + case 0x0C: Util::panic("[RECOMPILER] Unhandled syscall instruction {:016X}\n", (u64)regs.pc); + case 0x0D: Util::panic("[RECOMPILER] Unhandled break instruction {:016X}\n", (u64)regs.pc); + case 0x0F: break; // SYNC case 0x10: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)mfhi); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)mfhi); + code.call(rax); break; case 0x11: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)mthi); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)mthi); + code.call(rax); break; case 0x12: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)mflo); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)mflo); + code.call(rax); break; case 0x13: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)mtlo); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)mtlo); + code.call(rax); break; case 0x14: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsllv); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsllv); + code.call(rax); break; case 0x16: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsrlv); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsrlv); + code.call(rax); break; case 0x17: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsrav); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsrav); + code.call(rax); break; case 0x18: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)mult); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)mult); + code.call(rax); break; case 0x19: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)multu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)multu); + code.call(rax); break; case 0x1A: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)div); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)div); + code.call(rax); break; case 0x1B: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)divu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)divu); + code.call(rax); break; case 0x1C: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dmult); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dmult); + code.call(rax); break; case 0x1D: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dmultu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dmultu); + code.call(rax); break; case 0x1E: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)ddiv); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)ddiv); + code.call(rax); break; case 0x1F: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)ddivu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)ddivu); + code.call(rax); break; case 0x20: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)add); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)add); + code.call(rax); break; case 0x21: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)addu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)addu); + code.call(rax); break; case 0x22: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sub); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sub); + code.call(rax); break; case 0x23: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)subu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)subu); + code.call(rax); break; case 0x24: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)and_); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)and_); + code.call(rax); break; case 0x25: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)or_); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)or_); + code.call(rax); break; case 0x26: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)xor_); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)xor_); + code.call(rax); break; case 0x27: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)nor); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)nor); + code.call(rax); break; case 0x2A: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)slt); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)slt); + code.call(rax); break; case 0x2B: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sltu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sltu); + code.call(rax); break; case 0x2C: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dadd); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dadd); + code.call(rax); break; case 0x2D: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)daddu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)daddu); + code.call(rax); break; case 0x2E: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsub); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsub); + code.call(rax); break; case 0x2F: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsubu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsubu); + code.call(rax); break; case 0x30: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovge(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovge(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x31: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovae(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovae(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x32: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovl(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovl(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x33: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovb(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovb(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x34: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmove(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmove(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x36: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovne(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovne(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); res = true; break; case 0x38: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsll); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsll); + code.call(rax); break; case 0x3A: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsrl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsrl); + code.call(rax); break; case 0x3B: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsra); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsra); + code.call(rax); break; case 0x3C: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsll32); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsll32); + code.call(rax); break; case 0x3E: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsrl32); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsrl32); + code.call(rax); break; case 0x3F: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)dsra32); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)dsra32); + code.call(rax); break; default: - util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 7, mask & 7, instr, (u64)regs.oldPC); + Util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 7, mask & 7, instr, (u64)regs.oldPC); } return res; @@ -357,155 +340,147 @@ bool Dynarec::regimm(n64::Registers& regs, u32 instr) { // 000r_rccc switch (mask) { // TODO: named constants for clearer code case 0x00: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovl(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovl(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)b); + code.call(rax); break; case 0x01: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovge(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovge(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)b); + code.call(rax); break; case 0x02: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovl(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovl(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bl); + code.call(rax); break; case 0x03: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovge(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovge(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bl); + code.call(rax); break; case 0x08: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], s64(s16(instr))); - code.cmovge(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + s64(s16(instr))); + code.cmovge(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x09: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], u64(s64(s16(instr)))); - code.cmovae(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + u64(s64(s16(instr)))); + code.cmovae(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x0A: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], s64(s16(instr))); - code.cmovl(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + s64(s16(instr))); + code.cmovl(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x0B: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], u64(s64(s16(instr)))); - code.cmovb(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + u64(s64(s16(instr)))); + code.cmovb(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x0C: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], s64(s16(instr))); - code.cmove(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + s64(s16(instr))); + code.cmove(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x0E: - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], s64(s16(instr))); - code.cmovne(code.cl, code.ch); - code.mov(code.rsi, code.cl.cvt64()); - code.mov(code.rax, (u64)trap); - code.call(code.rax); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + s64(s16(instr))); + code.cmovne(cl, ch); + code.mov(rsi, cl.cvt64()); + code.mov(rax, (u64)trap); + code.call(rax); break; case 0x10: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovl(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)blink); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovl(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)blink); + code.call(rax); break; case 0x11: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovge(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)blink); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovge(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)blink); + code.call(rax); break; case 0x12: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovl(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bllink); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovl(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bllink); + code.call(rax); break; case 0x13: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)regs.gpr); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovge(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bllink); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovge(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bllink); + code.call(rax); break; default: - util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); + Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); } return true; @@ -515,340 +490,327 @@ bool Dynarec::Exec(n64::Registers& regs, Mem& mem, u32 instr) { u8 mask = (instr >> 26) & 0x3f; bool res = false; - code.mov(code.rdi, (u64)®s); - code.push(code.rbp); // 00rr_rccc switch(mask) { // TODO: named constants for clearer code case 0x00: res = special(regs, instr); break; case 0x01: res = regimm(regs, instr); break; case 0x02: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)j); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)j); + code.call(rax); res = true; break; case 0x03: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)jal); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)jal); + code.call(rax); res = true; break; case 0x04: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmove(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rbx, qword[rdi + GPR_OFFSET(RS(instr))]); + code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); + code.xor_(rdx, rdx); + code.cmp(rbx, rcx); + code.sete(dl); + code.mov(rax, (u64)b); + code.call(rax); res = true; break; case 0x05: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.r8, 0); - code.mov(code.r9, 1); - code.mov(code.rax, code.qword[code.rbp + offsetof(n64::Registers, gpr[RS(instr)])]); - code.mov(code.rcx, code.qword[code.rbp + offsetof(n64::Registers, gpr[RT(instr)])]); - code.cmp(code.rax, code.rcx); - code.cmovne(code.r8, code.r9); - code.mov(code.rdx, code.r8); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rbx, qword[rdi + GPR_OFFSET(RS(instr))]); + code.mov(rcx, qword[rdi + GPR_OFFSET(RT(instr))]); + code.xor_(rdx, rdx); + code.cmp(rbx, rcx); + code.setne(dl); + code.mov(rax, (u64)b); + code.call(rax); res = true; break; case 0x06: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovle(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rbx, qword[rdi + GPR_OFFSET(RS(instr))]); + code.test(rbx, rbx); + code.xor_(rdx, rdx); + code.setnz(dl); + code.mov(rax, (u64)b); + code.call(rax); res = true; break; case 0x07: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovg(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rbx, qword[rdi + GPR_OFFSET(RS(instr))]); + code.test(rbx, rbx); + code.xor_(rdx, rdx); + code.setg(dl); + code.mov(rax, (u64)b); + code.call(rax); res = true; break; case 0x08: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)addi); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)addi); + code.call(rax); break; case 0x09: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)addiu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)addiu); + code.call(rax); break; case 0x0A: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)slti); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)slti); + code.call(rax); break; case 0x0B: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)sltiu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)sltiu); + code.call(rax); break; case 0x0C: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)andi); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)andi); + code.call(rax); break; case 0x0D: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)ori); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)ori); + code.call(rax); break; case 0x0E: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)xori); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)xori); + code.call(rax); break; case 0x0F: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)lui); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)lui); + code.call(rax); break; case 0x10: cop0Decode(regs, instr, *this); break; case 0x11: res = cop1Decode(regs, instr, *this); break; case 0x12: cop2Decode(regs, instr); break; case 0x14: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmove(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmove(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bl); + code.call(rax); break; case 0x15: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], code.qword[RT(instr)]); - code.cmovne(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], + qword[rdi + GPR_OFFSET(RT(instr))]); + code.cmovne(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bl); + code.call(rax); break; case 0x16: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovle(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)bl); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovle(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)bl); + code.call(rax); break; case 0x17: - code.mov(code.rsi, (u64)instr); - code.mov(code.rbp, (u64)®s); - code.mov(code.cl, 0); - code.mov(code.ch, 1); - code.cmp(code.qword[RS(instr)], 0); - code.cmovg(code.cl, code.ch); - code.mov(code.rdx, code.cl.cvt64()); - code.mov(code.rax, (u64)b); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(cl, 0); + code.mov(ch, 1); + code.cmp(qword[rdi + GPR_OFFSET(RS(instr))], 0); + code.cmovg(cl, ch); + code.mov(rdx, cl.cvt64()); + code.mov(rax, (u64)b); + code.call(rax); break; case 0x18: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)daddi); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)daddi); + code.call(rax); break; case 0x19: - code.mov(code.rsi, (u64)instr); - code.mov(code.rax, (u64)daddiu); - code.call(code.rax); + code.mov(rsi, (u64)instr); + code.mov(rax, (u64)daddiu); + code.call(rax); break; case 0x1A: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)ldl); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)ldl); + code.call(rax); break; case 0x1B: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)ldr); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)ldr); + code.call(rax); break; - case 0x1F: util::panic("[RECOMPILER] Unhandled reserved instruction exception {:016X}\n", regs.oldPC); break; + case 0x1F: Util::panic("[RECOMPILER] Unhandled reserved instruction exception {:016X}\n", regs.oldPC); break; case 0x20: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lb); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lb); + code.call(rax); break; case 0x21: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lh); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lh); + code.call(rax); break; case 0x22: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lwl); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lwl); + code.call(rax); break; case 0x23: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lw); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lw); + code.call(rax); break; case 0x24: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lbu); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lbu); + code.call(rax); break; case 0x25: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lhu); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lhu); + code.call(rax); break; case 0x26: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lwr); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lwr); + code.call(rax); break; case 0x27: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lwu); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lwu); + code.call(rax); break; case 0x28: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sb); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sb); + code.call(rax); break; case 0x29: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sh); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sh); + code.call(rax); break; case 0x2A: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)swl); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)swl); + code.call(rax); break; case 0x2B: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sw); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sw); + code.call(rax); break; case 0x2C: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sdl); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sdl); + code.call(rax); break; case 0x2D: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sdr); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sdr); + code.call(rax); break; case 0x2E: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)swr); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)swr); + code.call(rax); break; - case 0x2F: code.nop(); break; // CACHE + case 0x2F: break; // CACHE case 0x30: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)ll); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)ll); + code.call(rax); break; case 0x31: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lwc1); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lwc1); + code.call(rax); break; case 0x34: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)lld); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)lld); + code.call(rax); break; case 0x35: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)ldc1); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)ldc1); + code.call(rax); break; case 0x37: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)ld); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)ld); + code.call(rax); break; case 0x38: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sc); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sc); + code.call(rax); break; case 0x39: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)swc1); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)swc1); + code.call(rax); break; case 0x3C: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)scd); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)scd); + code.call(rax); break; case 0x3D: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sdc1); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sdc1); + code.call(rax); break; case 0x3F: - code.mov(code.rsi, (u64)&mem); - code.mov(code.rdx, (u64)instr); - code.mov(code.rax, (u64)sd); - code.call(code.rax); + code.mov(rsi, (u64)&mem); + code.mov(rdx, (u64)instr); + code.mov(rax, (u64)sd); + code.call(rax); break; default: - util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})\n", mask, instr, (u64)regs.oldPC); + Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})\n", mask, instr, (u64)regs.oldPC); } - code.pop(code.rbp); return res; } } diff --git a/src/backend/core/interpreter/cop/cop0instructions.cpp b/src/backend/core/interpreter/cop/cop0instructions.cpp index 43c67067..b9fd947a 100644 --- a/src/backend/core/interpreter/cop/cop0instructions.cpp +++ b/src/backend/core/interpreter/cop/cop0instructions.cpp @@ -34,7 +34,7 @@ void Cop0::eret(Registers& regs) { void Cop0::tlbr(Registers& regs) { u8 Index = index & 0b111111; if (Index >= 32) { - util::panic("TLBR with TLB index {}", index); + Util::panic("TLBR with TLB index {}", index); } TLBEntry entry = tlb[Index]; @@ -55,7 +55,7 @@ void Cop0::tlbw(int index_, Registers& regs) { page_mask.mask = top | (top >> 1); if(index_ >= 32) { - util::panic("TLBWI with TLB index {}", index_); + Util::panic("TLBWI with TLB index {}", index_); } tlb[index_].entryHi.raw = entryHi.raw; diff --git a/src/backend/core/interpreter/cop/cop1instructions.cpp b/src/backend/core/interpreter/cop/cop1instructions.cpp index d9e34384..11c0064d 100644 --- a/src/backend/core/interpreter/cop/cop1instructions.cpp +++ b/src/backend/core/interpreter/cop/cop1instructions.cpp @@ -121,7 +121,7 @@ void Cop1::cfc1(Registers& regs, u32 instr) const { switch(fd) { case 0: val = fcr0; break; case 31: val = fcr31.raw; break; - default: util::panic("Undefined CFC1 with rd != 0 or 31\n"); + default: Util::panic("Undefined CFC1 with rd != 0 or 31\n"); } regs.gpr[RT(instr)] = val; } @@ -135,7 +135,7 @@ void Cop1::ctc1(Registers& regs, u32 instr) { val &= 0x183ffff; fcr31.raw = val; } break; - default: util::panic("Undefined CTC1 with rd != 0 or 31\n"); + default: Util::panic("Undefined CTC1 with rd != 0 or 31\n"); } } diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index eb088b00..9012f5e1 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -63,7 +63,7 @@ void Interpreter::special(Registers& regs, u32 instr) { case 0x3E: dsrl32(regs, instr); break; case 0x3F: dsra32(regs, instr); break; default: - util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 7, mask & 7, instr, (u64)regs.oldPC); + Util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 7, mask & 7, instr, (u64)regs.oldPC); } } @@ -86,7 +86,7 @@ void Interpreter::regimm(Registers& regs, u32 instr) { case 0x12: bllink(regs, instr, regs.gpr[RS(instr)] < 0); break; case 0x13: bllink(regs, instr, regs.gpr[RS(instr)] >= 0); break; default: - util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); + Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})\n", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); } } @@ -169,7 +169,7 @@ void Interpreter::Exec(Registers& regs, Mem& mem, u32 instr) { case 0x3D: regs.cop1.sdc1(regs, mem, instr); break; case 0x3F: sd(regs, mem, instr); break; default: - util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})\n", mask, instr, (u64)regs.oldPC); + Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})\n", mask, instr, (u64)regs.oldPC); } } } \ No newline at end of file diff --git a/src/backend/core/mmio/AI.cpp b/src/backend/core/mmio/AI.cpp index f7eec1e3..1b814684 100644 --- a/src/backend/core/mmio/AI.cpp +++ b/src/backend/core/mmio/AI.cpp @@ -69,7 +69,7 @@ void AI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { dac.precision = bitrate + 1; break; default: - util::panic("Unhandled AI write at addr {:08X} with val {:08X}\n", addr, val); + Util::panic("Unhandled AI write at addr {:08X} with val {:08X}\n", addr, val); } } @@ -84,7 +84,7 @@ void AI::Step(Mem& mem, Registers& regs, int cpuCycles, float volumeL, float vol if(volumeR > 0 && volumeL > 0) { u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF; dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF); - u32 data = util::ReadAccess(mem.mmio.rdp.rdram.data(), dmaAddr[0] & RDRAM_DSIZE); + u32 data = Util::ReadAccess(mem.mmio.rdp.rdram.data(), dmaAddr[0] & RDRAM_DSIZE); s16 l = s16(data >> 16); s16 r = s16(data); diff --git a/src/backend/core/mmio/MI.cpp b/src/backend/core/mmio/MI.cpp index 6742792f..5092573e 100644 --- a/src/backend/core/mmio/MI.cpp +++ b/src/backend/core/mmio/MI.cpp @@ -23,7 +23,7 @@ auto MI::Read(u32 paddr) const -> u32 { case 0x8: return miIntr.raw & 0x3F; case 0xC: return miIntrMask.raw & 0x3F; default: - util::panic("Unhandled MI[{:08X}] read\n", paddr); + Util::panic("Unhandled MI[{:08X}] read\n", paddr); } } @@ -78,7 +78,7 @@ void MI::Write(Registers& regs, u32 paddr, u32 val) { UpdateInterrupt(*this, regs); break; default: - util::panic("Unhandled MI[{:08X}] write ({:08X})\n", val, paddr); + Util::panic("Unhandled MI[{:08X}] write ({:08X})\n", val, paddr); } } } diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 9c3865d0..89b49d99 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -34,7 +34,7 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 { case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030: return stub[(addr & 0xff) - 5]; default: - util::panic("Unhandled PI[{:08X}] read\n", addr); + Util::panic("Unhandled PI[{:08X}] read\n", addr); } } @@ -57,7 +57,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { dramAddr = dram_addr + len; cartAddr = cart_addr + len; InterruptRaise(mi, regs, Interrupt::PI); - //util::print("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})\n", len, dramAddr, cartAddr); + //Util::print("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})\n", len, dramAddr, cartAddr); } break; case 0x0460000C: { u32 len = (val & 0x00FFFFFF) + 1; @@ -73,7 +73,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { dramAddr = dram_addr + len; cartAddr = cart_addr + len; InterruptRaise(mi, regs, Interrupt::PI); - //util::print("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})\n", len, cart_addr, dram_addr); + //Util::print("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})\n", len, cart_addr, dram_addr); } break; case 0x04600010: if(val & 2) { @@ -84,7 +84,7 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { stub[(addr & 0xff) - 5] = val & 0xff; break; default: - util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); + Util::panic("Unhandled PI[{:08X}] write ({:08X})\n", val, addr); } } } \ No newline at end of file diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 5911c121..c99e2044 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -53,7 +53,7 @@ void ProcessPIFCommands(u8* pifRam, Controller& controller, Mem& mem) { res[3] = controller.joy_y; break; case 2: case 3: res[0] = 0; break; - default: util::panic("Unimplemented PIF command {}", cmd[2]); + default: Util::panic("Unimplemented PIF command {}", cmd[2]); } i += t + rlen; diff --git a/src/backend/core/mmio/RI.cpp b/src/backend/core/mmio/RI.cpp index 6323f993..e206f45c 100644 --- a/src/backend/core/mmio/RI.cpp +++ b/src/backend/core/mmio/RI.cpp @@ -20,7 +20,7 @@ auto RI::Read(u32 addr) const -> u32 { case 0x0470000C: return select; case 0x04700010: return refresh; default: - util::panic("Unhandled RI[{:08X}] read\n", addr); + Util::panic("Unhandled RI[{:08X}] read\n", addr); } } @@ -31,7 +31,7 @@ void RI::Write(u32 addr, u32 val) { case 0x0470000C: select = val; break; case 0x04700010: refresh = val; break; default: - util::panic("Unhandled RI[{:08X}] write with val {:08X}\n", addr, val); + Util::panic("Unhandled RI[{:08X}] write with val {:08X}\n", addr, val); } } } diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 98ea29b0..7f67a9c7 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -28,7 +28,7 @@ auto SI::Read(MI& mi, u32 addr) const -> u32 { return val; } default: - util::panic("Unhandled SI[{:08X}] read\n", addr); + Util::panic("Unhandled SI[{:08X}] read\n", addr); } } @@ -45,7 +45,7 @@ void DMA(Mem& mem, Registers& regs) { for(int i = 0; i < 64; i++) { mem.pifRam[i] = mem.mmio.rdp.rdram[BYTE_ADDRESS(si.dramAddr + i)]; } - util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr); + Util::debug("SI DMA from PIF RAM to RDRAM ({:08X} to {:08X})\n", si.pifAddr, si.dramAddr); ProcessPIFCommands(mem.pifRam, si.controller, mem); } InterruptRaise(mem.mmio.mi, regs, Interrupt::SI); @@ -67,13 +67,13 @@ void SI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { status.dmaBusy = true; toDram = false; scheduler.enqueueRelative({SI_DMA_DELAY, DMA}); - util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF); + Util::debug("SI DMA from RDRAM to PIF RAM ({:08X} to {:08X})\n", dramAddr, val & 0x1FFFFFFF); } break; case 0x04800018: InterruptLower(mem.mmio.mi, regs, Interrupt::SI); break; default: - util::panic("Unhandled SI[%08X] write (%08X)\n", addr, val); + Util::panic("Unhandled SI[%08X] write (%08X)\n", addr, val); } } } \ No newline at end of file diff --git a/src/backend/core/mmio/VI.cpp b/src/backend/core/mmio/VI.cpp index d6ecef15..610ee289 100644 --- a/src/backend/core/mmio/VI.cpp +++ b/src/backend/core/mmio/VI.cpp @@ -39,7 +39,7 @@ u32 VI::Read(u32 paddr) const { case 0x04400030: return xscale.raw; case 0x04400034: return yscale.raw; default: - util::panic("Unimplemented VI[%08X] read\n", paddr); + Util::panic("Unimplemented VI[%08X] read\n", paddr); } } @@ -81,7 +81,7 @@ void VI::Write(MI& mi, Registers& regs, u32 paddr, u32 val) { case 0x04400030: xscale.raw = val; break; case 0x04400034: yscale.raw = val; break; default: - util::panic("Unimplemented VI[%08X] write (%08X)\n", paddr, val); + Util::panic("Unimplemented VI[%08X] write (%08X)\n", paddr, val); } } } \ No newline at end of file diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 9e828c63..6270eec6 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -48,7 +48,7 @@ u32 Cop0::GetReg32(u8 addr) { case 23: case 24: case 25: case 31: return openbus; default: - util::panic("Unsupported word read from COP0 register {}\n", index); + Util::panic("Unsupported word read from COP0 register {}\n", index); } } @@ -69,7 +69,7 @@ u64 Cop0::GetReg64(u8 addr) { case 23: case 24: case 25: case 31: return openbus; default: - util::panic("Unsupported word read from COP0 register {}\n", index); + Util::panic("Unsupported word read from COP0 register {}\n", index); } } @@ -131,7 +131,7 @@ void Cop0::SetReg32(u8 addr, u32 value) { case 23: case 24: case 25: case 31: break; default: - util::panic("Unsupported word read from COP0 register {}\n", index); + Util::panic("Unsupported word read from COP0 register {}\n", index); } } @@ -159,7 +159,7 @@ void Cop0::SetReg64(u8 addr, u64 value) { case COP0_REG_LLADDR: LLAddr = value; break; case COP0_REG_ERROREPC: ErrorEPC = (s64)value; break; default: - util::panic("Unsupported word write to COP0 register {}\n", addr); + Util::panic("Unsupported word write to COP0 register {}\n", addr); } } @@ -264,7 +264,7 @@ void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC) regs.cop0.cause.exceptionCode = static_cast(code); if(regs.cop0.status.bev) { - util::panic("BEV bit set!\n"); + Util::panic("BEV bit set!\n"); } else { switch(code) { case ExceptionCode::Interrupt: case ExceptionCode::TLBModification: @@ -285,7 +285,7 @@ void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC) regs.SetPC(s64(s32(0x80000000))); } break; - default: util::panic("Unhandled exception! {}\n", static_cast(code)); + default: Util::panic("Unhandled exception! {}\n", static_cast(code)); } } } @@ -303,7 +303,7 @@ void HandleTLBException(Registers& regs, u64 vaddr) { ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { switch(error) { - case NONE: util::panic("Getting TLB exception with error NONE\n"); + case NONE: Util::panic("Getting TLB exception with error NONE\n"); case INVALID: case MISS: return accessType == LOAD ? ExceptionCode::TLBLoad : ExceptionCode::TLBStore; @@ -313,7 +313,7 @@ ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { return accessType == LOAD ? ExceptionCode::AddressErrorLoad : ExceptionCode::AddressErrorStore; default: - util::panic("Getting TLB exception for unknown error code! ({})\n", error); + Util::panic("Getting TLB exception for unknown error code! ({})\n", error); } } @@ -332,10 +332,10 @@ void Cop0::decode(Registers& regs, Mem& mem, u32 instr) { case 0x06: tlbw(GetRandom(), regs); break; case 0x08: tlbp(regs); break; case 0x18: eret(regs); break; - default: util::panic("Unimplemented COP0 function {} {} ({:08X}) ({:016lX})", mask_cop2 >> 3, mask_cop2 & 7, instr, regs.oldPC); + default: Util::panic("Unimplemented COP0 function {} {} ({:08X}) ({:016lX})", mask_cop2 >> 3, mask_cop2 & 7, instr, regs.oldPC); } break; - default: util::panic("Unimplemented COP0 instruction {} {}", mask_cop >> 4, mask_cop & 7); + default: Util::panic("Unimplemented COP0 instruction {} {}", mask_cop >> 4, mask_cop & 7); } } } \ No newline at end of file diff --git a/src/backend/core/registers/Cop1.cpp b/src/backend/core/registers/Cop1.cpp index 2df1c63f..f632a05c 100644 --- a/src/backend/core/registers/Cop1.cpp +++ b/src/backend/core/registers/Cop1.cpp @@ -39,7 +39,7 @@ void Cop1::decode(Registers& regs, Interpreter& cpu, u32 instr) { case 1: cpu.b(regs, instr, regs.cop1.fcr31.compare); break; case 2: cpu.bl(regs, instr, !regs.cop1.fcr31.compare); break; case 3: cpu.bl(regs, instr, regs.cop1.fcr31.compare); break; - default: util::panic("Undefined BC COP1 {:02X}\n", mask_branch); + default: Util::panic("Undefined BC COP1 {:02X}\n", mask_branch); } break; case 0x10: // s @@ -82,7 +82,7 @@ void Cop1::decode(Registers& regs, Interpreter& cpu, u32 instr) { case 0x3D: ccond(regs, instr, NGE); break; case 0x3E: ccond(regs, instr, LE); break; case 0x3F: ccond(regs, instr, NGT); break; - default: util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x11: // d @@ -125,7 +125,7 @@ void Cop1::decode(Registers& regs, Interpreter& cpu, u32 instr) { case 0x3D: ccond(regs, instr, NGE); break; case 0x3E: ccond(regs, instr, LE); break; case 0x3F: ccond(regs, instr, NGT); break; - default: util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x14: // w @@ -139,7 +139,7 @@ void Cop1::decode(Registers& regs, Interpreter& cpu, u32 instr) { case 0x24: FireException(regs, ExceptionCode::ReservedInstruction, 1, true); break; - default: util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; case 0x15: // l @@ -156,10 +156,10 @@ void Cop1::decode(Registers& regs, Interpreter& cpu, u32 instr) { case 0x25: FireException(regs, ExceptionCode::ReservedInstruction, 1, true); break; - default: util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); + default: Util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC); } break; - default: util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7); + default: Util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7); } } } \ No newline at end of file diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index 0a73ccf6..114409aa 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -7,7 +7,7 @@ namespace n64 { inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) { u8 mask = instr & 0x3f; - //util::print("rsp special {:02X}\n", mask); + //Util::print("rsp special {:02X}\n", mask); switch(mask) { case 0x00: if(instr != 0) { @@ -41,25 +41,25 @@ inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) { case 0x27: rsp.nor(instr); break; case 0x2A: rsp.slt(instr); break; case 0x2B: rsp.sltu(instr); break; - default: util::panic("Unhandled RSP special instruction ({:06b})\n", mask); + default: Util::panic("Unhandled RSP special instruction ({:06b})\n", mask); } } inline void regimm(RSP& rsp, u32 instr) { u8 mask = ((instr >> 16) & 0x1F); - //util::print("rsp regimm {:02X}\n", mask); + //Util::print("rsp regimm {:02X}\n", mask); switch(mask) { case 0x00: rsp.b(instr, (s32)rsp.gpr[RS(instr)] < 0); break; case 0x01: rsp.b(instr, (s32)rsp.gpr[RS(instr)] >= 0); break; case 0x10: rsp.blink(instr, (s32)rsp.gpr[RS(instr)] < 0); break; case 0x11: rsp.blink(instr, (s32)rsp.gpr[RS(instr)] >= 0); break; - default: util::panic("Unhandled RSP regimm instruction ({:05b})\n", mask); + default: Util::panic("Unhandled RSP regimm instruction ({:05b})\n", mask); } } inline void lwc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; - //util::print("lwc2 {:02X}\n", mask); + //Util::print("lwc2 {:02X}\n", mask); switch(mask) { case 0x00: rsp.lbv(instr); break; case 0x01: rsp.lsv(instr); break; @@ -71,13 +71,13 @@ inline void lwc2(RSP& rsp, u32 instr) { case 0x07: rsp.luv(instr); break; case 0x0A: break; case 0x0B: rsp.ltv(instr); break; - default: util::panic("Unhandled RSP LWC2 {:05b}\n", mask); + default: Util::panic("Unhandled RSP LWC2 {:05b}\n", mask); } } inline void swc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; - //util::print("swc2 {:02X}\n", mask); + //Util::print("swc2 {:02X}\n", mask); switch(mask) { case 0x00: rsp.sbv(instr); break; case 0x01: rsp.ssv(instr); break; @@ -88,14 +88,14 @@ inline void swc2(RSP& rsp, u32 instr) { case 0x07: rsp.suv(instr); break; case 0x0A: rsp.swv(instr); break; case 0x0B: rsp.stv(instr); break; - default: util::panic("Unhandled RSP SWC2 {:05b}\n", mask); + default: Util::panic("Unhandled RSP SWC2 {:05b}\n", mask); } } inline void cop2(RSP& rsp, u32 instr) { u8 mask = instr & 0x3F; u8 mask_sub = (instr >> 21) & 0x1F; - //util::print("Cop2 {:02X}\n", mask); + //Util::print("Cop2 {:02X}\n", mask); switch(mask) { case 0x00: if((instr >> 25) & 1) { @@ -106,7 +106,7 @@ inline void cop2(RSP& rsp, u32 instr) { case 0x02: rsp.cfc2(instr); break; case 0x04: rsp.mtc2(instr); break; case 0x06: rsp.ctc2(instr); break; - default: util::panic("Unhandled RSP COP2 sub ({:05b})\n", mask_sub); + default: Util::panic("Unhandled RSP COP2 sub ({:05b})\n", mask_sub); } } break; @@ -150,7 +150,7 @@ inline void cop2(RSP& rsp, u32 instr) { case 0x33: rsp.vmov(instr); break; case 0x34: rsp.vrsq(instr); break; case 0x37: case 0x3F: break; - default: util::panic("Unhandled RSP COP2 ({:06b})\n", mask); + default: Util::panic("Unhandled RSP COP2 ({:06b})\n", mask); } } @@ -159,15 +159,15 @@ inline void cop0(Registers& regs, Mem& mem, u32 instr) { MMIO& mmio = mem.mmio; RSP& rsp = mmio.rsp; RDP& rdp = mmio.rdp; - //util::print("Cop0 {:02X}\n", mask); + //Util::print("Cop0 {:02X}\n", mask); if((instr & 0x7FF) == 0) { switch (mask) { case 0x00: rsp.mfc0(rdp, instr); break; case 0x04: rsp.mtc0(regs, mem, instr); break; - default: util::panic("Unhandled RSP COP0 ({:05b})\n", mask); + default: Util::panic("Unhandled RSP COP0 ({:05b})\n", mask); } } else { - util::panic("RSP COP0 unknown {:08X}\n", instr); + Util::panic("RSP COP0 unknown {:08X}\n", instr); } } @@ -176,7 +176,7 @@ void RSP::Exec(Registers ®s, Mem& mem, u32 instr) { MMIO& mmio = mem.mmio; RDP& rdp = mmio.rdp; MI& mi = mmio.mi; - //util::print("RSP {:02X}\n", mask); + //Util::print("RSP {:02X}\n", mask); switch(mask) { case 0x00: special(mi, regs, *this, instr); break; case 0x01: regimm(*this, instr); break; @@ -211,11 +211,11 @@ void RSP::Exec(Registers ®s, Mem& mem, u32 instr) { FILE *fp = fopen("imem.bin", "wb"); u8 *temp = (u8*)calloc(IMEM_SIZE, 1); memcpy(temp, imem, IMEM_SIZE); - util::SwapBuffer32(IMEM_SIZE, temp); + Util::SwapBuffer32(IMEM_SIZE, temp); fwrite(temp, 1, IMEM_SIZE, fp); free(temp); fclose(fp); - util::panic("Unhandled RSP instruction ({:06b}, {:04X})\n", mask, oldPC); + Util::panic("Unhandled RSP instruction ({:06b}, {:04X})\n", mask, oldPC); } } } \ No newline at end of file diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 9beb0943..1d1bddf2 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -45,7 +45,7 @@ inline auto GetCop0Reg(RSP& rsp, RDP& rdp, u8 index) -> u32{ case 13: return rdp.dpc.status.cmdBusy; case 14: return rdp.dpc.status.pipeBusy; case 15: return rdp.dpc.status.tmemBusy; - default: util::panic("Unhandled RSP COP0 register read at index {}\n", index); + default: Util::panic("Unhandled RSP COP0 register read at index {}\n", index); } } @@ -70,13 +70,13 @@ inline void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) { if(val == 0) { ReleaseSemaphore(rsp); } else { - util::panic("Write with non-zero value to RSP_COP0_RESERVED ({})\n", val); + Util::panic("Write with non-zero value to RSP_COP0_RESERVED ({})\n", val); } break; case 8: rdp.WriteStart(val); break; case 9: rdp.WriteEnd(mi, regs, rsp, val); break; case 11: rdp.WriteStatus(mi, regs, rsp, val); break; - default: util::panic("Unhandled RSP COP0 register write at index {}\n", index); + default: Util::panic("Unhandled RSP COP0 register write at index {}\n", index); } } @@ -735,7 +735,7 @@ void RSP::vmov(u32 instr) { se = (e & 0b111) | (vs & 0b000); break; default: - util::panic("VMOV: This should be unreachable!\n"); + Util::panic("VMOV: This should be unreachable!\n"); } u8 de = vs & 7; diff --git a/src/frontend/App.cpp b/src/frontend/App.cpp index 48fc3740..629f1737 100644 --- a/src/frontend/App.cpp +++ b/src/frontend/App.cpp @@ -4,7 +4,7 @@ App::App() : window(core) { DiscordEventHandlers handlers{}; Discord_Initialize("1049669178124148806", &handlers, 1, nullptr); - util::UpdateRPC(util::Idling); + Util::UpdateRPC(Util::Idling); } void App::Run() { diff --git a/src/frontend/App.hpp b/src/frontend/App.hpp index bd399f06..90ed1c28 100644 --- a/src/frontend/App.hpp +++ b/src/frontend/App.hpp @@ -4,7 +4,7 @@ struct App { App(); - ~App() { util::ClearRPC(); } + ~App() { Util::ClearRPC(); } void Run(); inline void LoadROM(const std::string& path) { window.LoadROM(core, path); diff --git a/src/frontend/imgui/GameList.cpp b/src/frontend/imgui/GameList.cpp index 4bf4cdea..90f38e0f 100644 --- a/src/frontend/imgui/GameList.cpp +++ b/src/frontend/imgui/GameList.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace nlohmann; namespace fs = std::filesystem; @@ -25,12 +26,12 @@ GameList::GameList(const std::string& path) { file.unsetf(std::ios::skipws); if(!file.is_open()) { - util::panic("Unable to open {}!", filename); + Util::panic("Unable to open {}!", filename); } file.seekg(0, std::ios::end); auto size = file.tellg(); - auto sizeAdjusted = util::NextPow2(size); + auto sizeAdjusted = Util::NextPow2(size); file.seekg(0, std::ios::beg); std::fill(rom.begin(), rom.end(), 0); @@ -39,7 +40,7 @@ GameList::GameList(const std::string& path) { file.close(); u32 crc{}; - util::GetRomCRC(sizeAdjusted, rom.data(), crc); + Util::GetRomCRC(sizeAdjusted, rom.data(), crc); bool found = false; @@ -72,6 +73,7 @@ GameList::GameList(const std::string& path) { }; gameDbFile.close(); + threadDone = true; }); searchThread.detach(); @@ -93,10 +95,9 @@ bool GameList::RenderWidget(float mainMenuBarHeight, std::string& rom) { ); static ImGuiTableFlags flags = - ImGuiTableFlags_Resizable - | ImGuiTableFlags_RowBg - | ImGuiTableFlags_BordersOuterV - | ImGuiTableFlags_SizingStretchProp; + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti + | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody + | ImGuiTableFlags_ScrollY; bool toOpen = false; if (ImGui::BeginTable("Games List", 4, flags)) { @@ -104,6 +105,7 @@ bool GameList::RenderWidget(float mainMenuBarHeight, std::string& rom) { ImGui::TableSetupColumn("Region"); ImGui::TableSetupColumn("Status"); ImGui::TableSetupColumn("Size"); + ImGui::TableSetupScrollFreeze(0, 1); // Make row always visible ImGui::TableHeadersRow(); int i = 0; diff --git a/src/frontend/imgui/GameList.hpp b/src/frontend/imgui/GameList.hpp index b041905c..c2c06fbf 100644 --- a/src/frontend/imgui/GameList.hpp +++ b/src/frontend/imgui/GameList.hpp @@ -1,6 +1,14 @@ #pragma once #include #include +#include + +enum GameInfoID { + Name_ID, + Region_ID, + Size_ID, + Status_ID +}; struct GameInfo { std::string name, region, size, status, path; @@ -15,4 +23,5 @@ struct GameList { [[nodiscard]] std::vector GetGamesList() const { return gamesList; } private: std::vector gamesList{}, notMatch{}; + std::atomic_bool threadDone = false; }; diff --git a/src/frontend/imgui/Settings.cpp b/src/frontend/imgui/Settings.cpp index cb18f326..bdf1c20d 100644 --- a/src/frontend/imgui/Settings.cpp +++ b/src/frontend/imgui/Settings.cpp @@ -35,7 +35,7 @@ Settings::Settings(n64::Core& core) { } else if(cpuType == "interpreter") { core.cpuType = n64::CpuType::Interpreter; } else { - util::panic("Unrecognized cpu type: {}\n", cpuType); + Util::panic("Unrecognized cpu type: {}\n", cpuType); } } else { settingsFile.clear(); diff --git a/src/frontend/imgui/Window.cpp b/src/frontend/imgui/Window.cpp index 7e45b241..4eaed421 100644 --- a/src/frontend/imgui/Window.cpp +++ b/src/frontend/imgui/Window.cpp @@ -39,13 +39,13 @@ void Window::InitSDL() { windowID = SDL_GetWindowID(window); if(volkInitialize() != VK_SUCCESS) { - util::panic("Failed to load Volk!"); + Util::panic("Failed to load Volk!"); } } static void check_vk_result(VkResult err) { if (err) { - util::panic("[vulkan] Error: VkResult = {}", err); + Util::panic("[vulkan] Error: VkResult = {}", err); } } @@ -181,7 +181,7 @@ void Window::LoadROM(n64::Core& core, const std::string &path) { gameName = fs::path(path).stem().string(); } - util::UpdateRPC(util::Playing, gameName); + Util::UpdateRPC(Util::Playing, gameName); windowTitle = "Gadolinium - " + gameName; shadowWindowTitle = windowTitle; renderGameList = false; @@ -215,7 +215,7 @@ float Window::Render(n64::Core& core) { nfdresult_t result = NFD_OpenDialog(&outpath, &filter, 1, nullptr); if (result == NFD_OKAY) { LoadROM(core, outpath); - util::UpdateRPC(util::Playing, gameName); + Util::UpdateRPC(Util::Playing, gameName); NFD_FreePath(outpath); } } @@ -241,7 +241,7 @@ float Window::Render(n64::Core& core) { renderGameList = true; windowTitle = "Gadolinium"; core.rom.clear(); - util::UpdateRPC(util::Idling); + Util::UpdateRPC(Util::Idling); SDL_SetWindowTitle(window, windowTitle.c_str()); core.Stop(); } @@ -250,10 +250,10 @@ float Window::Render(n64::Core& core) { if(core.pause) { shadowWindowTitle = windowTitle; windowTitle += " | Paused"; - util::UpdateRPC(util::Paused, gameName); + Util::UpdateRPC(Util::Paused, gameName); } else { windowTitle = shadowWindowTitle; - util::UpdateRPC(util::Playing, gameName); + Util::UpdateRPC(Util::Playing, gameName); } SDL_SetWindowTitle(window, windowTitle.c_str()); } diff --git a/src/utils/File.hpp b/src/utils/File.hpp index b0d58ca9..b9b3d4aa 100644 --- a/src/utils/File.hpp +++ b/src/utils/File.hpp @@ -2,7 +2,7 @@ #include #include -namespace util { +namespace Util { inline auto ReadFileBinary(const std::string& path, u32** buf) { std::ifstream file(path, std::ios::binary); file.unsetf(std::ios::skipws); diff --git a/src/utils/MemoryHelpers.hpp b/src/utils/MemoryHelpers.hpp index 8b7f7519..f3556a71 100644 --- a/src/utils/MemoryHelpers.hpp +++ b/src/utils/MemoryHelpers.hpp @@ -4,7 +4,7 @@ #include #include -namespace util { +namespace Util { template inline T ReadAccess(u8 *data, u32 index) { if constexpr (sizeof(T) == 1) { diff --git a/src/utils/log.hpp b/src/utils/log.hpp index 5b306379..07d90f18 100644 --- a/src/utils/log.hpp +++ b/src/utils/log.hpp @@ -3,7 +3,7 @@ #include #include -namespace util { +namespace Util { enum MessageType : u8 { Info, Debug, Warn, Error };