diff --git a/src/Discord.hpp b/src/Discord.hpp index f13ed6f3..1148ddf5 100644 --- a/src/Discord.hpp +++ b/src/Discord.hpp @@ -10,7 +10,7 @@ enum State { Paused }; -inline void UpdateRPC(State state, const std::string& game = "") { +FORCE_INLINE void UpdateRPC(State state, const std::string& game = "") { DiscordRichPresence presence{}; std::string textState, textDetails; @@ -36,7 +36,7 @@ inline void UpdateRPC(State state, const std::string& game = "") { Discord_UpdatePresence(&presence); } -inline void ClearRPC() { +FORCE_INLINE void ClearRPC() { Discord_ClearPresence(); } } \ No newline at end of file diff --git a/src/backend/MemoryRegions.hpp b/src/backend/MemoryRegions.hpp index 21bc2555..9f6b1e21 100644 --- a/src/backend/MemoryRegions.hpp +++ b/src/backend/MemoryRegions.hpp @@ -26,8 +26,14 @@ #define IMEM_REGION_END (IMEM_REGION_START + IMEM_DSIZE) #define PIF_RAM_REGION_START 0x1FC007C0 #define PIF_RAM_REGION_END 0x1FC007FF -#define CART_REGION_START 0x10000000 -#define CART_REGION_END 0x1FBFFFFF +#define CART_REGION_START_1_1 0x06000000 +#define CART_REGION_START_1_2 0x10000000 +#define CART_REGION_START_2_1 0x05000000 +#define CART_REGION_START_2_2 0x08000000 +#define CART_REGION_END_1_1 0x07FFFFFF +#define CART_REGION_END_1_2 0x1FBFFFFF +#define CART_REGION_END_2_1 0x05FFFFFF +#define CART_REGION_END_2_2 0x0FFFFFFF #define RDRAM_REGION RDRAM_REGION_START ... RDRAM_REGION_END #define DMEM_REGION DMEM_REGION_START ... DMEM_REGION_END @@ -42,7 +48,10 @@ #define RI_REGION 0x04700000 ... 0x047FFFFF #define SI_REGION 0x04800000 ... 0x048FFFFF #define SRAM_REGION 0x08000000 ... 0x0FFFFFFF -#define CART_REGION (CART_REGION_START) ... (CART_REGION_END) +#define CART_REGION_1_1 (CART_REGION_START_1_1) ... (CART_REGION_END_1_1) +#define CART_REGION_1_2 (CART_REGION_START_1_2) ... (CART_REGION_END_1_2) +#define CART_REGION_2_1 (CART_REGION_START_2_1) ... (CART_REGION_END_2_1) +#define CART_REGION_2_2 (CART_REGION_START_2_2) ... (CART_REGION_END_2_2) #define PIF_ROM_REGION 0x1FC00000 ... 0x1FC007BF #define PIF_RAM_REGION PIF_RAM_REGION_START ... PIF_RAM_REGION_END diff --git a/src/backend/MupenMovie.cpp b/src/backend/MupenMovie.cpp index 2ac21641..877583e9 100644 --- a/src/backend/MupenMovie.cpp +++ b/src/backend/MupenMovie.cpp @@ -119,7 +119,7 @@ bool TasMovieLoaded() { return loaded_tas_movie != nullptr; } -inline void LogController(const n64::Controller& controller) { +FORCE_INLINE void LogController(const n64::Controller& controller) { Util::print("c_right: {}", controller.c_right); Util::print("c_left: {}", controller.c_left); Util::print("c_down: {}", controller.c_down); diff --git a/src/backend/RomHelpers.hpp b/src/backend/RomHelpers.hpp index 264499f7..3f086075 100644 --- a/src/backend/RomHelpers.hpp +++ b/src/backend/RomHelpers.hpp @@ -8,7 +8,7 @@ namespace Util { #define V64 0x37804012 template -inline void SwapN64Rom(size_t size, u8 *rom, u32 endianness) { +FORCE_INLINE void SwapN64Rom(size_t size, u8 *rom, u32 endianness) { switch (endianness) { case V64: SwapBuffer16(size, rom); diff --git a/src/backend/core/Mem.cpp b/src/backend/core/Mem.cpp index 24218743..56700b55 100644 --- a/src/backend/core/Mem.cpp +++ b/src/backend/core/Mem.cpp @@ -27,7 +27,7 @@ void Mem::Reset() { mmio.Reset(); } -inline void SetROMCIC(u32 checksum, ROM& rom) { +FORCE_INLINE void SetROMCIC(u32 checksum, ROM& rom) { switch (checksum) { case 0xEC8B1325: rom.cicType = CIC_NUS_7102; break; // 7102 case 0x1DEB51A9: rom.cicType = CIC_NUS_6101; break; // 6101 @@ -121,7 +121,7 @@ u8 Mem::Read8(n64::Registers ®s, u32 paddr) { int offs = 3 - (paddr & 3); return (w >> (offs * 8)) & 0xff; } - case CART_REGION: + case CART_REGION_1_2: paddr = (paddr + 2) & ~2; return rom.cart[BYTE_ADDRESS(paddr) & rom.mask]; case 0x1FC00000 ... 0x1FC007BF: @@ -161,7 +161,7 @@ u16 Mem::Read16(n64::Registers ®s, u32 paddr) { case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: paddr = (paddr + 2) & ~3; return Util::ReadAccess(rom.cart, HALF_ADDRESS(paddr) & rom.mask); case 0x1FC00000 ... 0x1FC007BF: @@ -199,7 +199,7 @@ u32 Mem::Read32(n64::Registers ®s, u32 paddr) { case 0x04040000 ... 0x040FFFFF: case 0x04100000 ... 0x041FFFFF: case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: return Util::ReadAccess(rom.cart, paddr & rom.mask); case 0x1FC00000 ... 0x1FC007BF: return Util::ReadAccess(si.pif.bootrom, paddr - 0x1FC00000); @@ -235,7 +235,7 @@ u64 Mem::Read64(n64::Registers ®s, u32 paddr) { case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: return mmio.Read(paddr); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: return Util::ReadAccess(rom.cart, paddr & rom.mask); case 0x1FC00000 ... 0x1FC007BF: return Util::ReadAccess(si.pif.bootrom, paddr - 0x1FC00000); @@ -278,7 +278,7 @@ void Mem::Write8(Registers& regs, u32 paddr, u32 val) { case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: Util::panic("MMIO Write8!"); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: break; case PIF_RAM_REGION: val = val << (8 * (3 - (paddr & 3))); @@ -329,7 +329,7 @@ void Mem::Write16(Registers& regs, u32 paddr, u32 val) { case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: Util::panic("MMIO Write16!"); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: break; case PIF_RAM_REGION: val = val << (16 * !(paddr & 2)); @@ -424,7 +424,7 @@ void Mem::Write64(Registers& regs, u32 paddr, u64 val) { case 0x04300000 ... 0x044FFFFF: case 0x04500000 ... 0x048FFFFF: Util::panic("MMIO Write64!"); - case 0x10000000 ... 0x1FBFFFFF: + case CART_REGION_1_2: break; case PIF_RAM_REGION: Util::WriteAccess(si.pif.ram, paddr - PIF_RAM_REGION_START, htobe64(val)); diff --git a/src/backend/core/Mem.hpp b/src/backend/core/Mem.hpp index 12169b5b..47ee3f24 100644 --- a/src/backend/core/Mem.hpp +++ b/src/backend/core/Mem.hpp @@ -66,7 +66,7 @@ struct Mem { MMIO mmio; - inline void DumpRDRAM() const { + FORCE_INLINE void DumpRDRAM() const { FILE *fp = fopen("rdram.dump", "wb"); u8 *temp = (u8*)calloc(RDRAM_SIZE, 1); memcpy(temp, mmio.rdp.rdram, RDRAM_SIZE); @@ -76,7 +76,7 @@ struct Mem { fclose(fp); } - inline void DumpIMEM() const { + FORCE_INLINE void DumpIMEM() const { FILE *fp = fopen("imem.bin", "wb"); u8 *temp = (u8*)calloc(IMEM_SIZE, 1); memcpy(temp, mmio.rsp.imem, IMEM_SIZE); @@ -86,7 +86,7 @@ struct Mem { fclose(fp); } - inline void DumpDMEM() const { + FORCE_INLINE void DumpDMEM() const { FILE *fp = fopen("dmem.dump", "wb"); u8 *temp = (u8*)calloc(DMEM_SIZE, 1); memcpy(temp, mmio.rsp.dmem, DMEM_SIZE); diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index a5a58f36..40318913 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -73,7 +73,7 @@ void RDP::WriteStatus(MI& mi, Registers& regs, RSP& rsp, u32 val) { } } -inline void logCommand(u8 cmd) { +FORCE_INLINE void logCommand(u8 cmd) { switch(cmd) { case 0x08: Util::debug("Fill triangle"); break; case 0x09: Util::debug("Fill, zbuf triangle"); break; diff --git a/src/backend/core/RDP.hpp b/src/backend/core/RDP.hpp index 87cca928..281292f6 100644 --- a/src/backend/core/RDP.hpp +++ b/src/backend/core/RDP.hpp @@ -64,14 +64,14 @@ struct RDP { void RunCommand(MI& mi, Registers& regs, RSP& rsp); void OnFullSync(MI& mi, Registers& regs); - inline void WriteStart(u32 val) { + FORCE_INLINE void WriteStart(u32 val) { if(!dpc.status.startValid) { dpc.start = val & 0xFFFFF8; } dpc.status.startValid = true; } - inline void WriteEnd(MI& mi, Registers& regs, RSP& rsp, u32 val) { + FORCE_INLINE void WriteEnd(MI& mi, Registers& regs, RSP& rsp, u32 val) { dpc.end = val & 0xFFFFF8; if(dpc.status.startValid) { dpc.current = dpc.start; diff --git a/src/backend/core/RSP.cpp b/src/backend/core/RSP.cpp index 398a4fa8..93107cbc 100644 --- a/src/backend/core/RSP.cpp +++ b/src/backend/core/RSP.cpp @@ -34,7 +34,7 @@ void RSP::Reset() { } /* -inline void logRSP(const RSP& rsp, const u32 instr) { +FORCE_INLINE void logRSP(const RSP& rsp, const u32 instr) { Util::debug("{:04X} {:08X} ", rsp.oldPC, instr); for (auto gpr : rsp.gpr) { Util::debug("{:08X} ", gpr); diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 56697357..0049f1a6 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -152,29 +152,29 @@ struct RSP { bool semaphore = false; - inline void SetPC(u16 val) { + FORCE_INLINE void SetPC(u16 val) { oldPC = pc & 0xFFC; pc = val & 0xFFC; nextPC = pc + 4; } - inline s64 GetACC(int e) const { - s64 val = s64(acc.h.element[e]) << 32; - val |= s64(acc.m.element[e]) << 16; - val |= s64(acc.l.element[e]) << 00; + FORCE_INLINE s64 GetACC(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; if((val & 0x0000800000000000) != 0) { val |= 0xFFFF000000000000; } return val; } - inline void SetACC(int e, s64 val) { + FORCE_INLINE void SetACC(int e, s64 val) { acc.h.element[e] = val >> 32; acc.m.element[e] = val >> 16; acc.l.element[e] = val; } - inline u16 GetVCO() const { + FORCE_INLINE u16 GetVCO() const { u16 value = 0; for (int i = 0; i < 8; i++) { bool h = vco.h.element[7 - i] != 0; @@ -185,7 +185,7 @@ struct RSP { return value; } - inline u16 GetVCC() const { + FORCE_INLINE u16 GetVCC() const { u16 value = 0; for (int i = 0; i < 8; i++) { bool h = vcc.h.element[7 - i] != 0; @@ -196,7 +196,7 @@ struct RSP { return value; } - inline u8 GetVCE() const { + FORCE_INLINE u8 GetVCE() const { u8 value = 0; for(int i = 0; i < 8; i++) { bool l = vce.element[ELEMENT_INDEX(i)] != 0; @@ -205,37 +205,37 @@ struct RSP { return value; } - inline u32 ReadWord(u32 addr) { + FORCE_INLINE u32 ReadWord(u32 addr) { addr &= 0xfff; return GET_RSP_WORD(addr); } - inline void WriteWord(u32 addr, u32 val) { + FORCE_INLINE void WriteWord(u32 addr, u32 val) { addr &= 0xfff; SET_RSP_WORD(addr, val); } - inline u16 ReadHalf(u32 addr) { + FORCE_INLINE u16 ReadHalf(u32 addr) { addr &= 0xfff; return GET_RSP_HALF(addr); } - inline void WriteHalf(u32 addr, u16 val) { + FORCE_INLINE void WriteHalf(u32 addr, u16 val) { addr &= 0xfff; SET_RSP_HALF(addr, val); } - inline u8 ReadByte(u32 addr) { + FORCE_INLINE u8 ReadByte(u32 addr) { addr &= 0xfff; return RSP_BYTE(addr); } - inline void WriteByte(u32 addr, u8 val) { + FORCE_INLINE void WriteByte(u32 addr, u8 val) { addr &= 0xfff; RSP_BYTE(addr) = val; } - inline bool AcquireSemaphore() { + FORCE_INLINE bool AcquireSemaphore() { if(semaphore) { return true; } else { @@ -244,7 +244,7 @@ struct RSP { } } - inline void ReleaseSemaphore() { + FORCE_INLINE void ReleaseSemaphore() { semaphore = false; } @@ -357,7 +357,7 @@ struct RSP { void mtc2(u32 instr); template - inline void DMA(SPDMALen len, u8* rdram, RSP& rsp, bool bank) { + FORCE_INLINE void DMA(SPDMALen len, u8* rdram, RSP& rsp, bool bank) { u32 length = len.len + 1; length = (length + 0x7) & ~0x7; @@ -399,13 +399,13 @@ struct RSP { void WriteStatus(MI& mi, Registers& regs, u32 value); private: - inline void branch(u16 address, bool cond) { + FORCE_INLINE void branch(u16 address, bool cond) { if(cond) { nextPC = address & 0xFFC; } } - inline void branch_likely(u16 address, bool cond) { + FORCE_INLINE void branch_likely(u16 address, bool cond) { if(cond) { nextPC = address & 0xFFC; } else { diff --git a/src/backend/core/interpreter/cop/cop1instructions.cpp b/src/backend/core/interpreter/cop/cop1instructions.cpp index 1dca6fe1..84e2bff6 100644 --- a/src/backend/core/interpreter/cop/cop1instructions.cpp +++ b/src/backend/core/interpreter/cop/cop1instructions.cpp @@ -5,7 +5,7 @@ #include namespace n64 { -inline int PushRoundingMode(const FCR31& fcr31) { +FORCE_INLINE int PushRoundingMode(const FCR31& fcr31) { int og = fegetround(); switch(fcr31.rounding_mode) { case 0: fesetround(FE_TONEAREST); break; @@ -226,7 +226,7 @@ void Cop1::cvtld(Registers& regs, u32 instr) { } template -inline bool CalculateCondition(Registers& regs, T fs, T ft, CompConds cond) { +FORCE_INLINE bool CalculateCondition(Registers& regs, T fs, T ft, CompConds cond) { switch(cond) { case F: return false; case UN: return std::isnan(fs) || std::isnan(ft); diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index f936f803..872da53a 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -169,7 +169,7 @@ void Interpreter::branch_likely(bool cond, s64 address) { void Interpreter::b(u32 instr, bool cond) { s16 imm = instr; - s64 offset = (s64)imm << 2; + s64 offset = u64((s64)imm) << 2; s64 address = regs.pc + offset; branch(cond, address); } @@ -177,14 +177,14 @@ void Interpreter::b(u32 instr, bool cond) { void Interpreter::blink(u32 instr, bool cond) { regs.gpr[31] = regs.nextPC; s16 imm = instr; - s64 offset = (s64)imm << 2; + s64 offset = u64((s64)imm) << 2; s64 address = regs.pc + offset; branch(cond, address); } void Interpreter::bl(u32 instr, bool cond) { s16 imm = instr; - s64 offset = (s64)imm << 2; + s64 offset = u64((s64)imm) << 2; s64 address = regs.pc + offset; branch_likely(cond, address); } @@ -192,13 +192,13 @@ void Interpreter::bl(u32 instr, bool cond) { void Interpreter::bllink(u32 instr, bool cond) { regs.gpr[31] = regs.nextPC; s16 imm = instr; - s64 offset = (s64)imm << 2; + s64 offset = u64((s64)imm) << 2; s64 address = regs.pc + offset; branch_likely(cond, address); } void Interpreter::lui(u32 instr) { - s64 val = (s16)instr; + u64 val = s64((s16)instr); val <<= 16; regs.gpr[RT(instr)] = val; } diff --git a/src/backend/core/mmio/PI.cpp b/src/backend/core/mmio/PI.cpp index 5c52285f..380342d0 100644 --- a/src/backend/core/mmio/PI.cpp +++ b/src/backend/core/mmio/PI.cpp @@ -14,7 +14,6 @@ void PI::Reset() { cartAddr = 0; rdLen = 0; wrLen = 0; - memset(stub, 0, 8); } auto PI::Read(MI& mi, u32 addr) const -> u32 { @@ -46,14 +45,14 @@ auto PI::Read(MI& mi, u32 addr) const -> u32 { FORCE_INLINE u8 PIGetDomain(u32 address) { switch (address) { - case 0x6000000 ... 0x7FFFFFF: - case REGION_CART_1_2: + case CART_REGION_1_1: + case CART_REGION_1_2: return 1; - case REGION_CART_2_1: - case REGION_CART_2_2: + case CART_REGION_2_1: + case CART_REGION_2_2: return 2; default: - logfatal("Unknown PI domain for address %08X!\n", address); + Util::panic("Unknown PI domain for address {:08X}!", address); } } @@ -63,20 +62,20 @@ FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) { uint32_t pulse_width = 0; uint32_t release = 0; uint32_t page_size = 0; - uint32_t pages = 0; + uint32_t pages; switch (domain) { case 1: latency = pi.pi_bsd_dom1_lat + 1; pulse_width = pi.pi_bsd_dom1_pwd + 1; release = pi.pi_bsd_dom1_rls + 1; - page_size = pow(2, (pi.pi_bsd_dom1_pgs + 2)); + page_size = std::pow(2, (pi.pi_bsd_dom1_pgs + 2)); break; case 2: latency = pi.pi_bsd_dom2_lat + 1; pulse_width = pi.pi_bsd_dom2_pwd + 1; release = pi.pi_bsd_dom2_rls + 1; - page_size = pow(2, (pi.pi_bsd_dom2_pgs + 2)); + page_size = std::pow(2, (pi.pi_bsd_dom2_pgs + 2)); break; default: Util::panic("Unknown PI domain: %d\n", domain); @@ -90,26 +89,6 @@ FORCE_INLINE u32 PIAccessTiming(PI& pi, u8 domain, u32 length) { return cycles * 1.5; // Converting RCP clock speed to CPU clock speed } -template -FORCE_INLINE void DMA(Mem& mem, Registers& regs) { - MI& mi = mem.mmio.mi; - PI& pi = mem.mmio.pi; - u32 len = toCart ? pi.rdLen : pi.wrLen; - u32 cart_addr = pi.cartAddr & 0xFFFFFFFE; - u32 dram_addr = pi.dramAddr & 0x007FFFFE; - for(int i = 0; i < len; i++) { - if constexpr (toCart) { - mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE]; - } else { - mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask]; - } - } - pi.dramAddr = dram_addr + len; - pi.cartAddr = cart_addr + len; - InterruptRaise(mi, regs, Interrupt::PI); - Util::debug("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, pi.dramAddr, pi.cartAddr); -} - void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { MI& mi = mem.mmio.mi; switch(addr) { @@ -123,7 +102,14 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { len -= dram_addr & 0x7; } rdLen = len; - scheduler.enqueueRelative(Event{, DMA}); + for(int i = 0; i < len; i++) { + mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask] = mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE]; + } + + dramAddr = dram_addr + len; + cartAddr = cart_addr + len; + InterruptRaise(mi, regs, Interrupt::PI); + Util::debug("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr); } break; case 0x0460000C: { u32 len = (val & 0x00FFFFFF) + 1; @@ -133,16 +119,27 @@ void PI::Write(Mem& mem, Registers& regs, u32 addr, u32 val) { len -= (dram_addr & 0x7); } wrLen = len; - scheduler.enqueueRelative(Event{, DMA}); + for(int i = 0; i < len; i++) { + mem.mmio.rdp.rdram[BYTE_ADDRESS(dram_addr + i) & RDRAM_DSIZE] = mem.rom.cart[BYTE_ADDRESS(cart_addr + i) & mem.rom.mask]; + } + + dramAddr = dram_addr + len; + cartAddr = cart_addr + len; + InterruptRaise(mi, regs, Interrupt::PI); + Util::debug("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr); } break; case 0x04600010: if(val & 2) { InterruptLower(mi, regs, Interrupt::PI); } break; - case 0x04600014: case 0x04600018: case 0x0460001C: case 0x04600020: - case 0x04600024: case 0x04600028: case 0x0460002C: case 0x04600030: - stub[(addr & 0xff) - 5] = val & 0xff; - break; + case 0x04600014: pi_bsd_dom1_lat = val & 0xff; break; + case 0x04600018: pi_bsd_dom1_pwd = val & 0xff; break; + case 0x0460001C: pi_bsd_dom1_pgs = val & 0xff; break; + case 0x04600020: pi_bsd_dom1_rls = val & 0xff; break; + case 0x04600024: pi_bsd_dom2_lat = val & 0xff; break; + case 0x04600028: pi_bsd_dom2_pwd = val & 0xff; break; + case 0x0460002C: pi_bsd_dom2_pgs = val & 0xff; break; + case 0x04600030: pi_bsd_dom2_rls = val & 0xff; break; default: Util::panic("Unhandled PI[{:08X}] write ({:08X})", val, addr); } diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index b47cf6ae..0b6728bd 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -34,7 +34,7 @@ void PIF::LoadMempak(fs::path path) { fclose(f); } -inline size_t getSaveSize(SaveType saveType) { +FORCE_INLINE size_t getSaveSize(SaveType saveType) { switch (saveType) { case SAVE_NONE: return 0; @@ -110,7 +110,7 @@ void PIF::CICChallenge() { } } -inline u8 data_crc(const u8* data) { +FORCE_INLINE u8 data_crc(const u8* data) { u8 crc = 0; for (int i = 0; i <= 32; i++) { for (int j = 7; j >= 0; j--) { diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 3263c615..f290027e 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -127,7 +127,7 @@ struct PIF { ram[addr & PIF_RAM_DSIZE] = val; } - inline AccessoryType getAccessoryType() const { + FORCE_INLINE AccessoryType getAccessoryType() const { if (channel >= 4 || joybusDevices[channel].type != JOYBUS_CONTROLLER) { return ACCESSORY_NONE; } else { diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index e4d1feea..cfa19f00 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -169,7 +169,7 @@ void Cop0::SetReg64(u8 addr, u64 value) { } } -static inline u64 getVPN(u64 addr, u64 pageMask) { +static FORCE_INLINE u64 getVPN(u64 addr, u64 pageMask) { u64 mask = pageMask | 0x1fff; u64 vpn = (addr & 0xFFFFFFFFFF) | ((addr >> 22) & 0x30000000000); @@ -240,7 +240,7 @@ bool ProbeTLB(Registers& regs, TLBAccessType access_type, u64 vaddr, u32& paddr, return true; } -inline bool Is64BitAddressing(Cop0& cp0, u64 addr) { +FORCE_INLINE bool Is64BitAddressing(Cop0& cp0, u64 addr) { u8 region = (addr >> 62) & 3; switch(region) { case 0b00: return cp0.status.ux; diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index da50ca18..78a7a772 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -236,7 +236,7 @@ struct Cop0 { TLBError tlbError = NONE; s64 openbus{}; void decode(Registers&, u32); - inline u32 GetRandom() { + FORCE_INLINE u32 GetRandom() { int val = rand(); int wired = GetWired(); int lower, upper; @@ -252,8 +252,8 @@ struct Cop0 { return val; } private: - inline u32 GetWired() { return wired & 0x3F; } - inline u32 GetCount() { return u32(u64(count >> 1)); } + FORCE_INLINE u32 GetWired() { return wired & 0x3F; } + FORCE_INLINE u32 GetCount() { return u32(u64(count >> 1)); } void mtc0(n64::Registers&, u32); void dmtc0(n64::Registers&, u32); @@ -275,7 +275,7 @@ enum TLBAccessType { bool ProbeTLB(Registers& regs, TLBAccessType access_type, u64 vaddr, u32& paddr, int* match); -static inline bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { +static FORCE_INLINE bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { switch(u32(vaddr) >> 29) { case 0 ... 3: case 7: return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); diff --git a/src/backend/core/registers/Cop1.hpp b/src/backend/core/registers/Cop1.hpp index 1b1fb3a1..5b9d8938 100644 --- a/src/backend/core/registers/Cop1.hpp +++ b/src/backend/core/registers/Cop1.hpp @@ -68,7 +68,7 @@ struct Cop1 { friend struct Interpreter; template - inline void SetReg(Cop0& cop0, u8 index, T value) { + FORCE_INLINE void SetReg(Cop0& cop0, u8 index, T value) { if constexpr(sizeof(T) == 4) { if (cop0.status.fr) { fgr[index].lo = value; @@ -89,7 +89,7 @@ struct Cop1 { } template - inline T GetReg(Cop0& cop0, u8 index) { + FORCE_INLINE T GetReg(Cop0& cop0, u8 index) { if constexpr(sizeof(T) == 4) { if(cop0.status.fr) { return fgr[index].lo; @@ -110,7 +110,7 @@ struct Cop1 { } template - inline void SetCop1Reg(Cop0& cop0, u8 index, T value) { + FORCE_INLINE void SetCop1Reg(Cop0& cop0, u8 index, T value) { if constexpr (sizeof(T) == 4) { u32 raw; memcpy(&raw, &value, sizeof(T)); @@ -123,7 +123,7 @@ struct Cop1 { } template - inline T GetCop1Reg(Cop0& cop0, u8 index) { + FORCE_INLINE T GetCop1Reg(Cop0& cop0, u8 index) { T value; if constexpr (sizeof(T) == 4) { u32 raw = GetReg(cop0, index); diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index 5efde396..dd129b6d 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -5,7 +5,7 @@ #include namespace n64 { -inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) { +FORCE_INLINE void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) { u8 mask = instr & 0x3f; //Util::print("rsp special {:02X}", mask); switch(mask) { @@ -45,7 +45,7 @@ inline void special(MI& mi, Registers& regs, RSP& rsp, u32 instr) { } } -inline void regimm(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) { @@ -57,7 +57,7 @@ inline void regimm(RSP& rsp, u32 instr) { } } -inline void lwc2(RSP& rsp, u32 instr) { +FORCE_INLINE void lwc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; //Util::print("lwc2 {:02X}", mask); switch(mask) { @@ -77,7 +77,7 @@ inline void lwc2(RSP& rsp, u32 instr) { } } -inline void swc2(RSP& rsp, u32 instr) { +FORCE_INLINE void swc2(RSP& rsp, u32 instr) { u8 mask = (instr >> 11) & 0x1F; //Util::print("swc2 {:02X}", mask); switch(mask) { @@ -97,7 +97,7 @@ inline void swc2(RSP& rsp, u32 instr) { } } -inline void cop2(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); @@ -176,7 +176,7 @@ inline void cop2(RSP& rsp, u32 instr) { } } -inline void cop0(Registers& regs, Mem& mem, u32 instr) { +FORCE_INLINE void cop0(Registers& regs, Mem& mem, u32 instr) { u8 mask = (instr >> 21) & 0x1F; MMIO& mmio = mem.mmio; RSP& rsp = mmio.rsp; diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 76fd03cf..32f3bd25 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -7,7 +7,7 @@ #include namespace n64 { -inline bool AcquireSemaphore(RSP& rsp) { +FORCE_INLINE bool AcquireSemaphore(RSP& rsp) { if(rsp.semaphore) { return true; } else { @@ -16,11 +16,11 @@ inline bool AcquireSemaphore(RSP& rsp) { } } -inline void ReleaseSemaphore(RSP& rsp) { +FORCE_INLINE void ReleaseSemaphore(RSP& rsp) { rsp.semaphore = false; } -inline int SignExt7bit(u8 val, int sa) { +FORCE_INLINE int SignExt7bit(u8 val, int sa) { s8 sval = ((val << 1) & 0x80) | val; s32 sval32 = sval; @@ -28,7 +28,7 @@ inline int SignExt7bit(u8 val, int sa) { return val32 << sa; } -inline auto GetCop0Reg(RSP& rsp, RDP& rdp, u8 index) -> u32{ +FORCE_INLINE auto GetCop0Reg(RSP& rsp, RDP& rdp, u8 index) -> u32{ switch(index) { case 0: return rsp.lastSuccessfulSPAddr.raw; case 1: return rsp.lastSuccessfulDRAMAddr.raw; @@ -50,7 +50,7 @@ inline auto GetCop0Reg(RSP& rsp, RDP& rdp, u8 index) -> u32{ } } -inline void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) { +FORCE_INLINE void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) { MMIO& mmio = mem.mmio; RSP& rsp = mmio.rsp; RDP& rdp = mmio.rdp; @@ -81,7 +81,7 @@ inline void SetCop0Reg(Registers& regs, Mem& mem, u8 index, u32 val) { } } -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, int l0, int l1, int l2, int l3, int l4, int l5, int l6, int l7) { VPR vte{}; vte.element[ELEMENT_INDEX(0)] = vt.element[ELEMENT_INDEX(l0)]; vte.element[ELEMENT_INDEX(1)] = vt.element[ELEMENT_INDEX(l1)]; @@ -95,7 +95,7 @@ inline VPR Broadcast(const VPR& vt, int l0, int l1, int l2, int l3, int l4, int } #ifdef SIMD_SUPPORT -inline VPR GetVTE(const VPR& vt, u8 e) { +FORCE_INLINE VPR GetVTE(const VPR& vt, u8 e) { VPR vte{}; e &= 0xf; switch(e) { @@ -114,7 +114,7 @@ inline VPR GetVTE(const VPR& vt, u8 e) { return vte; } #else -inline VPR GetVTE(const VPR& vt, u8 e) { +FORCE_INLINE VPR GetVTE(const VPR& vt, u8 e) { VPR vte{}; e &= 0xf; switch(e) { @@ -702,13 +702,13 @@ void RSP::sltiu(u32 instr) { gpr[RT(instr)] = (u32)gpr[RS(instr)] < imm; } -inline s16 signedClamp(s64 val) { +FORCE_INLINE s16 signedClamp(s64 val) { if(val < -32768) return -32768; if(val > 32767) return 32767; return val; } -inline u16 unsignedClamp(s64 val) { +FORCE_INLINE u16 unsignedClamp(s64 val) { if(val < 0) return 0; if(val > 32767) return 65535; return val; @@ -914,7 +914,7 @@ void RSP::vmov(u32 instr) { #endif } -inline bool IsSignExtension(s16 hi, s16 lo) { +FORCE_INLINE bool IsSignExtension(s16 hi, s16 lo) { if (hi == 0) { return (lo & 0x8000) == 0; } else if (hi == -1) { @@ -1364,7 +1364,7 @@ void RSP::vlt(u32 instr) { } } -inline u32 rcp(s32 sinput) { +FORCE_INLINE u32 rcp(s32 sinput) { s32 mask = sinput >> 31; s32 input = sinput ^ mask; if (sinput > INT16_MIN) { @@ -1386,7 +1386,7 @@ inline u32 rcp(s32 sinput) { return result; } -inline u32 rsq(u32 input) { +FORCE_INLINE u32 rsq(u32 input) { if (input == 0) { return 0x7FFFFFFF; } else if (input == 0xFFFF8000) { @@ -1482,7 +1482,7 @@ void RSP::vrsq(u32 instr) { } // from nall, in ares -static inline s64 sclip(s64 x, u32 bits) { +static FORCE_INLINE s64 sclip(s64 x, u32 bits) { u64 b = 1ull << (bits - 1); u64 m = b * 2 - 1; return ((x & m) ^ b) - b; diff --git a/src/frontend/App.hpp b/src/frontend/App.hpp index 90ed1c28..12308d94 100644 --- a/src/frontend/App.hpp +++ b/src/frontend/App.hpp @@ -6,7 +6,7 @@ struct App { App(); ~App() { Util::ClearRPC(); } void Run(); - inline void LoadROM(const std::string& path) { + FORCE_INLINE void LoadROM(const std::string& path) { window.LoadROM(core, path); } private: diff --git a/src/frontend/imgui/Settings.hpp b/src/frontend/imgui/Settings.hpp index e52f5e10..5152bc36 100644 --- a/src/frontend/imgui/Settings.hpp +++ b/src/frontend/imgui/Settings.hpp @@ -8,9 +8,9 @@ struct Settings { Settings(n64::Core&); ~Settings(); - inline float GetVolumeL() const { return volumeL; }; - inline float GetVolumeR() const { return volumeR; }; - inline bool GetLockChannels() const { return lockChannels; } + FORCE_INLINE float GetVolumeL() const { return volumeL; }; + FORCE_INLINE float GetVolumeR() const { return volumeR; }; + FORCE_INLINE bool GetLockChannels() const { return lockChannels; } void RenderWidget(bool& show); private: diff --git a/src/frontend/imgui/Widgets.hpp b/src/frontend/imgui/Widgets.hpp index 022aa624..ddce214d 100644 --- a/src/frontend/imgui/Widgets.hpp +++ b/src/frontend/imgui/Widgets.hpp @@ -1,7 +1,7 @@ #pragma once #include -inline bool CreateComboList(const char* label, int* index, const char** items, int items_count) { +FORCE_INLINE bool CreateComboList(const char* label, int* index, const char** items, int items_count) { if (ImGui::BeginCombo(label, items[*index])) { for (int n = 0; n < items_count; n++) { const bool is_selected = (*index == n); diff --git a/src/utils/File.hpp b/src/utils/File.hpp index f1808a1e..03716fac 100644 --- a/src/utils/File.hpp +++ b/src/utils/File.hpp @@ -3,7 +3,7 @@ #include namespace Util { -inline auto ReadFileBinary(const std::string& path, u32** buf) { +FORCE_INLINE auto ReadFileBinary(const std::string& path, u32** buf) { std::ifstream file(path, std::ios::binary); file.unsetf(std::ios::skipws); if(!file.is_open()) { @@ -20,7 +20,7 @@ inline auto ReadFileBinary(const std::string& path, u32** buf) { return size; } -inline size_t NextPow2(size_t num) { +FORCE_INLINE size_t NextPow2(size_t num) { // Taken from "Bit Twiddling Hacks" by Sean Anderson: // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 --num; diff --git a/src/utils/MemoryHelpers.hpp b/src/utils/MemoryHelpers.hpp index f35a7acc..69c8a000 100644 --- a/src/utils/MemoryHelpers.hpp +++ b/src/utils/MemoryHelpers.hpp @@ -6,7 +6,7 @@ namespace Util { template -inline T ReadAccess(u8 *data, u32 index) { +FORCE_INLINE T ReadAccess(u8 *data, u32 index) { if constexpr (sizeof(T) == 1) { // return data[index]; } else if constexpr (sizeof(T) == 2 || sizeof(T) == 4) { @@ -25,7 +25,7 @@ inline T ReadAccess(u8 *data, u32 index) { } template -inline void WriteAccess(u8 *data, u32 index, T val) { +FORCE_INLINE void WriteAccess(u8 *data, u32 index, T val) { if constexpr (sizeof(T) == 1) { data[index] = val; return; @@ -40,21 +40,21 @@ inline void WriteAccess(u8 *data, u32 index, T val) { } } -inline void SwapBuffer32(size_t size, u8 *data) { +FORCE_INLINE void SwapBuffer32(size_t size, u8 *data) { for (int i = 0; i < size; i += 4) { u32 original = *(u32 *) &data[i]; *(u32 *) &data[i] = bswap_32(original); } } -inline void SwapBuffer16(size_t size, u8 *data) { +FORCE_INLINE void SwapBuffer16(size_t size, u8 *data) { for (int i = 0; i < size; i += 2) { u16 original = *(u16 *) &data[i]; *(u16 *) &data[i] = bswap_16(original); } } -inline u32 crc32(u32 crc, const u8 *buf, size_t len) { +FORCE_INLINE u32 crc32(u32 crc, const u8 *buf, size_t len) { static u32 table[256]; static int have_table = 0; u32 rem; @@ -87,19 +87,19 @@ inline u32 crc32(u32 crc, const u8 *buf, size_t len) { } #ifdef _WIN32 -inline void* aligned_alloc(size_t alignment, size_t size) { +FORCE_INLINE void* aligned_alloc(size_t alignment, size_t size) { return _aligned_malloc(size, alignment); } -inline void aligned_free(void* ptr) { +FORCE_INLINE void aligned_free(void* ptr) { _aligned_free(ptr); } #else -inline void* aligned_alloc(size_t alignment, size_t size) { +FORCE_INLINE void* aligned_alloc(size_t alignment, size_t size) { return std::aligned_alloc(alignment, size); } -inline void aligned_free(void* ptr) { +FORCE_INLINE void aligned_free(void* ptr) { std::free(ptr); } #endif