diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 10a8ae70..40a399f8 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -23,7 +23,7 @@ void Core::LoadROM(const std::string &rom_) { std::string archive_types[] = {".zip", ".7z", ".rar", ".tar"}; auto extension = fs::path(rom).extension().string(); - bool isArchive = std::any_of(std::begin(archive_types), std::end(archive_types), + const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; }); cpu->GetMem().LoadROM(isArchive, rom); diff --git a/src/backend/GameDB.cpp b/src/backend/GameDB.cpp index 01abd05a..52f7bec3 100644 --- a/src/backend/GameDB.cpp +++ b/src/backend/GameDB.cpp @@ -3,29 +3,29 @@ namespace n64 { void GameDB::match(Mem &mem) { - ROM &rom = mem.rom; - for (const auto &i : gamedb) { - bool matches_code = i.code == rom.code; + const ROM &rom = mem.rom; + for (const auto &[code, regions, saveType, name] : gamedb) { + const bool matches_code = code == rom.code; bool matches_region = false; - for (int j = 0; j < i.regions.size() && !matches_region; j++) { - if (i.regions[j] == rom.header.countryCode[0]) { + for (int j = 0; j < regions.size() && !matches_region; j++) { + if (regions[j] == rom.header.countryCode[0]) { matches_region = true; } } if (matches_code) { if (matches_region) { - mem.saveType = i.saveType; - mem.rom.gameNameDB = i.name; + mem.saveType = saveType; + mem.rom.gameNameDB = name; return; } Util::warn( "Matched code for {}, but not region! Game supposedly exists in regions [{}] but this image has region {}", - i.name, i.regions, rom.header.countryCode[0]); - mem.saveType = i.saveType; - mem.rom.gameNameDB = i.name; + name, regions, rom.header.countryCode[0]); + mem.saveType = saveType; + mem.rom.gameNameDB = name; return; } } diff --git a/src/backend/Scheduler.cpp b/src/backend/Scheduler.cpp index a7859d1c..87080aee 100644 --- a/src/backend/Scheduler.cpp +++ b/src/backend/Scheduler.cpp @@ -2,16 +2,16 @@ #include #include -void Scheduler::EnqueueRelative(u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); } +void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbsolute(t + ticks, type); } -void Scheduler::EnqueueAbsolute(u64 t, const EventType type) { events.push({t, type}); } +void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); } -u64 Scheduler::Remove(EventType type) { - for (auto &e : events) { - if (e.type == type) { - u64 ret = e.time - ticks; - e.type = NONE; - e.time = ticks; +u64 Scheduler::Remove(const EventType eventType) const { + for (auto &[time, type] : events) { + if (type == eventType) { + const u64 ret = time - ticks; + type = NONE; + time = ticks; return ret; } } @@ -19,14 +19,14 @@ u64 Scheduler::Remove(EventType type) { return 0; } -void Scheduler::Tick(u64 t, n64::Mem &mem) { +void Scheduler::Tick(const u64 t, n64::Mem &mem) { ticks += t; n64::MI &mi = mem.mmio.mi; n64::SI &si = mem.mmio.si; n64::PI &pi = mem.mmio.pi; while (ticks >= events.top().time) { - switch (auto type = events.top().type) { + switch (const auto type = events.top().type) { case SI_DMA: si.DMA(); break; diff --git a/src/backend/Scheduler.hpp b/src/backend/Scheduler.hpp index e7bd04fa..33dd8d78 100644 --- a/src/backend/Scheduler.hpp +++ b/src/backend/Scheduler.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include @@ -25,13 +24,12 @@ struct Event { struct IterableEvents { std::priority_queue, std::greater<>> events; -public: explicit IterableEvents() = default; [[nodiscard]] auto top() const { return events.top(); } auto pop() { events.pop(); } - [[nodiscard]] auto begin() const { return (Event *)(&events.top()); } + [[nodiscard]] auto begin() const { return const_cast(&events.top()); } [[nodiscard]] auto end() const { return begin() + events.size(); } - auto push(Event e) { events.push(e); } + auto push(const Event e) { events.push(e); } }; struct Scheduler { @@ -39,10 +37,10 @@ struct Scheduler { void EnqueueRelative(u64, EventType); void EnqueueAbsolute(u64, EventType); - u64 Remove(EventType); + [[nodiscard]] u64 Remove(EventType) const; void Tick(u64 t, n64::Mem &); - IterableEvents events; + IterableEvents events{}; u64 ticks = 0; u8 index = 0; }; diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp index 9184006d..3857276f 100644 --- a/src/backend/core/BaseCPU.hpp +++ b/src/backend/core/BaseCPU.hpp @@ -8,12 +8,12 @@ struct BaseCPU { virtual ~BaseCPU() = default; virtual int Step() = 0; virtual void Reset() = 0; - virtual bool ShouldServiceInterrupt() = 0; + [[nodiscard]] virtual bool ShouldServiceInterrupt() const = 0; virtual void CheckCompareInterrupt() = 0; virtual std::vector Serialize() = 0; virtual void Deserialize(const std::vector &) = 0; virtual Mem &GetMem() = 0; virtual Registers &GetRegs() = 0; - virtual Disassembler::DisassemblyResult Disassemble(u32, u32) const = 0; + [[nodiscard]] virtual Disassembler::DisassemblyResult Disassemble(u32, u32) const = 0; }; } // namespace n64 diff --git a/src/backend/core/Disassembler.cpp b/src/backend/core/Disassembler.cpp index de23b618..4d063da0 100644 --- a/src/backend/core/Disassembler.cpp +++ b/src/backend/core/Disassembler.cpp @@ -1,9 +1,9 @@ #include -Disassembler::DisassemblyResult Disassembler::DisassembleSimple(u32 address, u32 instruction) { +Disassembler::DisassemblyResult Disassembler::DisassembleSimple(const u32 address, const u32 instruction) const { cs_insn *insn; - auto bytes = Util::IntegralToBuffer(instruction); - auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); + const auto bytes = Util::IntegralToBuffer(instruction); + const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); if (count <= 0) return {}; @@ -15,10 +15,10 @@ Disassembler::DisassemblyResult Disassembler::DisassembleSimple(u32 address, u32 return result; } -Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(u32 address, u32 instruction) { +Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(const u32 address, const u32 instruction) const { cs_insn *insn; - auto bytes = Util::IntegralToBuffer(instruction); - auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); + const auto bytes = Util::IntegralToBuffer(instruction); + const auto count = cs_disasm(handle, bytes.data(), bytes.size(), address, 0, &insn); if (count <= 0) return {}; @@ -27,10 +27,10 @@ Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(u32 address, u result.address = insn[0].address; result.mnemonic = insn[0].mnemonic; - result.full += result.address + ":\t"; + result.full += fmt::format("0x{:016X}", result.address) + ":\t"; result.full += result.mnemonic + "\t"; - cs_detail *details = insn[0].detail; + const cs_detail *details = insn[0].detail; auto formatOperand = [&](const cs_mips_op &operand) { switch (operand.type) { case MIPS_OP_IMM: @@ -39,6 +39,8 @@ Disassembler::DisassemblyResult Disassembler::DisassembleDetailed(u32 address, u return fmt::format("{}(0x{:X})", cs_reg_name(handle, operand.mem.base), operand.mem.disp); case MIPS_OP_REG: return fmt::format("{}", cs_reg_name(handle, operand.reg)); + default: + return std::string{""}; } }; diff --git a/src/backend/core/Disassembler.hpp b/src/backend/core/Disassembler.hpp index d03ff8a1..240c57e8 100644 --- a/src/backend/core/Disassembler.hpp +++ b/src/backend/core/Disassembler.hpp @@ -25,8 +25,8 @@ struct Disassembler { ~Disassembler() { cs_close(&handle); } private: - DisassemblyResult DisassembleDetailed(u32 address, u32 instruction); - DisassemblyResult DisassembleSimple(u32 address, u32 instruction); + DisassemblyResult DisassembleDetailed(u32 address, u32 instruction) const; + DisassemblyResult DisassembleSimple(u32 address, u32 instruction) const; explicit Disassembler(const bool rsp) : rsp(rsp) { if (cs_open(CS_ARCH_MIPS, static_cast((rsp ? CS_MODE_32 : CS_MODE_64) | CS_MODE_BIG_ENDIAN), &handle) != diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 4f0be20c..ae79f3ce 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -3,11 +3,11 @@ namespace n64 { Interpreter::Interpreter(ParallelRDP ¶llel) : mem(regs, parallel) {} -bool Interpreter::ShouldServiceInterrupt() { - bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; - bool interrupts_enabled = regs.cop0.status.ie == 1; - bool currently_handling_exception = regs.cop0.status.exl == 1; - bool currently_handling_error = regs.cop0.status.erl == 1; +bool Interpreter::ShouldServiceInterrupt() const { + const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; + const bool interrupts_enabled = regs.cop0.status.ie == 1; + const bool currently_handling_exception = regs.cop0.status.exl == 1; + const bool currently_handling_error = regs.cop0.status.erl == 1; return interrupts_pending && interrupts_enabled && !currently_handling_exception && !currently_handling_error; } @@ -15,13 +15,13 @@ bool Interpreter::ShouldServiceInterrupt() { void Interpreter::CheckCompareInterrupt() { regs.cop0.count++; regs.cop0.count &= 0x1FFFFFFFF; - if (regs.cop0.count == (u64)regs.cop0.compare << 1) { + if (regs.cop0.count == static_cast(regs.cop0.compare) << 1) { regs.cop0.cause.ip7 = 1; mem.mmio.mi.UpdateInterrupt(); } } -Disassembler::DisassemblyResult Interpreter::Disassemble(u32 address, u32 instruction) const { +Disassembler::DisassemblyResult Interpreter::Disassemble(const u32 address, const u32 instruction) const { return Disassembler::instance().Disassemble(address, instruction); } @@ -40,11 +40,11 @@ int Interpreter::Step() { u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, regs.pc, paddr)) { regs.cop0.HandleTLBException(regs.pc); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.pc); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.pc); return 1; } - u32 instruction = mem.Read(regs, paddr); + const u32 instruction = mem.Read(regs, paddr); if (ShouldServiceInterrupt()) { regs.cop0.FireException(ExceptionCode::Interrupt, 0, regs.pc); diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 3742a2ea..89c906a8 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -20,7 +20,7 @@ struct Interpreter : BaseCPU { Mem &GetMem() override { return mem; } Registers &GetRegs() override { return regs; } - Disassembler::DisassemblyResult Disassemble(u32, u32) const override; + [[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override; private: Registers regs; @@ -29,7 +29,7 @@ private: friend struct Cop1; #define check_address_error(mask, vaddr) \ (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) - bool ShouldServiceInterrupt() override; + bool ShouldServiceInterrupt() const override; void CheckCompareInterrupt() override; std::vector Serialize() override; void Deserialize(const std::vector &) override; @@ -118,7 +118,7 @@ private: void srav(u32); void srl(u32); void srlv(u32); - void trap(bool); + void trap(bool) const; void or_(u32); void ori(u32); void xor_(u32); diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index ee3b34fd..261fba58 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -4,11 +4,11 @@ namespace n64 { JIT::JIT(ParallelRDP ¶llel) : mem(regs, parallel) {} -bool JIT::ShouldServiceInterrupt() { - bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; - bool interrupts_enabled = regs.cop0.status.ie == 1; - bool currently_handling_exception = regs.cop0.status.exl == 1; - bool currently_handling_error = regs.cop0.status.erl == 1; +bool JIT::ShouldServiceInterrupt() const { + const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; + const bool interrupts_enabled = regs.cop0.status.ie == 1; + const bool currently_handling_exception = regs.cop0.status.exl == 1; + const bool currently_handling_error = regs.cop0.status.erl == 1; return interrupts_pending && interrupts_enabled && !currently_handling_exception && !currently_handling_error; } @@ -16,7 +16,7 @@ bool JIT::ShouldServiceInterrupt() { void JIT::CheckCompareInterrupt() { regs.cop0.count++; regs.cop0.count &= 0x1FFFFFFFF; - if (regs.cop0.count == (u64)regs.cop0.compare << 1) { + if (regs.cop0.count == static_cast(regs.cop0.compare) << 1) { regs.cop0.cause.ip7 = 1; mem.mmio.mi.UpdateInterrupt(); } @@ -41,10 +41,10 @@ int JIT::Step() { u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, pc, paddr)) { /*regs.cop0.HandleTLBException(pc); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, pc); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, pc); return 1;*/ Util::panic("[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address!", - static_cast(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD))); + static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD))); } instruction = mem.Read(regs, paddr); diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 597adade..e5e08ae4 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -20,7 +20,7 @@ struct JIT : BaseCPU { Registers &GetRegs() override { return regs; } - Disassembler::DisassemblyResult Disassemble(u32, u32) const override { return {}; } + [[nodiscard]] Disassembler::DisassemblyResult Disassemble(u32, u32) const override { return {}; } private: Registers regs; @@ -29,7 +29,7 @@ private: friend struct Cop1; #define check_address_error(mask, vaddr) \ (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) - bool ShouldServiceInterrupt() override; + bool ShouldServiceInterrupt() const override; void CheckCompareInterrupt() override; std::vector Serialize() override; void Deserialize(const std::vector &) override; diff --git a/src/backend/core/MMIO.cpp b/src/backend/core/MMIO.cpp index 7356c061..3175102e 100644 --- a/src/backend/core/MMIO.cpp +++ b/src/backend/core/MMIO.cpp @@ -36,7 +36,7 @@ u32 MMIO::Read(u32 addr) { } } -void MMIO::Write(u32 addr, u32 val) { +void MMIO::Write(const u32 addr, const u32 val) { switch (addr) { case RSP_REGION: rsp.Write(addr, val); @@ -82,14 +82,30 @@ std::vector MMIO::Serialize() { index += sizeof(DPC); memcpy(res.data() + index, rdp.cmd_buf, 0xFFFFF); index += 0xFFFFF; - std::copy(rdp.rdram.begin(), rdp.rdram.end(), res.begin() + index); + std::ranges::copy(rdp.rdram, res.begin() + index); index += RDRAM_SIZE; memcpy(res.data() + index, &mi, sizeof(MI)); index += sizeof(MI); memcpy(res.data() + index, &vi, sizeof(VI)); index += sizeof(VI); - memcpy(res.data() + index, &ai, sizeof(AI)); - index += sizeof(AI); + memcpy(res.data() + index, &ai.dmaEnable, sizeof(ai.dmaEnable)); + index += sizeof(ai.dmaEnable); + memcpy(res.data() + index, &ai.dacRate, sizeof(ai.dacRate)); + index += sizeof(ai.dacRate); + memcpy(res.data() + index, &ai.bitrate, sizeof(ai.bitrate)); + index += sizeof(ai.bitrate); + memcpy(res.data() + index, &ai.dmaCount, sizeof(ai.dmaCount)); + index += sizeof(ai.dmaCount); + memcpy(res.data() + index, &ai.dmaLen, sizeof(ai.dmaLen)); + index += sizeof(ai.dmaLen); + memcpy(res.data() + index, &ai.dmaAddr, sizeof(ai.dmaAddr)); + index += sizeof(ai.dmaAddr); + memcpy(res.data() + index, &ai.dmaAddrCarry, sizeof(ai.dmaAddrCarry)); + index += sizeof(ai.dmaAddrCarry); + memcpy(res.data() + index, &ai.cycles, sizeof(ai.cycles)); + index += sizeof(ai.cycles); + memcpy(res.data() + index, &ai.dac, sizeof(ai.dac)); + index += sizeof(ai.dac); memcpy(res.data() + index, &pi, sizeof(PI)); index += sizeof(PI); memcpy(res.data() + index, &ri, sizeof(RI)); @@ -113,14 +129,30 @@ void MMIO::Deserialize(const std::vector &data) { index += sizeof(DPC); memcpy(rdp.cmd_buf, data.data() + index, 0xFFFFF); index += 0xFFFFF; - std::copy(data.begin() + index, data.begin() + index + RDRAM_SIZE, rdp.rdram.begin()); + std::copy_n(data.begin() + index, RDRAM_SIZE, rdp.rdram.begin()); index += RDRAM_SIZE; memcpy(&mi, data.data() + index, sizeof(MI)); index += sizeof(MI); memcpy(&vi, data.data() + index, sizeof(VI)); index += sizeof(VI); - memcpy(&ai, data.data() + index, sizeof(AI)); - index += sizeof(AI); + memcpy(&ai.dmaEnable, data.data() + index, sizeof(ai.dmaEnable)); + index += sizeof(ai.dmaEnable); + memcpy(&ai.dacRate, data.data() + index, sizeof(ai.dacRate)); + index += sizeof(ai.dacRate); + memcpy(&ai.bitrate, data.data() + index, sizeof(ai.bitrate)); + index += sizeof(ai.bitrate); + memcpy(&ai.dmaCount, data.data() + index, sizeof(ai.dmaCount)); + index += sizeof(ai.dmaCount); + memcpy(&ai.dmaLen, data.data() + index, sizeof(ai.dmaLen)); + index += sizeof(ai.dmaLen); + memcpy(&ai.dmaAddr, data.data() + index, sizeof(ai.dmaAddr)); + index += sizeof(ai.dmaAddr); + memcpy(&ai.dmaAddrCarry, data.data() + index, sizeof(ai.dmaAddrCarry)); + index += sizeof(ai.dmaAddrCarry); + memcpy(&ai.cycles, data.data() + index, sizeof(ai.cycles)); + index += sizeof(ai.cycles); + memcpy(&ai.dac, data.data() + index, sizeof(ai.dac)); + index += sizeof(ai.dac); memcpy(&pi, data.data() + index, sizeof(PI)); index += sizeof(PI); memcpy(&ri, data.data() + index, sizeof(RI)); diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index acf5ad71..bd93cf86 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -8,13 +8,13 @@ #include namespace n64 { -Mem::Mem(Registers ®s, ParallelRDP ¶llel) : flash(saveData), mmio(*this, regs, parallel) { +Mem::Mem(Registers ®s, ParallelRDP ¶llel) : mmio(*this, regs, parallel), flash(saveData) { rom.cart.resize(CART_SIZE); - std::fill(rom.cart.begin(), rom.cart.end(), 0); + std::ranges::fill(rom.cart, 0); } void Mem::Reset() { - std::fill(rom.cart.begin(), rom.cart.end(), 0); + std::ranges::fill(rom.cart, 0); flash.Reset(); if (saveData.is_mapped()) { std::error_code error; @@ -87,7 +87,7 @@ FORCE_INLINE void SetROMCIC(u32 checksum, ROM &rom) { } std::vector Mem::OpenArchive(const std::string &path, size_t &sizeAdjusted) { - auto stream = ar_open_file(fs::path(path).string().c_str()); + const auto stream = ar_open_file(fs::path(path).string().c_str()); if (!stream) { Util::panic("Could not open archive! Are you sure it's an archive?"); @@ -115,17 +115,17 @@ std::vector Mem::OpenArchive(const std::string &path, size_t &sizeAdjusted) auto filename = ar_entry_get_name(archive); auto extension = fs::path(filename).extension(); - if (std::any_of(rom_exts.begin(), rom_exts.end(), [&](auto x) { return extension == x; })) { - auto size = ar_entry_get_size(archive); + if (std::ranges::any_of(rom_exts, [&](const auto& x) { return extension == x; })) { + const auto size = ar_entry_get_size(archive); sizeAdjusted = Util::NextPow2(size); buf.resize(sizeAdjusted); ar_entry_uncompress(archive, buf.data(), size); break; - } else { - ar_close_archive(archive); - ar_close(stream); - Util::panic("Could not find any rom image in the archive!"); } + + ar_close_archive(archive); + ar_close(stream); + Util::panic("Could not find any rom image in the archive!"); } ar_close_archive(archive); @@ -139,10 +139,10 @@ std::vector Mem::OpenROM(const std::string &filename, size_t &sizeAdjusted) return buf; } -void Mem::LoadROM(bool isArchive, const std::string &filename) { - size_t sizeAdjusted; +void Mem::LoadROM(const bool isArchive, const std::string &filename) { u32 endianness; { + size_t sizeAdjusted; std::vector buf{}; if (isArchive) { buf = OpenArchive(filename, sizeAdjusted); @@ -153,7 +153,7 @@ void Mem::LoadROM(bool isArchive, const std::string &filename) { endianness = bswap(*reinterpret_cast(buf.data())); Util::SwapN64Rom(buf, endianness); - std::copy(buf.begin(), buf.end(), rom.cart.begin()); + std::ranges::copy(buf, rom.cart.begin()); rom.mask = sizeAdjusted - 1; memcpy(&rom.header, buf.data(), sizeof(ROMHeader)); } @@ -178,7 +178,7 @@ void Mem::LoadROM(bool isArchive, const std::string &filename) { rom.gameNameCart[i] = '\0'; } - u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0); + const u32 checksum = Util::crc32(0, &rom.cart[0x40], 0x9c0); SetROMCIC(checksum, rom); endianness = bswap(*reinterpret_cast(rom.cart.data())); Util::SwapN64Rom(rom.cart, endianness); @@ -186,15 +186,15 @@ void Mem::LoadROM(bool isArchive, const std::string &filename) { } template <> -u8 Mem::Read(n64::Registers ®s, u32 paddr) { - SI &si = mmio.si; +u8 Mem::Read(Registers ®s, const u32 paddr) { + const SI &si = mmio.si; switch (paddr) { case RDRAM_REGION: return mmio.rdp.ReadRDRAM(paddr); case RSP_MEM_REGION: { - auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; + const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; return src[BYTE_ADDRESS(paddr & 0xfff)]; } case REGION_CART: @@ -206,9 +206,9 @@ u8 Mem::Read(n64::Registers ®s, u32 paddr) { Util::panic("MMIO Read!\n"); case AI_REGION: { - u32 w = mmio.ai.Read(paddr & ~3); - int offs = 3 - (paddr & 3); - return (w >> (offs * 8)) & 0xff; + const u32 w = mmio.ai.Read(paddr & ~3); + const int offs = 3 - (paddr & 3); + return w >> offs * 8 & 0xff; } case PIF_ROM_REGION: return si.pif.bootrom[BYTE_ADDRESS(paddr) - PIF_ROM_REGION_START]; @@ -221,19 +221,20 @@ u8 Mem::Read(n64::Registers ®s, u32 paddr) { return 0; default: Util::panic("Unimplemented 8-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc); + return 0; } } template <> -u16 Mem::Read(n64::Registers ®s, u32 paddr) { - SI &si = mmio.si; +u16 Mem::Read(Registers ®s, const u32 paddr) { + const SI &si = mmio.si; switch (paddr) { case RDRAM_REGION: return mmio.rdp.ReadRDRAM(paddr); case RSP_MEM_REGION: { - auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; + const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; return Util::ReadAccess(src, HALF_ADDRESS(paddr & 0xfff)); } case MMIO_REGION: @@ -251,19 +252,20 @@ u16 Mem::Read(n64::Registers ®s, u32 paddr) { return 0; default: Util::panic("Unimplemented 16-bit read at address {:08X} (PC = {:016X})", paddr, (u64)regs.pc); + return 0; } } template <> -u32 Mem::Read(n64::Registers ®s, u32 paddr) { - SI &si = mmio.si; +u32 Mem::Read(Registers ®s, const u32 paddr) { + const SI &si = mmio.si; switch (paddr) { case RDRAM_REGION: return mmio.rdp.ReadRDRAM(paddr); case RSP_MEM_REGION: { - auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; + const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; return Util::ReadAccess(src, paddr & 0xfff); } case MMIO_REGION: @@ -285,15 +287,15 @@ u32 Mem::Read(n64::Registers ®s, u32 paddr) { } template <> -u64 Mem::Read(n64::Registers ®s, u32 paddr) { - SI &si = mmio.si; +u64 Mem::Read(Registers ®s, const u32 paddr) { + const SI &si = mmio.si; switch (paddr) { case RDRAM_REGION: return mmio.rdp.ReadRDRAM(paddr); case RSP_MEM_REGION: { - auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; + const auto &src = paddr & 0x1000 ? mmio.rsp.imem : mmio.rsp.dmem; return Util::ReadAccess(src, paddr & 0xfff); } case MMIO_REGION: @@ -397,7 +399,7 @@ void Mem::Write(Registers ®s, u32 paddr, u32 val) { } template <> -void Mem::Write(Registers ®s, u32 paddr, u32 val) { +void Mem::Write(Registers ®s, const u32 paddr, const u32 val) { SI &si = mmio.si; switch (paddr) { @@ -434,7 +436,7 @@ void Mem::Write(Registers ®s, u32 paddr, u32 val) { } } -void Mem::Write(Registers ®s, u32 paddr, u64 val) { +void Mem::Write(const Registers ®s, const u32 paddr, u64 val) { SI &si = mmio.si; switch (paddr) { @@ -472,7 +474,7 @@ void Mem::Write(Registers ®s, u32 paddr, u64 val) { } template <> -u32 Mem::BackupRead(u32 addr) { +u32 Mem::BackupRead(const u32 addr) { switch (saveType) { case SAVE_NONE: return 0; @@ -490,7 +492,7 @@ u32 Mem::BackupRead(u32 addr) { } template <> -u8 Mem::BackupRead(u32 addr) { +u8 Mem::BackupRead(const u32 addr) { switch (saveType) { case SAVE_NONE: return 0; @@ -513,7 +515,7 @@ u8 Mem::BackupRead(u32 addr) { } template <> -void Mem::BackupWrite(u32 addr, u32 val) { +void Mem::BackupWrite(const u32 addr, const u32 val) { switch (saveType) { case SAVE_NONE: Util::warn("Accessing cartridge with save type SAVE_NONE in write word"); @@ -532,7 +534,7 @@ void Mem::BackupWrite(u32 addr, u32 val) { } template <> -void Mem::BackupWrite(u32 addr, u8 val) { +void Mem::BackupWrite(const u32 addr, const u8 val) { switch (saveType) { case SAVE_NONE: Util::warn("Accessing cartridge with save type SAVE_NONE in write word"); @@ -572,8 +574,8 @@ std::vector Mem::Serialize() { } void Mem::Deserialize(const std::vector &data) { - mmio.Deserialize(std::vector(data.begin(), data.begin() + mmioSize)); - flash.Deserialize(std::vector(data.begin() + mmioSize, data.begin() + mmioSize + flashSize)); + mmio.Deserialize(std::vector(data.begin(), data.begin() + mmioSize)); + flash.Deserialize(std::vector(data.begin() + mmioSize, data.begin() + mmioSize + flashSize)); memcpy(saveData.data(), data.data() + mmioSize + flashSize, saveData.size()); } } // namespace n64 diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 5f03d36d..517e3c25 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -62,7 +62,7 @@ struct Flash { FLASH_COMMAND_READ = 0xF0, }; - void CommandExecute(); + void CommandExecute() const; void CommandStatus(); void CommandSetEraseOffs(u32); void CommandErase(); @@ -96,7 +96,7 @@ struct Mem { T Read(Registers &, u32); template void Write(Registers &, u32, u32); - void Write(Registers &, u32, u64); + void Write(const Registers &, u32, u64); template T BackupRead(u32); @@ -108,21 +108,21 @@ struct Mem { FORCE_INLINE void DumpRDRAM() const { std::vector temp{}; temp.resize(RDRAM_SIZE); - std::copy(mmio.rdp.rdram.begin(), mmio.rdp.rdram.end(), temp.begin()); + std::ranges::copy(mmio.rdp.rdram, temp.begin()); Util::SwapBuffer(temp); Util::WriteFileBinary(temp, "rdram.bin"); } FORCE_INLINE void DumpIMEM() const { std::array temp{}; - std::copy(mmio.rsp.imem.begin(), mmio.rsp.imem.end(), temp.begin()); + std::ranges::copy(mmio.rsp.imem, temp.begin()); Util::SwapBuffer(temp); Util::WriteFileBinary(temp, "imem.bin"); } FORCE_INLINE void DumpDMEM() const { std::array temp{}; - std::copy(mmio.rsp.dmem.begin(), mmio.rsp.dmem.end(), temp.begin()); + std::ranges::copy(mmio.rsp.dmem, temp.begin()); Util::SwapBuffer(temp); Util::WriteFileBinary(temp, "dmem.bin"); } @@ -141,9 +141,9 @@ private: mio::mmap_sink saveData{}; int mmioSize{}, flashSize{}; - FORCE_INLINE bool IsROMPAL() { - static const char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'}; - return std::any_of(std::begin(pal_codes), std::end(pal_codes), [this](char a) { return rom.cart[0x3d] == a; }); + [[nodiscard]] FORCE_INLINE bool IsROMPAL() const { + static constexpr char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'}; + return std::ranges::any_of(pal_codes, [this](char a) { return rom.cart[0x3d] == a; }); } }; } // namespace n64 diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index c1b79d6b..7bb7162a 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -7,7 +7,7 @@ namespace n64 { RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) { rdram.resize(RDRAM_SIZE); - std::fill(rdram.begin(), rdram.end(), 0); + std::ranges::fill(rdram, 0); memset(cmd_buf, 0, 0x100000); dpc.status.raw = 0x80; } @@ -15,75 +15,75 @@ RDP::RDP(Mem &mem, ParallelRDP ¶llel) : mem(mem), parallel(parallel) { void RDP::Reset() { dpc = {}; dpc.status.raw = 0x80; - std::fill(rdram.begin(), rdram.end(), 0); + std::ranges::fill(rdram, 0); memset(cmd_buf, 0, 0x100000); } template <> -void RDP::WriteRDRAM(size_t idx, u8 v) { - size_t real = BYTE_ADDRESS(idx); - if (real < RDRAM_SIZE) { +void RDP::WriteRDRAM(const size_t idx, const u8 v) { + if (const size_t real = BYTE_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] { rdram[real] = v; } } template <> -void RDP::WriteRDRAM(size_t idx, u16 v) { - size_t real = HALF_ADDRESS(idx); - if (real < RDRAM_SIZE) { +void RDP::WriteRDRAM(const size_t idx, const u16 v) { + if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] { Util::WriteAccess(rdram, real, v); } } template <> -void RDP::WriteRDRAM(size_t idx, u32 v) { - if (idx < RDRAM_SIZE) { +void RDP::WriteRDRAM(const size_t idx, const u32 v) { + if (idx < RDRAM_SIZE) [[likely]] { Util::WriteAccess(rdram, idx, v); } } template <> -void RDP::WriteRDRAM(size_t idx, u64 v) { - if (idx < RDRAM_SIZE) { +void RDP::WriteRDRAM(const size_t idx, const u64 v) { + if (idx < RDRAM_SIZE) [[likely]] { Util::WriteAccess(rdram, idx, v); } } template <> -u8 RDP::ReadRDRAM(size_t idx) { - size_t real = BYTE_ADDRESS(idx); - if (real >= RDRAM_SIZE) - return 0; - return rdram[real]; +u8 RDP::ReadRDRAM(const size_t idx) { + if (const size_t real = BYTE_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] + return rdram[real]; + + return 0; } template <> -u16 RDP::ReadRDRAM(size_t idx) { - size_t real = HALF_ADDRESS(idx); - if (real >= RDRAM_SIZE) - return 0; - return Util::ReadAccess(rdram, real); +u16 RDP::ReadRDRAM(const size_t idx) { + if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] + return Util::ReadAccess(rdram, real); + + return 0; } template <> -u32 RDP::ReadRDRAM(size_t idx) { - if (idx >= RDRAM_SIZE) - return 0; - return Util::ReadAccess(rdram, idx); +u32 RDP::ReadRDRAM(const size_t idx) { + if (idx < RDRAM_SIZE) [[likely]] + return Util::ReadAccess(rdram, idx); + + return 0; } template <> -u64 RDP::ReadRDRAM(size_t idx) { - if (idx >= RDRAM_SIZE) - return 0; - return Util::ReadAccess(rdram, idx); +u64 RDP::ReadRDRAM(const size_t idx) { + if (idx < RDRAM_SIZE) [[likely]] + return Util::ReadAccess(rdram, idx); + + return 0; } static const int cmd_lens[64] = {2, 2, 2, 2, 2, 2, 2, 2, 8, 12, 24, 28, 24, 28, 40, 44, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; -auto RDP::Read(u32 addr) const -> u32 { +auto RDP::Read(const u32 addr) const -> u32 { switch (addr) { case 0x04100000: return dpc.start; @@ -104,9 +104,11 @@ auto RDP::Read(u32 addr) const -> u32 { default: Util::panic("Unhandled DP Command Registers read (addr: {:08X})", addr); } + + return 0; } -void RDP::Write(u32 addr, u32 val) { +void RDP::Write(const u32 addr, const u32 val) { switch (addr) { case 0x04100000: WriteStart(val); @@ -122,7 +124,7 @@ void RDP::Write(u32 addr, u32 val) { } } -void RDP::WriteStatus(u32 val) { +void RDP::WriteStatus(const u32 val) { DPCStatusWrite temp{}; temp.raw = val; @@ -201,39 +203,40 @@ void RDP::RunCommand() { const u32 current = dpc.current & 0xFFFFF8; const u32 end = dpc.end & 0xFFFFF8; - int len = end - current; + const auto len = static_cast(end) - static_cast(current); if (len <= 0) return; - if (len + (remaining_cmds * 4) > 0xFFFFF) { + if (len + remaining_cmds * 4 > 0xFFFFF) { Util::panic("Too many RDP commands"); return; } if (dpc.status.xbusDmemDma) { for (int i = 0; i < len; i += 4) { - u32 cmd = Util::ReadAccess(mem.mmio.rsp.dmem, (current + i) & 0xFFF); + const u32 cmd = Util::ReadAccess(mem.mmio.rsp.dmem, (current + i) & 0xFFF); cmd_buf[remaining_cmds + (i >> 2)] = cmd; } } else { if (end > 0x7FFFFFF || current > 0x7FFFFFF) { // if (end > RDRAM_DSIZE || current > RDRAM_DSIZE) return; } + for (int i = 0; i < len; i += 4) { - u32 cmd = Util::ReadAccess(rdram, current + i); + const u32 cmd = Util::ReadAccess(rdram, current + i); cmd_buf[remaining_cmds + (i >> 2)] = cmd; } } - int word_len = (len >> 2) + remaining_cmds; + const int word_len = (len >> 2) + remaining_cmds; int buf_index = 0; bool processed_all = true; while (buf_index < word_len) { - u8 cmd = (cmd_buf[buf_index] >> 24) & 0x3F; + const u8 cmd = (cmd_buf[buf_index] >> 24) & 0x3F; - int cmd_len = cmd_lens[cmd]; + const int cmd_len = cmd_lens[cmd]; if ((buf_index + cmd_len) * 4 > len + (remaining_cmds * 4)) { remaining_cmds = word_len - buf_index; diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index f7e567d6..8cc8baf5 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -4,7 +4,7 @@ #include namespace n64 { -RSP::RSP(Mem &mem, Registers ®s) : mem(mem), regs(regs) { Reset(); } +RSP::RSP(Mem &mem, Registers ®s) : regs(regs), mem(mem) { Reset(); } void RSP::Reset() { lastSuccessfulSPAddr.raw = 0; @@ -65,7 +65,7 @@ FORCE_INLINE void logRSP(const RSP& rsp, const u32 instr) { } */ -auto RSP::Read(u32 addr) -> u32 { +auto RSP::Read(const u32 addr) -> u32 { switch (addr) { case 0x04040000: return lastSuccessfulSPAddr.raw & 0x1FF8; @@ -89,9 +89,9 @@ auto RSP::Read(u32 addr) -> u32 { } } -void RSP::WriteStatus(u32 value) { +void RSP::WriteStatus(const u32 value) { MI &mi = mem.mmio.mi; - auto write = SPStatusWrite{.raw = value}; + const auto write = SPStatusWrite{.raw = value}; if (write.clearHalt && !write.setHalt) { spStatus.halt = false; } @@ -123,7 +123,7 @@ void RSP::DMA() { length = (length + 0x7) & ~0x7; - std::array &src = spDMASPAddr.bank ? imem : dmem; + const auto &src = spDMASPAddr.bank ? imem : dmem; u32 mem_address = spDMASPAddr.address & 0xFF8; u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8; @@ -134,7 +134,7 @@ void RSP::DMA() { mem.mmio.rdp.WriteRDRAM(BYTE_ADDRESS(dram_address + j), src[(mem_address + j) & DMEM_DSIZE]); } - int skip = i == spDMALen.count ? 0 : spDMALen.skip; + const int skip = i == spDMALen.count ? 0 : spDMALen.skip; dram_address += (length + skip); dram_address &= 0xFFFFF8; @@ -155,7 +155,7 @@ void RSP::DMA() { length = (length + 0x7) & ~0x7; - std::array &dst = spDMASPAddr.bank ? imem : dmem; + auto &dst = spDMASPAddr.bank ? imem : dmem; u32 mem_address = spDMASPAddr.address & 0xFF8; u32 dram_address = spDMADRAMAddr.address & 0xFFFFF8; @@ -166,7 +166,7 @@ void RSP::DMA() { dst[(mem_address + j) & DMEM_DSIZE] = mem.mmio.rdp.ReadRDRAM(BYTE_ADDRESS(dram_address + j)); } - int skip = i == spDMALen.count ? 0 : spDMALen.skip; + const int skip = i == spDMALen.count ? 0 : spDMALen.skip; dram_address += (length + skip); dram_address &= 0xFFFFF8; @@ -181,7 +181,7 @@ void RSP::DMA() { spDMALen.raw = 0xFF8 | (spDMALen.skip << 20); } -void RSP::Write(u32 addr, u32 val) { +void RSP::Write(const u32 addr, const u32 val) { switch (addr) { case 0x04040000: spDMASPAddr.raw = val & 0x1FF8; diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 04566227..174f66e6 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -118,9 +118,9 @@ struct Registers; #define DE(x) (((x) >> 11) & 0x1F) #define CLEAR_SET(val, clear, set) \ do { \ - if (clear && !set) \ + if ((clear) && !(set)) \ (val) = 0; \ - if (set && !clear) \ + if ((set) && !(clear)) \ (val) = 1; \ } \ while (0) @@ -131,13 +131,15 @@ struct RSP { FORCE_INLINE void Step() { gpr[0] = 0; - u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); + const u32 instr = Util::ReadAccess(imem, pc & IMEM_DSIZE); oldPC = pc & 0xFFC; pc = nextPC & 0xFFC; nextPC += 4; Exec(instr); } + + void SetVTE(const VPR &vt, u8 e); auto Read(u32 addr) -> u32; void Write(u32 addr, u32 val); void Exec(u32 instr); @@ -151,6 +153,7 @@ struct RSP { std::array dmem{}; std::array imem{}; VPR vpr[32]{}; + VPR vte{}; s32 gpr[32]{}; VPR vce{}; s16 divIn{}, divOut{}; @@ -167,13 +170,13 @@ struct RSP { bool semaphore = false; - FORCE_INLINE void SetPC(u16 val) { + FORCE_INLINE void SetPC(const u16 val) { oldPC = pc & 0xFFC; pc = val & 0xFFC; nextPC = pc + 4; } - FORCE_INLINE s64 GetACC(int e) const { + [[nodiscard]] FORCE_INLINE s64 GetACC(const int e) const { s64 val = u64(acc.h.element[e]) << 32; val |= u64(acc.m.element[e]) << 16; val |= u64(acc.l.element[e]) << 00; @@ -183,69 +186,69 @@ struct RSP { return val; } - FORCE_INLINE void SetACC(int e, s64 val) { + FORCE_INLINE void SetACC(const int e, const s64 val) { acc.h.element[e] = val >> 32; acc.m.element[e] = val >> 16; acc.l.element[e] = val; } - FORCE_INLINE u16 GetVCO() const { + [[nodiscard]] FORCE_INLINE u16 GetVCO() const { u16 value = 0; for (int i = 0; i < 8; i++) { - bool h = vco.h.element[7 - i] != 0; - bool l = vco.l.element[7 - i] != 0; - u32 mask = (l << i) | (h << (i + 8)); + const bool h = vco.h.element[7 - i] != 0; + const bool l = vco.l.element[7 - i] != 0; + const u32 mask = (l << i) | (h << (i + 8)); value |= mask; } return value; } - FORCE_INLINE u16 GetVCC() const { + [[nodiscard]] FORCE_INLINE u16 GetVCC() const { u16 value = 0; for (int i = 0; i < 8; i++) { - bool h = vcc.h.element[7 - i] != 0; - bool l = vcc.l.element[7 - i] != 0; - u32 mask = (l << i) | (h << (i + 8)); + const bool h = vcc.h.element[7 - i] != 0; + const bool l = vcc.l.element[7 - i] != 0; + const u32 mask = (l << i) | (h << (i + 8)); value |= mask; } return value; } - FORCE_INLINE u8 GetVCE() const { + [[nodiscard]] FORCE_INLINE u8 GetVCE() const { u8 value = 0; for (int i = 0; i < 8; i++) { - bool l = vce.element[ELEMENT_INDEX(i)] != 0; + const bool l = vce.element[ELEMENT_INDEX(i)] != 0; value |= (l << i); } return value; } - FORCE_INLINE u32 ReadWord(u32 addr) { + [[nodiscard]] FORCE_INLINE u32 ReadWord(u32 addr) const { addr &= 0xfff; return GET_RSP_WORD(addr); } - FORCE_INLINE void WriteWord(u32 addr, u32 val) { + FORCE_INLINE void WriteWord(u32 addr, const u32 val) { addr &= 0xfff; SET_RSP_WORD(addr, val); } - FORCE_INLINE u16 ReadHalf(u32 addr) { + [[nodiscard]] FORCE_INLINE u16 ReadHalf(u32 addr) const { addr &= 0xfff; return GET_RSP_HALF(addr); } - FORCE_INLINE void WriteHalf(u32 addr, u16 val) { + FORCE_INLINE void WriteHalf(u32 addr, const u16 val) { addr &= 0xfff; SET_RSP_HALF(addr, val); } - FORCE_INLINE u8 ReadByte(u32 addr) { + [[nodiscard]] FORCE_INLINE u8 ReadByte(u32 addr) const { addr &= 0xfff; return RSP_BYTE(addr); } - FORCE_INLINE void WriteByte(u32 addr, u8 val) { + FORCE_INLINE void WriteByte(u32 addr, const u8 val) { addr &= 0xfff; RSP_BYTE(addr) = val; } @@ -364,8 +367,8 @@ struct RSP { void vor(u32 instr); void vnor(u32 instr); void vzero(u32 instr); - void mfc0(RDP &rdp, u32 instr); - void mtc0(u32 instr); + void mfc0(const RDP &rdp, u32 instr); + void mtc0(u32 instr) const; void mfc2(u32 instr); void mtc2(u32 instr); @@ -376,13 +379,13 @@ struct RSP { private: Registers ®s; Mem &mem; - FORCE_INLINE void branch(u16 address, bool cond) { + FORCE_INLINE void branch(const u16 address, const bool cond) { if (cond) { nextPC = address & 0xFFC; } } - FORCE_INLINE void branch_likely(u16 address, bool cond) { + FORCE_INLINE void branch_likely(const u16 address, const bool cond) { if (cond) { nextPC = address & 0xFFC; } else { diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index 11ea44ed..db3bd216 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -3,10 +3,9 @@ #include namespace n64 { -void Interpreter::special(u32 instr) { - u8 mask = (instr & 0x3F); +void Interpreter::special(const u32 instr) { // 00rr_rccc - switch (mask) { // TODO: named constants for clearer code + switch (const u8 mask = instr & 0x3F) { case SLL: if (instr != 0) { sll(instr); @@ -166,14 +165,13 @@ void Interpreter::special(u32 instr) { break; default: Util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 7, mask & 7, instr, - (u64)regs.oldPC); + static_cast(regs.oldPC)); } } -void Interpreter::regimm(u32 instr) { - u8 mask = ((instr >> 16) & 0x1F); +void Interpreter::regimm(const u32 instr) { // 000r_rccc - switch (mask) { // TODO: named constants for clearer code + switch (const u8 mask = instr >> 16 & 0x1F) { case BLTZ: b(instr, regs.Read(RS(instr)) < 0); break; @@ -187,22 +185,22 @@ void Interpreter::regimm(u32 instr) { bl(instr, regs.Read(RS(instr)) >= 0); break; case TGEI: - trap(regs.Read(RS(instr)) >= s64(s16(instr))); + trap(regs.Read(RS(instr)) >= static_cast(static_cast(instr))); break; case TGEIU: - trap(regs.Read(RS(instr)) >= u64(s64(s16(instr)))); + trap(regs.Read(RS(instr)) >= static_cast(static_cast(static_cast(instr)))); break; case TLTI: - trap(regs.Read(RS(instr)) < s64(s16(instr))); + trap(regs.Read(RS(instr)) < static_cast(static_cast(instr))); break; case TLTIU: - trap(regs.Read(RS(instr)) < u64(s64(s16(instr)))); + trap(regs.Read(RS(instr)) < static_cast(static_cast(static_cast(instr)))); break; case TEQI: - trap(regs.Read(RS(instr)) == s64(s16(instr))); + trap(regs.Read(RS(instr)) == static_cast(static_cast(instr))); break; case TNEI: - trap(regs.Read(RS(instr)) != s64(s16(instr))); + trap(regs.Read(RS(instr)) != static_cast(static_cast(instr))); break; case BLTZAL: blink(instr, regs.Read(RS(instr)) < 0); @@ -217,11 +215,12 @@ void Interpreter::regimm(u32 instr) { bllink(instr, regs.Read(RS(instr)) >= 0); break; default: - Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); + Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, + static_cast(regs.oldPC)); } } -void Interpreter::cop2Decode(u32 instr) { +void Interpreter::cop2Decode(const u32 instr) { if (!regs.cop0.status.cu2) { regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 2, regs.oldPC); return; @@ -250,10 +249,9 @@ void Interpreter::cop2Decode(u32 instr) { } } -void Interpreter::Exec(u32 instr) { - u8 mask = (instr >> 26) & 0x3f; +void Interpreter::Exec(const u32 instr) { // 00rr_rccc - switch (mask) { // TODO: named constants for clearer code + switch (const u8 mask = instr >> 26 & 0x3f) { case SPECIAL: special(instr); break; @@ -416,7 +414,7 @@ void Interpreter::Exec(u32 instr) { sd(instr); break; default: - Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", mask, instr, (u64)regs.oldPC); + Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", mask, instr, static_cast(regs.oldPC)); } } } // namespace n64 diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index d2a65c8e..35755853 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -4,112 +4,106 @@ #define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) namespace n64 { -void Interpreter::add(u32 instr) { - u32 rs = regs.Read(RS(instr)); - u32 rt = regs.Read(RT(instr)); - u32 result = rs + rt; - if (check_signed_overflow(rs, rt, result)) { +void Interpreter::add(const u32 instr) { + const u32 rs = regs.Read(RS(instr)); + const u32 rt = regs.Read(RT(instr)); + if (const u32 result = rs + rt; check_signed_overflow(rs, rt, result)) { regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { - regs.Write(RD(instr), s32(result)); + regs.Write(RD(instr), static_cast(result)); } } -void Interpreter::addu(u32 instr) { - s32 rs = (s32)regs.Read(RS(instr)); - s32 rt = (s32)regs.Read(RT(instr)); - s32 result = rs + rt; +void Interpreter::addu(const u32 instr) { + const s32 rs = regs.Read(RS(instr)); + const s32 rt = regs.Read(RT(instr)); + const s32 result = rs + rt; regs.Write(RD(instr), result); } -void Interpreter::addi(u32 instr) { - u32 rs = regs.Read(RS(instr)); - u32 imm = s32(s16(instr)); - u32 result = rs + imm; - if (check_signed_overflow(rs, imm, result)) { +void Interpreter::addi(const u32 instr) { + const u32 rs = regs.Read(RS(instr)); + const u32 imm = static_cast(static_cast(instr)); + if (const u32 result = rs + imm; check_signed_overflow(rs, imm, result)) { regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { - regs.Write(RT(instr), s32(result)); + regs.Write(RT(instr), static_cast(result)); } } -void Interpreter::addiu(u32 instr) { - s32 rs = regs.Read(RS(instr)); - s16 imm = (s16)(instr); - s32 result = rs + imm; +void Interpreter::addiu(const u32 instr) { + const s32 rs = regs.Read(RS(instr)); + const s16 imm = static_cast(instr); + const s32 result = rs + imm; regs.Write(RT(instr), result); } -void Interpreter::dadd(u32 instr) { - u64 rs = regs.Read(RS(instr)); - u64 rt = regs.Read(RT(instr)); - u64 result = rt + rs; - if (check_signed_overflow(rs, rt, result)) { +void Interpreter::dadd(const u32 instr) { + const u64 rs = regs.Read(RS(instr)); + const u64 rt = regs.Read(RT(instr)); + if (const u64 result = rt + rs; check_signed_overflow(rs, rt, result)) { regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { regs.Write(RD(instr), result); } } -void Interpreter::daddu(u32 instr) { - s64 rs = regs.Read(RS(instr)); - s64 rt = regs.Read(RT(instr)); +void Interpreter::daddu(const u32 instr) { + const s64 rs = regs.Read(RS(instr)); + const s64 rt = regs.Read(RT(instr)); regs.Write(RD(instr), rs + rt); } -void Interpreter::daddi(u32 instr) { - u64 imm = s64(s16(instr)); - u64 rs = regs.Read(RS(instr)); - u64 result = imm + rs; - if (check_signed_overflow(rs, imm, result)) { +void Interpreter::daddi(const u32 instr) { + const u64 imm = s64(s16(instr)); + const u64 rs = regs.Read(RS(instr)); + if (const u64 result = imm + rs; check_signed_overflow(rs, imm, result)) { regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { regs.Write(RT(instr), result); } } -void Interpreter::daddiu(u32 instr) { - s16 imm = (s16)(instr); - s64 rs = regs.Read(RS(instr)); +void Interpreter::daddiu(const u32 instr) { + const s16 imm = static_cast(instr); + const s64 rs = regs.Read(RS(instr)); regs.Write(RT(instr), rs + imm); } -void Interpreter::div(u32 instr) { - s64 dividend = regs.Read(RS(instr)); - s64 divisor = regs.Read(RT(instr)); +void Interpreter::div(const u32 instr) { + const s64 dividend = regs.Read(RS(instr)); - if (divisor == 0) { + if (const s64 divisor = regs.Read(RT(instr)); divisor == 0) { regs.hi = dividend; if (dividend >= 0) { - regs.lo = s64(-1); + regs.lo = static_cast(-1); } else { - regs.lo = s64(1); + regs.lo = static_cast(1); } } else { - s32 quotient = dividend / divisor; - s32 remainder = dividend % divisor; + const s32 quotient = dividend / divisor; + const s32 remainder = dividend % divisor; regs.lo = quotient; regs.hi = remainder; } } -void Interpreter::divu(u32 instr) { - u32 dividend = regs.Read(RS(instr)); - u32 divisor = regs.Read(RT(instr)); - if (divisor == 0) { +void Interpreter::divu(const u32 instr) { + const u32 dividend = regs.Read(RS(instr)); + if (const u32 divisor = regs.Read(RT(instr)); divisor == 0) { regs.lo = -1; regs.hi = (s32)dividend; } else { - s32 quotient = (s32)(dividend / divisor); - s32 remainder = (s32)(dividend % divisor); + const s32 quotient = (s32)(dividend / divisor); + const s32 remainder = (s32)(dividend % divisor); regs.lo = quotient; regs.hi = remainder; } } -void Interpreter::ddiv(u32 instr) { - s64 dividend = regs.Read(RS(instr)); - s64 divisor = regs.Read(RT(instr)); +void Interpreter::ddiv(const u32 instr) { + const s64 dividend = regs.Read(RS(instr)); + const s64 divisor = regs.Read(RT(instr)); if (dividend == 0x8000000000000000 && divisor == 0xFFFFFFFFFFFFFFFF) { regs.lo = dividend; regs.hi = 0; @@ -121,35 +115,35 @@ void Interpreter::ddiv(u32 instr) { regs.lo = 1; } } else { - s64 quotient = dividend / divisor; - s64 remainder = dividend % divisor; + const s64 quotient = dividend / divisor; + const s64 remainder = dividend % divisor; regs.lo = quotient; regs.hi = remainder; } } -void Interpreter::ddivu(u32 instr) { - u64 dividend = regs.Read(RS(instr)); - u64 divisor = regs.Read(RT(instr)); +void Interpreter::ddivu(const u32 instr) { + const u64 dividend = regs.Read(RS(instr)); + const u64 divisor = regs.Read(RT(instr)); if (divisor == 0) { regs.lo = -1; regs.hi = (s64)dividend; } else { - u64 quotient = dividend / divisor; - u64 remainder = dividend % divisor; + const u64 quotient = dividend / divisor; + const u64 remainder = dividend % divisor; regs.lo = (s64)quotient; regs.hi = (s64)remainder; } } -void Interpreter::branch(bool cond, s64 address) { +void Interpreter::branch(const bool cond, const s64 address) { regs.delaySlot = true; if (cond) { regs.nextPC = address; } } -void Interpreter::branch_likely(bool cond, s64 address) { +void Interpreter::branch_likely(const bool cond, const s64 address) { if (cond) { regs.delaySlot = true; regs.nextPC = address; @@ -158,55 +152,54 @@ void Interpreter::branch_likely(bool cond, s64 address) { } } -void Interpreter::b(u32 instr, bool cond) { - s16 imm = instr; - s64 offset = u64((s64)imm) << 2; - s64 address = regs.pc + offset; +void Interpreter::b(const u32 instr, const bool cond) { + const s16 imm = instr; + const s64 offset = u64((s64)imm) << 2; + const s64 address = regs.pc + offset; branch(cond, address); } -void Interpreter::blink(u32 instr, bool cond) { +void Interpreter::blink(const u32 instr, const bool cond) { regs.Write(31, regs.nextPC); - s16 imm = instr; - s64 offset = u64((s64)imm) << 2; - s64 address = regs.pc + offset; + const s16 imm = instr; + const s64 offset = u64((s64)imm) << 2; + const s64 address = regs.pc + offset; branch(cond, address); } -void Interpreter::bl(u32 instr, bool cond) { - s16 imm = instr; - s64 offset = u64((s64)imm) << 2; - s64 address = regs.pc + offset; +void Interpreter::bl(const u32 instr, const bool cond) { + const s16 imm = instr; + const s64 offset = u64((s64)imm) << 2; + const s64 address = regs.pc + offset; branch_likely(cond, address); } -void Interpreter::bllink(u32 instr, bool cond) { +void Interpreter::bllink(const u32 instr, const bool cond) { regs.Write(31, regs.nextPC); - s16 imm = instr; - s64 offset = u64((s64)imm) << 2; - s64 address = regs.pc + offset; + const s16 imm = instr; + const s64 offset = u64((s64)imm) << 2; + const s64 address = regs.pc + offset; branch_likely(cond, address); } -void Interpreter::lui(u32 instr) { +void Interpreter::lui(const u32 instr) { u64 val = s64((s16)instr); val <<= 16; regs.Write(RT(instr), val); } -void Interpreter::lb(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; - u32 paddr = 0; - if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { +void Interpreter::lb(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; + if (u32 paddr = 0; !regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { regs.Write(RT(instr), (s8)mem.Read(regs, paddr)); } } -void Interpreter::lh(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lh(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; if (check_address_error(0b1, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -216,15 +209,15 @@ void Interpreter::lh(u32 instr) { u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { regs.Write(RT(instr), (s16)mem.Read(regs, paddr)); } } -void Interpreter::lw(u32 instr) { - s16 offset = instr; - u64 address = regs.Read(RS(instr)) + offset; +void Interpreter::lw(const u32 instr) { + const s16 offset = instr; + const u64 address = regs.Read(RS(instr)) + offset; if (check_address_error(0b11, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -234,20 +227,20 @@ void Interpreter::lw(u32 instr) { u32 physical = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, physical)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { regs.Write(RT(instr), (s32)mem.Read(regs, physical)); } } -void Interpreter::ll(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::ll(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 physical; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, physical)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - s32 result = mem.Read(regs, physical); + const s32 result = mem.Read(regs, physical); if (check_address_error(0b11, address)) { regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; @@ -260,38 +253,38 @@ void Interpreter::ll(u32 instr) { } } -void Interpreter::lwl(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lwl(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u32 shift = 8 * ((address ^ 0) & 3); - u32 mask = 0xFFFFFFFF << shift; - u32 data = mem.Read(regs, paddr & ~3); - s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data << shift)); + const u32 shift = 8 * ((address ^ 0) & 3); + const u32 mask = 0xFFFFFFFF << shift; + const u32 data = mem.Read(regs, paddr & ~3); + const s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data << shift)); regs.Write(RT(instr), result); } } -void Interpreter::lwr(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lwr(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u32 shift = 8 * ((address ^ 3) & 3); - u32 mask = 0xFFFFFFFF >> shift; - u32 data = mem.Read(regs, paddr & ~3); - s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data >> shift)); + const u32 shift = 8 * ((address ^ 3) & 3); + const u32 mask = 0xFFFFFFFF >> shift; + const u32 data = mem.Read(regs, paddr & ~3); + const s32 result = s32((regs.Read(RT(instr)) & ~mask) | (data >> shift)); regs.Write(RT(instr), result); } } -void Interpreter::ld(u32 instr) { - s64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::ld(const u32 instr) { + const s64 address = regs.Read(RS(instr)) + (s16)instr; if (check_address_error(0b111, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -301,24 +294,24 @@ void Interpreter::ld(u32 instr) { u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - s64 value = mem.Read(regs, paddr); + const s64 value = mem.Read(regs, paddr); regs.Write(RT(instr), value); } } -void Interpreter::lld(u32 instr) { +void Interpreter::lld(const u32 instr) { if (!regs.cop0.is64BitAddressing && !regs.cop0.kernelMode) { regs.cop0.FireException(ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } - u64 address = regs.Read(RS(instr)) + (s16)instr; + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { if (check_address_error(0b111, address)) { regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -330,50 +323,50 @@ void Interpreter::lld(u32 instr) { } } -void Interpreter::ldl(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::ldl(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr = 0; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - s32 shift = 8 * ((address ^ 0) & 7); - u64 mask = 0xFFFFFFFFFFFFFFFF << shift; - u64 data = mem.Read(regs, paddr & ~7); - s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data << shift)); + const s32 shift = 8 * ((address ^ 0) & 7); + const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; + const u64 data = mem.Read(regs, paddr & ~7); + const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data << shift)); regs.Write(RT(instr), result); } } -void Interpreter::ldr(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::ldr(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - s32 shift = 8 * ((address ^ 7) & 7); - u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; - u64 data = mem.Read(regs, paddr & ~7); - s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data >> shift)); + const s32 shift = 8 * ((address ^ 7) & 7); + const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; + const u64 data = mem.Read(regs, paddr & ~7); + const s64 result = (s64)((regs.Read(RT(instr)) & ~mask) | (data >> shift)); regs.Write(RT(instr), result); } } -void Interpreter::lbu(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lbu(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u8 value = mem.Read(regs, paddr); + const u8 value = mem.Read(regs, paddr); regs.Write(RT(instr), value); } } -void Interpreter::lhu(u32 instr) { - s64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lhu(const u32 instr) { + const s64 address = regs.Read(RS(instr)) + (s16)instr; if (check_address_error(0b1, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -382,15 +375,15 @@ void Interpreter::lhu(u32 instr) { u32 paddr; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u16 value = mem.Read(regs, paddr); + const u16 value = mem.Read(regs, paddr); regs.Write(RT(instr), value); } } -void Interpreter::lwu(u32 instr) { - s64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::lwu(const u32 instr) { + const s64 address = regs.Read(RS(instr)) + (s16)instr; if (check_address_error(0b11, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); @@ -400,26 +393,26 @@ void Interpreter::lwu(u32 instr) { u32 paddr; if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u32 value = mem.Read(regs, paddr); + const u32 value = mem.Read(regs, paddr); regs.Write(RT(instr), value); } } -void Interpreter::sb(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sb(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.Read(RT(instr))); } } -void Interpreter::sc(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sc(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; if (regs.cop0.llbit) { regs.cop0.llbit = false; @@ -435,7 +428,7 @@ void Interpreter::sc(u32 instr) { if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.Write(RT(instr), 0); regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.Read(RT(instr))); regs.Write(RT(instr), 1); @@ -445,13 +438,13 @@ void Interpreter::sc(u32 instr) { } } -void Interpreter::scd(u32 instr) { +void Interpreter::scd(const u32 instr) { if (!regs.cop0.is64BitAddressing && !regs.cop0.kernelMode) { regs.cop0.FireException(ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } - s64 address = regs.Read(RS(instr)) + (s16)instr; + const s64 address = regs.Read(RS(instr)) + (s16)instr; if (regs.cop0.llbit) { regs.cop0.llbit = false; @@ -467,7 +460,7 @@ void Interpreter::scd(u32 instr) { if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.Write(RT(instr), 0); regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.Read(RT(instr))); regs.Write(RT(instr), 1); @@ -477,21 +470,21 @@ void Interpreter::scd(u32 instr) { } } -void Interpreter::sh(u32 instr) { - s64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sh(const u32 instr) { + const s64 address = regs.Read(RS(instr)) + (s16)instr; u32 physical; if (!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.Read(RT(instr))); } } -void Interpreter::sw(u32 instr) { - s16 offset = instr; - u64 address = regs.Read(RS(instr)) + offset; +void Interpreter::sw(const u32 instr) { + const s16 offset = instr; + const u64 address = regs.Read(RS(instr)) + offset; if (check_address_error(0b11, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC); @@ -501,14 +494,14 @@ void Interpreter::sw(u32 instr) { u32 physical; if (!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.Read(RT(instr))); } } -void Interpreter::sd(u32 instr) { - s64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sd(const u32 instr) { + const s64 address = regs.Read(RS(instr)) + (s16)instr; if (check_address_error(0b111, address)) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC); @@ -518,241 +511,266 @@ void Interpreter::sd(u32 instr) { u32 physical; if (!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.Read(RT(instr))); } } -void Interpreter::sdl(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sdl(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - s32 shift = 8 * ((address ^ 0) & 7); - u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; - u64 data = mem.Read(regs, paddr & ~7); - u64 rt = regs.Read(RT(instr)); + const s32 shift = 8 * ((address ^ 0) & 7); + const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; + const u64 data = mem.Read(regs, paddr & ~7); + const u64 rt = regs.Read(RT(instr)); mem.Write(regs, paddr & ~7, (data & ~mask) | (rt >> shift)); } } -void Interpreter::sdr(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::sdr(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - s32 shift = 8 * ((address ^ 7) & 7); - u64 mask = 0xFFFFFFFFFFFFFFFF << shift; - u64 data = mem.Read(regs, paddr & ~7); - u64 rt = regs.Read(RT(instr)); + const s32 shift = 8 * ((address ^ 7) & 7); + const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; + const u64 data = mem.Read(regs, paddr & ~7); + const u64 rt = regs.Read(RT(instr)); mem.Write(regs, paddr & ~7, (data & ~mask) | (rt << shift)); } } -void Interpreter::swl(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::swl(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - u32 shift = 8 * ((address ^ 0) & 3); - u32 mask = 0xFFFFFFFF >> shift; - u32 data = mem.Read(regs, paddr & ~3); - u32 rt = regs.Read(RT(instr)); + const u32 shift = 8 * ((address ^ 0) & 3); + const u32 mask = 0xFFFFFFFF >> shift; + const u32 data = mem.Read(regs, paddr & ~3); + const u32 rt = regs.Read(RT(instr)); mem.Write(regs, paddr & ~3, (data & ~mask) | (rt >> shift)); } } -void Interpreter::swr(u32 instr) { - u64 address = regs.Read(RS(instr)) + (s16)instr; +void Interpreter::swr(const u32 instr) { + const u64 address = regs.Read(RS(instr)) + (s16)instr; u32 paddr; if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { regs.cop0.HandleTLBException(address); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - u32 shift = 8 * ((address ^ 3) & 3); - u32 mask = 0xFFFFFFFF << shift; - u32 data = mem.Read(regs, paddr & ~3); - u32 rt = regs.Read(RT(instr)); + const u32 shift = 8 * ((address ^ 3) & 3); + const u32 mask = 0xFFFFFFFF << shift; + const u32 data = mem.Read(regs, paddr & ~3); + const u32 rt = regs.Read(RT(instr)); mem.Write(regs, paddr & ~3, (data & ~mask) | (rt << shift)); } } -void Interpreter::ori(u32 instr) { - s64 imm = (u16)instr; - s64 result = imm | regs.Read(RS(instr)); +void Interpreter::ori(const u32 instr) { + const s64 imm = (u16)instr; + const s64 result = imm | regs.Read(RS(instr)); regs.Write(RT(instr), result); } -void Interpreter::or_(u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) | regs.Read(RT(instr))); } +void Interpreter::or_(const u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) | regs.Read(RT(instr))); } -void Interpreter::nor(u32 instr) { regs.Write(RD(instr), ~(regs.Read(RS(instr)) | regs.Read(RT(instr)))); } +void Interpreter::nor(const u32 instr) { + regs.Write(RD(instr), ~(regs.Read(RS(instr)) | regs.Read(RT(instr)))); +} -void Interpreter::j(u32 instr) { - s32 target = (instr & 0x3ffffff) << 2; - s64 address = (regs.oldPC & ~0xfffffff) | target; +void Interpreter::j(const u32 instr) { + const s32 target = (instr & 0x3ffffff) << 2; + const s64 address = (regs.oldPC & ~0xfffffff) | target; branch(true, address); } -void Interpreter::jal(u32 instr) { +void Interpreter::jal(const u32 instr) { regs.Write(31, regs.nextPC); j(instr); } -void Interpreter::jalr(u32 instr) { - u64 addr = regs.Read(RS(instr)); - s64 currentNextPC = regs.nextPC; +void Interpreter::jalr(const u32 instr) { + const u64 addr = regs.Read(RS(instr)); + const s64 currentNextPC = regs.nextPC; branch(true, addr); regs.Write(RD(instr), currentNextPC); } -void Interpreter::jr(u32 instr) { - u64 address = regs.Read(RS(instr)); +void Interpreter::jr(const u32 instr) { + const u64 address = regs.Read(RS(instr)); branch(true, address); } -void Interpreter::slti(u32 instr) { - s16 imm = instr; +void Interpreter::slti(const u32 instr) { + const s16 imm = instr; regs.Write(RT(instr), regs.Read(RS(instr)) < imm); } -void Interpreter::sltiu(u32 instr) { - s16 imm = instr; +void Interpreter::sltiu(const u32 instr) { + const s16 imm = instr; regs.Write(RT(instr), regs.Read(RS(instr)) < imm); } -void Interpreter::slt(u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) < regs.Read(RT(instr))); } +void Interpreter::slt(const u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) < regs.Read(RT(instr))); } -void Interpreter::sltu(u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) < regs.Read(RT(instr))); } +void Interpreter::sltu(const u32 instr) { + regs.Write(RD(instr), regs.Read(RS(instr)) < regs.Read(RT(instr))); +} -void Interpreter::xori(u32 instr) { - s64 imm = (u16)instr; +void Interpreter::xori(const u32 instr) { + const s64 imm = (u16)instr; regs.Write(RT(instr), regs.Read(RS(instr)) ^ imm); } -void Interpreter::xor_(u32 instr) { regs.Write(RD(instr), regs.Read(RT(instr)) ^ regs.Read(RS(instr))); } +void Interpreter::xor_(const u32 instr) { + regs.Write(RD(instr), regs.Read(RT(instr)) ^ regs.Read(RS(instr))); +} -void Interpreter::andi(u32 instr) { - s64 imm = (u16)instr; +void Interpreter::andi(const u32 instr) { + const s64 imm = (u16)instr; regs.Write(RT(instr), regs.Read(RS(instr)) & imm); } -void Interpreter::and_(u32 instr) { regs.Write(RD(instr), regs.Read(RS(instr)) & regs.Read(RT(instr))); } +void Interpreter::and_(const u32 instr) { + regs.Write(RD(instr), regs.Read(RS(instr)) & regs.Read(RT(instr))); +} -void Interpreter::sll(u32 instr) { - u8 sa = ((instr >> 6) & 0x1f); - s32 result = regs.Read(RT(instr)) << sa; +void Interpreter::sll(const u32 instr) { + const u8 sa = ((instr >> 6) & 0x1f); + const s32 result = regs.Read(RT(instr)) << sa; regs.Write(RD(instr), (s64)result); } -void Interpreter::sllv(u32 instr) { - u8 sa = (regs.Read(RS(instr))) & 0x1F; - u32 rt = regs.Read(RT(instr)); - s32 result = rt << sa; +void Interpreter::sllv(const u32 instr) { + const u8 sa = (regs.Read(RS(instr))) & 0x1F; + const u32 rt = regs.Read(RT(instr)); + const s32 result = rt << sa; regs.Write(RD(instr), (s64)result); } -void Interpreter::dsll32(u32 instr) { - u8 sa = ((instr >> 6) & 0x1f); - s64 result = regs.Read(RT(instr)) << (sa + 32); +void Interpreter::dsll32(const u32 instr) { + const u8 sa = ((instr >> 6) & 0x1f); + const s64 result = regs.Read(RT(instr)) << (sa + 32); regs.Write(RD(instr), result); } -void Interpreter::dsll(u32 instr) { - u8 sa = ((instr >> 6) & 0x1f); - s64 result = regs.Read(RT(instr)) << sa; +void Interpreter::dsll(const u32 instr) { + const u8 sa = ((instr >> 6) & 0x1f); + const s64 result = regs.Read(RT(instr)) << sa; regs.Write(RD(instr), result); } -void Interpreter::dsllv(u32 instr) { - s64 sa = regs.Read(RS(instr)) & 63; - s64 result = regs.Read(RT(instr)) << sa; +void Interpreter::dsllv(const u32 instr) { + const s64 sa = regs.Read(RS(instr)) & 63; + const s64 result = regs.Read(RT(instr)) << sa; regs.Write(RD(instr), result); } -void Interpreter::srl(u32 instr) { - u32 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - u32 result = rt >> sa; +void Interpreter::srl(const u32 instr) { + const u32 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const u32 result = rt >> sa; regs.Write(RD(instr), (s32)result); } -void Interpreter::srlv(u32 instr) { - u8 sa = (regs.Read(RS(instr)) & 0x1F); - u32 rt = regs.Read(RT(instr)); - s32 result = rt >> sa; +void Interpreter::srlv(const u32 instr) { + const u8 sa = (regs.Read(RS(instr)) & 0x1F); + const u32 rt = regs.Read(RT(instr)); + const s32 result = rt >> sa; regs.Write(RD(instr), (s64)result); } -void Interpreter::dsrl(u32 instr) { - u64 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - u64 result = rt >> sa; +void Interpreter::dsrl(const u32 instr) { + const u64 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const u64 result = rt >> sa; regs.Write(RD(instr), s64(result)); } -void Interpreter::dsrlv(u32 instr) { - u8 amount = (regs.Read(RS(instr)) & 63); - u64 rt = regs.Read(RT(instr)); - u64 result = rt >> amount; +void Interpreter::dsrlv(const u32 instr) { + const u8 amount = (regs.Read(RS(instr)) & 63); + const u64 rt = regs.Read(RT(instr)); + const u64 result = rt >> amount; regs.Write(RD(instr), s64(result)); } -void Interpreter::dsrl32(u32 instr) { - u64 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - u64 result = rt >> (sa + 32); +void Interpreter::dsrl32(const u32 instr) { + const u64 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const u64 result = rt >> (sa + 32); regs.Write(RD(instr), s64(result)); } -void Interpreter::sra(u32 instr) { - s64 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - s32 result = rt >> sa; +void Interpreter::sra(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const s32 result = rt >> sa; regs.Write(RD(instr), result); } -void Interpreter::srav(u32 instr) { - s64 rs = regs.Read(RS(instr)); - s64 rt = regs.Read(RT(instr)); - u8 sa = rs & 0x1f; - s32 result = rt >> sa; +void Interpreter::srav(const u32 instr) { + const s64 rs = regs.Read(RS(instr)); + const s64 rt = regs.Read(RT(instr)); + const u8 sa = rs & 0x1f; + const s32 result = rt >> sa; regs.Write(RD(instr), result); } -void Interpreter::dsra(u32 instr) { - s64 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - s64 result = rt >> sa; +void Interpreter::dsra(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const s64 result = rt >> sa; regs.Write(RD(instr), result); } -void Interpreter::dsrav(u32 instr) { - s64 rt = regs.Read(RT(instr)); - s64 rs = regs.Read(RS(instr)); - s64 sa = rs & 63; - s64 result = rt >> sa; +void Interpreter::dsrav(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const s64 rs = regs.Read(RS(instr)); + const s64 sa = rs & 63; + const s64 result = rt >> sa; regs.Write(RD(instr), result); } -void Interpreter::dsra32(u32 instr) { - s64 rt = regs.Read(RT(instr)); - u8 sa = ((instr >> 6) & 0x1f); - s64 result = rt >> (sa + 32); +void Interpreter::dsra32(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const u8 sa = ((instr >> 6) & 0x1f); + const s64 result = rt >> (sa + 32); regs.Write(RD(instr), result); } -void Interpreter::dsub(u32 instr) { - s64 rt = regs.Read(RT(instr)); - s64 rs = regs.Read(RS(instr)); - s64 result = rs - rt; +void Interpreter::dsub(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const s64 rs = regs.Read(RS(instr)); + if (const s64 result = rs - rt; check_signed_underflow(rs, rt, result)) { + regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); + } else { + regs.Write(RD(instr), result); + } +} + +void Interpreter::dsubu(const u32 instr) { + const u64 rt = regs.Read(RT(instr)); + const u64 rs = regs.Read(RS(instr)); + const u64 result = rs - rt; + regs.Write(RD(instr), s64(result)); +} + +void Interpreter::sub(const u32 instr) { + const s32 rt = regs.Read(RT(instr)); + const s32 rs = regs.Read(RS(instr)); + const s32 result = rs - rt; if (check_signed_underflow(rs, rt, result)) { regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { @@ -760,87 +778,69 @@ void Interpreter::dsub(u32 instr) { } } -void Interpreter::dsubu(u32 instr) { - u64 rt = regs.Read(RT(instr)); - u64 rs = regs.Read(RS(instr)); - u64 result = rs - rt; - regs.Write(RD(instr), s64(result)); -} - -void Interpreter::sub(u32 instr) { - s32 rt = regs.Read(RT(instr)); - s32 rs = regs.Read(RS(instr)); - s32 result = rs - rt; - if (check_signed_underflow(rs, rt, result)) { - regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); - } else { - regs.Write(RD(instr), result); - } -} - -void Interpreter::subu(u32 instr) { - u32 rt = regs.Read(RT(instr)); - u32 rs = regs.Read(RS(instr)); - u32 result = rs - rt; +void Interpreter::subu(const u32 instr) { + const u32 rt = regs.Read(RT(instr)); + const u32 rs = regs.Read(RS(instr)); + const u32 result = rs - rt; regs.Write(RD(instr), (s64)((s32)result)); } -void Interpreter::dmultu(u32 instr) { - u64 rt = regs.Read(RT(instr)); - u64 rs = regs.Read(RS(instr)); - u128 result = (u128)rt * (u128)rs; +void Interpreter::dmultu(const u32 instr) { + const u64 rt = regs.Read(RT(instr)); + const u64 rs = regs.Read(RS(instr)); + const u128 result = (u128)rt * (u128)rs; regs.lo = (s64)(result & 0xFFFFFFFFFFFFFFFF); regs.hi = (s64)(result >> 64); } -void Interpreter::dmult(u32 instr) { - s64 rt = regs.Read(RT(instr)); - s64 rs = regs.Read(RS(instr)); - s128 result = (s128)rt * (s128)rs; +void Interpreter::dmult(const u32 instr) { + const s64 rt = regs.Read(RT(instr)); + const s64 rs = regs.Read(RS(instr)); + const s128 result = (s128)rt * (s128)rs; regs.lo = result & 0xFFFFFFFFFFFFFFFF; regs.hi = result >> 64; } -void Interpreter::multu(u32 instr) { - u32 rt = regs.Read(RT(instr)); - u32 rs = regs.Read(RS(instr)); - u64 result = (u64)rt * (u64)rs; +void Interpreter::multu(const u32 instr) { + const u32 rt = regs.Read(RT(instr)); + const u32 rs = regs.Read(RS(instr)); + const u64 result = (u64)rt * (u64)rs; regs.lo = (s64)((s32)result); regs.hi = (s64)((s32)(result >> 32)); } -void Interpreter::mult(u32 instr) { - s32 rt = regs.Read(RT(instr)); - s32 rs = regs.Read(RS(instr)); - s64 result = (s64)rt * (s64)rs; +void Interpreter::mult(const u32 instr) { + const s32 rt = regs.Read(RT(instr)); + const s32 rs = regs.Read(RS(instr)); + const s64 result = (s64)rt * (s64)rs; regs.lo = (s64)((s32)result); regs.hi = (s64)((s32)(result >> 32)); } -void Interpreter::mflo(u32 instr) { regs.Write(RD(instr), regs.lo); } +void Interpreter::mflo(const u32 instr) { regs.Write(RD(instr), regs.lo); } -void Interpreter::mfhi(u32 instr) { regs.Write(RD(instr), regs.hi); } +void Interpreter::mfhi(const u32 instr) { regs.Write(RD(instr), regs.hi); } -void Interpreter::mtlo(u32 instr) { regs.lo = regs.Read(RS(instr)); } +void Interpreter::mtlo(const u32 instr) { regs.lo = regs.Read(RS(instr)); } -void Interpreter::mthi(u32 instr) { regs.hi = regs.Read(RS(instr)); } +void Interpreter::mthi(const u32 instr) { regs.hi = regs.Read(RS(instr)); } -void Interpreter::trap(bool cond) { +void Interpreter::trap(const bool cond) const { if (cond) { regs.cop0.FireException(ExceptionCode::Trap, 0, regs.oldPC); } } -void Interpreter::mtc2(u32 instr) { cop2Latch = regs.Read(RT(instr)); } +void Interpreter::mtc2(const u32 instr) { cop2Latch = regs.Read(RT(instr)); } -void Interpreter::mfc2(u32 instr) { - s32 value = cop2Latch; +void Interpreter::mfc2(const u32 instr) { + const s32 value = cop2Latch; regs.Write(RT(instr), value); } -void Interpreter::dmtc2(u32 instr) { cop2Latch = regs.Read(RT(instr)); } +void Interpreter::dmtc2(const u32 instr) { cop2Latch = regs.Read(RT(instr)); } -void Interpreter::dmfc2(u32 instr) { regs.Write(RT(instr), cop2Latch); } +void Interpreter::dmfc2(const u32 instr) { regs.Write(RT(instr), cop2Latch); } void Interpreter::ctc2(u32) {} diff --git a/src/backend/core/mem/Flash.cpp b/src/backend/core/mem/Flash.cpp index a8b4913d..cc517187 100644 --- a/src/backend/core/mem/Flash.cpp +++ b/src/backend/core/mem/Flash.cpp @@ -50,7 +50,7 @@ void Flash::Load(SaveType saveType, const std::string &path) { } } -void Flash::CommandExecute() { +void Flash::CommandExecute() const { Util::trace("Flash::CommandExecute"); switch (state) { case FlashState::Idle: @@ -119,7 +119,7 @@ std::vector Flash::Serialize() { index += sizeof(eraseOffs); memcpy(res.data() + index, &writeOffs, sizeof(writeOffs)); index += sizeof(writeOffs); - std::copy(writeBuf.begin(), writeBuf.end(), res.begin() + index); + std::ranges::copy(writeBuf, res.begin() + index); return res; } @@ -192,31 +192,31 @@ void Flash::Write(u32 index, u8 val) { } template <> -u8 Flash::Read(u32 index) const { +u8 Flash::Read(const u32 index) const { switch (state) { case FlashState::Idle: Util::panic("Flash read byte while in state FLASH_STATE_IDLE"); case FlashState::Write: Util::panic("Flash read byte while in state FLASH_STATE_WRITE"); case FlashState::Read: - { - if (saveData.is_mapped()) { - u8 value = saveData[index]; - Util::trace("Flash read byte in state read: index {:08X} = {:02X}", index, value); - return value; - } else { - Util::panic("Accessing flash when not mapped!"); - } + if (saveData.is_mapped()) { + const u8 value = saveData[index]; + Util::trace("Flash read byte in state read: index {:08X} = {:02X}", index, value); + return value; } + + Util::panic("Accessing flash when not mapped!"); + case FlashState::Status: { - u32 offset = (7 - (index % 8)) * 8; - u8 value = (status >> offset) & 0xFF; + const u32 offset = (7 - (index % 8)) * 8; + const u8 value = (status >> offset) & 0xFF; Util::trace("Flash read byte in state status: index {:08X} = {:02X}", index, value); return value; } default: Util::panic("Flash read byte while in unknown state"); + return 0; } } diff --git a/src/backend/core/mmio/AI.cpp b/src/backend/core/mmio/AI.cpp index 597fbfda..ea1c4821 100644 --- a/src/backend/core/mmio/AI.cpp +++ b/src/backend/core/mmio/AI.cpp @@ -21,7 +21,7 @@ void AI::Reset() { // https://github.com/ares-emulator/ares/blob/master/ares/n64/ai/io.cpp // https://github.com/ares-emulator/ares/blob/master/LICENSE -auto AI::Read(u32 addr) const -> u32 { +auto AI::Read(const u32 addr) const -> u32 { if (addr == 0x0450000C) { u32 val = 0; val |= (dmaCount > 1); @@ -36,7 +36,7 @@ auto AI::Read(u32 addr) const -> u32 { return dmaLen[0]; } -void AI::Write(u32 addr, u32 val) { +void AI::Write(const u32 addr, const u32 val) { switch (addr) { case 0x04500000: if (dmaCount < 2) { @@ -45,7 +45,7 @@ void AI::Write(u32 addr, u32 val) { break; case 0x04500004: { - u32 len = (val & 0x3FFFF) & ~7; + const u32 len = (val & 0x3FFFF) & ~7; if (dmaCount < 2) { if (dmaCount == 0) mem.mmio.mi.InterruptRaise(MI::Interrupt::AI); @@ -62,7 +62,7 @@ void AI::Write(u32 addr, u32 val) { break; case 0x04500010: { - u32 oldDacFreq = dac.freq; + const u32 oldDacFreq = dac.freq; dacRate = val & 0x3FFF; dac.freq = std::max(1.f, (float)GetVideoFrequency(mem.IsROMPAL()) / (dacRate + 1)) * 1.037; dac.period = N64_CPU_FREQ / dac.freq; @@ -80,7 +80,7 @@ void AI::Write(u32 addr, u32 val) { } } -void AI::Step(u32 cpuCycles, float volumeL, float volumeR) { +void AI::Step(const u32 cpuCycles, const float volumeL, const float volumeR) { cycles += cpuCycles; while (cycles > dac.period) { if (dmaCount == 0) { @@ -88,18 +88,18 @@ void AI::Step(u32 cpuCycles, float volumeL, float volumeR) { } if (dmaLen[0] && dmaEnable) { - u32 addrHi = ((dmaAddr[0] >> 13) + dmaAddrCarry) & 0x7FF; - dmaAddr[0] = (addrHi << 13) | (dmaAddr[0] & 0x1FFF); - u32 data = mem.mmio.rdp.ReadRDRAM(dmaAddr[0]); - s16 l = s16(data >> 16); - s16 r = s16(data); + const u32 addrHi = (dmaAddr[0] >> 13) + dmaAddrCarry & 0x7FF; + dmaAddr[0] = addrHi << 13 | dmaAddr[0] & 0x1FFF; + const u32 data = mem.mmio.rdp.ReadRDRAM(dmaAddr[0]); + const s16 l = s16(data >> 16); + const s16 r = s16(data); if (volumeR > 0 && volumeL > 0) { device.PushSample((float)l / INT16_MAX, volumeL, (float)r / INT16_MAX, volumeR); } - u32 addrLo = (dmaAddr[0] + 4) & 0x1FFF; - dmaAddr[0] = (dmaAddr[0] & ~0x1FFF) | addrLo; + const u32 addrLo = dmaAddr[0] + 4 & 0x1FFF; + dmaAddr[0] = dmaAddr[0] & ~0x1FFF | addrLo; dmaAddrCarry = addrLo == 0; dmaLen[0] -= 4; } diff --git a/src/backend/core/mmio/Audio.cpp b/src/backend/core/mmio/Audio.cpp index c26a9ada..acd92bef 100644 --- a/src/backend/core/mmio/Audio.cpp +++ b/src/backend/core/mmio/Audio.cpp @@ -31,13 +31,13 @@ AudioDevice::AudioDevice() { } } -void AudioDevice::PushSample(float left, float volumeL, float right, float volumeR) { - float adjustedL = left * volumeL; - float adjustedR = right * volumeR; - float samples[]{adjustedL, adjustedR}; +void AudioDevice::PushSample(const float left, const float volumeL, const float right, const float volumeR) { + const float adjustedL = left * volumeL; + const float adjustedR = right * volumeR; + const float samples[]{adjustedL, adjustedR}; - auto availableBytes = (float)SDL_GetAudioStreamAvailable(audioStream); - if (availableBytes <= BYTES_PER_HALF_SECOND) { + if (const auto availableBytes = static_cast(SDL_GetAudioStreamAvailable(audioStream)); + availableBytes <= BYTES_PER_HALF_SECOND) { SDL_PutAudioStreamData(audioStream, samples, 2 * sizeof(float)); } @@ -47,7 +47,7 @@ void AudioDevice::PushSample(float left, float volumeL, float right, float volum } } -void AudioDevice::AdjustSampleRate(int sampleRate) { +void AudioDevice::AdjustSampleRate(const int sampleRate) { LockMutex(); SDL_DestroyAudioStream(audioStream); diff --git a/src/backend/core/mmio/Audio.hpp b/src/backend/core/mmio/Audio.hpp index a7d7a9bf..f6b29aea 100644 --- a/src/backend/core/mmio/Audio.hpp +++ b/src/backend/core/mmio/Audio.hpp @@ -11,16 +11,16 @@ struct AudioDevice { void PushSample(float, float, float, float); void AdjustSampleRate(int); - void LockMutex() { + void LockMutex() const { if (audioStreamMutex) SDL_LockMutex(audioStreamMutex); } - void UnlockMutex() { + void UnlockMutex() const { if (audioStreamMutex) SDL_UnlockMutex(audioStreamMutex); } - SDL_AudioStream *GetStream() { return audioStream; } + SDL_AudioStream *GetStream() const { return audioStream; } private: SDL_AudioStream *audioStream; diff --git a/src/backend/core/mmio/Interrupt.cpp b/src/backend/core/mmio/Interrupt.cpp index 9ca45158..634081d0 100644 --- a/src/backend/core/mmio/Interrupt.cpp +++ b/src/backend/core/mmio/Interrupt.cpp @@ -2,7 +2,7 @@ #include namespace n64 { -void MI::InterruptRaise(Interrupt intr) { +void MI::InterruptRaise(const Interrupt intr) { switch (intr) { case Interrupt::VI: miIntr.vi = true; @@ -27,7 +27,7 @@ void MI::InterruptRaise(Interrupt intr) { UpdateInterrupt(); } -void MI::InterruptLower(Interrupt intr) { +void MI::InterruptLower(const Interrupt intr) { switch (intr) { case Interrupt::VI: miIntr.vi = false; @@ -52,8 +52,8 @@ void MI::InterruptLower(Interrupt intr) { UpdateInterrupt(); } -void MI::UpdateInterrupt() { - bool interrupt = miIntr.raw & miIntrMask.raw; +void MI::UpdateInterrupt() const { + const bool interrupt = miIntr.raw & miIntrMask.raw; regs.cop0.cause.ip2 = interrupt; } } // namespace n64 diff --git a/src/backend/core/mmio/MI.cpp b/src/backend/core/mmio/MI.cpp index c75ef73e..da44accb 100644 --- a/src/backend/core/mmio/MI.cpp +++ b/src/backend/core/mmio/MI.cpp @@ -66,8 +66,8 @@ void MI::Write(u32 paddr, u32 val) { break; case 0xC: for (int bit = 0; bit < 6; bit++) { - int clearbit = bit << 1; - int setbit = (bit << 1) + 1; + const int clearbit = bit << 1; + const int setbit = (bit << 1) + 1; if (val & (1 << clearbit)) { miIntrMask.raw &= ~(1 << bit); diff --git a/src/backend/core/mmio/MI.hpp b/src/backend/core/mmio/MI.hpp index e5bf8a1e..c1912971 100644 --- a/src/backend/core/mmio/MI.hpp +++ b/src/backend/core/mmio/MI.hpp @@ -21,13 +21,13 @@ struct Registers; struct MI { enum class Interrupt : u8 { VI, SI, PI, AI, DP, SP }; - MI(Registers &); + explicit MI(Registers &); void Reset(); [[nodiscard]] auto Read(u32) const -> u32; void Write(u32, u32); void InterruptRaise(Interrupt intr); void InterruptLower(Interrupt intr); - void UpdateInterrupt(); + void UpdateInterrupt() const; u32 miMode{}; MIIntr miIntr{}, miIntrMask{}; diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index b3091002..771f5ff3 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -65,7 +65,7 @@ auto PI::BusRead(u32 addr) -> u8 { case REGION_PI_ROM: { // round to nearest 4 byte boundary, keeping old LSB - u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM; + const u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM; if (index >= mem.rom.cart.size()) { Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM! ({}/0x{:016X})", addr, index, index, mem.rom.cart.size(), mem.rom.cart.size()); @@ -104,7 +104,7 @@ auto PI::BusRead(u32 addr) -> u8 { { addr = (addr + 2) & ~2; // round to nearest 4 byte boundary, keeping old LSB - u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM; + const u32 index = BYTE_ADDRESS(addr) - SREGION_PI_ROM; if (index >= mem.rom.cart.size()) { Util::warn("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM! ({}/0x{:016X})", addr, index, index, mem.rom.cart.size(), mem.rom.cart.size()); @@ -178,7 +178,7 @@ auto PI::BusRead(u32 addr) -> u16 { case REGION_PI_ROM: { addr = (addr + 2) & ~3; - u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM; + const u32 index = HALF_ADDRESS(addr) - SREGION_PI_ROM; if (index > mem.rom.cart.size() - 1) { Util::panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); } @@ -312,7 +312,7 @@ void PI::BusWrite(u32 addr, u32 val) { { if (val < CART_ISVIEWER_SIZE) { std::string message(val + 1, 0); - std::copy(mem.isviewer.begin(), mem.isviewer.begin() + val, message.begin()); + std::copy_n(mem.isviewer.begin(), val, message.begin()); Util::print("{}", message); } else { Util::panic("ISViewer buffer size is emulated at {} bytes, but received a flush command for {} bytes!", @@ -355,7 +355,7 @@ auto PI::BusRead(u32 addr) -> u64 { Util::panic("Reading dword from address 0x{:08X} in unsupported region: REGION_PI_SRAM", addr); case REGION_PI_ROM: { - u32 index = addr - SREGION_PI_ROM; + const u32 index = addr - SREGION_PI_ROM; if (index > mem.rom.cart.size() - 7) { // -7 because we're reading an entire dword Util::panic("Address 0x{:08X} accessed an index {}/0x{:X} outside the bounds of the ROM!", addr, index, index); } @@ -439,7 +439,7 @@ auto PI::Read(u32 addr) const -> u32 { } } -u8 PI::GetDomain(u32 address) { +u8 PI::GetDomain(const u32 address) { switch (address) { case REGION_PI_UNKNOWN: case REGION_PI_64DD_ROM: @@ -453,13 +453,12 @@ u8 PI::GetDomain(u32 address) { } } -u32 PI::AccessTiming(u8 domain, u32 length) const { +u32 PI::AccessTiming(const u8 domain, const u32 length) const { uint32_t cycles = 0; uint32_t latency = 0; uint32_t pulse_width = 0; uint32_t release = 0; uint32_t page_size = 0; - uint32_t pages; switch (domain) { case 1: @@ -478,7 +477,7 @@ u32 PI::AccessTiming(u8 domain, u32 length) const { Util::panic("Unknown PI domain: {}\n", domain); } - pages = ceil((double)length / page_size); + const uint32_t pages = ceil((double)length / page_size); cycles += (14 + latency) * pages; cycles += (pulse_width + release) * (length / 2); @@ -489,7 +488,7 @@ u32 PI::AccessTiming(u8 domain, u32 length) const { // rdram -> cart template <> void PI::DMA() { - s32 len = rdLen + 1; + const s32 len = rdLen + 1; Util::trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { @@ -512,7 +511,7 @@ void PI::DMA() { // cart -> rdram template <> void PI::DMA() { - s32 len = wrLen + 1; + const s32 len = wrLen + 1; Util::trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < 0x08010000) { diff --git a/src/backend/core/mmio/PI.hpp b/src/backend/core/mmio/PI.hpp index 44944e7b..664065b8 100644 --- a/src/backend/core/mmio/PI.hpp +++ b/src/backend/core/mmio/PI.hpp @@ -9,7 +9,7 @@ struct Registers; struct PI { PI(Mem &, Registers &); void Reset(); - auto Read(u32) const -> u32; + [[nodiscard]] auto Read(u32) const -> u32; void Write(u32, u32); template diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 68da81e4..79f830a6 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -85,7 +85,7 @@ FORCE_INLINE size_t GetSaveSize(SaveType saveType) { } } -void PIF::LoadEeprom(SaveType saveType, const std::string &path) { +void PIF::LoadEeprom(const SaveType saveType, const std::string &path) { if (saveType == SAVE_EEPROM_16k || saveType == SAVE_EEPROM_4k) { fs::path eepromPath_ = path; if (!savePath.empty()) { @@ -134,7 +134,7 @@ void PIF::CICChallenge() { challenge[i * 2 + 1] = (ram[0x30 + i] >> 0) & 0x0F; } - n64_cic_nus_6105((char *)challenge, (char *)response, CHL_LEN - 2); + n64_cic_nus_6105(reinterpret_cast(challenge), reinterpret_cast(response), CHL_LEN - 2); for (int i = 0; i < 15; i++) { ram[0x30 + i] = (response[i * 2] << 4) + response[i * 2 + 1]; @@ -145,7 +145,7 @@ FORCE_INLINE u8 DataCRC(const u8 *data) { u8 crc = 0; for (int i = 0; i <= 32; i++) { for (int j = 7; j >= 0; j--) { - u8 xorVal = ((crc & 0x80) != 0) ? 0x85 : 0x00; + const u8 xorVal = ((crc & 0x80) != 0) ? 0x85 : 0x00; crc <<= 1; if (i < 32) { @@ -164,27 +164,25 @@ FORCE_INLINE u8 DataCRC(const u8 *data) { #define BCD_ENCODE(x) (((x) / 10) << 4 | ((x) % 10)) #define BCD_DECODE(x) (((x) >> 4) * 10 + ((x) & 15)) -void PIF::ProcessCommands(Mem &mem) { - u8 control = ram[63]; +void PIF::ProcessCommands(const Mem &mem) { + const u8 control = ram[63]; if (control & 1) { channel = 0; int i = 0; while (i < 63) { u8 *cmd = &ram[i++]; - u8 cmdlen = cmd[CMD_LEN] & 0x3F; - if (cmdlen == 0 || cmdlen == 0x3D) { + if (const u8 cmdlen = cmd[CMD_LEN] & 0x3F; cmdlen == 0 || cmdlen == 0x3D) { channel++; } else if (cmdlen == 0x3E) { break; } else if (cmdlen == 0x3F) { - continue; } else { - u8 r = ram[i++]; + const u8 r = ram[i++]; if (r == 0xFE) { break; } - u8 reslen = r & 0x3F; + const u8 reslen = r & 0x3F; u8 *res = &ram[i + cmdlen]; switch (cmd[CMD_IDX]) { @@ -225,7 +223,7 @@ void PIF::ProcessCommands(Mem &mem) { case 2: { auto now = std::time(nullptr); - auto *gmtm = gmtime(&now); + const auto *gmtm = gmtime(&now); res[0] = BCD_ENCODE(gmtm->tm_sec); res[1] = BCD_ENCODE(gmtm->tm_min); res[2] = BCD_ENCODE(gmtm->tm_hour) + 0x80; @@ -321,7 +319,7 @@ void PIF::MempakWrite(u8 *cmd, u8 *res) { void PIF::EepromRead(const u8 *cmd, u8 *res, const Mem &mem) const { assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { - u8 offset = cmd[3]; + const u8 offset = cmd[3]; if ((offset * 8) >= GetSaveSize(mem.saveType)) { Util::panic("Out of range EEPROM read! offset: {:02X}", offset); } @@ -335,7 +333,7 @@ void PIF::EepromRead(const u8 *cmd, u8 *res, const Mem &mem) const { void PIF::EepromWrite(const u8 *cmd, u8 *res, const Mem &mem) { assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { - u8 offset = cmd[3]; + const u8 offset = cmd[3]; if ((offset * 8) >= GetSaveSize(mem.saveType)) { Util::panic("Out of range EEPROM write! offset: {:02X}", offset); } @@ -348,7 +346,7 @@ void PIF::EepromWrite(const u8 *cmd, u8 *res, const Mem &mem) { } } -void PIF::HLE(bool pal, CICType cicType) { +void PIF::HLE(const bool pal, const CICType cicType) const { mem.Write(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); switch (cicType) { @@ -609,13 +607,13 @@ void PIF::HLE(bool pal, CICType cicType) { regs.Write(22, (cicSeeds[cicType] >> 8) & 0xFF); regs.cop0.Reset(); mem.Write(regs, 0x04300004, 0x01010101); - std::copy(mem.rom.cart.begin(), mem.rom.cart.begin() + 0x1000, mem.mmio.rsp.dmem.begin()); - regs.SetPC32(s32(0xA4000040)); + std::copy_n(mem.rom.cart.begin(), 0x1000, mem.mmio.rsp.dmem.begin()); + regs.SetPC32(static_cast(0xA4000040)); } -void PIF::Execute() { - CICType cicType = mem.rom.cicType; - bool pal = mem.rom.pal; +void PIF::Execute() const { + const CICType cicType = mem.rom.cicType; + const bool pal = mem.rom.pal; mem.Write(regs, PIF_RAM_REGION_START + 0x24, cicSeeds[cicType]); switch (cicType) { case UNKNOWN_CIC_TYPE: diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 1ddfcdea..b64bbff0 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -184,11 +184,11 @@ struct PIF { void Reset(); void MaybeLoadMempak(); void LoadEeprom(SaveType, const std::string &); - void ProcessCommands(Mem &); + void ProcessCommands(const Mem &); void InitDevices(SaveType); void CICChallenge(); - void Execute(); - void HLE(bool pal, CICType cicType); + void Execute() const; + void HLE(bool pal, CICType cicType) const; bool ReadButtons(u8 *); void ControllerID(u8 *) const; void MempakRead(const u8 *, u8 *); @@ -214,26 +214,26 @@ struct PIF { Mem &mem; Registers ®s; - FORCE_INLINE u8 Read(u32 addr) { + [[nodiscard]] FORCE_INLINE u8 Read(u32 addr) const { addr &= 0x7FF; if (addr < 0x7c0) return bootrom[addr]; return ram[addr & PIF_RAM_DSIZE]; } - FORCE_INLINE void Write(u32 addr, u8 val) { + FORCE_INLINE void Write(u32 addr, const u8 val) { addr &= 0x7FF; if (addr < 0x7c0) return; ram[addr & PIF_RAM_DSIZE] = val; } - FORCE_INLINE AccessoryType GetAccessoryType() const { + [[nodiscard]] FORCE_INLINE AccessoryType GetAccessoryType() const { if (channel >= 4 || joybusDevices[channel].type != JOYBUS_CONTROLLER) { return ACCESSORY_NONE; - } else { - return joybusDevices[channel].accessoryType; } + + return joybusDevices[channel].accessoryType; } }; } // namespace n64 diff --git a/src/backend/core/mmio/PIF/Device.cpp b/src/backend/core/mmio/PIF/Device.cpp index ab0236b2..434c762c 100644 --- a/src/backend/core/mmio/PIF/Device.cpp +++ b/src/backend/core/mmio/PIF/Device.cpp @@ -96,7 +96,7 @@ bool PIF::ReadButtons(u8 *res) { case JOYBUS_16KB_EEPROM: case JOYBUS_CONTROLLER: if (movie.IsLoaded()) { - Controller controller = movie.NextInputs(); + const Controller controller = movie.NextInputs(); res[0] = controller.byte1; res[1] = controller.byte2; res[2] = controller.joyX; diff --git a/src/backend/core/mmio/PIF/MupenMovie.hpp b/src/backend/core/mmio/PIF/MupenMovie.hpp index e4c5c60c..f5fa86ba 100644 --- a/src/backend/core/mmio/PIF/MupenMovie.hpp +++ b/src/backend/core/mmio/PIF/MupenMovie.hpp @@ -47,7 +47,7 @@ static_assert(sizeof(TASMovieHeader) == 1024); struct MupenMovie { MupenMovie() = default; - MupenMovie(const fs::path &); + explicit MupenMovie(const fs::path &); bool Load(const fs::path &); void Reset(); n64::Controller NextInputs(); diff --git a/src/backend/core/mmio/SI.cpp b/src/backend/core/mmio/SI.cpp index 95eaf44c..d9086caf 100644 --- a/src/backend/core/mmio/SI.cpp +++ b/src/backend/core/mmio/SI.cpp @@ -3,7 +3,7 @@ #include namespace n64 { -SI::SI(Mem &mem, Registers ®s) : mem(mem), regs(regs), pif(mem, regs) { Reset(); } +SI::SI(Mem &mem, Registers ®s) : pif(mem, regs), mem(mem), regs(regs) { Reset(); } void SI::Reset() { status.raw = 0; diff --git a/src/backend/core/mmio/SI.hpp b/src/backend/core/mmio/SI.hpp index cbd0a3da..386b23d9 100644 --- a/src/backend/core/mmio/SI.hpp +++ b/src/backend/core/mmio/SI.hpp @@ -27,7 +27,7 @@ struct SI { u32 pifAddr{}; bool toDram = false; - auto Read(u32) const -> u32; + [[nodiscard]] auto Read(u32) const -> u32; void Write(u32, u32); template void DMA(); diff --git a/src/backend/core/mmio/VI.cpp b/src/backend/core/mmio/VI.cpp index f5e369ab..fdf88732 100644 --- a/src/backend/core/mmio/VI.cpp +++ b/src/backend/core/mmio/VI.cpp @@ -24,7 +24,7 @@ void VI::Reset() { swaps = {}; } -u32 VI::Read(u32 paddr) const { +u32 VI::Read(const u32 paddr) const { switch (paddr) { case 0x04400000: return status.raw; @@ -59,7 +59,7 @@ u32 VI::Read(u32 paddr) const { } } -void VI::Write(u32 paddr, u32 val) { +void VI::Write(const u32 paddr, const u32 val) { switch (paddr) { case 0x04400000: status.raw = val; @@ -67,7 +67,7 @@ void VI::Write(u32 paddr, u32 val) { break; case 0x04400004: { - u32 masked = val & 0xFFFFFF; + const u32 masked = val & 0xFFFFFF; if (origin != masked) { swaps++; } diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 188d808f..1b12f07e 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -43,7 +43,7 @@ void Cop0::Reset() { openbus = {}; } -u32 Cop0::GetReg32(u8 addr) { +u32 Cop0::GetReg32(const u8 addr) { switch (addr) { case COP0_REG_INDEX: return index.raw & INDEX_MASK; @@ -108,7 +108,7 @@ u32 Cop0::GetReg32(u8 addr) { } } -u64 Cop0::GetReg64(u8 addr) const { +u64 Cop0::GetReg64(const u8 addr) const { switch (addr) { case COP0_REG_ENTRYLO0: return entryLo0.raw; @@ -145,7 +145,7 @@ u64 Cop0::GetReg64(u8 addr) const { } } -void Cop0::SetReg32(u8 addr, u32 value) { +void Cop0::SetReg32(const u8 addr, const u32 value) { openbus = value & 0xFFFFFFFF; switch (addr) { case COP0_REG_INDEX: @@ -241,7 +241,7 @@ void Cop0::SetReg32(u8 addr, u32 value) { } } -void Cop0::SetReg64(u8 addr, u64 value) { +void Cop0::SetReg64(const u8 addr, const u64 value) { openbus = value; switch (addr) { case COP0_REG_ENTRYLO0: @@ -286,24 +286,23 @@ void Cop0::SetReg64(u8 addr, u64 value) { } } -static FORCE_INLINE u64 getVPN(u64 addr, u64 pageMask) { - u64 mask = pageMask | 0x1fff; - u64 vpn = (addr & 0xFFFFFFFFFF) | ((addr >> 22) & 0x30000000000); +static FORCE_INLINE u64 getVPN(const u64 addr, const u64 pageMask) { + const u64 mask = pageMask | 0x1fff; + const u64 vpn = addr & 0xFFFFFFFFFF | addr >> 22 & 0x30000000000; return vpn & ~mask; } -TLBEntry *Cop0::TLBTryMatch(u64 vaddr, int *match) { +TLBEntry *Cop0::TLBTryMatch(const u64 vaddr, int *match) const { for (int i = 0; i < 32; i++) { - TLBEntry *entry = ®s.cop0.tlb[i]; - if (entry->initialized) { - u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw); - u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw); + if (TLBEntry *entry = ®s.cop0.tlb[i]; entry->initialized) { + const u64 entry_vpn = getVPN(entry->entryHi.raw, entry->pageMask.raw); + const u64 vaddr_vpn = getVPN(vaddr, entry->pageMask.raw); - bool vpn_match = entry_vpn == vaddr_vpn; - bool asid_match = entry->global || (regs.cop0.entryHi.asid == entry->entryHi.asid); + const bool vpn_match = entry_vpn == vaddr_vpn; - if (vpn_match && asid_match) { + if (const bool asid_match = entry->global || regs.cop0.entryHi.asid == entry->entryHi.asid; + vpn_match && asid_match) { if (match) { *match = i; } @@ -315,15 +314,15 @@ TLBEntry *Cop0::TLBTryMatch(u64 vaddr, int *match) { return nullptr; } -bool Cop0::ProbeTLB(TLBAccessType access_type, u64 vaddr, u32 &paddr, int *match) { - TLBEntry *entry = TLBTryMatch(vaddr, match); +bool Cop0::ProbeTLB(const TLBAccessType accessType, const u64 vaddr, u32 &paddr, int *match) const { + const TLBEntry *entry = TLBTryMatch(vaddr, match); if (!entry) { regs.cop0.tlbError = MISS; return false; } - u32 mask = (entry->pageMask.mask << 12) | 0xFFF; - u32 odd = vaddr & (mask + 1); + const u32 mask = entry->pageMask.mask << 12 | 0xFFF; + const u32 odd = vaddr & (mask + 1); u32 pfn; if (!odd) { @@ -332,7 +331,7 @@ bool Cop0::ProbeTLB(TLBAccessType access_type, u64 vaddr, u32 &paddr, int *match return false; } - if (access_type == STORE && !entry->entryLo0.d) { + if (accessType == STORE && !entry->entryLo0.d) { regs.cop0.tlbError = MODIFICATION; return false; } @@ -344,7 +343,7 @@ bool Cop0::ProbeTLB(TLBAccessType access_type, u64 vaddr, u32 &paddr, int *match return false; } - if (access_type == STORE && !entry->entryLo1.d) { + if (accessType == STORE && !entry->entryLo1.d) { regs.cop0.tlbError = MODIFICATION; return false; } @@ -352,14 +351,13 @@ bool Cop0::ProbeTLB(TLBAccessType access_type, u64 vaddr, u32 &paddr, int *match pfn = entry->entryLo1.pfn; } - paddr = (pfn << 12) | (vaddr & mask); + paddr = pfn << 12 | vaddr & mask; return true; } -FORCE_INLINE bool Is64BitAddressing(Cop0 &cp0, u64 addr) { - u8 region = (addr >> 62) & 3; - switch (region) { +FORCE_INLINE bool Is64BitAddressing(const Cop0 &cp0, const u64 addr) { + switch (addr >> 62 & 3) { case 0b00: return cp0.status.ux; case 0b01: @@ -371,8 +369,8 @@ FORCE_INLINE bool Is64BitAddressing(Cop0 &cp0, u64 addr) { } } -void Cop0::FireException(ExceptionCode code, int cop, s64 pc) { - bool old_exl = regs.cop0.status.exl; +void Cop0::FireException(const ExceptionCode code, const int cop, s64 pc) const { + const bool old_exl = regs.cop0.status.exl; if (!regs.cop0.status.exl) { if ((regs.cop0.cause.branchDelay = regs.prevDelaySlot)) { @@ -424,18 +422,18 @@ void Cop0::FireException(ExceptionCode code, int cop, s64 pc) { regs.cop0.Update(); } -void Cop0::HandleTLBException(u64 vaddr) { - u64 vpn2 = (vaddr >> 13) & 0x7FFFF; - u64 xvpn2 = (vaddr >> 13) & 0x7FFFFFF; +void Cop0::HandleTLBException(const u64 vaddr) const { + const u64 vpn2 = vaddr >> 13 & 0x7FFFF; + const u64 xvpn2 = vaddr >> 13 & 0x7FFFFFF; regs.cop0.badVaddr = vaddr; regs.cop0.context.badvpn2 = vpn2; regs.cop0.xcontext.badvpn2 = xvpn2; - regs.cop0.xcontext.r = (vaddr >> 62) & 3; + regs.cop0.xcontext.r = vaddr >> 62 & 3; regs.cop0.entryHi.vpn2 = xvpn2; - regs.cop0.entryHi.r = (vaddr >> 62) & 3; + regs.cop0.entryHi.r = vaddr >> 62 & 3; } -ExceptionCode Cop0::GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { +ExceptionCode Cop0::GetTLBExceptionCode(const TLBError error, const TLBAccessType accessType) { switch (error) { case NONE: Util::panic("Getting TLB exception with error NONE"); @@ -448,6 +446,7 @@ ExceptionCode Cop0::GetTLBExceptionCode(TLBError error, TLBAccessType accessType return accessType == LOAD ? ExceptionCode::AddressErrorLoad : ExceptionCode::AddressErrorStore; default: Util::panic("Getting TLB exception for unknown error code! ({})", static_cast(error)); + return {}; } } @@ -467,9 +466,9 @@ template void Cop0::decode(JIT &, u32); void Cop0::decodeJIT(JIT &cpu, u32 instr) {} -void Cop0::decodeInterp(u32 instr) { - u8 mask_cop = (instr >> 21) & 0x1F; - u8 mask_cop2 = instr & 0x3F; +void Cop0::decodeInterp(const u32 instr) { + const u8 mask_cop = instr >> 21 & 0x1F; + const u8 mask_cop2 = instr & 0x3F; switch (mask_cop) { case 0x00: mfc0(instr); @@ -510,13 +509,17 @@ void Cop0::decodeInterp(u32 instr) { } } -bool Cop0::MapVAddr(TLBAccessType accessType, u64 vaddr, u32 &paddr) { +bool Cop0::MapVAddr(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) { if (regs.cop0.is64BitAddressing) [[unlikely]] { if (regs.cop0.kernelMode) [[likely]] { return MapVAddr64(accessType, vaddr, paddr); - } else if (regs.cop0.userMode) { + } + + if (regs.cop0.userMode) { return UserMapVAddr64(accessType, vaddr, paddr); - } else if (regs.cop0.supervisorMode) { + } + + if (regs.cop0.supervisorMode) { Util::panic("Supervisor mode memory access, 64 bit mode"); } else { Util::panic("Unknown mode! This should never happen!"); @@ -524,9 +527,13 @@ bool Cop0::MapVAddr(TLBAccessType accessType, u64 vaddr, u32 &paddr) { } else { if (regs.cop0.kernelMode) [[likely]] { return MapVAddr32(accessType, vaddr, paddr); - } else if (regs.cop0.userMode) { + } + + if (regs.cop0.userMode) { return UserMapVAddr32(accessType, vaddr, paddr); - } else if (regs.cop0.supervisorMode) { + } + + if (regs.cop0.supervisorMode) { Util::panic("Supervisor mode memory access, 32 bit mode"); } else { Util::panic("Unknown mode! This should never happen!"); @@ -534,7 +541,7 @@ bool Cop0::MapVAddr(TLBAccessType accessType, u64 vaddr, u32 &paddr) { } } -bool Cop0::UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) { +bool Cop0::UserMapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const { switch (vaddr) { case VREGION_KUSEG: return ProbeTLB(accessType, s64(s32(vaddr)), paddr, nullptr); @@ -544,8 +551,8 @@ bool Cop0::UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) { } } -bool Cop0::MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) { - switch ((u32(vaddr) >> 29) & 7) { +bool Cop0::MapVAddr32(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const { + switch (u32(vaddr) >> 29 & 7) { case 0 ... 3: case 7: return ProbeTLB(accessType, s64(s32(vaddr)), paddr, nullptr); @@ -561,7 +568,7 @@ bool Cop0::MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) { return false; } -bool Cop0::UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) { +bool Cop0::UserMapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const { switch (vaddr) { case VREGION_XKUSEG: return ProbeTLB(accessType, vaddr, paddr, nullptr); @@ -571,7 +578,7 @@ bool Cop0::UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) { } } -bool Cop0::MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) { +bool Cop0::MapVAddr64(const TLBAccessType accessType, const u64 vaddr, u32 &paddr) const { switch (vaddr) { case VREGION_XKUSEG: case VREGION_XKSSEG: @@ -581,15 +588,13 @@ bool Cop0::MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) { if (!regs.cop0.kernelMode) { Util::panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); } - u8 high_two_bits = (vaddr >> 62) & 0b11; - if (high_two_bits != 0b10) { + if (const u8 high_two_bits = (vaddr >> 62) & 0b11; high_two_bits != 0b10) { Util::panic("Access to XKPHYS address 0x{:016X} with high two bits != 0b10!", vaddr); } - u8 subsegment = (vaddr >> 59) & 0b11; + const u8 subsegment = (vaddr >> 59) & 0b11; bool cached = subsegment != 2; // do something with this eventually // If any bits in the range of 58:32 are set, the address is invalid. - bool valid = (vaddr & 0x07FFFFFF00000000) == 0; - if (!valid) { + if (const bool valid = (vaddr & 0x07FFFFFF00000000) == 0; !valid) { regs.cop0.tlbError = DISALLOWED_ADDRESS; return false; } diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index c01d556a..466ce548 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -240,9 +240,9 @@ struct Cop0 { s64 openbus{}; template void decode(T &, u32); - FORCE_INLINE u32 GetRandom() { + [[nodiscard]] FORCE_INLINE u32 GetRandom() const { u32 val = rand(); - auto wired_ = GetWired(); + const auto wired_ = GetWired(); u32 lower, upper; if (wired_ > 31) { lower = 0; @@ -257,7 +257,7 @@ struct Cop0 { } FORCE_INLINE void Update() { - bool exception = status.exl || status.erl; + const bool exception = status.exl || status.erl; kernelMode = exception || status.ksu == 0; supervisorMode = !exception && status.ksu == 1; @@ -267,17 +267,17 @@ struct Cop0 { enum TLBAccessType { LOAD, STORE }; - bool ProbeTLB(TLBAccessType access_type, u64 vaddr, u32 &paddr, int *match); - void FireException(ExceptionCode code, int cop, s64 pc); + bool ProbeTLB(TLBAccessType accessType, u64 vaddr, u32 &paddr, int *match) const; + void FireException(ExceptionCode code, int cop, s64 pc) const; bool MapVAddr(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); - bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr); + bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) const; + bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32 &paddr) const; + bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) const; + bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32 &paddr) const; - TLBEntry *TLBTryMatch(u64 vaddr, int *match); - void HandleTLBException(u64 vaddr); - ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType access_type); + TLBEntry *TLBTryMatch(u64 vaddr, int *match) const; + void HandleTLBException(u64 vaddr) const; + static ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType); private: Registers ®s; diff --git a/src/backend/core/registers/Cop1.cpp b/src/backend/core/registers/Cop1.cpp index 1285ac1b..a3b3604d 100644 --- a/src/backend/core/registers/Cop1.cpp +++ b/src/backend/core/registers/Cop1.cpp @@ -26,9 +26,9 @@ template void Cop1::decode(JIT &, u32); void Cop1::decodeInterp(Interpreter &cpu, u32 instr) { - u8 mask_sub = (instr >> 21) & 0x1F; - u8 mask_fun = instr & 0x3F; - u8 mask_branch = (instr >> 16) & 0x1F; + const u8 mask_sub = (instr >> 21) & 0x1F; + const u8 mask_fun = instr & 0x3F; + const u8 mask_branch = (instr >> 16) & 0x1F; switch (mask_sub) { // 000r_rccc case 0x00: diff --git a/src/backend/core/registers/Cop1.hpp b/src/backend/core/registers/Cop1.hpp index 0dcb7f5d..edf7e00b 100644 --- a/src/backend/core/registers/Cop1.hpp +++ b/src/backend/core/registers/Cop1.hpp @@ -131,9 +131,9 @@ struct Cop1 { template bool CheckResult(T &); template - bool CheckArg(T &); + bool CheckArg(T); template - bool CheckArgs(T &, T &); + bool CheckArgs(T, T); template bool isqnan(T); @@ -141,9 +141,9 @@ struct Cop1 { bool XORDERED(T fs, T ft); template - bool CheckCVTArg(float &f); + bool CheckCVTArg(float f); template - bool CheckCVTArg(double &f); + bool CheckCVTArg(double f); template bool TestExceptions(); @@ -156,11 +156,11 @@ struct Cop1 { private: template - auto FGR_T(Cop0Status &, u32) -> T &; + auto FGR_T(const Cop0Status &, u32) -> T &; template - auto FGR_S(Cop0Status &, u32) -> T &; + auto FGR_S(const Cop0Status &, u32) -> T &; template - auto FGR_D(Cop0Status &, u32) -> T &; + auto FGR_D(const Cop0Status &, u32) -> T &; void decodeInterp(Interpreter &, u32); void decodeJIT(JIT &, u32); void absd(u32 instr); diff --git a/src/backend/core/registers/cop/cop0instructions.cpp b/src/backend/core/registers/cop/cop0instructions.cpp index 04eb9013..36233dbc 100644 --- a/src/backend/core/registers/cop/cop0instructions.cpp +++ b/src/backend/core/registers/cop/cop0instructions.cpp @@ -3,13 +3,13 @@ #include namespace n64 { -void Cop0::mtc0(u32 instr) { SetReg32(RD(instr), regs.Read(RT(instr))); } +void Cop0::mtc0(const u32 instr) { SetReg32(RD(instr), regs.Read(RT(instr))); } -void Cop0::dmtc0(u32 instr) { SetReg64(RD(instr), regs.Read(RT(instr))); } +void Cop0::dmtc0(const u32 instr) { SetReg64(RD(instr), regs.Read(RT(instr))); } -void Cop0::mfc0(u32 instr) { regs.Write(RT(instr), s32(GetReg32(RD(instr)))); } +void Cop0::mfc0(const u32 instr) { regs.Write(RT(instr), s32(GetReg32(RD(instr)))); } -void Cop0::dmfc0(u32 instr) const { regs.Write(RT(instr), s64(GetReg64(RD(instr)))); } +void Cop0::dmfc0(const u32 instr) const { regs.Write(RT(instr), s64(GetReg64(RD(instr)))); } void Cop0::eret() { if (status.erl) { @@ -29,7 +29,7 @@ void Cop0::tlbr() { Util::panic("TLBR with TLB index {}", index.i); } - TLBEntry entry = tlb[index.i]; + const TLBEntry entry = tlb[index.i]; entryHi.raw = entry.entryHi.raw; entryLo0.raw = entry.entryLo0.raw & 0x3FFFFFFF; @@ -40,10 +40,10 @@ void Cop0::tlbr() { pageMask.raw = entry.pageMask.raw; } -void Cop0::tlbw(int index_) { +void Cop0::tlbw(const int index_) { PageMask page_mask{}; page_mask = pageMask; - u32 top = page_mask.mask & 0xAAA; + const u32 top = page_mask.mask & 0xAAA; page_mask.mask = top | (top >> 1); if (index_ >= 32) { @@ -63,8 +63,7 @@ void Cop0::tlbw(int index_) { void Cop0::tlbp() { int match = -1; - TLBEntry *entry = TLBTryMatch(entryHi.raw, &match); - if (entry && match >= 0) { + if (const TLBEntry *entry = TLBTryMatch(entryHi.raw, &match); entry && match >= 0) { index.raw = match; } else { index.raw = 0; diff --git a/src/backend/core/registers/cop/cop1instructions.cpp b/src/backend/core/registers/cop/cop1instructions.cpp index 756c7b29..b3f90fc1 100644 --- a/src/backend/core/registers/cop/cop1instructions.cpp +++ b/src/backend/core/registers/cop/cop1instructions.cpp @@ -7,136 +7,133 @@ namespace n64 { template <> -auto Cop1::FGR_T(Cop0Status &status, u32 index) -> s32 & { +auto Cop1::FGR_T(const Cop0Status &status, const u32 index) -> s32 & { if (status.fr) { return fgr[index].int32; - } else if (index & 1) { - return fgr[index & ~1].int32h; - } else { - return fgr[index & ~1].int32; } + + if (index & 1) { + return fgr[index & ~1].int32h; + } + + return fgr[index & ~1].int32; } template <> -auto Cop1::FGR_T(Cop0Status &status, u32 index) -> u32 & { - return (u32 &)FGR_T(status, index); +auto Cop1::FGR_T(const Cop0Status &status, const u32 index) -> u32 & { + return reinterpret_cast(FGR_T(status, index)); } template <> -auto Cop1::FGR_T(Cop0Status &, u32 index) -> float & { +auto Cop1::FGR_T(const Cop0Status &, const u32 index) -> float & { return fgr[index].float32; } template <> -auto Cop1::FGR_T(Cop0Status &status, u32 index) -> s64 & { +auto Cop1::FGR_T(const Cop0Status &status, const u32 index) -> s64 & { if (status.fr) { return fgr[index].int64; - } else { - return fgr[index & ~1].int64; } + + return fgr[index & ~1].int64; } template <> -auto Cop1::FGR_T(Cop0Status &status, u32 index) -> u64 & { - return (u64 &)FGR_T(status, index); +auto Cop1::FGR_T(const Cop0Status &status, const u32 index) -> u64 & { + return reinterpret_cast(FGR_T(status, index)); } template <> -auto Cop1::FGR_T(Cop0Status &, u32 index) -> double & { +auto Cop1::FGR_T(const Cop0Status &, const u32 index) -> double & { return fgr[index].float64; } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> s32 & { +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> s32 & { if (status.fr) { return fgr[index].int32; - } else { - return fgr[index & ~1].int32; } + + return fgr[index & ~1].int32; } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> u32 & { - return (u32 &)FGR_S(status, index); +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> u32 & { + return reinterpret_cast(FGR_S(status, index)); } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> float & { +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> float & { if (status.fr) { return fgr[index].float32; - } else { - return fgr[index & ~1].float32; } + + return fgr[index & ~1].float32; } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> s64 & { +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> s64 & { return FGR_T(status, index); } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> u64 & { - return (u64 &)FGR_S(status, index); +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> u64 & { + return reinterpret_cast(FGR_S(status, index)); } template <> -auto Cop1::FGR_S(Cop0Status &status, u32 index) -> double & { +auto Cop1::FGR_S(const Cop0Status &status, const u32 index) -> double & { if (status.fr) { return fgr[index].float64; - } else { - return fgr[index & ~1].float64; } + + return fgr[index & ~1].float64; } template <> -auto Cop1::FGR_D(Cop0Status &, u32 index) -> s32 & { +auto Cop1::FGR_D(const Cop0Status &, const u32 index) -> s32 & { fgr[index].int32h = 0; return fgr[index].int32; } template <> -auto Cop1::FGR_D(Cop0Status &status, u32 index) -> u32 & { - return (u32 &)FGR_D(status, index); +auto Cop1::FGR_D(const Cop0Status &status, const u32 index) -> u32 & { + return reinterpret_cast(FGR_D(status, index)); } template <> -auto Cop1::FGR_D(Cop0Status &, u32 index) -> float & { +auto Cop1::FGR_D(const Cop0Status &, const u32 index) -> float & { fgr[index].float32h = 0; return fgr[index].float32; } template <> -auto Cop1::FGR_D(Cop0Status &, u32 index) -> s64 & { +auto Cop1::FGR_D(const Cop0Status &, const u32 index) -> s64 & { return fgr[index].int64; } template <> -auto Cop1::FGR_D(Cop0Status &status, u32 index) -> u64 & { - return (u64 &)FGR_D(status, index); +auto Cop1::FGR_D(const Cop0Status &status, const u32 index) -> u64 & { + return reinterpret_cast(FGR_D(status, index)); } template <> -auto Cop1::FGR_D(Cop0Status &status, u32 index) -> double & { +auto Cop1::FGR_D(const Cop0Status &status, const u32 index) -> double & { return FGR_T(status, index); } -template -To floatIntegerCast(From f) { - return std::bit_cast(f); +template <> +bool Cop1::isqnan(const float f) { + return std::bit_cast(f) >> 22 & 1; } template <> -bool Cop1::isqnan(float f) { - return (floatIntegerCast(f) >> 22) & 1; +bool Cop1::isqnan(const double f) { + return std::bit_cast(f) >> 51 & 1; } template <> -bool Cop1::isqnan(double f) { - return (floatIntegerCast(f) >> 51) & 1; -} - -template <> -bool Cop1::CheckCVTArg(float &f) { +bool Cop1::CheckCVTArg(const float f) { switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -156,7 +153,7 @@ bool Cop1::CheckCVTArg(float &f) { } template <> -bool Cop1::CheckCVTArg(double &f) { +bool Cop1::CheckCVTArg(const double f) { switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -176,7 +173,7 @@ bool Cop1::CheckCVTArg(double &f) { } template <> -bool Cop1::CheckCVTArg(float &f) { +bool Cop1::CheckCVTArg(const float f) { switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -196,7 +193,7 @@ bool Cop1::CheckCVTArg(float &f) { } template <> -bool Cop1::CheckCVTArg(double &f) { +bool Cop1::CheckCVTArg(const double f) { switch (std::fpclassify(f)) { case FP_SUBNORMAL: case FP_INFINITE: @@ -216,7 +213,7 @@ bool Cop1::CheckCVTArg(double &f) { } template -bool Cop1::CheckArg(T &f) { +bool Cop1::CheckArg(const T f) { switch (std::fpclassify(f)) { case FP_SUBNORMAL: SetCauseUnimplemented(); @@ -233,7 +230,7 @@ bool Cop1::CheckArg(T &f) { } template -bool Cop1::CheckArgs(T &f1, T &f2) { +bool Cop1::CheckArgs(const T f1, const T f2) { auto class1 = std::fpclassify(f1), class2 = std::fpclassify(f2); if ((class1 == FP_NAN && !isqnan(f1)) || (class2 == FP_NAN && !isqnan(f2))) { SetCauseUnimplemented(); @@ -277,7 +274,7 @@ template bool Cop1::CheckFPUUsable(); template bool Cop1::CheckFPUUsable(); template -FORCE_INLINE T FlushResult(T f, u32 round) { +FORCE_INLINE T FlushResult(T f, const u32 round) { switch (round) { case FE_TONEAREST: case FE_TOWARDZERO: @@ -337,7 +334,7 @@ bool Cop1::CheckResult(double &f) { template bool Cop1::TestExceptions() { - u32 exc = std::fetestexcept(FE_ALL_EXCEPT); + const u32 exc = std::fetestexcept(FE_ALL_EXCEPT); if (!exc) return false; @@ -427,13 +424,22 @@ bool Cop1::SetCauseInvalid() { return; \ type res = v##res; -#define CHECK_FPE(type, res, operation) CHECK_FPE_IMPL(type, res, operation, false) -#define CHECK_FPE_CONV(type, res, operation) CHECK_FPE_IMPL(type, res, operation, true) +#define CHECK_FPE_IMPL_CONST(type, res, operation, convert) \ + feclearexcept(FE_ALL_EXCEPT); \ + volatile type v##res = [&]() -> type { return operation; }(); \ + if (TestExceptions()) \ + return; \ + const type res = v##res; -void Cop1::absd(u32 instr) { +#define CHECK_FPE(type, res, operation) CHECK_FPE_IMPL(type, res, operation, false) +#define CHECK_FPE_CONST(type, res, operation) CHECK_FPE_IMPL_CONST(type, res, operation, false) +#define CHECK_FPE_CONV(type, res, operation) CHECK_FPE_IMPL(type, res, operation, true) +#define CHECK_FPE_CONV_CONST(type, res, operation) CHECK_FPE_IMPL_CONST(type, res, operation, true) + +void Cop1::absd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; auto fd = std::abs(fs); @@ -442,10 +448,10 @@ void Cop1::absd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::abss(u32 instr) { +void Cop1::abss(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; auto fd = std::abs(fs); @@ -454,11 +460,11 @@ void Cop1::abss(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::adds(u32 instr) { +void Cop1::adds(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(float, fd, fs + ft) @@ -467,11 +473,11 @@ void Cop1::adds(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::addd(u32 instr) { +void Cop1::addd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(double, fd, fs + ft) @@ -480,50 +486,50 @@ void Cop1::addd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::ceills(u32 instr) { +void Cop1::ceills(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundCeil(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundCeil(fs)); FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::ceilld(u32 instr) { +void Cop1::ceilld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundCeil(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundCeil(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::ceilws(u32 instr) { +void Cop1::ceilws(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundCeil(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundCeil(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::ceilwd(u32 instr) { +void Cop1::ceilwd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundCeil(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundCeil(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cfc1(u32 instr) { +void Cop1::cfc1(const u32 instr) { if (!CheckFPUUsable()) return; - u8 fd = RD(instr); + const u8 fd = RD(instr); s32 val = 0; switch (fd) { case 0: @@ -538,17 +544,17 @@ void Cop1::cfc1(u32 instr) { regs.Write(RT(instr), val); } -void Cop1::ctc1(u32 instr) { +void Cop1::ctc1(const u32 instr) { if (!CheckFPUUsable()) return; - u8 fs = RD(instr); - u32 val = regs.Read(RT(instr)); + const u8 fs = RD(instr); + const u32 val = regs.Read(RT(instr)); switch (fs) { case 0: break; case 31: { - u32 prevRound = fcr31.rounding_mode; + const u32 prevRound = fcr31.rounding_mode; fcr31.write(val); if (prevRound != fcr31.rounding_mode) { switch (fcr31.rounding_mode) { @@ -585,10 +591,10 @@ void Cop1::ctc1(u32 instr) { } } -void Cop1::cvtds(u32 instr) { +void Cop1::cvtds(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; CHECK_FPE(double, fd, fs) @@ -597,33 +603,33 @@ void Cop1::cvtds(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtsd(u32 instr) { +void Cop1::cvtsd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; - CHECK_FPE(float, fd, (float)fs) + CHECK_FPE(float, fd, static_cast(fs)) if (!CheckResult(fd)) return; FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtsw(u32 instr) { +void Cop1::cvtsw(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); CHECK_FPE(float, fd, fs) if (!CheckResult(fd)) return; FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtsl(u32 instr) { +void Cop1::cvtsl(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - if (fs >= s64(0x0080000000000000) || fs < s64(0xff80000000000000)) { + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + if (fs >= 0x0080000000000000 || fs < static_cast(0xff80000000000000)) { SetCauseUnimplemented(); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -634,52 +640,53 @@ void Cop1::cvtsl(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtwd(u32 instr) { +void Cop1::cvtwd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundCurrent(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundCurrent(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtws(u32 instr) { +void Cop1::cvtws(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundCurrent(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundCurrent(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtls(u32 instr) { +void Cop1::cvtls(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundCurrent(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundCurrent(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtdw(u32 instr) { +void Cop1::cvtdw(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); CHECK_FPE(double, fd, fs) if (!CheckResult(fd)) return; FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtdl(u32 instr) { +void Cop1::cvtdl(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - if (fs >= s64(0x0080000000000000) || fs < s64(0xff80000000000000)) { + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + + if (fs >= 0x0080000000000000 || fs < static_cast(0xff80000000000000)) { SetCauseUnimplemented(); regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -690,18 +697,18 @@ void Cop1::cvtdl(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::cvtld(u32 instr) { +void Cop1::cvtld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundCurrent(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundCurrent(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } template -bool Cop1::XORDERED(T fs, T ft) { +bool Cop1::XORDERED(const T fs, const T ft) { if (std::isnan(fs) || std::isnan(ft)) { if (std::isnan(fs) && (!quiet || isqnan(fs)) && SetCauseInvalid()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); @@ -722,176 +729,173 @@ bool Cop1::XORDERED(T fs, T ft) { #define UNORDERED(type, cf) XORDERED template -void Cop1::cf(u32 instr) { +void Cop1::cf(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); - if (!UNORDERED(T, 0)(fs, ft)) + + const T fs = FGR_S(regs.cop0.status, FS(instr)); + if (const T ft = FGR_T(regs.cop0.status, FT(instr)); !UNORDERED(T, 0)(fs, ft)) return; fcr31.compare = 0; } template -void Cop1::cun(u32 instr) { +void Cop1::cun(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); - if (!UNORDERED(T, 1)(fs, ft)) + const T fs = FGR_S(regs.cop0.status, FS(instr)); + if (const T ft = FGR_T(regs.cop0.status, FT(instr)); !UNORDERED(T, 1)(fs, ft)) return; fcr31.compare = 0; } template -void Cop1::ceq(u32 instr) { +void Cop1::ceq(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs == ft; } template -void Cop1::cueq(u32 instr) { +void Cop1::cueq(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs == ft; } template -void Cop1::colt(u32 instr) { +void Cop1::colt(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs < ft; } template -void Cop1::cult(u32 instr) { +void Cop1::cult(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs < ft; } template -void Cop1::cole(u32 instr) { +void Cop1::cole(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs <= ft; } template -void Cop1::cule(u32 instr) { +void Cop1::cule(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!UNORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs <= ft; } template -void Cop1::csf(u32 instr) { +void Cop1::csf(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); - if (!ORDERED(T, 0)(fs, ft)) + const T fs = FGR_S(regs.cop0.status, FS(instr)); + if (const T ft = FGR_T(regs.cop0.status, FT(instr)); !ORDERED(T, 0)(fs, ft)) return; fcr31.compare = 0; } template -void Cop1::cngle(u32 instr) { +void Cop1::cngle(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); - if (!ORDERED(T, 1)(fs, ft)) + const T fs = FGR_S(regs.cop0.status, FS(instr)); + if (const T ft = FGR_T(regs.cop0.status, FT(instr)); !ORDERED(T, 1)(fs, ft)) return; fcr31.compare = 0; } template -void Cop1::cseq(u32 instr) { +void Cop1::cseq(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs == ft; } template -void Cop1::cngl(u32 instr) { +void Cop1::cngl(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs == ft; } template -void Cop1::clt(u32 instr) { +void Cop1::clt(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs < ft; } template -void Cop1::cnge(u32 instr) { +void Cop1::cnge(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs < ft; } template -void Cop1::cle(u32 instr) { +void Cop1::cle(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 0)(fs, ft)) return; fcr31.compare = fs <= ft; } template -void Cop1::cngt(u32 instr) { +void Cop1::cngt(const u32 instr) { if (!CheckFPUUsable()) return; - T fs = FGR_S(regs.cop0.status, FS(instr)); - T ft = FGR_T(regs.cop0.status, FT(instr)); + const T fs = FGR_S(regs.cop0.status, FS(instr)); + const T ft = FGR_T(regs.cop0.status, FT(instr)); if (!ORDERED(T, 1)(fs, ft)) return; fcr31.compare = fs <= ft; @@ -930,11 +934,11 @@ template void Cop1::cnge(u32 instr); template void Cop1::cle(u32 instr); template void Cop1::cngt(u32 instr); -void Cop1::divs(u32 instr) { +void Cop1::divs(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(float, fd, fs / ft) @@ -943,11 +947,11 @@ void Cop1::divs(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::divd(u32 instr) { +void Cop1::divd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(double, fd, fs / ft) @@ -956,11 +960,11 @@ void Cop1::divd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::muls(u32 instr) { +void Cop1::muls(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(float, fd, fs *ft) @@ -969,11 +973,11 @@ void Cop1::muls(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::muld(u32 instr) { +void Cop1::muld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(double, fd, fs *ft) @@ -982,11 +986,11 @@ void Cop1::muld(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::subs(u32 instr) { +void Cop1::subs(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(float, fd, fs - ft) @@ -995,11 +999,11 @@ void Cop1::subs(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::subd(u32 instr) { +void Cop1::subd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); - auto ft = FGR_T(regs.cop0.status, FT(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto ft = FGR_T(regs.cop0.status, FT(instr)); if (!CheckArgs(fs, ft)) return; CHECK_FPE(double, fd, fs - ft) @@ -1008,18 +1012,18 @@ void Cop1::subd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::movs(u32 instr) { movd(instr); } +void Cop1::movs(const u32 instr) { movd(instr); } -void Cop1::movd(u32 instr) { +void Cop1::movd(const u32 instr) { if (!CheckFPUUsable()) return; FGR_D(regs.cop0.status, FD(instr)) = FGR_S(regs.cop0.status, FS(instr)); } -void Cop1::negs(u32 instr) { +void Cop1::negs(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; CHECK_FPE(float, fd, -fs) @@ -1028,10 +1032,10 @@ void Cop1::negs(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::negd(u32 instr) { +void Cop1::negd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; CHECK_FPE(double, fd, -fs) @@ -1040,10 +1044,10 @@ void Cop1::negd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::sqrts(u32 instr) { +void Cop1::sqrts(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; CHECK_FPE(float, fd, sqrtf(fs)) @@ -1052,10 +1056,10 @@ void Cop1::sqrts(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::sqrtd(u32 instr) { +void Cop1::sqrtd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckArg(fs)) return; CHECK_FPE(double, fd, sqrt(fs)) @@ -1064,13 +1068,13 @@ void Cop1::sqrtd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::roundls(u32 instr) { +void Cop1::roundls(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundNearest(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs)) if (fd != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -1078,13 +1082,13 @@ void Cop1::roundls(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::roundld(u32 instr) { +void Cop1::roundld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundNearest(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundNearest(fs)) if (fd != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -1092,13 +1096,13 @@ void Cop1::roundld(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::roundws(u32 instr) { +void Cop1::roundws(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundNearest(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs)) if (fd != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -1106,13 +1110,13 @@ void Cop1::roundws(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::roundwd(u32 instr) { +void Cop1::roundwd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundNearest(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundNearest(fs)) if (fd != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; @@ -1120,96 +1124,96 @@ void Cop1::roundwd(u32 instr) { FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::floorls(u32 instr) { +void Cop1::floorls(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundFloor(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundFloor(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::floorld(u32 instr) { +void Cop1::floorld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundFloor(fs)) + CHECK_FPE_CONST(s64, fd, Util::roundFloor(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::floorws(u32 instr) { +void Cop1::floorws(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundFloor(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundFloor(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::floorwd(u32 instr) { +void Cop1::floorwd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundFloor(fs)) + CHECK_FPE_CONV_CONST(s32, fd, Util::roundFloor(fs)) FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::truncws(u32 instr) { +void Cop1::truncws(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundTrunc(fs)) - if ((float)fd != fs && SetCauseInexact()) { + CHECK_FPE_CONV_CONST(s32, fd, Util::roundTrunc(fs)) + if (static_cast(fd) != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; } FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::truncwd(u32 instr) { +void Cop1::truncwd(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE_CONV(s32, fd, Util::roundTrunc(fs)) - if ((double)fd != fs && SetCauseInexact()) { + CHECK_FPE_CONV_CONST(s32, fd, Util::roundTrunc(fs)) + if (static_cast(fd) != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; } FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::truncls(u32 instr) { +void Cop1::truncls(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundTrunc(fs)) - if ((float)fd != fs && SetCauseInexact()) { + CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs)) + if (static_cast(fd) != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; } FGR_D(regs.cop0.status, FD(instr)) = fd; } -void Cop1::truncld(u32 instr) { +void Cop1::truncld(const u32 instr) { if (!CheckFPUUsable()) return; - auto fs = FGR_S(regs.cop0.status, FS(instr)); + const auto fs = FGR_S(regs.cop0.status, FS(instr)); if (!CheckCVTArg(fs)) return; - CHECK_FPE(s64, fd, Util::roundTrunc(fs)) - if ((double)fd != fs && SetCauseInexact()) { + CHECK_FPE_CONST(s64, fd, Util::roundTrunc(fs)) + if (static_cast(fd) != fs && SetCauseInexact()) { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return; } @@ -1280,26 +1284,24 @@ void Cop1::sdc1(T &cpu, Mem &mem, u32 instr) { template void Cop1::sdc1(Interpreter &, Mem &, u32); template void Cop1::sdc1(JIT &, Mem &, u32); -void Cop1::lwc1Interp(Mem &mem, u32 instr) { - u64 addr = (s64)(s16)instr + regs.Read(BASE(instr)); +void Cop1::lwc1Interp(Mem &mem, const u32 instr) { + const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); - u32 physical; - if (!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { + if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { regs.cop0.HandleTLBException(addr); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u32 data = mem.Read(regs, physical); + const u32 data = mem.Read(regs, physical); FGR_T(regs.cop0.status, FT(instr)) = data; } } -void Cop1::swc1Interp(Mem &mem, u32 instr) { - u64 addr = (s64)(s16)instr + regs.Read(BASE(instr)); +void Cop1::swc1Interp(Mem &mem, const u32 instr) { + const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); - u32 physical; - if (!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { + if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { regs.cop0.HandleTLBException(addr); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, FGR_T(regs.cop0.status, FT(instr))); } @@ -1312,50 +1314,48 @@ void Cop1::unimplemented() { regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); } -void Cop1::ldc1Interp(Mem &mem, u32 instr) { - u64 addr = (s64)(s16)instr + regs.Read(BASE(instr)); +void Cop1::ldc1Interp(Mem &mem, const u32 instr) { + const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); - u32 physical; - if (!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { + if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { regs.cop0.HandleTLBException(addr); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { - u64 data = mem.Read(regs, physical); + const u64 data = mem.Read(regs, physical); FGR_T(regs.cop0.status, FT(instr)) = data; } } -void Cop1::sdc1Interp(Mem &mem, u32 instr) { - u64 addr = (s64)(s16)instr + regs.Read(BASE(instr)); +void Cop1::sdc1Interp(Mem &mem, const u32 instr) { + const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); - u32 physical; - if (!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { + if (u32 physical; !regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { regs.cop0.HandleTLBException(addr); - regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, FGR_T(regs.cop0.status, FT(instr))); } } -void Cop1::mfc1(u32 instr) { +void Cop1::mfc1(const u32 instr) { if (!CheckFPUUsable()) return; regs.Write(RT(instr), FGR_T(regs.cop0.status, FS(instr))); } -void Cop1::dmfc1(u32 instr) { +void Cop1::dmfc1(const u32 instr) { if (!CheckFPUUsable()) return; regs.Write(RT(instr), FGR_S(regs.cop0.status, FS(instr))); } -void Cop1::mtc1(u32 instr) { +void Cop1::mtc1(const u32 instr) { if (!CheckFPUUsable()) return; FGR_T(regs.cop0.status, FS(instr)) = regs.Read(RT(instr)); } -void Cop1::dmtc1(u32 instr) { +void Cop1::dmtc1(const u32 instr) { if (!CheckFPUUsable()) return; FGR_S(regs.cop0.status, FS(instr)) = regs.Read(RT(instr)); diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index 91c2b984..2e721f5f 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -4,10 +4,8 @@ #include namespace n64 { -FORCE_INLINE void special(MI &mi, Registers ®s, RSP &rsp, u32 instr) { - u8 mask = instr & 0x3f; - // Util::print("rsp special {:02X}", mask); - switch (mask) { +FORCE_INLINE void special(MI &mi, RSP &rsp, const u32 instr) { + switch (const u8 mask = instr & 0x3f) { case 0x00: if (instr != 0) { rsp.sll(instr); @@ -73,31 +71,27 @@ FORCE_INLINE void special(MI &mi, Registers ®s, RSP &rsp, u32 instr) { } } -FORCE_INLINE void regimm(RSP &rsp, u32 instr) { - u8 mask = ((instr >> 16) & 0x1F); - // Util::print("rsp regimm {:02X}", mask); - switch (mask) { +FORCE_INLINE void regimm(RSP &rsp, const u32 instr) { + switch (const u8 mask = instr >> 16 & 0x1F) { case 0x00: - rsp.b(instr, (s32)rsp.gpr[RS(instr)] < 0); + rsp.b(instr, rsp.gpr[RS(instr)] < 0); break; case 0x01: - rsp.b(instr, (s32)rsp.gpr[RS(instr)] >= 0); + rsp.b(instr, rsp.gpr[RS(instr)] >= 0); break; case 0x10: - rsp.blink(instr, (s32)rsp.gpr[RS(instr)] < 0); + rsp.blink(instr, rsp.gpr[RS(instr)] < 0); break; case 0x11: - rsp.blink(instr, (s32)rsp.gpr[RS(instr)] >= 0); + rsp.blink(instr, rsp.gpr[RS(instr)] >= 0); break; default: Util::panic("Unhandled RSP regimm instruction ({:05b})", mask); } } -FORCE_INLINE void lwc2(RSP &rsp, u32 instr) { - u8 mask = (instr >> 11) & 0x1F; - // Util::print("lwc2 {:02X}", mask); - switch (mask) { +FORCE_INLINE void lwc2(RSP &rsp, const u32 instr) { + switch (const u8 mask = instr >> 11 & 0x1F) { case 0x00: rsp.lbv(instr); break; @@ -138,10 +132,8 @@ FORCE_INLINE void lwc2(RSP &rsp, u32 instr) { } } -FORCE_INLINE void swc2(RSP &rsp, u32 instr) { - u8 mask = (instr >> 11) & 0x1F; - // Util::print("swc2 {:02X}", mask); - switch (mask) { +FORCE_INLINE void swc2(RSP &rsp, const u32 instr) { + switch (const u8 mask = instr >> 11 & 0x1F) { case 0x00: rsp.sbv(instr); break; @@ -183,13 +175,11 @@ FORCE_INLINE void swc2(RSP &rsp, u32 instr) { } } -FORCE_INLINE void cop2(RSP &rsp, u32 instr) { - u8 mask = instr & 0x3F; - u8 mask_sub = (instr >> 21) & 0x1F; - // Util::print("Cop2 {:02X}", mask); - switch (mask) { +FORCE_INLINE void cop2(RSP &rsp, const u32 instr) { + const u8 mask_sub = instr >> 21 & 0x1F; + switch (const u8 mask = instr & 0x3F) { case 0x00: - if ((instr >> 25) & 1) { + if (instr >> 25 & 1) { rsp.vmulf(instr); } else { switch (mask_sub) { @@ -355,14 +345,13 @@ FORCE_INLINE void cop2(RSP &rsp, u32 instr) { } } -FORCE_INLINE void cop0(Registers ®s, Mem &mem, u32 instr) { - u8 mask = (instr >> 21) & 0x1F; +FORCE_INLINE void cop0(Mem &mem, const u32 instr) { MMIO &mmio = mem.mmio; RSP &rsp = mmio.rsp; RDP &rdp = mmio.rdp; - // Util::print("Cop0 {:02X}", mask); + if ((instr & 0x7FF) == 0) { - switch (mask) { + switch (const u8 mask = instr >> 21 & 0x1F) { case 0x00: rsp.mfc0(rdp, instr); break; @@ -377,14 +366,12 @@ FORCE_INLINE void cop0(Registers ®s, Mem &mem, u32 instr) { } } -void RSP::Exec(u32 instr) { - u8 mask = (instr >> 26) & 0x3F; +void RSP::Exec(const u32 instr) { MMIO &mmio = mem.mmio; MI &mi = mmio.mi; - // Util::print("RSP {:02X}", mask); - switch (mask) { + switch (const u8 mask = instr >> 26 & 0x3F) { case 0x00: - special(mi, regs, *this, instr); + special(mi, *this, instr); break; case 0x01: regimm(*this, instr); @@ -396,16 +383,16 @@ void RSP::Exec(u32 instr) { jal(instr); break; case 0x04: - b(instr, (s32)gpr[RT(instr)] == (s32)gpr[RS(instr)]); + b(instr, gpr[RT(instr)] == gpr[RS(instr)]); break; case 0x05: - b(instr, (s32)gpr[RT(instr)] != (s32)gpr[RS(instr)]); + b(instr, gpr[RT(instr)] != gpr[RS(instr)]); break; case 0x06: - b(instr, (s32)gpr[RS(instr)] <= 0); + b(instr, gpr[RS(instr)] <= 0); break; case 0x07: - b(instr, (s32)gpr[RS(instr)] > 0); + b(instr, gpr[RS(instr)] > 0); break; case 0x08: case 0x09: @@ -430,7 +417,7 @@ void RSP::Exec(u32 instr) { lui(instr); break; case 0x10: - cop0(regs, mem, instr); + cop0(mem, instr); break; case 0x12: cop2(*this, instr); diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 4c4ce188..cc00d2d4 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -10,23 +10,23 @@ namespace n64 { FORCE_INLINE bool AcquireSemaphore(RSP &rsp) { if (rsp.semaphore) { return true; - } else { - rsp.semaphore = true; - return false; } + + rsp.semaphore = true; + return false; } FORCE_INLINE void ReleaseSemaphore(RSP &rsp) { rsp.semaphore = false; } -FORCE_INLINE int SignExt7bit(u8 val, int sa) { - s8 sval = ((val << 1) & 0x80) | val; +FORCE_INLINE int SignExt7bit(const u8 val, const int sa) { + const s8 sval = val << 1 & 0x80 | val; - s32 sval32 = sval; - u32 val32 = sval32; + const s32 sval32 = sval; + const u32 val32 = sval32; return val32 << sa; } -FORCE_INLINE auto GetCop0Reg(RSP &rsp, RDP &rdp, u8 index) -> u32 { +FORCE_INLINE auto GetCop0Reg(RSP &rsp, const RDP &rdp, const u8 index) -> u32 { switch (index) { case 0: return rsp.lastSuccessfulSPAddr.raw; @@ -61,14 +61,14 @@ FORCE_INLINE auto GetCop0Reg(RSP &rsp, RDP &rdp, u8 index) -> u32 { return rdp.dpc.status.tmemBusy; default: Util::panic("Unhandled RSP COP0 register read at index {}", index); + return 0; } } -FORCE_INLINE void SetCop0Reg(Registers ®s, Mem &mem, u8 index, u32 val) { +FORCE_INLINE void SetCop0Reg(Mem &mem, const u8 index, const u32 val) { MMIO &mmio = mem.mmio; RSP &rsp = mmio.rsp; RDP &rdp = mmio.rdp; - MI &mi = mmio.mi; switch (index) { case 0: rsp.spDMASPAddr.raw = val; @@ -108,7 +108,8 @@ FORCE_INLINE void SetCop0Reg(Registers ®s, Mem &mem, u8 index, u32 val) { } } -FORCE_INLINE VPR Broadcast(const VPR &vt, int l0, int l1, int l2, int l3, int l4, int l5, int l6, int l7) { +FORCE_INLINE VPR Broadcast(const VPR &vt, const int l0, const int l1, const int l2, const int l3, const int l4, + const int l5, const int l6, const int l7) { VPR vte{}; vte.element[ELEMENT_INDEX(0)] = vt.element[ELEMENT_INDEX(l0)]; vte.element[ELEMENT_INDEX(1)] = vt.element[ELEMENT_INDEX(l1)]; @@ -122,12 +123,12 @@ FORCE_INLINE VPR Broadcast(const VPR &vt, int l0, int l1, int l2, int l3, int l4 } #ifdef SIMD_SUPPORT -FORCE_INLINE VPR GetVTE(const VPR &vt, u8 e) { - VPR vte{}; +void RSP::SetVTE(const VPR &vt, u8 e) { e &= 0xf; switch (e & 0xf) { case 0 ... 1: - return vt; + vte = vt; + break; case 2: vte.single = _mm_shufflehi_epi16(_mm_shufflelo_epi16(vt.single, 0xF5), 0xF5); break; @@ -148,20 +149,19 @@ FORCE_INLINE VPR GetVTE(const VPR &vt, u8 e) { break; case 8 ... 15: { - int index = ELEMENT_INDEX(e - 8); + const int index = ELEMENT_INDEX(e - 8); vte.single = _mm_set1_epi16(vt.element[index]); } break; } - return vte; } #else -FORCE_INLINE VPR GetVTE(const VPR &vt, u8 e) { - VPR vte{}; +void RSP::SetVTE(const VPR &vt, u8 e) { e &= 0xf; switch (e) { case 0 ... 1: - return vt; + vte = vt; + break; case 2 ... 3: vte = Broadcast(vt, e - 2, e - 2, e, e, e + 2, e + 2, e + 4, e + 4); break; @@ -177,24 +177,23 @@ FORCE_INLINE VPR GetVTE(const VPR &vt, u8 e) { } break; } - return vte; } #endif -void RSP::add(u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] + gpr[RT(instr)]; } +void RSP::add(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] + gpr[RT(instr)]; } -void RSP::addi(u32 instr) { - s32 op1 = gpr[RS(instr)]; - s16 op2 = instr; - s32 result = op1 + op2; +void RSP::addi(const u32 instr) { + const s32 op1 = gpr[RS(instr)]; + const s16 op2 = instr; + const s32 result = op1 + op2; gpr[RT(instr)] = result; } -void RSP::and_(u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] & gpr[RS(instr)]; } +void RSP::and_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] & gpr[RS(instr)]; } -void RSP::andi(u32 instr) { gpr[RT(instr)] = gpr[RS(instr)] & (u16)instr; } +void RSP::andi(const u32 instr) { gpr[RT(instr)] = gpr[RS(instr)] & (u16)instr; } -void RSP::cfc2(u32 instr) { +void RSP::cfc2(const u32 instr) { s16 value = 0; switch (RD(instr) & 3) { case 0: @@ -211,8 +210,8 @@ void RSP::cfc2(u32 instr) { gpr[RT(instr)] = value; } -void RSP::ctc2(u32 instr) { - u16 value = gpr[RT(instr)]; +void RSP::ctc2(const u32 instr) { + const u16 value = gpr[RT(instr)]; switch (RD(instr) & 3) { case 0: for (int i = 0; i < 8; i++) { @@ -235,49 +234,49 @@ void RSP::ctc2(u32 instr) { } } -void RSP::b(u32 instr, bool cond) { - u32 address = ((instr & 0xFFFF) << 2) + pc; +void RSP::b(const u32 instr, const bool cond) { + const u32 address = ((instr & 0xFFFF) << 2) + pc; branch(address, cond); } -void RSP::blink(u32 instr, bool cond) { +void RSP::blink(const u32 instr, const bool cond) { b(instr, cond); gpr[31] = pc + 4; } -void RSP::lb(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::lb(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; gpr[RT(instr)] = (s32)(s8)ReadByte(address); } -void RSP::lh(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::lh(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; gpr[RT(instr)] = (s32)(s16)ReadHalf(address); } -void RSP::lw(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::lw(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; gpr[RT(instr)] = ReadWord(address); } -void RSP::lbu(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::lbu(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; gpr[RT(instr)] = ReadByte(address); } -void RSP::lhu(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::lhu(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; gpr[RT(instr)] = ReadHalf(address); } -void RSP::lui(u32 instr) { +void RSP::lui(const u32 instr) { u32 imm = ((u16)instr) << 16; gpr[RT(instr)] = imm; } #define OFFSET(x) ((x) & 0x7F) -void RSP::lqv(u32 instr) { +void RSP::lqv(const u32 instr) { int e = E1(instr); u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); u32 end = ((addr & ~15) + 15); @@ -287,15 +286,15 @@ void RSP::lqv(u32 instr) { } } -void RSP::lpv(u32 instr) { - int e = E1(instr); +void RSP::lpv(const u32 instr) { + const int e = E1(instr); u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); - int addrOffset = addr & 7; + const int addrOffset = addr & 7; addr &= ~7; for (int elem = 0; elem < 8; elem++) { - int elemOffset = (16 - e + (elem + addrOffset)) & 0xF; + const int elemOffset = (16 - e + (elem + addrOffset)) & 0xF; u16 value = ReadByte(addr + elemOffset); value <<= 8; @@ -303,16 +302,16 @@ void RSP::lpv(u32 instr) { } } -void RSP::luv(u32 instr) { +void RSP::luv(const u32 instr) { u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); - int e = E1(instr); + const int e = E1(instr); - int addrOffset = addr & 7; + const int addrOffset = addr & 7; addr &= ~7; for (int elem = 0; elem < 8; elem++) { - int elemOffset = (16 - e + (elem + addrOffset)) & 0xF; + const int elemOffset = (16 - e + (elem + addrOffset)) & 0xF; u16 value = ReadByte(addr + elemOffset); value <<= 7; @@ -320,11 +319,11 @@ void RSP::luv(u32 instr) { } } -void RSP::suv(u32 instr) { +void RSP::suv(const u32 instr) { u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); - int start = E1(instr); - int end = start + 8; + const int start = E1(instr); + const int end = start + 8; for (int offset = start; offset < end; offset++) { if ((offset & 15) < 8) { @@ -335,10 +334,10 @@ void RSP::suv(u32 instr) { } } -void RSP::ldv(u32 instr) { - int e = E1(instr); +void RSP::ldv(const u32 instr) { + const int e = E1(instr); u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); - u32 end = e + 8 > 16 ? 16 : e + 8; + const u32 end = e + 8 > 16 ? 16 : e + 8; for (int i = e; i < end; i++) { vpr[VT(instr)].byte[BYTE_INDEX(i)] = ReadByte(addr); @@ -346,27 +345,27 @@ void RSP::ldv(u32 instr) { } } -void RSP::lsv(u32 instr) { - u8 e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); - u16 val = ReadHalf(addr); +void RSP::lsv(const u32 instr) { + const u8 e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); + const u16 val = ReadHalf(addr); vpr[VT(instr)].byte[BYTE_INDEX(e)] = val >> 8; if (e < 15) { vpr[VT(instr)].byte[BYTE_INDEX(e + 1)] = val; } } -void RSP::lbv(u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); +void RSP::lbv(const u32 instr) { + const u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); vpr[VT(instr)].byte[BYTE_INDEX(E1(instr))] = ReadByte(address); } -void RSP::llv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); +void RSP::llv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); for (int i = 0; i < 4; i++) { - int elem = i + e; + const int elem = i + e; if (elem > 15) { break; } @@ -375,60 +374,60 @@ void RSP::llv(u32 instr) { } } -void RSP::j(u32 instr) { - u32 target = (instr & 0x3ffffff) << 2; +void RSP::j(const u32 instr) { + const u32 target = (instr & 0x3ffffff) << 2; nextPC = target; } -void RSP::jal(u32 instr) { +void RSP::jal(const u32 instr) { j(instr); gpr[31] = pc + 4; } -void RSP::jr(u32 instr) { nextPC = gpr[RS(instr)]; } +void RSP::jr(const u32 instr) { nextPC = gpr[RS(instr)]; } -void RSP::jalr(u32 instr) { +void RSP::jalr(const u32 instr) { jr(instr); gpr[RD(instr)] = pc + 4; } -void RSP::nor(u32 instr) { gpr[RD(instr)] = ~(gpr[RT(instr)] | gpr[RS(instr)]); } +void RSP::nor(const u32 instr) { gpr[RD(instr)] = ~(gpr[RT(instr)] | gpr[RS(instr)]); } -void RSP::ori(u32 instr) { - s32 op1 = gpr[RS(instr)]; - u32 op2 = instr & 0xffff; - s32 result = op1 | op2; +void RSP::ori(const u32 instr) { + const s32 op1 = gpr[RS(instr)]; + const u32 op2 = instr & 0xffff; + const s32 result = op1 | op2; gpr[RT(instr)] = result; } -void RSP::xori(u32 instr) { - s32 op1 = gpr[RS(instr)]; - u32 op2 = instr & 0xffff; - s32 result = op1 ^ op2; +void RSP::xori(const u32 instr) { + const s32 op1 = gpr[RS(instr)]; + const u32 op2 = instr & 0xffff; + const s32 result = op1 ^ op2; gpr[RT(instr)] = result; } -void RSP::or_(u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] | gpr[RS(instr)]; } +void RSP::or_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] | gpr[RS(instr)]; } -void RSP::xor_(u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] ^ gpr[RS(instr)]; } +void RSP::xor_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] ^ gpr[RS(instr)]; } -void RSP::sb(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::sb(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; WriteByte(address, gpr[RT(instr)]); } -void RSP::sh(u32 instr) { - s16 imm = s16(instr); - u32 address = gpr[RS(instr)] + imm; +void RSP::sh(const u32 instr) { + const s16 imm = s16(instr); + const u32 address = gpr[RS(instr)] + imm; WriteHalf(address, gpr[RT(instr)]); } -void RSP::sw(u32 instr) { - u32 address = gpr[BASE(instr)] + (s16)instr; +void RSP::sw(const u32 instr) { + const u32 address = gpr[BASE(instr)] + (s16)instr; WriteWord(address, gpr[RT(instr)]); } -void RSP::swv(u32 instr) { +void RSP::swv(const u32 instr) { u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); int base = address & 7; address &= ~7; @@ -439,24 +438,24 @@ void RSP::swv(u32 instr) { } } -void RSP::sub(u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] - gpr[RT(instr)]; } +void RSP::sub(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] - gpr[RT(instr)]; } -void RSP::sqv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - u32 end = ((addr & ~15) + 15); +void RSP::sqv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); + const u32 end = ((addr & ~15) + 15); for (int i = 0; addr + i <= end; i++) { WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 15)]); } } -void RSP::spv(u32 instr) { - int e = E1(instr); +void RSP::spv(const u32 instr) { + const int e = E1(instr); u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); - int start = e; - int end = start + 8; + const int start = e; + const int end = start + 8; for (int offset = start; offset < end; offset++) { if ((offset & 15) < 8) { @@ -467,60 +466,60 @@ void RSP::spv(u32 instr) { } } -void RSP::srv(u32 instr) { +void RSP::srv(const u32 instr) { u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - int start = E1(instr); - int end = start + (address & 15); - int base = 16 - (address & 15); + const int start = E1(instr); + const int end = start + (address & 15); + const int base = 16 - (address & 15); address &= ~15; for (int i = start; i < end; i++) { WriteByte(address++, vpr[VT(instr)].byte[BYTE_INDEX((i + base) & 0xF)]); } } -void RSP::shv(u32 instr) { +void RSP::shv(const u32 instr) { u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - u32 in_addr_offset = address & 0x7; + const u32 in_addr_offset = address & 0x7; address &= ~0x7; - int e = E1(instr); + const int e = E1(instr); for (int i = 0; i < 8; i++) { - int byte_index = (i * 2) + e; + const int byte_index = (i * 2) + e; u16 val = vpr[VT(instr)].byte[BYTE_INDEX(byte_index & 15)] << 1; val |= vpr[VT(instr)].byte[BYTE_INDEX((byte_index + 1) & 15)] >> 7; u8 b = val & 0xFF; - int ofs = in_addr_offset + (i * 2); + const int ofs = in_addr_offset + (i * 2); WriteByte(address + (ofs & 0xF), b); } } -void RSP::lhv(u32 instr) { +void RSP::lhv(const u32 instr) { u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - u32 in_addr_offset = address & 0x7; + const u32 in_addr_offset = address & 0x7; address &= ~0x7; - int e = E1(instr); + const int e = E1(instr); for (int i = 0; i < 8; i++) { - int ofs = ((16 - e) + (i * 2) + in_addr_offset) & 0xF; + const int ofs = ((16 - e) + (i * 2) + in_addr_offset) & 0xF; u16 val = ReadByte(address + ofs); val <<= 7; vpr[VT(instr)].element[ELEMENT_INDEX(i)] = val; } } -void RSP::lfv(u32 instr) { +void RSP::lfv(const u32 instr) { VPR &vt = vpr[VT(instr)]; - int start = E1(instr); + const int start = E1(instr); u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - u32 base = (address & 7) - start; + const u32 base = (address & 7) - start; address &= ~7; - int end = std::min(start + 8, 16); + const int end = std::min(start + 8, 16); // TODO: should be possible to do with one loop VPR tmp{}; @@ -534,10 +533,10 @@ void RSP::lfv(u32 instr) { } } -void RSP::lrv(u32 instr) { +void RSP::lrv(const u32 instr) { u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - int e = E1(instr); - int start = 16 - ((address & 15) - e); + const int e = E1(instr); + const int start = 16 - ((address & 15) - e); address &= ~15; for (int i = start; i < 16; i++) { @@ -545,12 +544,12 @@ void RSP::lrv(u32 instr) { } } -void RSP::sfv(u32 instr) { - VPR &vt = vpr[VT(instr)]; +void RSP::sfv(const u32 instr) { + const VPR &vt = vpr[VT(instr)]; u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - int base = address & 7; + const int base = address & 7; address &= ~7; - int e = E1(instr); + const int e = E1(instr); u8 values[4] = {0, 0, 0, 0}; @@ -607,134 +606,134 @@ void RSP::sfv(u32 instr) { } } -void RSP::sbv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); +void RSP::sbv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); WriteByte(addr, vpr[VT(instr)].byte[BYTE_INDEX(e & 0xF)]); } -void RSP::sdv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::sdv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); for (int i = 0; i < 8; i++) { WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 0xF)]); } } -void RSP::ssv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); +void RSP::ssv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); - u8 hi = vpr[VT(instr)].byte[BYTE_INDEX(e & 15)]; - u8 lo = vpr[VT(instr)].byte[BYTE_INDEX((e + 1) & 15)]; - u16 val = (u16)hi << 8 | lo; + const u8 hi = vpr[VT(instr)].byte[BYTE_INDEX(e & 15)]; + const u8 lo = vpr[VT(instr)].byte[BYTE_INDEX((e + 1) & 15)]; + const u16 val = (u16)hi << 8 | lo; WriteHalf(addr, val); } -void RSP::slv(u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); +void RSP::slv(const u32 instr) { + const int e = E1(instr); + const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); for (int i = 0; i < 4; i++) { WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 0xF)]); } } -void RSP::stv(u32 instr) { +void RSP::stv(const u32 instr) { u32 base = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - u32 addrOffset = base & 0x7; + const u32 addrOffset = base & 0x7; base &= ~0x7; - u8 e = E1(instr) >> 1; + const u8 e = E1(instr) >> 1; for (int i = 0; i < 8; i++) { - u32 address = base; - u32 offset = (i << 1) + addrOffset; + const u32 address = base; + const u32 offset = (i << 1) + addrOffset; - int reg = (VT(instr) & 0x18) | ((i + e) & 0x7); + const int reg = (VT(instr) & 0x18) | ((i + e) & 0x7); - u16 val = vpr[reg].element[ELEMENT_INDEX(i & 0x7)]; - u16 hi = (val >> 8) & 0xFF; - u16 lo = (val >> 0) & 0xFF; + const u16 val = vpr[reg].element[ELEMENT_INDEX(i & 0x7)]; + const u16 hi = (val >> 8) & 0xFF; + const u16 lo = (val >> 0) & 0xFF; WriteByte(address + ((offset + 0) & 0xF), hi); WriteByte(address + ((offset + 1) & 0xF), lo); } } -void RSP::ltv(u32 instr) { +void RSP::ltv(const u32 instr) { u32 base = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); base &= ~0x7; - u8 e = E1(instr); + const u8 e = E1(instr); for (int i = 0; i < 8; i++) { - u32 address = base; - u32 offset = (i << 1) + e + (base & 8); + const u32 address = base; + const u32 offset = (i << 1) + e + (base & 8); - u16 hi = ReadByte(address + (offset & 0xF)); - u16 lo = ReadByte(address + ((offset + 1) & 0xF)); + const u16 hi = ReadByte(address + (offset & 0xF)); + const u16 lo = ReadByte(address + ((offset + 1) & 0xF)); - int reg = (VT(instr) & 0x18) | ((i + (e >> 1)) & 0x7); + const int reg = (VT(instr) & 0x18) | ((i + (e >> 1)) & 0x7); vpr[reg].element[ELEMENT_INDEX(i & 0x7)] = (hi << 8) | lo; } } -void RSP::sllv(u32 instr) { - u8 sa = (gpr[RS(instr)]) & 0x1F; - u32 rt = gpr[RT(instr)]; - u32 result = rt << sa; +void RSP::sllv(const u32 instr) { + const u8 sa = (gpr[RS(instr)]) & 0x1F; + const u32 rt = gpr[RT(instr)]; + const u32 result = rt << sa; gpr[RD(instr)] = result; } -void RSP::srlv(u32 instr) { - u8 sa = (gpr[RS(instr)]) & 0x1F; - u32 rt = gpr[RT(instr)]; - u32 result = rt >> sa; +void RSP::srlv(const u32 instr) { + const u8 sa = (gpr[RS(instr)]) & 0x1F; + const u32 rt = gpr[RT(instr)]; + const u32 result = rt >> sa; gpr[RD(instr)] = result; } -void RSP::srav(u32 instr) { - u8 sa = gpr[RS(instr)] & 0x1F; - s32 rt = gpr[RT(instr)]; - s32 result = rt >> sa; +void RSP::srav(const u32 instr) { + const u8 sa = gpr[RS(instr)] & 0x1F; + const s32 rt = gpr[RT(instr)]; + const s32 result = rt >> sa; gpr[RD(instr)] = result; } -void RSP::sll(u32 instr) { - u8 sa = (instr >> 6) & 0x1f; +void RSP::sll(const u32 instr) { + const u8 sa = (instr >> 6) & 0x1f; gpr[RD(instr)] = (u32)gpr[RT(instr)] << sa; } -void RSP::srl(u32 instr) { - u8 sa = (instr >> 6) & 0x1f; +void RSP::srl(const u32 instr) { + const u8 sa = (instr >> 6) & 0x1f; gpr[RD(instr)] = (u32)gpr[RT(instr)] >> sa; } -void RSP::sra(u32 instr) { - u8 sa = (instr >> 6) & 0x1f; +void RSP::sra(const u32 instr) { + const u8 sa = (instr >> 6) & 0x1f; gpr[RD(instr)] = gpr[RT(instr)] >> sa; } -void RSP::slt(u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] < gpr[RT(instr)]; } +void RSP::slt(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] < gpr[RT(instr)]; } -void RSP::sltu(u32 instr) { gpr[RD(instr)] = (u32)gpr[RS(instr)] < (u32)gpr[RT(instr)]; } +void RSP::sltu(const u32 instr) { gpr[RD(instr)] = (u32)gpr[RS(instr)] < (u32)gpr[RT(instr)]; } -void RSP::slti(u32 instr) { - s32 imm = (s16)instr; +void RSP::slti(const u32 instr) { + const s32 imm = (s16)instr; gpr[RT(instr)] = gpr[RS(instr)] < imm; } -void RSP::sltiu(u32 instr) { - s32 imm = (s16)instr; +void RSP::sltiu(const u32 instr) { + const s32 imm = (s16)instr; gpr[RT(instr)] = (u32)gpr[RS(instr)] < imm; } -FORCE_INLINE s16 signedClamp(s64 val) { +FORCE_INLINE s16 signedClamp(const s64 val) { if (val < -32768) return -32768; if (val > 32767) @@ -742,7 +741,7 @@ FORCE_INLINE s16 signedClamp(s64 val) { return val; } -FORCE_INLINE u16 unsignedClamp(s64 val) { +FORCE_INLINE u16 unsignedClamp(const s64 val) { if (val < 0) return 0; if (val > 32767) @@ -751,23 +750,23 @@ FORCE_INLINE u16 unsignedClamp(s64 val) { } #ifdef SIMD_SUPPORT -void RSP::vabs(u32 instr) { - VPR &vs = vpr[VS(instr)]; +void RSP::vabs(const u32 instr) { + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); - m128i isZero = _mm_cmpeq_epi16(vs.single, m128i{}); - m128i isNeg = _mm_srai_epi16(vs.single, 15); + const m128i isZero = _mm_cmpeq_epi16(vs.single, m128i{}); + const m128i isNeg = _mm_srai_epi16(vs.single, 15); m128i temp = _mm_andnot_si128(isZero, vte.single); temp = _mm_xor_si128(temp, isNeg); acc.l.single = _mm_sub_epi16(temp, isNeg); vd.single = _mm_subs_epi16(temp, isNeg); } #else -void RSP::vabs(u32 instr) { +void RSP::vabs(const u32 instr) { VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { if (vs.selement[i] < 0) { @@ -789,13 +788,13 @@ void RSP::vabs(u32 instr) { } #endif -void RSP::vadd(u32 instr) { - VPR &vs = vpr[VS(instr)]; +void RSP::vadd(const u32 instr) { + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - s32 result = vs.selement[i] + vte.selement[i] + (vco.l.selement[i] != 0); + const s32 result = vs.selement[i] + vte.selement[i] + (vco.l.selement[i] != 0); acc.l.element[i] = result; vd.element[i] = (u16)signedClamp(result); vco.l.element[i] = 0; @@ -803,13 +802,13 @@ void RSP::vadd(u32 instr) { } } -void RSP::vaddc(u32 instr) { - VPR &vs = vpr[VS(instr)]; +void RSP::vaddc(const u32 instr) { + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - u32 result = vs.element[i] + vte.element[i]; + const u32 result = vs.element[i] + vte.element[i]; acc.l.element[i] = result; vd.element[i] = result; vco.l.element[i] = ((result >> 16) & 1) ? 0xffff : 0; @@ -817,11 +816,11 @@ void RSP::vaddc(u32 instr) { } } -void RSP::vch(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vch(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { s16 vsElem = vs.selement[i]; @@ -829,7 +828,7 @@ void RSP::vch(u32 instr) { vco.l.element[i] = ((vsElem ^ vteElem) < 0) ? 0xffff : 0; if (vco.l.element[i]) { - s16 result = vsElem + vteElem; + const s16 result = vsElem + vteElem; acc.l.selement[i] = (result <= 0) ? -vteElem : vsElem; vcc.l.element[i] = result <= 0 ? 0xffff : 0; @@ -837,7 +836,7 @@ void RSP::vch(u32 instr) { vco.h.element[i] = (result != 0 && (vteElem != ~vsElem)) ? 0xffff : 0; vce.element[i] = result == -1 ? 0xffff : 0; } else { - s16 result = vsElem - vteElem; + const s16 result = vsElem - vteElem; acc.l.element[i] = (result >= 0) ? vteElem : vsElem; vcc.l.element[i] = vteElem < 0 ? 0xffff : 0; vcc.h.element[i] = result >= 0 ? 0xffff : 0; @@ -849,25 +848,25 @@ void RSP::vch(u32 instr) { } } -void RSP::vcr(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vcr(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { u16 vsE = vs.element[i]; - u16 vteE = vte.element[i]; + const u16 vteE = vte.element[i]; - bool signDiff = (0x8000 & (vsE ^ vteE)) == 0x8000; + const bool signDiff = (0x8000 & (vsE ^ vteE)) == 0x8000; u16 vtAbs = signDiff ? ~vteE : vteE; bool gte = s16(vteE) <= s16(signDiff ? 0xffff : vsE); bool lte = (((signDiff ? vsE : 0) + vteE) & 0x8000) == 0x8000; - bool check = signDiff ? lte : gte; - u16 result = check ? vtAbs : vsE; + const bool check = signDiff ? lte : gte; + const u16 result = check ? vtAbs : vsE; acc.l.element[i] = result; vd.element[i] = result; @@ -881,11 +880,11 @@ void RSP::vcr(u32 instr) { } } -void RSP::vcl(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vcl(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { u16 vs_element = vs.element[i]; @@ -893,8 +892,8 @@ void RSP::vcl(u32 instr) { if (vco.l.element[i]) { if (!vco.h.element[i]) { - u16 clamped_sum = vs_element + vte_element; - bool overflow = (vs_element + vte_element) != clamped_sum; + const u16 clamped_sum = vs_element + vte_element; + const bool overflow = (vs_element + vte_element) != clamped_sum; if (vce.element[i]) { vcc.l.element[i] = (!clamped_sum || !overflow) ? 0xffff : 0; } else { @@ -915,10 +914,10 @@ void RSP::vcl(u32 instr) { vd.element[i] = acc.l.element[i]; } } -void RSP::vmov(u32 instr) { - u8 e = E2(instr), vs = VS(instr) & 7; +void RSP::vmov(const u32 instr) { + const u8 e = E2(instr), vs = VS(instr) & 7; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); u8 se; switch (e) { @@ -938,7 +937,7 @@ void RSP::vmov(u32 instr) { Util::panic("VMOV: This should be unreachable!"); } - u8 de = vs & 7; + const u8 de = vs & 7; vd.element[ELEMENT_INDEX(de)] = vte.element[ELEMENT_INDEX(se)]; #ifdef SIMD_SUPPORT @@ -950,46 +949,45 @@ void RSP::vmov(u32 instr) { #endif } -FORCE_INLINE bool IsSignExtension(s16 hi, s16 lo) { +FORCE_INLINE bool IsSignExtension(const s16 hi, const s16 lo) { if (hi == 0) { return (lo & 0x8000) == 0; - } else if (hi == -1) { + } + if (hi == -1) { return (lo & 0x8000) == 0x8000; } return false; } -void RSP::vmulf(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmulf(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s16 op1 = vte.element[i]; - s16 op2 = vs.element[i]; - s32 prod = op1 * op2; + const s16 op1 = vte.element[i]; + const s16 op2 = vs.element[i]; + const s32 prod = op1 * op2; s64 accum = prod; accum = (accum * 2) + 0x8000; SetACC(i, accum); - s16 result = signedClamp(accum >> 16); + const s16 result = signedClamp(accum >> 16); vd.element[i] = result; } } -void RSP::vmulq(u32 instr) { - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vmulq(const u32 instr) { + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); VPR &vd = vpr[VD(instr)]; for (int i = 0; i < 8; i++) { - s32 product = vs.selement[i] * vte.selement[i]; - if (product < 0) { - product += 31; - } + const bool neg = vte.selement[i] < 0 && vs.selement[i] >= 0 || vs.selement[i] < 0 && vte.selement[i] >= 0; + const s32 product = vs.selement[i] * vte.selement[i] + 31 * neg; acc.h.element[i] = product >> 16; acc.m.element[i] = product; @@ -998,37 +996,37 @@ void RSP::vmulq(u32 instr) { } } -void RSP::vmulu(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmulu(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s16 op1 = vte.element[i]; - s16 op2 = vs.element[i]; - s32 prod = op1 * op2; + const s16 op1 = vte.element[i]; + const s16 op2 = vs.element[i]; + const s32 prod = op1 * op2; s64 accum = prod; accum = (accum * 2) + 0x8000; SetACC(i, accum); - u16 result = unsignedClamp(accum >> 16); + const u16 result = unsignedClamp(accum >> 16); vd.element[i] = result; } } -void RSP::vmudl(u32 instr) { - u8 e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmudl(const u32 instr) { + const u8 e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - u64 op1 = vte.element[i]; - u64 op2 = vs.element[i]; - u64 prod = op1 * op2; - u64 accum = prod >> 16; + const u64 op1 = vte.element[i]; + const u64 op2 = vs.element[i]; + const u64 prod = op1 * op2; + const u64 accum = prod >> 16; SetACC(i, accum); @@ -1045,50 +1043,46 @@ void RSP::vmudl(u32 instr) { } } -void RSP::vmudh(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmudh(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s32 prod = vs.selement[i] * vte.selement[i]; - s64 accum = prod; - - s16 result = signedClamp(accum); - - accum <<= 16; + const s32 prod = vs.selement[i] * vte.selement[i]; + const s16 result = signedClamp(prod); + const s64 accum = static_cast(prod) << 16; SetACC(i, accum); vd.element[i] = result; } } -void RSP::vmudm(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmudm(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s32 prod = vs.selement[i] * vte.element[i]; - s64 accum = prod; - - s16 result = signedClamp(accum >> 16); + const s32 prod = vs.selement[i] * vte.element[i]; + const s64 accum = prod; + const s16 result = signedClamp(accum >> 16); SetACC(i, accum); vd.element[i] = result; } } -void RSP::vmudn(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmudn(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s16 op1 = vte.element[i]; - u16 op2 = vs.element[i]; - s32 prod = op1 * op2; - s64 accum = prod; + const s16 op1 = vte.element[i]; + const u16 op2 = vs.element[i]; + const s32 prod = op1 * op2; + const s64 accum = prod; SetACC(i, accum); u16 result; @@ -1105,15 +1099,14 @@ void RSP::vmudn(u32 instr) { } #ifdef SIMD_SUPPORT -void RSP::vmadh(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmadh(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); - m128i lo, hi, omask; - lo = _mm_mullo_epi16(vs.single, vte.single); - hi = _mm_mulhi_epi16(vs.single, vte.single); - omask = _mm_adds_epu16(acc.m.single, lo); + SetVTE(vpr[VT(instr)], e); + m128i lo = _mm_mullo_epi16(vs.single, vte.single); + m128i hi = _mm_mulhi_epi16(vs.single, vte.single); + m128i omask = _mm_adds_epu16(acc.m.single, lo); acc.m.single = _mm_add_epi16(acc.m.single, lo); omask = _mm_cmpeq_epi16(acc.m.single, omask); omask = _mm_cmpeq_epi16(omask, m128i{}); @@ -1124,11 +1117,11 @@ void RSP::vmadh(u32 instr) { vd.single = _mm_packs_epi32(lo, hi); } #else -void RSP::vmadh(u32 instr) { +void RSP::vmadh(const u32 instr) { int e = E2(instr); VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { s16 op1 = vte.element[i]; s16 op2 = vs.element[i]; @@ -1147,18 +1140,18 @@ void RSP::vmadh(u32 instr) { } #endif -void RSP::vmadl(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmadl(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - u64 op1 = vte.element[i]; - u64 op2 = vs.element[i]; - u64 prod = op1 * op2; - u64 accDelta = prod >> 16; - u64 accum = GetACC(i) + accDelta; + const u64 op1 = vte.element[i]; + const u64 op2 = vs.element[i]; + const u64 prod = op1 * op2; + const u64 accDelta = prod >> 16; + const u64 accum = GetACC(i) + accDelta; SetACC(i, accum); @@ -1175,19 +1168,17 @@ void RSP::vmadl(u32 instr) { } } #ifdef SIMD_SUPPORT -void RSP::vmadm(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); +void RSP::vmadm(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); - m128i lo, hi, sign, vta, omask; - lo = _mm_mullo_epi16(vs.single, vte.single); - hi = _mm_mulhi_epu16(vs.single, vte.single); - sign = _mm_srai_epi16(vs.single, 15); - vta = _mm_and_si128(vte.single, sign); + m128i lo = _mm_mullo_epi16(vs.single, vte.single); + m128i hi = _mm_mulhi_epu16(vs.single, vte.single); + const m128i sign = _mm_srai_epi16(vs.single, 15); + const m128i vta = _mm_and_si128(vte.single, sign); hi = _mm_sub_epi16(hi, vta); - omask = _mm_adds_epu16(acc.l.single, lo); + m128i omask = _mm_adds_epu16(acc.l.single, lo); acc.l.single = _mm_add_epi16(acc.l.single, lo); omask = _mm_cmpeq_epi16(acc.l.single, omask); omask = _mm_cmpeq_epi16(omask, m128i{}); @@ -1201,22 +1192,21 @@ void RSP::vmadm(u32 instr) { acc.h.single = _mm_sub_epi16(acc.h.single, omask); lo = _mm_unpacklo_epi16(acc.m.single, acc.h.single); hi = _mm_unpackhi_epi16(acc.m.single, acc.h.single); + VPR &vd = vpr[VD(instr)]; vd.single = _mm_packs_epi32(lo, hi); } -void RSP::vmadn(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); +void RSP::vmadn(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); - m128i lo, hi, sign, vsa, omask, nhi, nmd, shi, smd, cmask, cval; - lo = _mm_mullo_epi16(vs.single, vte.single); - hi = _mm_mulhi_epu16(vs.single, vte.single); - sign = _mm_srai_epi16(vte.single, 15); - vsa = _mm_and_si128(vs.single, sign); + const m128i lo = _mm_mullo_epi16(vs.single, vte.single); + m128i hi = _mm_mulhi_epu16(vs.single, vte.single); + const m128i sign = _mm_srai_epi16(vte.single, 15); + const m128i vsa = _mm_and_si128(vs.single, sign); hi = _mm_sub_epi16(hi, vsa); - omask = _mm_adds_epu16(acc.l.single, lo); + m128i omask = _mm_adds_epu16(acc.l.single, lo); acc.l.single = _mm_add_epi16(acc.l.single, lo); omask = _mm_cmpeq_epi16(acc.l.single, omask); omask = _mm_cmpeq_epi16(omask, m128i{}); @@ -1228,20 +1218,21 @@ void RSP::vmadn(u32 instr) { hi = _mm_srai_epi16(hi, 15); acc.h.single = _mm_add_epi16(acc.h.single, hi); acc.h.single = _mm_sub_epi16(acc.h.single, omask); - nhi = _mm_srai_epi16(acc.h.single, 15); - nmd = _mm_srai_epi16(acc.m.single, 15); - shi = _mm_cmpeq_epi16(nhi, acc.h.single); - smd = _mm_cmpeq_epi16(nhi, nmd); - cmask = _mm_and_si128(smd, shi); - cval = _mm_cmpeq_epi16(nhi, m128i{}); + const m128i nhi = _mm_srai_epi16(acc.h.single, 15); + const m128i nmd = _mm_srai_epi16(acc.m.single, 15); + const m128i shi = _mm_cmpeq_epi16(nhi, acc.h.single); + const m128i smd = _mm_cmpeq_epi16(nhi, nmd); + const m128i cmask = _mm_and_si128(smd, shi); + const m128i cval = _mm_cmpeq_epi16(nhi, m128i{}); + VPR &vd = vpr[VD(instr)]; vd.single = _mm_blendv_epi8(cval, acc.l.single, cmask); } #else -void RSP::vmadm(u32 instr) { +void RSP::vmadm(const u32 instr) { int e = E2(instr); VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { s32 prod = vs.selement[i] * vte.element[i]; @@ -1256,11 +1247,11 @@ void RSP::vmadm(u32 instr) { } } -void RSP::vmadn(u32 instr) { +void RSP::vmadn(const u32 instr) { int e = E2(instr); VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { s32 prod = vs.element[i] * vte.selement[i]; @@ -1282,48 +1273,46 @@ void RSP::vmadn(u32 instr) { } #endif -void RSP::vmacf(u32 instr) { +void RSP::vmacf(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - s16 op1 = vte.element[i]; - s16 op2 = vs.element[i]; - s32 prod = op1 * op2; + const s16 op1 = vte.element[i]; + const s16 op2 = vs.element[i]; + const s32 prod = op1 * op2; - s64 accDelta = prod; - accDelta *= 2; + const s64 accDelta = static_cast(prod) * 2; s64 accum = GetACC(i) + accDelta; SetACC(i, accum); accum = GetACC(i); - s16 result = signedClamp(accum >> 16); + const s16 result = signedClamp(accum >> 16); vd.element[i] = result; } } -void RSP::vmacu(u32 instr) { +void RSP::vmacu(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - s16 op1 = vte.element[i]; - s16 op2 = vs.element[i]; - s32 prod = op1 * op2; - s64 accDelta = prod; - accDelta *= 2; + const s16 op1 = vte.element[i]; + const s16 op2 = vs.element[i]; + const s32 prod = op1 * op2; + const s64 accDelta = static_cast(prod) * 2; s64 accum = GetACC(i) + accDelta; SetACC(i, accum); accum = GetACC(i); - u16 result = unsignedClamp(accum >> 16); + const u16 result = unsignedClamp(accum >> 16); vd.element[i] = result; } } -void RSP::vmacq(u32 instr) { +void RSP::vmacq(const u32 instr) { VPR &vd = vpr[VD(instr)]; for (int i = 0; i < 8; i++) { @@ -1340,117 +1329,122 @@ void RSP::vmacq(u32 instr) { } } -void RSP::veq(u32 instr) { - int e = E2(instr); +void RSP::veq(const u32 instr) { + const int e = E2(instr); VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - vcc.l.element[i] = (vco.h.element[i] == 0) && (vs.element[i] == vte.element[i]) ? 0xffff : 0; + vcc.l.element[i] = vco.h.element[i] == 0 && vs.element[i] == vte.element[i] ? 0xffff : 0; acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; vd.element[i] = acc.l.element[i]; vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0; } } -void RSP::vne(u32 instr) { - int e = E2(instr); +void RSP::vne(const u32 instr) { + const int e = E2(instr); VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - vcc.l.element[i] = vco.h.element[i] || (vs.element[i] != vte.element[i]) ? 0xffff : 0; + vcc.l.element[i] = vco.h.element[i] || vs.element[i] != vte.element[i] ? 0xffff : 0; acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; vd.element[i] = acc.l.element[i]; vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0; } } -void RSP::vge(u32 instr) { - int e = E2(instr); +void RSP::vge(const u32 instr) { + const int e = E2(instr); VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - bool eql = vs.selement[i] == vte.selement[i]; - bool neg = !(vco.h.element[i] && vco.l.element[i]) && eql; - vcc.l.element[i] = (neg || (vs.selement[i] > vte.selement[i])) ? 0xffff : 0; + const bool eql = vs.selement[i] == vte.selement[i]; + const bool neg = !(vco.h.element[i] && vco.l.element[i]) && eql; + vcc.l.element[i] = neg || vs.selement[i] > vte.selement[i] ? 0xffff : 0; acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; vd.element[i] = acc.l.element[i]; vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0; } } -void RSP::vlt(u32 instr) { - int e = E2(instr); +void RSP::vlt(const u32 instr) { + const int e = E2(instr); VPR &vd = vpr[VD(instr)]; - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - bool eql = vs.element[i] == vte.element[i]; - bool neg = vco.h.element[i] && vco.l.element[i] && eql; - vcc.l.element[i] = (neg || (vs.selement[i] < vte.selement[i])) ? 0xffff : 0; + const bool eql = vs.element[i] == vte.element[i]; + const bool neg = vco.h.element[i] && vco.l.element[i] && eql; + vcc.l.element[i] = neg || vs.selement[i] < vte.selement[i] ? 0xffff : 0; acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; vd.element[i] = acc.l.element[i]; vcc.h.element[i] = vco.h.element[i] = vco.l.element[i] = 0; } } -FORCE_INLINE u32 rcp(s32 sinput) { - s32 mask = sinput >> 31; +FORCE_INLINE u32 rcp(const s32 sinput) { + const s32 mask = sinput >> 31; s32 input = sinput ^ mask; if (sinput > INT16_MIN) { input -= mask; } if (input == 0) { return 0x7FFFFFFF; - } else if (sinput == INT16_MIN) { + } + if (sinput == INT16_MIN) { return 0xFFFF0000; } - u32 shift = __builtin_clz(input); - u64 dinput = (u64)input; - u32 index = ((dinput << shift) & 0x7FC00000) >> 22; + const u32 shift = std::countl_zero(static_cast(input)); + const u64 dinput = static_cast(input); + const u32 index = (dinput << shift & 0x7FC00000) >> 22; s32 result = rcpRom[index]; result = (0x10000 | result) << 14; - result = (result >> (31 - shift)) ^ mask; + result = result >> (31 - shift) ^ mask; return result; } FORCE_INLINE u32 rsq(u32 input) { if (input == 0) { return 0x7FFFFFFF; - } else if (input == 0xFFFF8000) { + } + + if (input == 0xFFFF8000) { return 0xFFFF0000; - } else if (input > 0xFFFF8000) { + } + + if (input > 0xFFFF8000) { input--; } - s32 sinput = input; - s32 mask = sinput >> 31; + const s32 sinput = input; + const s32 mask = sinput >> 31; input ^= mask; - int shift = __builtin_clz(input) + 1; + const int shift = std::countl_zero(input) + 1; - int index = (((input << shift) >> 24) | ((shift & 1) << 8)); - u32 rom = (((u32)rsqRom[index]) << 14); - int r_shift = ((32 - shift) >> 1); - u32 result = (0x40000000 | rom) >> r_shift; + const int index = (((input << shift) >> 24) | ((shift & 1) << 8)); + const u32 rom = (((u32)rsqRom[index]) << 14); + const int r_shift = ((32 - shift) >> 1); + const u32 result = (0x40000000 | rom) >> r_shift; return result ^ mask; } -void RSP::vrcpl(u32 instr) { +void RSP::vrcpl(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vt = vpr[VT(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); - int e = E2(instr) & 7; - int de = DE(instr) & 7; + const VPR &vt = vpr[VT(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); + const int e = E2(instr) & 7; + const int de = DE(instr) & 7; s32 input; if (divInLoaded) { @@ -1459,7 +1453,7 @@ void RSP::vrcpl(u32 instr) { input = vt.selement[ELEMENT_INDEX(e)]; } - s32 result = rcp(input); + const s32 result = rcp(input); divOut = result >> 16; divIn = 0; divInLoaded = false; @@ -1475,14 +1469,14 @@ void RSP::vrcpl(u32 instr) { vd.element[ELEMENT_INDEX(de)] = result; } -void RSP::vrcp(u32 instr) { +void RSP::vrcp(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vt = vpr[VT(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); - int e = E2(instr) & 7; - int de = DE(instr) & 7; - s32 input = vt.selement[ELEMENT_INDEX(e)]; - s32 result = rcp(input); + const VPR &vt = vpr[VT(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); + const int e = E2(instr) & 7; + const int de = DE(instr) & 7; + const s32 input = vt.selement[ELEMENT_INDEX(e)]; + const s32 result = rcp(input); vd.element[ELEMENT_INDEX(de)] = result; divOut = result >> 16; divInLoaded = false; @@ -1496,14 +1490,14 @@ void RSP::vrcp(u32 instr) { #endif } -void RSP::vrsq(u32 instr) { +void RSP::vrsq(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vt = vpr[VT(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); - int e = E2(instr) & 7; - int de = VS(instr) & 7; - s32 input = vt.selement[ELEMENT_INDEX(e)]; - u32 result = rsq(input); + const VPR &vt = vpr[VT(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); + const int e = E2(instr) & 7; + const int de = VS(instr) & 7; + const s32 input = vt.selement[ELEMENT_INDEX(e)]; + const u32 result = rsq(input); vd.element[ELEMENT_INDEX(de)] = result & 0xFFFF; divOut = result >> 16; divInLoaded = false; @@ -1518,18 +1512,18 @@ void RSP::vrsq(u32 instr) { } // from nall, in ares -static FORCE_INLINE s64 sclip(s64 x, u32 bits) { - u64 b = 1ull << (bits - 1); - u64 m = b * 2 - 1; +static FORCE_INLINE s64 sclip(const s64 x, const u32 bits) { + const u64 b = 1ull << (bits - 1); + const u64 m = b * 2 - 1; return ((x & m) ^ b) - b; } -void RSP::vrndn(u32 instr) { +void RSP::vrndn(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - s32 product = (s16)vte.selement[i]; + s32 product = vte.selement[i]; if (VS(instr) & 1) { product <<= 16; @@ -1555,12 +1549,12 @@ void RSP::vrndn(u32 instr) { } } -void RSP::vrndp(u32 instr) { +void RSP::vrndp(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + SetVTE(vpr[VT(instr)], E2(instr)); for (int i = 0; i < 8; i++) { - s32 product = (s16)vte.selement[i]; + s32 product = vte.selement[i]; if (VS(instr) & 1) { product <<= 16; @@ -1586,12 +1580,12 @@ void RSP::vrndp(u32 instr) { } } -void RSP::vrsql(u32 instr) { +void RSP::vrsql(const u32 instr) { VPR &vd = vpr[VD(instr)]; - VPR &vt = vpr[VT(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); - int e = E2(instr) & 7; - int de = DE(instr) & 7; + const VPR &vt = vpr[VT(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); + const int e = E2(instr) & 7; + const int de = DE(instr) & 7; s32 input; if (divInLoaded) { @@ -1600,7 +1594,7 @@ void RSP::vrsql(u32 instr) { input = vt.selement[ELEMENT_INDEX(e)]; } - u32 result = rsq(input); + const u32 result = rsq(input); divOut = result >> 16; divInLoaded = false; @@ -1615,12 +1609,12 @@ void RSP::vrsql(u32 instr) { vd.element[ELEMENT_INDEX(de)] = result; } -void RSP::vrcph(u32 instr) { - int e = E2(instr) & 7; - int de = DE(instr) & 7; +void RSP::vrcph(const u32 instr) { + const int e = E2(instr) & 7; + const int de = DE(instr) & 7; VPR &vd = vpr[VD(instr)]; - VPR &vt = vpr[VT(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); + const VPR &vt = vpr[VT(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); #ifdef SIMD_SUPPORT acc.l.single = vte.single; @@ -1635,8 +1629,8 @@ void RSP::vrcph(u32 instr) { divInLoaded = true; } -void RSP::vsar(u32 instr) { - u8 e = E2(instr); +void RSP::vsar(const u32 instr) { + const u8 e = E2(instr); VPR &vd = vpr[VD(instr)]; switch (e) { case 0x8: @@ -1678,14 +1672,14 @@ void RSP::vsar(u32 instr) { } } -void RSP::vsubc(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vsubc(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - u32 result = vs.element[i] - vte.element[i]; + const u32 result = vs.element[i] - vte.element[i]; acc.l.element[i] = result; vd.element[i] = result; @@ -1694,14 +1688,14 @@ void RSP::vsubc(u32 instr) { } } -void RSP::vsub(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vsub(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { - s32 result = vs.selement[i] - vte.selement[i] - (vco.l.element[i] != 0); + const s32 result = vs.selement[i] - vte.selement[i] - (vco.l.element[i] != 0); acc.l.element[i] = result; vd.element[i] = signedClamp(result); @@ -1710,11 +1704,11 @@ void RSP::vsub(u32 instr) { } } -void RSP::vmrg(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vmrg(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; @@ -1724,11 +1718,11 @@ void RSP::vmrg(u32 instr) { } } -void RSP::vxor(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vxor(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] ^ vs.element[i]; @@ -1736,11 +1730,11 @@ void RSP::vxor(u32 instr) { } } -void RSP::vnxor(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vnxor(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] ^ vs.element[i]); @@ -1748,11 +1742,11 @@ void RSP::vnxor(u32 instr) { } } -void RSP::vand(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vand(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] & vs.element[i]; @@ -1760,11 +1754,11 @@ void RSP::vand(u32 instr) { } } -void RSP::vnand(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vnand(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] & vs.element[i]); @@ -1772,11 +1766,11 @@ void RSP::vnand(u32 instr) { } } -void RSP::vnor(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vnor(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] | vs.element[i]); @@ -1784,11 +1778,11 @@ void RSP::vnor(u32 instr) { } } -void RSP::vor(u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; +void RSP::vor(const u32 instr) { + const int e = E2(instr); + const VPR &vs = vpr[VS(instr)]; VPR &vd = vpr[VD(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], e); + SetVTE(vpr[VT(instr)], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] | vs.element[i]; @@ -1796,9 +1790,9 @@ void RSP::vor(u32 instr) { } } -void RSP::vzero(u32 instr) { - VPR &vs = vpr[VS(instr)]; - VPR vte = GetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vzero(const u32 instr) { + const VPR &vs = vpr[VS(instr)]; + SetVTE(vpr[VT(instr)], E2(instr)); VPR &vd = vpr[VD(instr)]; for (int i = 0; i < 8; i++) { @@ -1808,21 +1802,21 @@ void RSP::vzero(u32 instr) { memset(&vd, 0, sizeof(VPR)); } -void RSP::mfc0(RDP &rdp, u32 instr) { gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr)); } +void RSP::mfc0(const RDP &rdp, const u32 instr) { gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr)); } -void RSP::mtc0(u32 instr) { SetCop0Reg(regs, mem, RD(instr), gpr[RT(instr)]); } +void RSP::mtc0(const u32 instr) const { SetCop0Reg(mem, RD(instr), gpr[RT(instr)]); } -void RSP::mfc2(u32 instr) { - u8 hi = vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))]; - u8 lo = vpr[RD(instr)].byte[BYTE_INDEX((E1(instr) + 1) & 0xF)]; - s16 elem = (hi << 8) | lo; +void RSP::mfc2(const u32 instr) { + const u8 hi = vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))]; + const u8 lo = vpr[RD(instr)].byte[BYTE_INDEX((E1(instr) + 1) & 0xF)]; + const s16 elem = hi << 8 | lo; gpr[RT(instr)] = elem; } -void RSP::mtc2(u32 instr) { - u16 element = gpr[RT(instr)]; - u8 lo = element; - u8 hi = element >> 8; +void RSP::mtc2(const u32 instr) { + const u16 element = gpr[RT(instr)]; + const u8 lo = element; + const u8 hi = element >> 8; vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))] = hi; if (E1(instr) < 15) { vpr[RD(instr)].byte[BYTE_INDEX(E1(instr) + 1)] = lo; diff --git a/src/frontend/AudioSettings.cpp b/src/frontend/AudioSettings.cpp index 121f9eef..e3e5dee5 100644 --- a/src/frontend/AudioSettings.cpp +++ b/src/frontend/AudioSettings.cpp @@ -1,6 +1,6 @@ #include -AudioSettings::AudioSettings(nlohmann::json &settings) : settings(settings), QWidget(nullptr) { +AudioSettings::AudioSettings(nlohmann::json &settings) : QWidget(nullptr), settings(settings) { lockChannels->setChecked(JSONGetField(settings, "audio", "lock")); volumeL->setValue(JSONGetField(settings, "audio", "volumeL") * 100); volumeR->setValue(JSONGetField(settings, "audio", "volumeR") * 100); diff --git a/src/frontend/AudioSettings.hpp b/src/frontend/AudioSettings.hpp index 8392508f..c6836ef5 100644 --- a/src/frontend/AudioSettings.hpp +++ b/src/frontend/AudioSettings.hpp @@ -6,7 +6,7 @@ #include #include -class AudioSettings : public QWidget { +class AudioSettings final : public QWidget { std::unique_ptr lockChannels = std::make_unique(); std::unique_ptr labelLock = std::make_unique("Lock channels:"); std::unique_ptr labelL = std::make_unique("Volume L"); @@ -17,7 +17,7 @@ class AudioSettings : public QWidget { public: std::unique_ptr volumeL = std::make_unique(Qt::Horizontal), volumeR = std::make_unique(Qt::Horizontal); - AudioSettings(nlohmann::json &); + explicit AudioSettings(nlohmann::json &); nlohmann::json &settings; Q_SIGNALS: void modified(); diff --git a/src/frontend/CPUSettings.cpp b/src/frontend/CPUSettings.cpp index 6b989e15..5a709c36 100644 --- a/src/frontend/CPUSettings.cpp +++ b/src/frontend/CPUSettings.cpp @@ -2,7 +2,7 @@ #include #include -CPUSettings::CPUSettings(nlohmann::json &settings) : settings(settings), QWidget(nullptr) { +CPUSettings::CPUSettings(nlohmann::json &settings) : QWidget(nullptr), settings(settings) { cpuTypes->addItems({ "Interpreter" //, "Dynamic Recompiler" }); diff --git a/src/frontend/CPUSettings.hpp b/src/frontend/CPUSettings.hpp index 829da8d5..9166316a 100644 --- a/src/frontend/CPUSettings.hpp +++ b/src/frontend/CPUSettings.hpp @@ -5,13 +5,13 @@ #include #include -class CPUSettings : public QWidget { +class CPUSettings final : public QWidget { std::unique_ptr cpuTypes = std::make_unique(); std::unique_ptr label = std::make_unique("CPU type:"); std::unique_ptr mainLayout = std::make_unique(); Q_OBJECT public: - CPUSettings(nlohmann::json &); + explicit CPUSettings(nlohmann::json &); nlohmann::json &settings; Q_SIGNALS: void modified(); diff --git a/src/frontend/CodeModel.hpp b/src/frontend/CodeModel.hpp index 3a3dc1f8..dde8e663 100644 --- a/src/frontend/CodeModel.hpp +++ b/src/frontend/CodeModel.hpp @@ -4,9 +4,9 @@ class CodeModel final : public QAbstractTableModel { Q_OBJECT public: - ~CodeModel() override {} + ~CodeModel() override = default; explicit CodeModel(QObject *parent = nullptr) {} - int rowCount(const QModelIndex &parent = QModelIndex()) const override { return 1; } - int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 2; } - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { return {}; } + [[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override { return 1; } + [[nodiscard]] int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 2; } + [[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { return {}; } }; \ No newline at end of file diff --git a/src/frontend/Debugger.hpp b/src/frontend/Debugger.hpp index b37f2987..b82c275d 100644 --- a/src/frontend/Debugger.hpp +++ b/src/frontend/Debugger.hpp @@ -6,7 +6,7 @@ #include #include -class Debugger : public QWidget { +class Debugger final : public QWidget { std::unique_ptr disassembly = std::make_unique(), cpuState = std::make_unique(); std::unique_ptr codeView = std::make_unique(disassembly.get()), diff --git a/src/frontend/EmuThread.hpp b/src/frontend/EmuThread.hpp index 7a73f17c..75193987 100644 --- a/src/frontend/EmuThread.hpp +++ b/src/frontend/EmuThread.hpp @@ -9,7 +9,7 @@ namespace n64 { struct Core; } -class EmuThread : public QThread { +class EmuThread final : public QThread { Q_OBJECT RenderWidget &renderWidget; diff --git a/src/frontend/InputSettings.hpp b/src/frontend/InputSettings.hpp index 0ca408df..921a6cf6 100644 --- a/src/frontend/InputSettings.hpp +++ b/src/frontend/InputSettings.hpp @@ -8,7 +8,7 @@ #include #include -class InputSettings : public QWidget { +class InputSettings final : public QWidget { bool grabbing = false; int whichGrabbing = -1; diff --git a/src/frontend/KaizenQt.cpp b/src/frontend/KaizenQt.cpp index bf8649a2..68e097ea 100644 --- a/src/frontend/KaizenQt.cpp +++ b/src/frontend/KaizenQt.cpp @@ -75,15 +75,15 @@ void KaizenQt::Quit() const noexcept { QApplication::quit(); } -void KaizenQt::LoadTAS(const QString &fileName) const noexcept { - if (emuThread->core->LoadTAS(fs::path(fileName.toStdString()))) { - auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB; - auto movieName = fs::path(fileName.toStdString()).stem().string(); +void KaizenQt::LoadTAS(const QString &path) const noexcept { + if (emuThread->core->LoadTAS(fs::path(path.toStdString()))) { + const auto gameNameDB = emuThread->core->cpu->GetMem().rom.gameNameDB; + const auto movieName = fs::path(path.toStdString()).stem().string(); Util::RPC::GetInstance().Update(Util::RPC::MovieReplay, gameNameDB, movieName); return; } - Util::panic("Could not load TAS movie {}!", fileName.toStdString()); + Util::panic("Could not load TAS movie {}!", path.toStdString()); } void KaizenQt::keyPressEvent(QKeyEvent *e) { diff --git a/src/frontend/MainWindow.cpp b/src/frontend/MainWindow.cpp index 79cf3e59..a86f3173 100644 --- a/src/frontend/MainWindow.cpp +++ b/src/frontend/MainWindow.cpp @@ -103,7 +103,7 @@ void MainWindow::Retranslate() { void MainWindow::ConnectSignalsToSlots() noexcept { connect(actionOpen.get(), &QAction::triggered, this, [this]() { - QString file_name = QFileDialog::getOpenFileName( + const QString file_name = QFileDialog::getOpenFileName( this, "Nintendo 64 executable", QString(), "All supported types (*.zip *.ZIP *.7z *.7Z *.rar *.RAR *.tar *.TAR *.n64 *.N64 *.v64 *.V64 *.z64 *.Z64)"); diff --git a/src/frontend/MainWindow.hpp b/src/frontend/MainWindow.hpp index 77d2d952..c99ad048 100644 --- a/src/frontend/MainWindow.hpp +++ b/src/frontend/MainWindow.hpp @@ -12,11 +12,11 @@ #include #include -class MainWindow : public QMainWindow { +class MainWindow final : public QMainWindow { Q_OBJECT public: - MainWindow(const std::shared_ptr &) noexcept; + explicit MainWindow(const std::shared_ptr &) noexcept; std::unique_ptr actionOpenDebuggerWindow{}; std::unique_ptr actionAbout{}; diff --git a/src/frontend/RenderWidget.hpp b/src/frontend/RenderWidget.hpp index 713f6993..2eb9036c 100644 --- a/src/frontend/RenderWidget.hpp +++ b/src/frontend/RenderWidget.hpp @@ -10,7 +10,7 @@ namespace n64 { struct Core; } -struct QtInstanceFactory : Vulkan::InstanceFactory { +struct QtInstanceFactory final : Vulkan::InstanceFactory { VkInstance create_instance(const VkInstanceCreateInfo *info) override { handle.setApiVersion({1, 3, 0}); QByteArrayList exts; @@ -36,7 +36,7 @@ struct QtInstanceFactory : Vulkan::InstanceFactory { QVulkanInstance handle; }; -class QtParallelRdpWindowInfo : public ParallelRDP::WindowInfo { +class QtParallelRdpWindowInfo final : public ParallelRDP::WindowInfo { public: explicit QtParallelRdpWindowInfo(QWindow *window) : window(window) {} CoordinatePair get_window_size() override { @@ -56,8 +56,8 @@ public: const auto &extensions = window->vulkanInstance()->supportedExtensions(); vec.reserve(extensions.size()); - for (const auto &ext : extensions) { - vec.emplace_back(ext.name); + for (const auto &[name, _] : extensions) { + vec.emplace_back(name); } return vec; @@ -96,7 +96,7 @@ private: bool canPollEvents = true; }; -class RenderWidget : public QWidget { +class RenderWidget final : public QWidget { public: [[nodiscard]] VkInstance instance() const { return qtVkInstanceFactory->handle.vkInstance(); } explicit RenderWidget(const std::shared_ptr &); diff --git a/src/frontend/SettingsWindow.cpp b/src/frontend/SettingsWindow.cpp index 26e093ad..36c6ce56 100644 --- a/src/frontend/SettingsWindow.cpp +++ b/src/frontend/SettingsWindow.cpp @@ -1,7 +1,7 @@ #include #include -std::string savePath = ""; +std::string savePath; SettingsWindow::SettingsWindow() : QWidget(nullptr) { settings = JSONOpenOrCreate("resources/settings.json"); diff --git a/src/frontend/SettingsWindow.hpp b/src/frontend/SettingsWindow.hpp index 178c5b67..06a85836 100644 --- a/src/frontend/SettingsWindow.hpp +++ b/src/frontend/SettingsWindow.hpp @@ -11,7 +11,7 @@ #include #include -class SettingsWindow : public QWidget { +class SettingsWindow final : public QWidget { std::unique_ptr cancel = std::make_unique("Cancel"); std::unique_ptr apply = std::make_unique("Apply"); std::unique_ptr iconProv = std::make_unique(); @@ -28,8 +28,8 @@ public: SettingsWindow(); void hideEvent(QHideEvent *event) override { emit gotClosed(); } void showEvent(QShowEvent *event) override { emit gotOpened(); } - float getVolumeL() { return float(audioSettings->volumeL->value()) / 100.f; } - float getVolumeR() { return float(audioSettings->volumeR->value()) / 100.f; } + [[nodiscard]] float getVolumeL() const { return static_cast(audioSettings->volumeL->value()) / 100.f; } + [[nodiscard]] float getVolumeR() const { return static_cast(audioSettings->volumeR->value()) / 100.f; } std::array keyMap{}; nlohmann::json settings; diff --git a/src/frontend/main.cpp b/src/frontend/main.cpp index 19d38bca..0c8dc281 100644 --- a/src/frontend/main.cpp +++ b/src/frontend/main.cpp @@ -3,8 +3,8 @@ #include int main(int argc, char **argv) { - QApplication app(argc, argv); - app.setStyle("fusion"); + const QApplication app(argc, argv); + QApplication::setStyle("fusion"); QCoreApplication::setOrganizationName("kaizen"); QCoreApplication::setApplicationName("Kaizen"); QCommandLineParser parser; @@ -13,7 +13,7 @@ int main(int argc, char **argv) { parser.addOptions({{"rom", "Rom to launch from command-line", "path"}, {"movie", "Mupen Movie to replay", "path"}}); parser.process(app); - KaizenQt kaizenQt; + const KaizenQt kaizenQt; if (parser.isSet("rom")) { kaizenQt.LoadROM(parser.value("rom")); if (parser.isSet("movie")) { @@ -21,5 +21,5 @@ int main(int argc, char **argv) { } } - return app.exec(); + return QApplication::exec(); } diff --git a/src/utils/MemoryHelpers.hpp b/src/utils/MemoryHelpers.hpp index 8201c555..5204ed99 100644 --- a/src/utils/MemoryHelpers.hpp +++ b/src/utils/MemoryHelpers.hpp @@ -2,7 +2,6 @@ #include #include #include -#include #include namespace Util { @@ -17,7 +16,7 @@ static FORCE_INLINE std::vector IntegralToBuffer(const T &val) { } template -static FORCE_INLINE T ReadAccess(const u8 *data, const u32 index) { +static constexpr FORCE_INLINE T ReadAccess(const u8 *data, const u32 index) { if constexpr (sizeof(T) == 8) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); @@ -29,7 +28,7 @@ static FORCE_INLINE T ReadAccess(const u8 *data, const u32 index) { } template -static FORCE_INLINE T ReadAccess(const std::vector &data, const u32 index) { +static constexpr FORCE_INLINE T ReadAccess(const std::vector &data, const u32 index) { if constexpr (sizeof(T) == 8) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); @@ -41,7 +40,7 @@ static FORCE_INLINE T ReadAccess(const std::vector &data, const u32 index) { } template -static FORCE_INLINE T ReadAccess(const std::array &data, const u32 index) { +static constexpr FORCE_INLINE T ReadAccess(const std::array &data, const u32 index) { if constexpr (sizeof(T) == 8) { u32 hi = *reinterpret_cast(&data[index + 0]); u32 lo = *reinterpret_cast(&data[index + 4]); @@ -53,7 +52,7 @@ static FORCE_INLINE T ReadAccess(const std::array &data, const u32 ind } template -static FORCE_INLINE void WriteAccess(std::array &data, const u32 index, const T val) { +static constexpr FORCE_INLINE void WriteAccess(std::array &data, const u32 index, const T val) { if constexpr (sizeof(T) == 8) { const u32 hi = val >> 32; const u32 lo = val; @@ -66,7 +65,7 @@ static FORCE_INLINE void WriteAccess(std::array &data, const u32 index } template -static FORCE_INLINE void WriteAccess(std::vector &data, const u32 index, const T val) { +static constexpr FORCE_INLINE void WriteAccess(std::vector &data, const u32 index, const T val) { if constexpr (sizeof(T) == 8) { const u32 hi = val >> 32; const u32 lo = val; @@ -79,7 +78,7 @@ static FORCE_INLINE void WriteAccess(std::vector &data, const u32 index, con } template -static FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const T val) { +static constexpr FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const T val) { if constexpr (sizeof(T) == 8) { const u32 hi = val >> 32; const u32 lo = val; @@ -92,7 +91,7 @@ static FORCE_INLINE void WriteAccess(u8 *data, const u32 index, const T val) { } template -static FORCE_INLINE void SwapBuffer(std::vector &data) { +static constexpr FORCE_INLINE void SwapBuffer(std::vector &data) { for (size_t i = 0; i < data.size(); i += sizeof(T)) { const T original = *reinterpret_cast(&data[i]); *reinterpret_cast(&data[i]) = bswap(original); @@ -100,7 +99,7 @@ static FORCE_INLINE void SwapBuffer(std::vector &data) { } template -static FORCE_INLINE void SwapBuffer(std::array &data) { +static constexpr FORCE_INLINE void SwapBuffer(std::array &data) { for (size_t i = 0; i < data.size(); i += sizeof(T)) { const T original = *reinterpret_cast(&data[i]); *reinterpret_cast(&data[i]) = bswap(original);