From 00e637645c629ee67f369d24243d7be245a72dfb Mon Sep 17 00:00:00 2001 From: Robert Xu Date: Tue, 10 Feb 2015 23:17:39 -0500 Subject: [PATCH 01/25] Fix building on OS X 10.10 --- Utilities/StrFmt.h | 48 +++++++++++++++++++++++++ Utilities/Thread.cpp | 74 +++++++++++++++++++++++++++++++++----- rpcs3/Emu/Cell/PPUThread.h | 14 ++++++++ rpcs3/Emu/FS/VFS.h | 2 +- rpcs3/Emu/IdManager.h | 2 +- rpcs3/Emu/Memory/vm.h | 15 ++++++++ 6 files changed, 145 insertions(+), 10 deletions(-) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index bdc99a83af..e9c7c23334 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -263,6 +263,30 @@ namespace fmt } }; + template<> + struct get_fmt + { + static std::string text(const char* fmt, size_t len, unsigned long arg) + { + if (fmt[len - 1] == 'x') + { + return to_hex(arg, get_fmt_precision(fmt, len)); + } + else if (fmt[len - 1] == 'X') + { + return fmt::toupper(to_hex(arg, get_fmt_precision(fmt, len))); + } + else if (fmt[len - 1] == 'd' || fmt[len - 1] == 'u') + { + return to_udec(arg); + } + else + { + throw "Invalid formatting (unsigned long): " + std::string(fmt, len); + } + } + }; + template<> struct get_fmt { @@ -359,6 +383,30 @@ namespace fmt } }; + template<> + struct get_fmt + { + static std::string text(const char* fmt, size_t len, long arg) + { + if (fmt[len - 1] == 'x') + { + return to_hex((u64)arg, get_fmt_precision(fmt, len)); + } + else if (fmt[len - 1] == 'X') + { + return fmt::toupper(to_hex((u64)arg, get_fmt_precision(fmt, len))); + } + else if (fmt[len - 1] == 'd') + { + return to_sdec(arg); + } + else + { + throw "Invalid formatting (long): " + std::string(fmt, len); + } + } + }; + template<> struct get_fmt { diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 25d5981e23..faa0b1b04e 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -9,6 +9,8 @@ #ifdef _WIN32 #include #else +#define _XOPEN_SOURCE +#define __USE_GNU #include #include #endif @@ -195,21 +197,72 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_ typedef CONTEXT x64_context; #define RIP 16 -#define X64REG(context, reg) ((&context->Rax)[reg]) +#define X64REG(context, reg) (&(&context->Rax)[reg]) #else typedef ucontext_t x64_context; -typedef decltype(REG_RIP) reg_table_t; #define RIP 16 +#ifdef __APPLE__ + +#define X64REG(context, reg) (darwin_x64reg(context, reg)) + +uint64_t* darwin_x64reg(x64_context *context, int reg) +{ + auto *state = &context->uc_mcontext->__ss; + switch(reg) + { + case 0: // RAX + return &state->__rax; + case 1: // RCX + return &state->__rcx; + case 2: // RDX + return &state->__rdx; + case 3: // RBX + return &state->__rbx; + case 4: // RSP + return &state->__rsp; + case 5: // RBP + return &state->__rbp; + case 6: // RSI + return &state->__rsi; + case 7: // RDI + return &state->__rdi; + case 8: // R8 + return &state->__r8; + case 9: // R9 + return &state->__r9; + case 10: // R10 + return &state->__r10; + case 11: // R11 + return &state->__r11; + case 12: // R12 + return &state->__r12; + case 13: // R13 + return &state->__r13; + case 14: // R14 + return &state->__r14; + case 15: // R15 + return &state->__r15; + case 16: // RIP + return &state->__rip; + default: // FAIL + assert(0); + } +} + +#else +typedef decltype(REG_RIP) reg_table_t; + static const reg_table_t reg_table[17] = { REG_RAX, REG_RCX, REG_RDX, REG_RBX, REG_RSP, REG_RBP, REG_RSI, REG_RDI, REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP }; -#define X64REG(context, reg) (context->uc_mcontext.gregs[reg_table[reg]]) +#define X64REG(context, reg) (&context->uc_mcontext.gregs[reg_table[reg]]) +#endif // __APPLE__ #endif @@ -222,19 +275,19 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte x64_op_t op; x64_reg_t reg; size_t size; - decode_x64_reg_op((const u8*)X64REG(context, RIP), op, reg, size); + decode_x64_reg_op((const u8*)(*X64REG(context, RIP)), op, reg, size); // get x64 reg value (for store operations) u64 reg_value; if (reg - X64R32 < 16) { // load the value from x64 register - reg_value = (u32)X64REG(context, reg - X64R32); + reg_value = (u32)*X64REG(context, reg - X64R32); } else if (reg == X64_IMM32) { // load the immediate value (assuming it's at the end of the instruction) - reg_value = *(u32*)(X64REG(context, RIP) + size - 4); + reg_value = *(u32*)(*X64REG(context, RIP) + size - 4); } else { @@ -265,7 +318,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte if (reg - X64R32 < 16) { // store the value into x64 register - X64REG(context, reg - X64R32) = (u32)reg_value; + *X64REG(context, reg - X64R32) = (u32)reg_value; } else { @@ -274,7 +327,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte } // skip decoded instruction - X64REG(context, RIP) += size; + *X64REG(context, RIP) += size; return true; } @@ -324,7 +377,12 @@ const PVOID exception_handler = (atexit([]{ RemoveVectoredExceptionHandler(excep void signal_handler(int sig, siginfo_t* info, void* uct) { const u64 addr64 = (u64)info->si_addr - (u64)vm::g_base_addr; + +#ifdef __APPLE__ + const bool is_writing = ((ucontext_t*)uct)->uc_mcontext->__es.__err & 0x2; +#else const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2; +#endif if ((u32)addr64 == addr64 && GetCurrentNamedThread()) { diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 834200b1ae..1c32cd7e3e 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -887,6 +887,20 @@ struct cast_ppu_gpr } }; +template<> +struct cast_ppu_gpr +{ + __forceinline static u64 to_gpr(const unsigned long& value) + { + return value; + } + + __forceinline static unsigned long from_gpr(const u64 reg) + { + return static_cast(reg); + } +}; + template<> struct cast_ppu_gpr { diff --git a/rpcs3/Emu/FS/VFS.h b/rpcs3/Emu/FS/VFS.h index 38a63e94c4..9d202d4cb9 100644 --- a/rpcs3/Emu/FS/VFS.h +++ b/rpcs3/Emu/FS/VFS.h @@ -61,7 +61,7 @@ struct VFS struct links_sorter { - bool operator()(const std::vector& a, const std::vector& b) + bool operator()(const std::vector& a, const std::vector& b) const { return b.size() < a.size(); } diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index ef3c78aacd..ac066d142f 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -252,7 +252,7 @@ public: else { assert(!"Invalid ID type"); - return{}; + return std::set{}; } } }; diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index a49c21eaab..0955c24b33 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -84,6 +84,21 @@ namespace vm } }; + template<> + struct cast_ptr + { + __forceinline static u32 cast(const unsigned long addr, const char* func) + { + const u32 res = static_cast(addr); + if (res != addr) + { + vm::error(addr, func); + } + + return res; + } + }; + template<> struct cast_ptr { From 0eebfb0aaaad4ae3fefe26f251b1975dc78ba21c Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 12 Feb 2015 23:10:25 +0300 Subject: [PATCH 02/25] Memory cleanup: u64 -> u32, empty TLS fixed cellGameContentPermit fixed --- rpcs3/Emu/Cell/RawSPUThread.cpp | 12 +- rpcs3/Emu/Cell/RawSPUThread.h | 5 +- rpcs3/Emu/Memory/Memory.cpp | 202 +++++++------------ rpcs3/Emu/Memory/Memory.h | 12 +- rpcs3/Emu/Memory/MemoryBlock.h | 92 ++++----- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 23 ++- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 6 +- rpcs3/Emu/SysCalls/Modules/cellGcmSys.h | 1 - rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 12 +- rpcs3/Gui/RSXDebugger.cpp | 8 +- 10 files changed, 161 insertions(+), 212 deletions(-) diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index ba4c98f363..041ea63968 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -19,9 +19,9 @@ RawSPUThread::~RawSPUThread() Memory.CloseRawSPU(this, m_index); } -bool RawSPUThread::Read32(const u64 addr, u32* value) +bool RawSPUThread::Read32(const u32 addr, u32* value) { - const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; + const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch (offset) { @@ -68,9 +68,9 @@ bool RawSPUThread::Read32(const u64 addr, u32* value) return true; } -bool RawSPUThread::Write32(const u64 addr, const u32 value) +bool RawSPUThread::Write32(const u32 addr, const u32 value) { - const u64 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; + const u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET; switch (offset) { @@ -198,7 +198,7 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value) void RawSPUThread::InitRegs() { - ls_offset = m_offset = (u32)GetStartAddr() + RAW_SPU_LS_OFFSET; + ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET; SPUThread::InitRegs(); } @@ -213,5 +213,5 @@ void RawSPUThread::Task() SPUThread::Task(); - SPU.NPC.SetValue((u32)PC); + SPU.NPC.SetValue(PC); } diff --git a/rpcs3/Emu/Cell/RawSPUThread.h b/rpcs3/Emu/Cell/RawSPUThread.h index c52dc696a1..7c166c6468 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.h +++ b/rpcs3/Emu/Cell/RawSPUThread.h @@ -16,9 +16,8 @@ public: RawSPUThread(CPUThreadType type = CPU_THREAD_RAW_SPU); virtual ~RawSPUThread(); - bool Read32(const u64 addr, u32* value); - - bool Write32(const u64 addr, const u32 value); + bool Read32(const u32 addr, u32* value); + bool Write32(const u32 addr, const u32 value); public: virtual void InitRegs(); diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 7f87615796..00eee9da85 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -17,42 +17,36 @@ MemoryBase Memory; -void MemoryBase::RegisterPages(u64 addr, u32 size) +void MemoryBase::RegisterPages(u32 addr, u32 size) { + assert(size && (size | addr) % 4096 == 0); + LV2_LOCK(0); - //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%llx, size=0x%x)", addr, size); - for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) + //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%x, size=0x%x)", addr, size); + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if (i >= sizeof(m_pages) / sizeof(m_pages[0])) - { - LOG_ERROR(MEMORY, "%s(): invalid address 0x%llx", __FUNCTION__, i * 4096); - break; - } if (m_pages[i]) { - LOG_ERROR(MEMORY, "Page already registered (addr=0x%llx)", i * 4096); + LOG_ERROR(MEMORY, "Page already registered (addr=0x%x)", i * 4096); Emu.Pause(); } m_pages[i] = 1; // TODO: define page parameters } } -void MemoryBase::UnregisterPages(u64 addr, u32 size) +void MemoryBase::UnregisterPages(u32 addr, u32 size) { + assert(size && (size | addr) % 4096 == 0); + LV2_LOCK(0); - //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%llx, size=0x%x)", addr, size); - for (u64 i = addr / 4096; i < (addr + size) / 4096; i++) + //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%x, size=0x%x)", addr, size); + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if (i >= sizeof(m_pages) / sizeof(m_pages[0])) - { - LOG_ERROR(MEMORY, "%s(): invalid address 0x%llx", __FUNCTION__, i * 4096); - break; - } if (!m_pages[i]) { - LOG_ERROR(MEMORY, "Page not registered (addr=0x%llx)", i * 4096); + LOG_ERROR(MEMORY, "Page not registered (addr=0x%x)", i * 4096); Emu.Pause(); } m_pages[i] = 0; // TODO: define page parameters @@ -187,29 +181,27 @@ u32 MemoryBase::ReadMMIO32(u32 addr) throw fmt::Format("%s(addr=0x%x) failed", __FUNCTION__, addr); } -bool MemoryBase::Map(const u64 addr, const u32 size) +bool MemoryBase::Map(const u32 addr, const u32 size) { + assert(size && (size | addr) % 4096 == 0); + LV2_LOCK(0); - if ((addr | (addr + size)) & ~0xFFFFFFFFull) + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - return false; - } - else - { - for (u32 i = (u32)addr / 4096; i <= ((u32)addr + size - 1) / 4096; i++) + if (m_pages[i]) { - if (m_pages[i]) return false; + return false; } } MemoryBlocks.push_back((new MemoryBlock())->SetRange(addr, size)); - LOG_WARNING(MEMORY, "Memory mapped at 0x%llx: size=0x%x", addr, size); + LOG_WARNING(MEMORY, "Memory mapped at 0x%x: size=0x%x", addr, size); return true; } -bool MemoryBase::Unmap(const u64 addr) +bool MemoryBase::Unmap(const u32 addr) { LV2_LOCK(0); @@ -225,11 +217,13 @@ bool MemoryBase::Unmap(const u64 addr) return false; } -MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size) - : MemInfo(_addr, PAGE_4K(_size)) +MemBlockInfo::MemBlockInfo(u32 addr, u32 size) + : MemInfo(addr, size) { - void* real_addr = vm::get_ptr(vm::cast(_addr)); - void* priv_addr = vm::get_priv_ptr(vm::cast(_addr)); + assert(size && (size | addr) % 4096 == 0); + + void* real_addr = vm::get_ptr(addr); + void* priv_addr = vm::get_priv_ptr(addr); #ifdef _WIN32 if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE)) @@ -237,12 +231,12 @@ MemBlockInfo::MemBlockInfo(u64 _addr, u32 _size) if (mprotect(real_addr, size, PROT_READ | PROT_WRITE) || mprotect(priv_addr, size, PROT_READ | PROT_WRITE)) #endif { - LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%llx, size=0x%x)", addr, size); + LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%x, size=0x%x)", addr, size); Emu.Pause(); } else { - Memory.RegisterPages(_addr, PAGE_4K(_size)); + Memory.RegisterPages(addr, size); mem = real_addr; memset(mem, 0, size); // ??? @@ -257,12 +251,12 @@ void MemBlockInfo::Free() #ifdef _WIN32 DWORD old; - if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(vm::cast(addr)), size, PAGE_NOACCESS, &old)) + if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(addr), size, PAGE_NOACCESS, &old)) #else - if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(vm::cast(addr)), size, PROT_NONE)) + if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(addr), size, PROT_NONE)) #endif { - LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%llx, size=0x%x)", addr, size); + LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%x, size=0x%x)", addr, size); Emu.Pause(); } } @@ -316,15 +310,8 @@ void MemoryBlock::Delete() Init(); } -u64 MemoryBlock::FixAddr(const u64 addr) const +MemoryBlock* MemoryBlock::SetRange(const u32 start, const u32 size) { - return addr - GetStartAddr(); -} - -MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size) -{ - if (start + size > 0x100000000) return nullptr; - range_start = start; range_size = size; @@ -332,11 +319,6 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size) return this; } -bool MemoryBlock::IsMyAddress(const u64 addr) -{ - return mem && addr >= GetStartAddr() && addr < GetEndAddr(); -} - DynamicMemoryBlockBase::DynamicMemoryBlockBase() : MemoryBlock() , m_max_size(0) @@ -357,22 +339,12 @@ const u32 DynamicMemoryBlockBase::GetUsedSize() const return size; } -bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr) +bool DynamicMemoryBlockBase::IsInMyRange(const u32 addr, const u32 size) { - return addr >= MemoryBlock::GetStartAddr() && addr < MemoryBlock::GetStartAddr() + GetSize(); + return addr >= MemoryBlock::GetStartAddr() && addr + size - 1 <= MemoryBlock::GetEndAddr(); } -bool DynamicMemoryBlockBase::IsInMyRange(const u64 addr, const u32 size) -{ - return IsInMyRange(addr) && IsInMyRange(addr + size - 1); -} - -bool DynamicMemoryBlockBase::IsMyAddress(const u64 addr) -{ - return IsInMyRange(addr); -} - -MemoryBlock* DynamicMemoryBlockBase::SetRange(const u64 start, const u32 size) +MemoryBlock* DynamicMemoryBlockBase::SetRange(const u32 start, const u32 size) { LV2_LOCK(0); @@ -396,8 +368,10 @@ void DynamicMemoryBlockBase::Delete() MemoryBlock::Delete(); } -bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size) +bool DynamicMemoryBlockBase::AllocFixed(u32 addr, u32 size) { + assert(size); + size = PAGE_4K(size + (addr & 4095)); // align size addr &= ~4095; // align start address @@ -420,13 +394,15 @@ bool DynamicMemoryBlockBase::AllocFixed(u64 addr, u32 size) return true; } -void DynamicMemoryBlockBase::AppendMem(u64 addr, u32 size) /* private */ +void DynamicMemoryBlockBase::AppendMem(u32 addr, u32 size) /* private */ { m_allocated.emplace_back(addr, size); } -u64 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) +u32 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) { + assert(size && align); + if (!MemoryBlock::GetStartAddr()) { LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::AllocAlign(size=0x%x, align=0x%x): memory block not initialized", size, align); @@ -449,7 +425,7 @@ u64 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) LV2_LOCK(0); - for (u64 addr = MemoryBlock::GetStartAddr(); addr <= MemoryBlock::GetEndAddr() - exsize;) + for (u32 addr = MemoryBlock::GetStartAddr(); addr <= MemoryBlock::GetEndAddr() - exsize;) { bool is_good_addr = true; @@ -486,7 +462,7 @@ bool DynamicMemoryBlockBase::Alloc() return AllocAlign(GetSize() - GetUsedSize()) != 0; } -bool DynamicMemoryBlockBase::Free(u64 addr) +bool DynamicMemoryBlockBase::Free(u32 addr) { LV2_LOCK(0); @@ -501,45 +477,19 @@ bool DynamicMemoryBlockBase::Free(u64 addr) } } - LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%llx): failed", addr); + LOG_ERROR(MEMORY, "DynamicMemoryBlock::Free(addr=0x%x): failed", addr); for (u32 i = 0; i < m_allocated.size(); i++) { - LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); + LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%x, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); } return false; } -u8* DynamicMemoryBlockBase::GetMem(u64 addr) const -{ - return MemoryBlock::GetMem(addr); -} - -bool DynamicMemoryBlockBase::IsLocked(u64 addr) -{ - LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::IsLocked() not implemented"); - Emu.Pause(); - return false; -} - -bool DynamicMemoryBlockBase::Lock(u64 addr, u32 size) -{ - LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::Lock() not implemented"); - Emu.Pause(); - return false; -} - -bool DynamicMemoryBlockBase::Unlock(u64 addr, u32 size) -{ - LOG_ERROR(MEMORY, "DynamicMemoryBlockBase::Unlock() not implemented"); - Emu.Pause(); - return false; -} - VirtualMemoryBlock::VirtualMemoryBlock() : MemoryBlock(), m_reserve_size(0) { } -MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size) +MemoryBlock* VirtualMemoryBlock::SetRange(const u32 start, const u32 size) { range_start = start; range_size = size; @@ -547,32 +497,16 @@ MemoryBlock* VirtualMemoryBlock::SetRange(const u64 start, const u32 size) return this; } -bool VirtualMemoryBlock::IsInMyRange(const u64 addr) +bool VirtualMemoryBlock::IsInMyRange(const u32 addr, const u32 size) { - return addr >= GetStartAddr() && addr < GetStartAddr() + GetSize() - GetReservedAmount(); + return addr >= GetStartAddr() && addr + size - 1 <= GetEndAddr() - GetReservedAmount(); } -bool VirtualMemoryBlock::IsInMyRange(const u64 addr, const u32 size) +u32 VirtualMemoryBlock::Map(u32 realaddr, u32 size) { - return IsInMyRange(addr) && IsInMyRange(addr + size - 1); -} + assert(size); -bool VirtualMemoryBlock::IsMyAddress(const u64 addr) -{ - for (u32 i = 0; i= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) - { - return true; - } - } - - return false; -} - -u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size) -{ - for (u64 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) + for (u32 addr = GetStartAddr(); addr <= GetEndAddr() - GetReservedAmount() - size;) { bool is_good_addr = true; @@ -598,16 +532,28 @@ u64 VirtualMemoryBlock::Map(u64 realaddr, u32 size) return 0; } -bool VirtualMemoryBlock::Map(u64 realaddr, u32 size, u64 addr) +bool VirtualMemoryBlock::Map(u32 realaddr, u32 size, u32 addr) { - if (!IsInMyRange(addr, size) && (IsMyAddress(addr) || IsMyAddress(addr + size - 1))) + assert(size); + + if (!IsInMyRange(addr, size)) + { return false; + } + + for (u32 i = 0; i= m_mapped_memory[i].addr && addr + size - 1 <= m_mapped_memory[i].addr + m_mapped_memory[i].size - 1) + { + return false; + } + } m_mapped_memory.emplace_back(addr, realaddr, size); return true; } -bool VirtualMemoryBlock::UnmapRealAddress(u64 realaddr, u32& size) +bool VirtualMemoryBlock::UnmapRealAddress(u32 realaddr, u32& size) { for (u32 i = 0; iGetSize() - UserMemory->GetUsedSize(); } - u64 Alloc(const u32 size, const u32 align) + u32 Alloc(const u32 size, const u32 align) { return UserMemory->AllocAlign(size, align); } - bool Free(const u64 addr) + bool Free(const u32 addr) { return UserMemory->Free(addr); } - bool Map(const u64 addr, const u32 size); + bool Map(const u32 addr, const u32 size); - bool Unmap(const u64 addr); + bool Unmap(const u32 addr); }; extern MemoryBase Memory; diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 1dcf833553..81dfcd3e1d 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -2,20 +2,20 @@ #define PAGE_4K(x) (x + 4095) & ~(4095) -//#include - struct MemInfo { - u64 addr; + u32 addr; u32 size; - MemInfo(u64 _addr, u32 _size) - : addr(_addr) - , size(_size) + MemInfo(u32 addr, u32 size) + : addr(addr) + , size(size) { } - MemInfo() : addr(0), size(0) + MemInfo() + : addr(0) + , size(0) { } }; @@ -24,7 +24,7 @@ struct MemBlockInfo : public MemInfo { void *mem; - MemBlockInfo(u64 _addr, u32 _size); + MemBlockInfo(u32 addr, u32 size); void Free(); @@ -58,11 +58,11 @@ struct MemBlockInfo : public MemInfo struct VirtualMemInfo : public MemInfo { - u64 realAddress; + u32 realAddress; - VirtualMemInfo(u64 _addr, u64 _realaddr, u32 _size) - : MemInfo(_addr, _size) - , realAddress(_realaddr) + VirtualMemInfo(u32 addr, u32 realaddr, u32 size) + : MemInfo(addr, size) + , realAddress(realaddr) { } @@ -77,7 +77,7 @@ class MemoryBlock { protected: u8* mem; - u64 range_start; + u32 range_start; u32 range_size; public: @@ -93,25 +93,17 @@ private: public: virtual void Delete(); - u64 FixAddr(const u64 addr) const; + virtual MemoryBlock* SetRange(const u32 start, const u32 size); - virtual MemoryBlock* SetRange(const u64 start, const u32 size); - virtual bool IsMyAddress(const u64 addr); - virtual bool IsLocked(const u64 addr) { return false; } - - const u64 GetStartAddr() const { return range_start; } - const u64 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; } + const u32 GetStartAddr() const { return range_start; } + const u32 GetEndAddr() const { return GetStartAddr() + GetSize() - 1; } virtual const u32 GetSize() const { return range_size; } virtual const u32 GetUsedSize() const { return GetSize(); } - u8* GetMem() const { return mem; } - virtual u8* GetMem(u64 addr) const { return mem + addr; } - virtual bool AllocFixed(u64 addr, u32 size) { return false; } - virtual u64 AllocAlign(u32 size, u32 align = 1) { return 0; } + virtual bool AllocFixed(u32 addr, u32 size) { return false; } + virtual u32 AllocAlign(u32 size, u32 align = 1) { return 0; } virtual bool Alloc() { return false; } - virtual bool Free(u64 addr) { return false; } - virtual bool Lock(u64 addr, u32 size) { return false; } - virtual bool Unlock(u64 addr, u32 size) { return false; } + virtual bool Free(u32 addr) { return false; } }; class DynamicMemoryBlockBase : public MemoryBlock @@ -125,26 +117,19 @@ public: const u32 GetSize() const { return m_max_size; } const u32 GetUsedSize() const; - virtual bool IsInMyRange(const u64 addr); - virtual bool IsInMyRange(const u64 addr, const u32 size); - virtual bool IsMyAddress(const u64 addr); - virtual bool IsLocked(const u64 addr); + virtual bool IsInMyRange(const u32 addr, const u32 size = 1); - virtual MemoryBlock* SetRange(const u64 start, const u32 size); + virtual MemoryBlock* SetRange(const u32 start, const u32 size); virtual void Delete(); - virtual bool AllocFixed(u64 addr, u32 size); - virtual u64 AllocAlign(u32 size, u32 align = 1); + virtual bool AllocFixed(u32 addr, u32 size); + virtual u32 AllocAlign(u32 size, u32 align = 1); virtual bool Alloc(); - virtual bool Free(u64 addr); - virtual bool Lock(u64 addr, u32 size); - virtual bool Unlock(u64 addr, u32 size); - - virtual u8* GetMem(u64 addr) const; + virtual bool Free(u32 addr); private: - void AppendMem(u64 addr, u32 size); + void AppendMem(u32 addr, u32 size); }; class VirtualMemoryBlock : public MemoryBlock @@ -155,22 +140,20 @@ class VirtualMemoryBlock : public MemoryBlock public: VirtualMemoryBlock(); - virtual MemoryBlock* SetRange(const u64 start, const u32 size); - virtual bool IsInMyRange(const u64 addr); - virtual bool IsInMyRange(const u64 addr, const u32 size); - virtual bool IsMyAddress(const u64 addr); + virtual MemoryBlock* SetRange(const u32 start, const u32 size); + virtual bool IsInMyRange(const u32 addr, const u32 size = 1); virtual void Delete(); // maps real address to virtual address space, returns the mapped address or 0 on failure (if no address is specified the // first mappable space is used) - virtual bool Map(u64 realaddr, u32 size, u64 addr); - virtual u64 Map(u64 realaddr, u32 size); + virtual bool Map(u32 realaddr, u32 size, u32 addr); + virtual u32 Map(u32 realaddr, u32 size); // Unmap real address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area - virtual bool UnmapRealAddress(u64 realaddr, u32& size); + virtual bool UnmapRealAddress(u32 realaddr, u32& size); // Unmap address (please specify only starting point, no midway memory will be unmapped), returns the size of the unmapped area - virtual bool UnmapAddress(u64 addr, u32& size); + virtual bool UnmapAddress(u32 addr, u32& size); // Reserve a certain amount so no one can use it, returns true on succces, false on failure virtual bool Reserve(u32 size); @@ -181,24 +164,23 @@ public: // Return the total amount of reserved memory virtual u32 GetReservedAmount(); - bool Read32(const u64 addr, u32* value); + bool Read32(const u32 addr, u32* value); - bool Write32(const u64 addr, const u32 value); + bool Write32(const u32 addr, const u32 value); // try to get the real address given a mapped address // return true for success - bool getRealAddr(u64 addr, u64& result); + bool getRealAddr(u32 addr, u32& result); - u64 RealAddr(u64 addr) + u32 RealAddr(u32 addr) { - u64 realAddr = 0; + u32 realAddr = 0; getRealAddr(addr, realAddr); return realAddr; } // return the mapped address given a real address, if not mapped return 0 - u64 getMappedAddress(u64 realAddress); + u32 getMappedAddress(u32 realAddress); }; typedef DynamicMemoryBlockBase DynamicMemoryBlock; - diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index e54aedb7e2..4e45ddb87c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -14,6 +14,7 @@ Module *cellGame = nullptr; std::string contentInfo = ""; std::string usrdir = ""; +bool path_set = false; int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, vm::ptr dirName) { @@ -52,6 +53,7 @@ int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr type, vm::ptr attributes, vm::ptr type, vm::ptr attributes, vm::ptr size, u32 reserved_addr) std::string titleId = psf.GetString("TITLE_ID"); contentInfo = "/dev_hdd0/game/" + titleId; usrdir = "/dev_hdd0/game/" + titleId + "/USRDIR"; + path_set = true; return CELL_GAME_RET_OK; } @@ -155,10 +160,15 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptrWarning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found"); + contentInfo = ""; + usrdir = ""; + path_set = true; return CELL_GAME_RET_NONE; } + contentInfo = "/dev_bdvd/PS3_GAME"; usrdir = "/dev_bdvd/PS3_GAME/USRDIR"; + path_set = true; } else { @@ -167,10 +177,15 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptrWarning("cellGameDataCheck(): '%s' directory not found", dir.c_str()); + contentInfo = ""; + usrdir = ""; + path_set = true; return CELL_GAME_RET_NONE; } + contentInfo = dir; usrdir = dir + "/USRDIR"; + path_set = true; } return CELL_GAME_RET_OK; @@ -186,9 +201,8 @@ int cellGameContentPermit(vm::ptr contentInfoPath, vm: return CELL_GAME_ERROR_PARAM; } - if (contentInfo == "" && usrdir == "") + if (!path_set) { - cellGame->Warning("cellGameContentPermit(): CELL_GAME_ERROR_FAILURE (no permission given)"); return CELL_GAME_ERROR_FAILURE; } @@ -197,6 +211,7 @@ int cellGameContentPermit(vm::ptr contentInfoPath, vm: contentInfo = ""; usrdir = ""; + path_set = false; return CELL_GAME_RET_OK; } @@ -476,6 +491,10 @@ void cellGame_init(Module *pxThis) { cellGame = pxThis; + contentInfo = ""; + usrdir = ""; + path_set = false; + // (TODO: Disc Exchange functions missing) cellGame->AddFunc(0xf52639ea, cellGameBootCheck); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 23659a60e5..547c1b61ad 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -842,16 +842,16 @@ void cellGcmGetOffsetTable(vm::ptr table) table->eaAddress = offsetTable.eaAddress; } -s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) +s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr address) { cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%llx)", ioOffset, address); - u64 realAddr; + u32 realAddr; if (!Memory.RSXIOMem.getRealAddr(ioOffset, realAddr)) return CELL_GCM_ERROR_FAILURE; - vm::write64(address, realAddr); + *address = realAddr; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h index 1ee95bdfaf..b7fad1b62f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h @@ -27,7 +27,6 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id); s32 cellGcmAddressToOffset(u64 address, vm::ptr> offset); u32 cellGcmGetMaxIoMapSize(); void cellGcmGetOffsetTable(vm::ptr table); -s32 cellGcmIoOffsetToAddress(u32 ioOffset, u64 address); s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size); s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags); s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 3fc79e4256..961e04dde3 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -24,8 +24,10 @@ Module *sysPrxForUser = nullptr; #define TLS_MAX 128 +#define TLS_SYS 0x30 u32 g_tls_start; // start of TLS memory area +u32 g_tls_size; std::array, TLS_MAX> g_tls_owners; @@ -38,8 +40,9 @@ u32 ppu_get_tls(u32 thread) { if (!g_tls_start) { - g_tls_start = vm::cast(Memory.MainMem.AllocAlign(Emu.GetTLSMemsz() * TLS_MAX, 4096)); // memory for up to TLS_MAX threads - sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, size = 0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", + g_tls_size = Emu.GetTLSMemsz() + TLS_SYS; + g_tls_start = vm::cast(Memory.MainMem.AllocAlign(g_tls_size * TLS_MAX, 4096)); // memory for up to TLS_MAX threads + sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz()); } @@ -52,7 +55,7 @@ u32 ppu_get_tls(u32 thread) { if (g_tls_owners[i] == thread) { - return g_tls_start + i * Emu.GetTLSMemsz(); // if already initialized, return TLS address + return g_tls_start + i * g_tls_size + TLS_SYS; // if already initialized, return TLS address } } @@ -61,7 +64,8 @@ u32 ppu_get_tls(u32 thread) u32 old = 0; if (g_tls_owners[i].compare_exchange_strong(old, thread)) { - const u32 addr = g_tls_start + i * Emu.GetTLSMemsz(); // get TLS address + const u32 addr = g_tls_start + i * g_tls_size + TLS_SYS; // get TLS address + memset(vm::get_ptr(addr - TLS_SYS), 0, TLS_SYS); // initialize system area with zeros memcpy(vm::get_ptr(addr), vm::get_ptr(Emu.GetTLSAddr()), Emu.GetTLSFilesz()); // initialize from TLS image memset(vm::get_ptr(addr + Emu.GetTLSFilesz()), 0, Emu.GetTLSMemsz() - Emu.GetTLSFilesz()); // fill the rest with zeros return addr; diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 69a09bc2cb..4c408b509e 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -331,9 +331,9 @@ void RSXDebugger::GoToGet(wxCommandEvent& event) { if (!RSXReady()) return; auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); - u64 realAddr; + u32 realAddr; if (Memory.RSXIOMem.getRealAddr(ctrl->get.read_relaxed(), realAddr)) { - m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32 + m_addr = realAddr; t_addr->SetValue(wxString::Format("%08x", m_addr)); UpdateInformation(); event.Skip(); @@ -345,9 +345,9 @@ void RSXDebugger::GoToPut(wxCommandEvent& event) { if (!RSXReady()) return; auto ctrl = vm::get_ptr(Emu.GetGSManager().GetRender().m_ctrlAddress); - u64 realAddr; + u32 realAddr; if (Memory.RSXIOMem.getRealAddr(ctrl->put.read_relaxed(), realAddr)) { - m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32 + m_addr = realAddr; t_addr->SetValue(wxString::Format("%08x", m_addr)); UpdateInformation(); event.Skip(); From 267de68441b4cbe355b77d4e2c30b3011efedd77 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 13 Feb 2015 17:04:03 +0300 Subject: [PATCH 03/25] Memory cleanup, page flags implemented RSXCMDMem, SPRXMem, MmaperMem removed MainMem range fixed --- rpcs3/Emu/ARMv7/ARMv7Decoder.cpp | 2 +- rpcs3/Emu/ARMv7/ARMv7Thread.cpp | 6 +- rpcs3/Emu/Cell/PPUThread.cpp | 2 +- rpcs3/Emu/Memory/Memory.cpp | 104 +-------- rpcs3/Emu/Memory/Memory.h | 27 +-- rpcs3/Emu/Memory/MemoryBlock.h | 14 +- rpcs3/Emu/Memory/vm.cpp | 217 +++++++++++++++---- rpcs3/Emu/Memory/vm.h | 30 ++- rpcs3/Emu/Memory/vm_var.h | 4 +- rpcs3/Emu/RSX/GCM.h | 1 + rpcs3/Emu/RSX/GL/GLGSRender.cpp | 57 +---- rpcs3/Emu/RSX/RSXThread.cpp | 4 +- rpcs3/Emu/RSX/RSXThread.h | 1 + rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 11 +- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_spu.cpp | 2 +- rpcs3/Emu/SysCalls/lv2/sys_vm.cpp | 7 +- rpcs3/Gui/InterpreterDisAsm.cpp | 2 +- rpcs3/Gui/MemoryStringSearcher.cpp | 2 +- rpcs3/Gui/MemoryViewer.cpp | 2 +- rpcs3/Gui/RSXDebugger.cpp | 16 +- rpcs3/Loader/ELF64.cpp | 2 +- 23 files changed, 259 insertions(+), 260 deletions(-) diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp index 70ccd9f240..0b62114b2b 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp @@ -1281,7 +1281,7 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump) const u32 i2 = (code.data >> 11) & 0x1 ^ s ^ 1; const u32 target = (addr + 4 & ~3) + sign<25, u32>(s << 24 | i2 << 23 | i1 << 22 | (code.data & 0x3ff0000) >> 4 | (code.data & 0x7ff) << 1); - const u32 instr = Memory.IsGoodAddr(target, 4) ? vm::psv::read32(target) : 0; + const u32 instr = vm::check_addr(target, 4) ? vm::psv::read32(target) : 0; // possibly a call to imported function: if (target >= end_addr && ((target - end_addr) % 16) == 0 && (instr & 0xfff000f0) == 0xe0700090) diff --git a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp index 0a57e4abcf..2e4d6c4ecb 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Thread.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Thread.cpp @@ -39,7 +39,7 @@ std::array, TLS_MAX> g_armv7_tls_owners; void armv7_init_tls() { - g_armv7_tls_start = Emu.GetTLSMemsz() ? vm::cast(Memory.PSV.RAM.AllocAlign(Emu.GetTLSMemsz() * TLS_MAX, 4096)) : 0; + g_armv7_tls_start = Emu.GetTLSMemsz() ? Memory.PSV.RAM.AllocAlign(Emu.GetTLSMemsz() * TLS_MAX, 4096) : 0; for (auto& v : g_armv7_tls_owners) { @@ -126,7 +126,7 @@ void ARMv7Thread::InitStack() if (!m_stack_addr) { assert(m_stack_size); - m_stack_addr = vm::cast(Memory.Alloc(m_stack_size, 4096)); + m_stack_addr = Memory.Alloc(m_stack_size, 4096); } } @@ -269,7 +269,7 @@ cpu_thread& armv7_thread::args(std::initializer_list values) argc++; } - argv = vm::cast(Memory.PSV.RAM.AllocAlign(argv_size, 4096)); // allocate arg list + argv = Memory.PSV.RAM.AllocAlign(argv_size, 4096); // allocate arg list memcpy(vm::get_ptr(argv), argv_data.data(), argv_size); // copy arg list return *this; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index e6d229583a..63ccda64d6 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -85,7 +85,7 @@ void PPUThread::InitStack() if (!m_stack_addr) { assert(m_stack_size); - m_stack_addr = vm::cast(Memory.StackMem.AllocAlign(m_stack_size, 4096)); + m_stack_addr = Memory.StackMem.AllocAlign(m_stack_size, 4096); } } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 00eee9da85..f5904b2c28 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -4,55 +4,8 @@ #include "Memory.h" #include "Emu/Cell/RawSPUThread.h" -#ifndef _WIN32 -#include - -/* OS X uses MAP_ANON instead of MAP_ANONYMOUS */ -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif -#else -#include -#endif - MemoryBase Memory; -void MemoryBase::RegisterPages(u32 addr, u32 size) -{ - assert(size && (size | addr) % 4096 == 0); - - LV2_LOCK(0); - - //LOG_NOTICE(MEMORY, "RegisterPages(addr=0x%x, size=0x%x)", addr, size); - for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) - { - if (m_pages[i]) - { - LOG_ERROR(MEMORY, "Page already registered (addr=0x%x)", i * 4096); - Emu.Pause(); - } - m_pages[i] = 1; // TODO: define page parameters - } -} - -void MemoryBase::UnregisterPages(u32 addr, u32 size) -{ - assert(size && (size | addr) % 4096 == 0); - - LV2_LOCK(0); - - //LOG_NOTICE(MEMORY, "UnregisterPages(addr=0x%x, size=0x%x)", addr, size); - for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) - { - if (!m_pages[i]) - { - LOG_ERROR(MEMORY, "Page not registered (addr=0x%x)", i * 4096); - Emu.Pause(); - } - m_pages[i] = 0; // TODO: define page parameters - } -} - u32 MemoryBase::InitRawSPU(MemoryBlock* raw_spu) { LV2_LOCK(0); @@ -93,7 +46,6 @@ void MemoryBase::Init(MemoryType type) if (m_inited) return; m_inited = true; - memset(m_pages, 0, sizeof(m_pages)); memset(RawSPUMem, 0, sizeof(RawSPUMem)); LOG_NOTICE(MEMORY, "Initializing memory: base_addr = 0x%llx, priv_addr = 0x%llx", (u64)vm::g_base_addr, (u64)vm::g_priv_addr); @@ -111,11 +63,8 @@ void MemoryBase::Init(MemoryType type) switch (type) { case Memory_PS3: - MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x2FFF0000)); - MemoryBlocks.push_back(UserMemory = PRXMem.SetRange(0x30000000, 0x10000000)); - MemoryBlocks.push_back(RSXCMDMem.SetRange(0x40000000, 0x10000000)); - MemoryBlocks.push_back(SPRXMem.SetRange(0x50000000, 0x10000000)); - MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); + MemoryBlocks.push_back(MainMem.SetRange(0x00010000, 0x1FFF0000)); + MemoryBlocks.push_back(UserMemory = Userspace.SetRange(0x20000000, 0x10000000)); MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); break; @@ -189,7 +138,7 @@ bool MemoryBase::Map(const u32 addr, const u32 size) for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) { - if (m_pages[i]) + if (vm::check_addr(i * 4096, 4096)) { return false; } @@ -220,45 +169,15 @@ bool MemoryBase::Unmap(const u32 addr) MemBlockInfo::MemBlockInfo(u32 addr, u32 size) : MemInfo(addr, size) { - assert(size && (size | addr) % 4096 == 0); - - void* real_addr = vm::get_ptr(addr); - void* priv_addr = vm::get_priv_ptr(addr); - -#ifdef _WIN32 - if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, PAGE_READWRITE)) -#else - if (mprotect(real_addr, size, PROT_READ | PROT_WRITE) || mprotect(priv_addr, size, PROT_READ | PROT_WRITE)) -#endif - { - LOG_ERROR(MEMORY, "Memory allocation failed (addr=0x%x, size=0x%x)", addr, size); - Emu.Pause(); - } - else - { - Memory.RegisterPages(addr, size); - - mem = real_addr; - memset(mem, 0, size); // ??? - } + vm::page_map(addr, size, vm::page_readable | vm::page_writable | vm::page_executable); } void MemBlockInfo::Free() { - if (mem) + if (addr && size) { - Memory.UnregisterPages(addr, size); -#ifdef _WIN32 - DWORD old; - - if (!VirtualProtect(mem, size, PAGE_NOACCESS, &old) || !VirtualProtect(vm::get_priv_ptr(addr), size, PAGE_NOACCESS, &old)) -#else - if (mprotect(mem, size, PROT_NONE) || mprotect(vm::get_priv_ptr(addr), size, PROT_NONE)) -#endif - { - LOG_ERROR(MEMORY, "Memory deallocation failed (addr=0x%x, size=0x%x)", addr, size); - Emu.Pause(); - } + vm::page_unmap(addr, size); + addr = size = 0; } } @@ -277,21 +196,14 @@ void MemoryBlock::Init() { range_start = 0; range_size = 0; - - mem = vm::get_ptr(0u); } void MemoryBlock::InitMemory() { - if (!range_size) - { - mem = vm::get_ptr(range_start); - } - else + if (range_size) { Free(); mem_inf = new MemBlockInfo(range_start, range_size); - mem = (u8*)mem_inf->mem; } } diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 84b459f9bb..a6e6edbf94 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -30,16 +30,12 @@ namespace vm class MemoryBase { std::vector MemoryBlocks; - u32 m_pages[0x100000000 / 4096]; // information about every page public: MemoryBlock* UserMemory; DynamicMemoryBlock MainMem; - DynamicMemoryBlock SPRXMem; - DynamicMemoryBlock PRXMem; - DynamicMemoryBlock RSXCMDMem; - DynamicMemoryBlock MmaperMem; + DynamicMemoryBlock Userspace; DynamicMemoryBlock RSXFBMem; DynamicMemoryBlock StackMem; MemoryBlock* RawSPUMem[(0x100000000 - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]; @@ -82,27 +78,6 @@ public: void Init(MemoryType type); - bool IsGoodAddr(const u32 addr) - { - return m_pages[addr / 4096] != 0; // TODO: define page parameters - } - - bool IsGoodAddr(const u32 addr, const u32 size) - { - if (!size || addr + size - 1 < addr) - { - return false; - } - else - { - for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) - { - if (!m_pages[i]) return false; // TODO: define page parameters - } - return true; - } - } - void Close(); __noinline void WriteMMIO32(u32 addr, const u32 data); diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 81dfcd3e1d..4cabf37db0 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -22,8 +22,6 @@ struct MemInfo struct MemBlockInfo : public MemInfo { - void *mem; - MemBlockInfo(u32 addr, u32 size); void Free(); @@ -32,27 +30,26 @@ struct MemBlockInfo : public MemInfo MemBlockInfo(MemBlockInfo &&other) : MemInfo(other.addr,other.size) - , mem(other.mem) { - other.mem = nullptr; + other.addr = 0; + other.size = 0; } MemBlockInfo& operator =(MemBlockInfo &other) = delete; MemBlockInfo& operator =(MemBlockInfo &&other) { - this->Free(); + Free(); this->addr = other.addr; this->size = other.size; - this->mem = other.mem; - other.mem = nullptr; + other.addr = 0; + other.size = 0; return *this; } ~MemBlockInfo() { Free(); - mem = nullptr; } }; @@ -76,7 +73,6 @@ struct VirtualMemInfo : public MemInfo class MemoryBlock { protected: - u8* mem; u32 range_start; u32 range_size; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 1a0b9edd5c..188f0f373e 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -80,6 +80,8 @@ namespace vm void* const g_base_addr = (atexit(finalize), initialize()); + std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page + class reservation_mutex_t { std::atomic m_owner; @@ -211,6 +213,12 @@ namespace vm { std::lock_guard lock(g_reservation_mutex); + u8 flags = g_page_info[addr >> 12].read_relaxed(); + if (!(flags & page_writable) || !(flags & page_allocated) || (flags & page_no_reservations)) + { + throw fmt::format("vm::reservation_acquire(addr=0x%x, size=0x%x) failed (invalid page flags: 0x%x)", addr, size, flags); + } + // silent unlocking to prevent priority boost for threads going to break reservation //g_reservation_mutex.do_notify = false; @@ -272,13 +280,9 @@ namespace vm { std::lock_guard lock(g_reservation_mutex); + if (!check_addr(addr)) { - LV2_LOCK(0); - - if (!Memory.IsGoodAddr(addr)) - { - return false; - } + return false; } if (is_writing) @@ -335,11 +339,157 @@ namespace vm _reservation_break(addr); } - bool check_addr(u32 addr) + void page_map(u32 addr, u32 size, u8 flags) { - // Checking address before using it is unsafe. - // The only safe way to check it is to protect both actions (checking and using) with mutex that is used for mapping/allocation. - return false; + assert(size && (size | addr) % 4096 == 0 && flags < page_allocated); + + std::lock_guard lock(g_reservation_mutex); + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + if (g_page_info[i].read_relaxed()) + { + throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (already mapped at 0x%x)", addr, size, flags, i * 4096); + } + } + + void* real_addr = vm::get_ptr(addr); + void* priv_addr = vm::get_priv_ptr(addr); + +#ifdef _WIN32 + auto protection = flags & page_writable ? PAGE_READWRITE : (flags & page_readable ? PAGE_READONLY : PAGE_NOACCESS); + if (!VirtualAlloc(priv_addr, size, MEM_COMMIT, PAGE_READWRITE) || !VirtualAlloc(real_addr, size, MEM_COMMIT, protection)) +#else + auto protection = flags & page_writable ? PROT_WRITE | PROT_READ : (flags & page_readable ? PROT_READ : PROT_NONE); + if (mprotect(priv_addr, size, PROT_READ | PROT_WRITE) || mprotect(real_addr, size, protection)) +#endif + { + throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (API)", addr, size, flags); + } + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + if (g_page_info[i].exchange(flags | page_allocated)) + { + throw fmt::format("vm::page_map(addr=0x%x, size=0x%x, flags=0x%x) failed (concurrent access at 0x%x)", addr, size, flags, i * 4096); + } + } + + memset(priv_addr, 0, size); // ??? + } + + bool page_protect(u32 addr, u32 size, u8 flags_test, u8 flags_set, u8 flags_clear) + { + u8 flags_inv = flags_set & flags_clear; + + assert(size && (size | addr) % 4096 == 0); + + flags_test |= page_allocated; + + std::lock_guard lock(g_reservation_mutex); + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + if ((g_page_info[i].read_relaxed() & flags_test) != (flags_test | page_allocated)) + { + return false; + } + } + + if (!flags_inv && !flags_set && !flags_clear) + { + return true; + } + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + _reservation_break(i * 4096); + + const u8 f1 = g_page_info[i]._or(flags_set & ~flags_inv) & (page_writable | page_readable); + g_page_info[i]._and_not(flags_clear & ~flags_inv); + const u8 f2 = (g_page_info[i] ^= flags_inv) & (page_writable | page_readable); + + if (f1 != f2) + { + void* real_addr = vm::get_ptr(i * 4096); + +#ifdef _WIN32 + DWORD old; + + auto protection = f2 & page_writable ? PAGE_READWRITE : (f2 & page_readable ? PAGE_READONLY : PAGE_NOACCESS); + if (!VirtualProtect(real_addr, size, protection, &old)) +#else + auto protection = f2 & page_writable ? PROT_WRITE | PROT_READ : (f2 & page_readable ? PROT_READ : PROT_NONE); + if (mprotect(real_addr, size, protection)) +#endif + { + throw fmt::format("vm::page_protect(addr=0x%x, size=0x%x, flags_test=0x%x, flags_set=0x%x, flags_clear=0x%x) failed (API)", addr, size, flags_test, flags_set, flags_clear); + } + } + } + + return true; + } + + void page_unmap(u32 addr, u32 size) + { + assert(size && (size | addr) % 4096 == 0); + + std::lock_guard lock(g_reservation_mutex); + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + if (!(g_page_info[i].read_relaxed() & page_allocated)) + { + throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (not mapped at 0x%x)", addr, size, i * 4096); + } + } + + for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++) + { + _reservation_break(i * 4096); + + if (!(g_page_info[i].exchange(0) & page_allocated)) + { + throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (concurrent access at 0x%x)", addr, size, i * 4096); + } + } + + void* real_addr = vm::get_ptr(addr); + void* priv_addr = vm::get_priv_ptr(addr); + +#ifdef _WIN32 + DWORD old; + + if (!VirtualProtect(real_addr, size, PAGE_NOACCESS, &old) || !VirtualProtect(priv_addr, size, PAGE_NOACCESS, &old)) +#else + if (mprotect(real_addr, size, PROT_NONE) || mprotect(priv_addr, size, PROT_NONE)) +#endif + { + throw fmt::format("vm::page_unmap(addr=0x%x, size=0x%x) failed (API)", addr, size); + } + } + + // Not checked if address is writable/readable. Checking address before using it is unsafe. + // The only safe way to check it is to protect both actions (checking and using) with mutex that is used for mapping/allocation. + bool check_addr(u32 addr, u32 size) + { + assert(size); + + if (addr + (size - 1) < addr) + { + return false; + } + + for (u32 i = addr / 4096; i <= (addr + size - 1) / 4096; i++) + { + if ((g_page_info[i].read_sync() & page_allocated) != page_allocated) + { + return false; + } + } + + return true; } //TODO @@ -406,6 +556,19 @@ namespace vm Memory.MainMem.Free(addr); } + u32 user_space_alloc(u32 size) + { + return Memory.Userspace.AllocAlign(size, 1); + } + u32 user_space_fixed_alloc(u32 addr, u32 size) + { + return Memory.Userspace.AllocFixed(addr, size) ? addr : 0; + } + void user_space_dealloc(u32 addr) + { + Memory.Userspace.Free(addr); + } + u32 g_stack_offset = 0; u32 stack_alloc(u32 size) @@ -421,32 +584,6 @@ namespace vm Memory.StackMem.Free(addr); } - u32 sprx_alloc(u32 size) - { - return Memory.SPRXMem.AllocAlign(size, 1); - } - u32 sprx_fixed_alloc(u32 addr, u32 size) - { - return Memory.SPRXMem.AllocFixed(Memory.SPRXMem.GetStartAddr() + addr, size) ? Memory.SPRXMem.GetStartAddr() + addr : 0; - } - void sprx_dealloc(u32 addr) - { - Memory.SPRXMem.Free(addr); - } - - u32 user_space_alloc(u32 size) - { - return Memory.PRXMem.AllocAlign(size, 1); - } - u32 user_space_fixed_alloc(u32 addr, u32 size) - { - return Memory.PRXMem.AllocFixed(addr, size) ? addr : 0; - } - void user_space_dealloc(u32 addr) - { - Memory.PRXMem.Free(addr); - } - void init() { Memory.Init(Memory_PS3); @@ -471,13 +608,9 @@ namespace vm location_info g_locations[memory_location_count] = { - { 0x00010000, 0x2FFF0000, ps3::main_alloc, ps3::main_fixed_alloc, ps3::main_dealloc }, + { 0x00010000, 0x1FFF0000, ps3::main_alloc, ps3::main_fixed_alloc, ps3::main_dealloc }, + { 0x20000000, 0x10000000, ps3::user_space_alloc, ps3::user_space_fixed_alloc, ps3::user_space_dealloc }, { 0xD0000000, 0x10000000, ps3::stack_alloc, ps3::stack_fixed_alloc, ps3::stack_dealloc }, - - //remove me - { 0x00010000, 0x2FFF0000, ps3::sprx_alloc, ps3::sprx_fixed_alloc, ps3::sprx_dealloc }, - - { 0x30000000, 0x10000000, ps3::user_space_alloc, ps3::user_space_fixed_alloc, ps3::user_space_dealloc }, }; void close() diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index a49c21eaab..5e07706646 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -8,16 +8,24 @@ namespace vm enum memory_location : uint { main, + user_space, stack, - //remove me - sprx, - - user_space, - memory_location_count }; + enum page_info_t : u8 + { + page_readable = (1 << 0), + page_writable = (1 << 1), + page_executable = (1 << 2), + + page_fault_notification = (1 << 3), + page_no_reservations = (1 << 4), + + page_allocated = (1 << 7), + }; + static void set_stack_size(u32 size) {} static void initialize_stack() {} @@ -34,11 +42,23 @@ namespace vm bool reservation_acquire(void* data, u32 addr, u32 size, const std::function& callback = nullptr); // attempt to atomically update reserved memory bool reservation_update(u32 addr, const void* data, u32 size); + // for internal use bool reservation_query(u32 addr, bool is_writing); + // for internal use void reservation_free(); // perform complete operation void reservation_op(u32 addr, u32 size, std::function proc); + // for internal use + void page_map(u32 addr, u32 size, u8 flags); + // for internal use + bool page_protect(u32 addr, u32 size, u8 flags_test = 0, u8 flags_set = 0, u8 flags_clear = 0); + // for internal use + void page_unmap(u32 addr, u32 size); + + // unsafe address check + bool check_addr(u32 addr, u32 size = 1); + bool map(u32 addr, u32 size, u32 flags); bool unmap(u32 addr, u32 size = 0, u32 flags = 0); u32 alloc(u32 size, memory_location location = user_space); diff --git a/rpcs3/Emu/Memory/vm_var.h b/rpcs3/Emu/Memory/vm_var.h index 06864950b9..a8c380aac1 100644 --- a/rpcs3/Emu/Memory/vm_var.h +++ b/rpcs3/Emu/Memory/vm_var.h @@ -35,7 +35,7 @@ namespace vm void alloc() { - m_addr = vm::cast(Memory.Alloc(size(), m_align)); + m_addr = Memory.Alloc(size(), m_align); m_ptr = vm::get_ptr(m_addr); } @@ -162,7 +162,7 @@ namespace vm void alloc() { - m_addr = vm::cast(Memory.Alloc(size(), m_align)); + m_addr = Memory.Alloc(size(), m_align); m_ptr = vm::get_ptr(m_addr); } diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 929b968503..c372ddd6b1 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -235,6 +235,7 @@ struct gcmInfo u32 config_addr; u32 context_addr; u32 control_addr; + u32 label_addr; }; struct CellGcmSurface diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 1b3df4a0bd..b1f0475d9d 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -104,12 +104,7 @@ void GLTexture::Init(RSXTexture& tex) Bind(); - const u64 texaddr = GetAddress(tex.GetOffset(), tex.GetLocation()); - if (!Memory.IsGoodAddr(texaddr)) - { - LOG_ERROR(RSX, "Bad texture address=0x%x", texaddr); - return; - } + const u32 texaddr = GetAddress(tex.GetOffset(), tex.GetLocation()); //LOG_WARNING(RSX, "texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", // m_offset, m_width, m_height, m_maxaniso, m_mipmap, m_remap, m_zfunc, m_wraps, m_wrapt, m_wrapr, m_minlod, m_maxlod); @@ -1242,11 +1237,6 @@ void GLGSRender::WriteDepthBuffer() } u32 address = GetAddress(m_surface_offset_z, m_context_dma_z - 0xfeed0000); - if (!Memory.IsGoodAddr(address)) - { - LOG_WARNING(RSX, "Bad depth buffer address: address=0x%x, offset=0x%x, dma=0x%x", address, m_surface_offset_z, m_context_dma_z); - return; - } auto ptr = vm::get_ptr(address); glBindBuffer(GL_PIXEL_PACK_BUFFER, g_pbo[4]); @@ -1279,11 +1269,6 @@ void GLGSRender::WriteColorBufferA() } u32 address = GetAddress(m_surface_offset_a, m_context_dma_color_a - 0xfeed0000); - if (!Memory.IsGoodAddr(address)) - { - LOG_ERROR(RSX, "Bad color buffer A address: address=0x%x, offset=0x%x, dma=0x%x", address, m_surface_offset_a, m_context_dma_color_a); - return; - } glReadBuffer(GL_COLOR_ATTACHMENT0); checkForGlError("WriteColorBufferA(): glReadBuffer"); @@ -1310,11 +1295,6 @@ void GLGSRender::WriteColorBufferB() } u32 address = GetAddress(m_surface_offset_b, m_context_dma_color_b - 0xfeed0000); - if (!Memory.IsGoodAddr(address)) - { - LOG_ERROR(RSX, "Bad color buffer B address: address=0x%x, offset=0x%x, dma=0x%x", address, m_surface_offset_b, m_context_dma_color_b); - return; - } glReadBuffer(GL_COLOR_ATTACHMENT1); checkForGlError("WriteColorBufferB(): glReadBuffer"); @@ -1341,11 +1321,6 @@ void GLGSRender::WriteColorBufferC() } u32 address = GetAddress(m_surface_offset_c, m_context_dma_color_c - 0xfeed0000); - if (!Memory.IsGoodAddr(address)) - { - LOG_ERROR(RSX, "Bad color buffer C address: address=0x%x, offset=0x%x, dma=0x%x", address, m_surface_offset_c, m_context_dma_color_c); - return; - } glReadBuffer(GL_COLOR_ATTACHMENT2); checkForGlError("WriteColorBufferC(): glReadBuffer"); @@ -1372,11 +1347,6 @@ void GLGSRender::WriteColorBufferD() } u32 address = GetAddress(m_surface_offset_d, m_context_dma_color_d - 0xfeed0000); - if (!Memory.IsGoodAddr(address)) - { - LOG_ERROR(RSX, "Bad color buffer D address: address=0x%x, offset=0x%x, dma=0x%x", address, m_surface_offset_d, m_context_dma_color_d); - return; - } glReadBuffer(GL_COLOR_ATTACHMENT3); checkForGlError("WriteColorBufferD(): glReadBuffer"); @@ -1682,14 +1652,9 @@ void GLGSRender::InitDrawBuffers() u32 format = GL_BGRA; CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - - if (Memory.IsGoodAddr(addr)) - { - u32 width = buffers[m_gcm_current_buffer].width; - u32 height = buffers[m_gcm_current_buffer].height; - - glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, vm::get_ptr(addr)); - } + u32 width = buffers[m_gcm_current_buffer].width; + u32 height = buffers[m_gcm_current_buffer].height; + glDrawPixels(width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, vm::get_ptr(addr)); } } @@ -2139,17 +2104,9 @@ void GLGSRender::Flip() format = GL_BGRA; CellGcmDisplayInfo* buffers = vm::get_ptr(m_gcm_buffers_addr); u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); - - if (Memory.IsGoodAddr(addr)) - { - width = buffers[m_gcm_current_buffer].width; - height = buffers[m_gcm_current_buffer].height; - src_buffer = vm::get_ptr(addr); - } - else - { - src_buffer = nullptr; - } + width = buffers[m_gcm_current_buffer].width; + height = buffers[m_gcm_current_buffer].height; + src_buffer = vm::get_ptr(addr); } else if (m_fbo.IsCreated()) { diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 45ab4e068d..e302ec5de5 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -261,7 +261,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const if (m_set_semaphore_offset) { m_set_semaphore_offset = false; - vm::write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, ARGS(0)); + vm::write32(m_label_addr + m_semaphore_offset, ARGS(0)); } break; } @@ -274,7 +274,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const u32 value = ARGS(0); value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); - vm::write32(Memory.RSXCMDMem.GetStartAddr() + m_semaphore_offset, value); + vm::write32(m_label_addr + m_semaphore_offset, value); } break; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 75ea01fe78..79bc63a96f 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -134,6 +134,7 @@ public: u32 m_gcm_current_buffer; u32 m_ctxt_addr; u32 m_report_main_addr; + u32 m_label_addr; // DMA u32 dma_report; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 56cd7a7e79..11e7b78220 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -41,8 +41,8 @@ s32 cellAudioInit() g_audio.start_time = get_system_time(); // alloc memory (only once until the emulator is stopped) - g_audio.buffer = g_audio.buffer ? g_audio.buffer : vm::cast(Memory.MainMem.AllocAlign(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, 4096)); - g_audio.indexes = g_audio.indexes ? g_audio.indexes : vm::cast(Memory.MainMem.AllocAlign(sizeof(u64) * AUDIO_PORT_COUNT, __alignof(u64))); + g_audio.buffer = g_audio.buffer ? g_audio.buffer : Memory.MainMem.AllocAlign(AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT, 4096); + g_audio.indexes = g_audio.indexes ? g_audio.indexes : Memory.MainMem.AllocAlign(sizeof(u64) * AUDIO_PORT_COUNT, __alignof(u64)); // clear memory memset(vm::get_ptr(g_audio.buffer), 0, AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 547c1b61ad..2b9ee49ff2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -76,7 +76,7 @@ void InitOffsetTable() u32 cellGcmGetLabelAddress(u8 index) { cellGcmSys->Log("cellGcmGetLabelAddress(index=%d)", index); - return (u32)Memory.RSXCMDMem.GetStartAddr() + 0x10 * index; + return gcm_info.label_addr + 0x10 * index; } vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 location) @@ -360,8 +360,6 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz current_config.memoryFrequency = 650000000; current_config.coreFrequency = 500000000; - Memory.RSXCMDMem.AllocAlign(cmdSize); - u32 ctx_begin = ioAddress/* + 0x1000*/; u32 ctx_size = 0x6ffc; current_context.begin = ctx_begin; @@ -369,9 +367,11 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz current_context.current = current_context.begin; current_context.callback.set(be_t::make(Emu.GetRSXCallback() - 4)); - gcm_info.context_addr = (u32)Memory.MainMem.AllocAlign(0x1000); + gcm_info.context_addr = Memory.MainMem.AllocAlign(0x1000); gcm_info.control_addr = gcm_info.context_addr + 0x40; + gcm_info.label_addr = Memory.MainMem.AllocAlign(0x1000); // ??? + vm::get_ref(gcm_info.context_addr) = current_context; vm::write32(context.addr(), gcm_info.context_addr); @@ -388,6 +388,7 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz render.m_gcm_buffers_count = 0; render.m_gcm_current_buffer = 0; render.m_main_mem_addr = 0; + render.m_label_addr = gcm_info.label_addr; render.Init(ctx_begin, ctx_size, gcm_info.control_addr, local_addr); return CELL_OK; @@ -1109,7 +1110,7 @@ int cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, ctx.addr(), id, label_index, label_value); int res = cellGcmSetPrepareFlip(ctx, id); - vm::write32(Memory.RSXCMDMem.GetStartAddr() + 0x10 * label_index, label_value); + vm::write32(gcm_info.label_addr + 0x10 * label_index, label_value); return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 961e04dde3..37ae8f610c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -41,7 +41,7 @@ u32 ppu_get_tls(u32 thread) if (!g_tls_start) { g_tls_size = Emu.GetTLSMemsz() + TLS_SYS; - g_tls_start = vm::cast(Memory.MainMem.AllocAlign(g_tls_size * TLS_MAX, 4096)); // memory for up to TLS_MAX threads + g_tls_start = Memory.MainMem.AllocAlign(g_tls_size * TLS_MAX, 4096); // memory for up to TLS_MAX threads sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz()); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index 8def286a85..26df83c60d 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -88,7 +88,7 @@ SPUThread* spu_thread_initialize(std::shared_ptr& group, u32 spu_n const u32 spu_ep = img.entry_point; // Copy SPU image: // TODO: use segment info - const u32 spu_offset = vm::cast(Memory.MainMem.AllocAlign(256 * 1024, 4096)); + const u32 spu_offset = Memory.MainMem.AllocAlign(256 * 1024, 4096); memcpy(vm::get_ptr(spu_offset), vm::get_ptr(img.addr), 256 * 1024); SPUThread& new_thread = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_SPU)); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp index ed0615c13b..ab9c5cdcf6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp @@ -27,7 +27,7 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a } // Use fixed address (TODO: search and use some free address instead) - u32 new_addr = Memory.IsGoodAddr(0x60000000) ? 0x70000000 : 0x60000000; + u32 new_addr = vm::check_addr(0x60000000) ? 0x70000000 : 0x60000000; // If container ID is SYS_MEMORY_CONTAINER_ID_INVALID, allocate directly. if(cid == SYS_MEMORY_CONTAINER_ID_INVALID) @@ -45,7 +45,10 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a } // Allocate actual memory using virtual size (physical size is ignored) - assert(Memory.Map(new_addr, vsize)); + if (!Memory.Map(new_addr, vsize)) + { + return CELL_ENOMEM; + } // Write a pointer for the allocated memory. vm::write32(addr, new_addr); diff --git a/rpcs3/Gui/InterpreterDisAsm.cpp b/rpcs3/Gui/InterpreterDisAsm.cpp index b16742f078..2fb7e97fe4 100644 --- a/rpcs3/Gui/InterpreterDisAsm.cpp +++ b/rpcs3/Gui/InterpreterDisAsm.cpp @@ -251,7 +251,7 @@ void InterpreterDisAsmFrame::ShowAddr(const u64 addr) disasm->offset = vm::get_ptr(CPU->GetOffset()); for(uint i=0, count = 4; iGetOffset() + PC, 4)) + if(!vm::check_addr(CPU->GetOffset() + PC, 4)) { m_list->SetItem(i, 0, wxString(IsBreakPoint(PC) ? ">>> " : " ") + wxString::Format("[%08llx] illegal address", PC)); count = 4; diff --git a/rpcs3/Gui/MemoryStringSearcher.cpp b/rpcs3/Gui/MemoryStringSearcher.cpp index 8676d57371..aa823d245e 100644 --- a/rpcs3/Gui/MemoryStringSearcher.cpp +++ b/rpcs3/Gui/MemoryStringSearcher.cpp @@ -45,7 +45,7 @@ void MemoryStringSearcher::Search(wxCommandEvent& event) u32 strIndex = 0; u32 numFound = 0; for (u32 addr = Memory.MainMem.GetStartAddr(); addr < Memory.MainMem.GetEndAddr(); addr++) { - if (!Memory.IsGoodAddr(addr)) { + if (!vm::check_addr(addr)) { strIndex = 0; continue; } diff --git a/rpcs3/Gui/MemoryViewer.cpp b/rpcs3/Gui/MemoryViewer.cpp index 59f3917713..f6455c12d7 100644 --- a/rpcs3/Gui/MemoryViewer.cpp +++ b/rpcs3/Gui/MemoryViewer.cpp @@ -200,7 +200,7 @@ void MemoryViewerPanel::ShowMemory() { u32 addr = m_addr + row * m_colcount + col; - if (Memory.IsGoodAddr(addr)) + if (vm::check_addr(addr)) { const u8 rmem = vm::read8(addr); t_mem_hex_str += wxString::Format("%02x ", rmem); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 4c408b509e..99ce16e0ae 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -259,14 +259,14 @@ void RSXDebugger::OnChangeToolsAddr(wxCommandEvent& event) void RSXDebugger::OnScrollMemory(wxMouseEvent& event) { - if(Memory.IsGoodAddr(m_addr)) + if(vm::check_addr(m_addr)) { int items = event.ControlDown() ? m_item_count : 1; for(int i=0; iGetId()) { u8 location = render.m_textures[m_cur_texture].GetLocation(); - if(location <= 1 && Memory.IsGoodAddr(GetAddress(render.m_textures[m_cur_texture].GetOffset(), location)) + if(location <= 1 && vm::check_addr(GetAddress(render.m_textures[m_cur_texture].GetOffset(), location)) && render.m_textures[m_cur_texture].GetWidth() && render.m_textures[m_cur_texture].GetHeight()) MemoryViewerPanel::ShowImage(this, GetAddress(render.m_textures[m_cur_texture].GetOffset(), location), 1, @@ -380,7 +380,7 @@ void RSXDebugger::GetMemory() { m_list_commands->SetItem(i, 0, wxString::Format("%08x", addr)); - if (isReady && Memory.IsGoodAddr(addr)) + if (isReady && vm::check_addr(addr)) { u32 cmd = vm::read32(addr); u32 count = (cmd >> 18) & 0x7ff; @@ -409,13 +409,13 @@ void RSXDebugger::GetBuffers() // TODO: Currently it only supports color buffers for (u32 bufferId=0; bufferId < render.m_gcm_buffers_count; bufferId++) { - if(!Memory.IsGoodAddr(render.m_gcm_buffers_addr)) + if(!vm::check_addr(render.m_gcm_buffers_addr)) continue; auto buffers = vm::get_ptr(render.m_gcm_buffers_addr); u32 RSXbuffer_addr = render.m_local_mem_addr + buffers[bufferId].offset; - if(!Memory.IsGoodAddr(RSXbuffer_addr)) + if(!vm::check_addr(RSXbuffer_addr)) continue; auto RSXbuffer = vm::get_ptr(RSXbuffer_addr); @@ -467,7 +467,7 @@ void RSXDebugger::GetBuffers() u32 TexBuffer_addr = GetAddress(offset, location); - if(!Memory.IsGoodAddr(TexBuffer_addr)) + if(!vm::check_addr(TexBuffer_addr)) return; unsigned char* TexBuffer = vm::get_ptr(TexBuffer_addr); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index ac64afc207..a83883484c 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -101,7 +101,7 @@ namespace loader segment.size = phdr.p_memsz; segment.size_file = phdr.p_filesz; - segment.begin.set(vm::alloc(segment.size, vm::sprx)); + segment.begin.set(vm::alloc(segment.size, vm::main)); if (!segment.begin) { From ba83767706c146dfdb5b0ff0e4dff6645eb09100 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 13 Feb 2015 18:26:42 +0300 Subject: [PATCH 04/25] Small fix --- rpcs3/Emu/Memory/Memory.cpp | 2 +- rpcs3/Emu/Memory/Memory.h | 5 ----- rpcs3/Emu/Memory/vm.cpp | 35 +++++++++++++++-------------------- rpcs3/Emu/Memory/vm.h | 10 +++------- 4 files changed, 19 insertions(+), 33 deletions(-) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index f5904b2c28..cf7187cf9f 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -48,7 +48,7 @@ void MemoryBase::Init(MemoryType type) memset(RawSPUMem, 0, sizeof(RawSPUMem)); - LOG_NOTICE(MEMORY, "Initializing memory: base_addr = 0x%llx, priv_addr = 0x%llx", (u64)vm::g_base_addr, (u64)vm::g_priv_addr); + LOG_NOTICE(MEMORY, "Initializing memory: g_base_addr = 0x%llx, g_priv_addr = 0x%llx", (u64)vm::g_base_addr, (u64)vm::g_priv_addr); #ifdef _WIN32 if (!vm::g_base_addr || !vm::g_priv_addr) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index a6e6edbf94..07151118ab 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -22,11 +22,6 @@ enum : u32 RAW_SPU_PROB_OFFSET = 0x00040000, }; -namespace vm -{ - extern void* const g_base_addr; -} - class MemoryBase { std::vector MemoryBlocks; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 188f0f373e..20b127ef19 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -25,35 +25,32 @@ namespace vm { -#ifdef _WIN32 - HANDLE g_memory_handle; -#endif - - void* g_priv_addr; - void* initialize() { #ifdef _WIN32 - g_memory_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0x1, 0x0, NULL); + HANDLE memory_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE | SEC_RESERVE, 0x1, 0x0, NULL); - void* base_addr = MapViewOfFile(g_memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000); // main memory - g_priv_addr = MapViewOfFile(g_memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000); // memory mirror for privileged access + void* base_addr = MapViewOfFile(memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000); + g_priv_addr = MapViewOfFile(memory_handle, FILE_MAP_WRITE, 0, 0, 0x100000000); + + CloseHandle(memory_handle); return base_addr; - - //return VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); #else - //shm_unlink("/rpcs3_vm"); - int memory_handle = shm_open("/rpcs3_vm", O_RDWR | O_CREAT | O_EXCL, 0); if (memory_handle == -1) { - printf("shm_open() failed\n"); + printf("shm_open('/rpcs3_vm') failed\n"); return (void*)-1; } - ftruncate(memory_handle, 0x100000000); + if (ftruncate(memory_handle, 0x100000000) == -1) + { + printf("ftruncate(memory_handle) failed\n"); + shm_unlink("/rpcs3_vm"); + return (void*)-1; + } void* base_addr = mmap(nullptr, 0x100000000, PROT_NONE, MAP_SHARED, memory_handle, 0); g_priv_addr = mmap(nullptr, 0x100000000, PROT_NONE, MAP_SHARED, memory_handle, 0); @@ -61,8 +58,6 @@ namespace vm shm_unlink("/rpcs3_vm"); return base_addr; - - //return mmap(nullptr, 0x100000000, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); #endif } @@ -71,14 +66,14 @@ namespace vm #ifdef _WIN32 UnmapViewOfFile(g_base_addr); UnmapViewOfFile(g_priv_addr); - CloseHandle(g_memory_handle); #else munmap(g_base_addr, 0x100000000); munmap(g_priv_addr, 0x100000000); #endif } - void* const g_base_addr = (atexit(finalize), initialize()); + void* g_base_addr = (atexit(finalize), initialize()); + void* g_priv_addr; std::array, 0x100000000ull / 4096> g_page_info = {}; // information about every page @@ -628,7 +623,7 @@ namespace vm { PPUThread& PPU = static_cast(CPU); - old_pos = (u32)PPU.GPR[1]; + old_pos = vm::cast(PPU.GPR[1], "SP"); PPU.GPR[1] -= align(size, 8); // room minimal possible size PPU.GPR[1] &= ~(align_v - 1); // fix stack alignment diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 5e07706646..b3b9cab231 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -5,6 +5,9 @@ class CPUThread; namespace vm { + extern void* g_base_addr; // base address of ps3/psv virtual memory for common access + extern void* g_priv_addr; // base address of ps3/psv virtual memory for privileged access + enum memory_location : uint { main, @@ -29,13 +32,6 @@ namespace vm static void set_stack_size(u32 size) {} static void initialize_stack() {} -#ifdef _WIN32 - extern HANDLE g_memory_handle; -#endif - - extern void* g_priv_addr; - extern void* const g_base_addr; - // break the reservation, return true if it was successfully broken bool reservation_break(u32 addr); // read memory and reserve it for further atomic update, return true if the previous reservation was broken From 0d489518abaf69254de268ec4e9a2e864da4c2b0 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 13 Feb 2015 23:24:18 +0300 Subject: [PATCH 05/25] Compilation fix --- Utilities/StrFmt.h | 4 ++ Utilities/Thread.cpp | 84 +++++++++++++++++++------------------- rpcs3/Emu/Cell/PPUThread.h | 2 + rpcs3/Emu/Memory/vm.h | 28 +++++++------ 4 files changed, 64 insertions(+), 54 deletions(-) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index e9c7c23334..1272b68aa8 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -263,6 +263,7 @@ namespace fmt } }; +#ifdef __APPLE__ template<> struct get_fmt { @@ -286,6 +287,7 @@ namespace fmt } } }; +#endif template<> struct get_fmt @@ -383,6 +385,7 @@ namespace fmt } }; +#ifdef __APPLE__ template<> struct get_fmt { @@ -406,6 +409,7 @@ namespace fmt } } }; +#endif template<> struct get_fmt diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index faa0b1b04e..24eb061d1e 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -210,49 +210,50 @@ typedef ucontext_t x64_context; uint64_t* darwin_x64reg(x64_context *context, int reg) { - auto *state = &context->uc_mcontext->__ss; - switch(reg) - { - case 0: // RAX - return &state->__rax; - case 1: // RCX - return &state->__rcx; - case 2: // RDX - return &state->__rdx; - case 3: // RBX - return &state->__rbx; - case 4: // RSP - return &state->__rsp; - case 5: // RBP - return &state->__rbp; - case 6: // RSI - return &state->__rsi; - case 7: // RDI - return &state->__rdi; - case 8: // R8 - return &state->__r8; - case 9: // R9 - return &state->__r9; - case 10: // R10 - return &state->__r10; - case 11: // R11 - return &state->__r11; - case 12: // R12 - return &state->__r12; - case 13: // R13 - return &state->__r13; - case 14: // R14 - return &state->__r14; - case 15: // R15 - return &state->__r15; - case 16: // RIP - return &state->__rip; - default: // FAIL - assert(0); - } + auto *state = &context->uc_mcontext->__ss; + switch(reg) + { + case 0: // RAX + return &state->__rax; + case 1: // RCX + return &state->__rcx; + case 2: // RDX + return &state->__rdx; + case 3: // RBX + return &state->__rbx; + case 4: // RSP + return &state->__rsp; + case 5: // RBP + return &state->__rbp; + case 6: // RSI + return &state->__rsi; + case 7: // RDI + return &state->__rdi; + case 8: // R8 + return &state->__r8; + case 9: // R9 + return &state->__r9; + case 10: // R10 + return &state->__r10; + case 11: // R11 + return &state->__r11; + case 12: // R12 + return &state->__r12; + case 13: // R13 + return &state->__r13; + case 14: // R14 + return &state->__r14; + case 15: // R15 + return &state->__r15; + case 16: // RIP + return &state->__rip; + default: // FAIL + assert(0); + } } #else + typedef decltype(REG_RIP) reg_table_t; static const reg_table_t reg_table[17] = @@ -262,6 +263,7 @@ static const reg_table_t reg_table[17] = }; #define X64REG(context, reg) (&context->uc_mcontext.gregs[reg_table[reg]]) + #endif // __APPLE__ #endif @@ -379,7 +381,7 @@ void signal_handler(int sig, siginfo_t* info, void* uct) const u64 addr64 = (u64)info->si_addr - (u64)vm::g_base_addr; #ifdef __APPLE__ - const bool is_writing = ((ucontext_t*)uct)->uc_mcontext->__es.__err & 0x2; + const bool is_writing = ((ucontext_t*)uct)->uc_mcontext->__es.__err & 0x2; #else const bool is_writing = ((ucontext_t*)uct)->uc_mcontext.gregs[REG_ERR] & 0x2; #endif diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 1c32cd7e3e..88f1cb392c 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -887,6 +887,7 @@ struct cast_ppu_gpr } }; +#ifdef __APPLE__ template<> struct cast_ppu_gpr { @@ -900,6 +901,7 @@ struct cast_ppu_gpr return static_cast(reg); } }; +#endif template<> struct cast_ppu_gpr diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index e94df66533..5f1d5a4338 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -100,20 +100,22 @@ namespace vm } }; - template<> - struct cast_ptr - { - __forceinline static u32 cast(const unsigned long addr, const char* func) - { - const u32 res = static_cast(addr); - if (res != addr) - { - vm::error(addr, func); - } +#ifdef __APPLE__ + template<> + struct cast_ptr + { + __forceinline static u32 cast(const unsigned long addr, const char* func) + { + const u32 res = static_cast(addr); + if (res != addr) + { + vm::error(addr, func); + } - return res; - } - }; + return res; + } + }; +#endif template<> struct cast_ptr From f01059283a54c18b904251ad97ee368f1b90c0d1 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 14 Feb 2015 00:45:36 +0300 Subject: [PATCH 06/25] Some cleanup --- Utilities/Thread.cpp | 2 + rpcs3/Emu/Cell/PPUInterpreter.h | 2 +- rpcs3/Emu/Cell/SPUThread.cpp | 6 +- rpcs3/Emu/Memory/Memory.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 158 +++++++++++----------- rpcs3/Emu/SysCalls/Modules/cellGcmSys.h | 17 +-- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 10 +- 8 files changed, 93 insertions(+), 110 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 24eb061d1e..926d49f8bd 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -9,8 +9,10 @@ #ifdef _WIN32 #include #else +#ifdef __APPLE__ #define _XOPEN_SOURCE #define __USE_GNU +#endif #include #include #endif diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 83a0101e6d..fdb7cc5250 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2504,7 +2504,7 @@ private: } void LWARX(u32 rd, u32 ra, u32 rb) { - const u32 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; + const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; be_t value; vm::reservation_acquire(&value, vm::cast(addr), sizeof(value)); diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 4c38ac24fd..e8a2a2ee18 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -437,7 +437,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) { //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - vm::reservation_acquire(vm::get_ptr(ls_offset + lsa), ea, 128, [this]() + vm::reservation_acquire(vm::get_ptr(ls_offset + lsa), vm::cast(ea), 128, [this]() { //std::shared_ptr t = Emu.GetCPU().GetThread(tid); @@ -457,7 +457,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) } else if (op == MFC_PUTLLC_CMD) // store conditional { - if (vm::reservation_update(ea, vm::get_ptr(ls_offset + lsa), 128)) + if (vm::reservation_update(vm::cast(ea), vm::get_ptr(ls_offset + lsa), 128)) { MFCArgs.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); } @@ -468,7 +468,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) } else // store unconditional (may be wrong) { - vm::reservation_op(ea, 128, [this, tag, lsa, ea]() + vm::reservation_op(vm::cast(ea), 128, [this, tag, lsa, ea]() { memcpy(vm::get_priv_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), 128); }); diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index cf7187cf9f..64e50ae1ed 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -359,7 +359,7 @@ u32 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) addr = (addr + (align - 1)) & ~(align - 1); } - //LOG_NOTICE(MEMORY, "AllocAlign(size=0x%x) -> 0x%llx", size, addr); + //LOG_NOTICE(MEMORY, "AllocAlign(size=0x%x) -> 0x%x", size, addr); AppendMem(addr, size); @@ -382,7 +382,7 @@ bool DynamicMemoryBlockBase::Free(u32 addr) { if (addr == m_allocated[num].addr) { - //LOG_NOTICE(MEMORY, "Free(0x%llx)", addr); + //LOG_NOTICE(MEMORY, "Free(0x%x)", addr); m_allocated.erase(m_allocated.begin() + num); return true; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 2b9ee49ff2..d8fc27a97d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -115,7 +115,7 @@ u64 cellGcmGetTimeStamp(u32 index) return vm::read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10); } -int cellGcmGetCurrentField() +s32 cellGcmGetCurrentField() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -226,13 +226,13 @@ u32 cellGcmGetDefaultSegmentWordSize() return 0x100; } -int cellGcmInitDefaultFifoMode(s32 mode) +s32 cellGcmInitDefaultFifoMode(s32 mode) { cellGcmSys->Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode); return CELL_OK; } -int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) +s32 cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) { cellGcmSys->Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize); return CELL_OK; @@ -242,7 +242,7 @@ int cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) // Hardware Resource Management //---------------------------------------------------------------------------- -int cellGcmBindTile(u8 index) +s32 cellGcmBindTile(u8 index) { cellGcmSys->Warning("cellGcmBindTile(index=%d)", index); @@ -258,7 +258,7 @@ int cellGcmBindTile(u8 index) return CELL_OK; } -int cellGcmBindZcull(u8 index) +s32 cellGcmBindZcull(u8 index) { cellGcmSys->Warning("cellGcmBindZcull(index=%d)", index); @@ -274,7 +274,7 @@ int cellGcmBindZcull(u8 index) return CELL_OK; } -int cellGcmGetConfiguration(vm::ptr config) +s32 cellGcmGetConfiguration(vm::ptr config) { cellGcmSys->Log("cellGcmGetConfiguration(config_addr=0x%x)", config.addr()); @@ -283,9 +283,9 @@ int cellGcmGetConfiguration(vm::ptr config) return CELL_OK; } -int cellGcmGetFlipStatus() +s32 cellGcmGetFlipStatus() { - int status = Emu.GetGSManager().GetRender().m_flip_status; + s32 status = Emu.GetGSManager().GetRender().m_flip_status; cellGcmSys->Log("cellGcmGetFlipStatus() -> %d", status); @@ -345,7 +345,7 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz Memory.RSXIOMem.SetRange(0, 0x10000000 /*256MB*/); } - if(cellGcmMapEaIoAddress(ioAddress, 0, ioSize) != CELL_OK) + if (gcmMapEaIoAddress(ioAddress, 0, ioSize, false) != CELL_OK) { cellGcmSys->Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; @@ -394,7 +394,7 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz return CELL_OK; } -int cellGcmResetFlipStatus() +s32 cellGcmResetFlipStatus() { cellGcmSys->Log("cellGcmResetFlipStatus()"); @@ -403,7 +403,7 @@ int cellGcmResetFlipStatus() return CELL_OK; } -int cellGcmSetDebugOutputLevel(int level) +s32 cellGcmSetDebugOutputLevel(s32 level) { cellGcmSys->Warning("cellGcmSetDebugOutputLevel(level=%d)", level); @@ -421,7 +421,7 @@ int cellGcmSetDebugOutputLevel(int level) return CELL_OK; } -int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height) +s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height) { cellGcmSys->Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)", id, offset, width ? pitch / width : pitch, width, height); @@ -444,14 +444,6 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height return CELL_OK; } -int cellGcmSetFlip(vm::ptr ctxt, u32 id) -{ - cellGcmSys->Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); - - int res = cellGcmSetPrepareFlip(ctxt, id); - return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; -} - void cellGcmSetFlipHandler(vm::ptr handler) { cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler.addr()); @@ -459,7 +451,7 @@ void cellGcmSetFlipHandler(vm::ptr handler) Emu.GetGSManager().GetRender().m_flip_handler = handler; } -int cellGcmSetFlipMode(u32 mode) +s32 cellGcmSetFlipMode(u32 mode) { cellGcmSys->Warning("cellGcmSetFlipMode(mode=%d)", mode); @@ -532,7 +524,15 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) return id; } -int cellGcmSetSecondVFrequency(u32 freq) +s32 cellGcmSetFlip(vm::ptr ctxt, u32 id) +{ + cellGcmSys->Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); + + s32 res = cellGcmSetPrepareFlip(ctxt, id); + return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; +} + +s32 cellGcmSetSecondVFrequency(u32 freq) { cellGcmSys->Warning("cellGcmSetSecondVFrequency(level=%d)", freq); @@ -550,7 +550,7 @@ int cellGcmSetSecondVFrequency(u32 freq) return CELL_OK; } -int cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) +s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) { cellGcmSys->Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); @@ -605,7 +605,7 @@ void cellGcmSetVBlankHandler(vm::ptr handler) Emu.GetGSManager().GetRender().m_vblank_handler = handler; } -int cellGcmSetWaitFlip(vm::ptr ctxt) +s32 cellGcmSetWaitFlip(vm::ptr ctxt) { cellGcmSys->Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.addr()); @@ -613,7 +613,7 @@ int cellGcmSetWaitFlip(vm::ptr ctxt) return CELL_OK; } -int cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask) +s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask) { cellGcmSys->Todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask); @@ -641,7 +641,7 @@ int cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, return CELL_OK; } -int cellGcmUnbindTile(u8 index) +s32 cellGcmUnbindTile(u8 index) { cellGcmSys->Warning("cellGcmUnbindTile(index=%d)", index); @@ -657,7 +657,7 @@ int cellGcmUnbindTile(u8 index) return CELL_OK; } -int cellGcmUnbindZcull(u8 index) +s32 cellGcmUnbindZcull(u8 index) { cellGcmSys->Warning("cellGcmUnbindZcull(index=%d)", index); @@ -691,7 +691,7 @@ u32 cellGcmGetDisplayInfo() return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; } -int cellGcmGetCurrentDisplayBufferId(u32 id_addr) +s32 cellGcmGetCurrentDisplayBufferId(u32 id_addr) { cellGcmSys->Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); @@ -700,19 +700,19 @@ int cellGcmGetCurrentDisplayBufferId(u32 id_addr) return CELL_OK; } -int cellGcmSetInvalidateTile() +s32 cellGcmSetInvalidateTile() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmDumpGraphicsError() +s32 cellGcmDumpGraphicsError() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmGetDisplayBufferByFlipIndex() +s32 cellGcmGetDisplayBufferByFlipIndex() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -725,7 +725,7 @@ u64 cellGcmGetLastFlipTime() return Emu.GetGSManager().GetRender().m_last_flip_time; } -int cellGcmGetLastSecondVTime() +s32 cellGcmGetLastSecondVTime() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -738,7 +738,7 @@ u64 cellGcmGetVBlankCount() return Emu.GetGSManager().GetRender().m_vblank_count; } -int cellGcmInitSystemMode(u64 mode) +s32 cellGcmInitSystemMode(u64 mode) { cellGcmSys->Log("cellGcmInitSystemMode(mode=0x%x)", mode); @@ -747,7 +747,7 @@ int cellGcmInitSystemMode(u64 mode) return CELL_OK; } -int cellGcmSetFlipImmediate(u8 id) +s32 cellGcmSetFlipImmediate(u8 id) { cellGcmSys->Todo("cellGcmSetFlipImmediate(fid=0x%x)", id); @@ -762,31 +762,31 @@ int cellGcmSetFlipImmediate(u8 id) return CELL_OK; } -int cellGcmSetGraphicsHandler() +s32 cellGcmSetGraphicsHandler() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetQueueHandler() +s32 cellGcmSetQueueHandler() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetSecondVHandler() +s32 cellGcmSetSecondVHandler() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetVBlankFrequency() +s32 cellGcmSetVBlankFrequency() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSortRemapEaIoAddress() +s32 cellGcmSortRemapEaIoAddress() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -795,31 +795,35 @@ int cellGcmSortRemapEaIoAddress() //---------------------------------------------------------------------------- // Memory Mapping //---------------------------------------------------------------------------- -s32 cellGcmAddressToOffset(u64 address, vm::ptr> offset) +s32 cellGcmAddressToOffset(u32 address, vm::ptr> offset) { cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr()); // Address not on main memory or local memory - if (address >= 0xD0000000) { + if (address >= 0xD0000000) + { return CELL_GCM_ERROR_FAILURE; } u32 result; // Address in local memory - if (Memory.RSXFBMem.IsInMyRange(address)) { - result = (u32)(address - Memory.RSXFBMem.GetStartAddr()); + if (Memory.RSXFBMem.IsInMyRange(address)) + { + result = address - Memory.RSXFBMem.GetStartAddr(); } // Address in main memory else check else { - u16 upper12Bits = offsetTable.ioAddress[address >> 20]; + const u32 upper12Bits = offsetTable.ioAddress[address >> 20]; // If the address is mapped in IO - if (upper12Bits != 0xFFFF) { - result = ((u64)upper12Bits << 20) | (address & 0xFFFFF); + if (upper12Bits != 0xFFFF) + { + result = (upper12Bits << 20) | (address & 0xFFFFF); } - else { + else + { return CELL_GCM_ERROR_FAILURE; } } @@ -845,7 +849,7 @@ void cellGcmGetOffsetTable(vm::ptr table) s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr address) { - cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%llx)", ioOffset, address); + cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%x)", ioOffset, address); u32 realAddr; @@ -897,17 +901,14 @@ s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) return gcmMapEaIoAddress(ea, io, size, true); } -s32 cellGcmMapLocalMemory(u64 address, u64 size) +s32 cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) { - cellGcmSys->Warning("cellGcmMapLocalMemory(address=0x%llx, size=0x%llx)", address, size); + cellGcmSys->Warning("cellGcmMapLocalMemory(address=*0x%x, size=*0x%x)", address, size); - if (!local_size && !local_addr) + if (!local_addr && !local_size && Memory.RSXFBMem.AllocFixed(local_addr = Memory.RSXFBMem.GetStartAddr(), local_size = 0xf900000 /* TODO */)) { - local_size = 0xf900000; //TODO - local_addr = (u32)Memory.RSXFBMem.GetStartAddr(); - Memory.RSXFBMem.AllocAlign(local_size); - vm::write32(address, local_addr); - vm::write32(size, local_size); + *address = local_addr; + *size = local_size; } else { @@ -970,18 +971,16 @@ s32 cellGcmReserveIoMapSize(u32 size) return CELL_OK; } -s32 cellGcmUnmapEaIoAddress(u64 ea) +s32 cellGcmUnmapEaIoAddress(u32 ea) { - cellGcmSys->Log("cellGcmUnmapEaIoAddress(ea=0x%llx)", ea); + cellGcmSys->Log("cellGcmUnmapEaIoAddress(ea=0x%x)", ea); u32 size; if (Memory.RSXIOMem.UnmapRealAddress(ea, size)) { - u64 io; - ea = ea >> 20; - io = offsetTable.ioAddress[ea]; + const u32 io = offsetTable.ioAddress[ea >>= 20]; - for (u32 i = 0; i> 20; i++) { offsetTable.ioAddress[ea + i] = 0xFFFF; offsetTable.eaAddress[io + i] = 0xFFFF; @@ -989,26 +988,23 @@ s32 cellGcmUnmapEaIoAddress(u64 ea) } else { - cellGcmSys->Error("cellGcmUnmapEaIoAddress : CELL_GCM_ERROR_FAILURE"); + cellGcmSys->Error("cellGcmUnmapEaIoAddress(ea=0x%x): UnmapRealAddress() failed"); return CELL_GCM_ERROR_FAILURE; } return CELL_OK; } -s32 cellGcmUnmapIoAddress(u64 io) +s32 cellGcmUnmapIoAddress(u32 io) { - cellGcmSys->Log("cellGcmUnmapIoAddress(io=0x%llx)", io); + cellGcmSys->Log("cellGcmUnmapIoAddress(io=0x%x)", io); u32 size; if (Memory.RSXIOMem.UnmapAddress(io, size)) { - u64 ea; - io = io >> 20; - size = size >> 20; - ea = offsetTable.eaAddress[io]; + const u32 ea = offsetTable.eaAddress[io >>= 20]; - for (u32 i = 0; i> 20; i++) { offsetTable.ioAddress[ea + i] = 0xFFFF; offsetTable.eaAddress[io + i] = 0xFFFF; @@ -1016,7 +1012,7 @@ s32 cellGcmUnmapIoAddress(u64 io) } else { - cellGcmSys->Error("cellGcmUnmapIoAddress : CELL_GCM_ERROR_FAILURE"); + cellGcmSys->Error("cellGcmUnmapIoAddress(io=0x%x): UnmapAddress() failed"); return CELL_GCM_ERROR_FAILURE; } @@ -1047,37 +1043,37 @@ s32 cellGcmUnreserveIoMapSize(u32 size) // Cursor //---------------------------------------------------------------------------- -int cellGcmInitCursor() +s32 cellGcmInitCursor() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetCursorPosition(s32 x, s32 y) +s32 cellGcmSetCursorPosition(s32 x, s32 y) { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetCursorDisable() +s32 cellGcmSetCursorDisable() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmUpdateCursor() +s32 cellGcmUpdateCursor() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetCursorEnable() +s32 cellGcmSetCursorEnable() { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; } -int cellGcmSetCursorImageOffset(u32 offset) +s32 cellGcmSetCursorImageOffset(u32 offset) { UNIMPLEMENTED_FUNC(cellGcmSys); return CELL_OK; @@ -1097,24 +1093,24 @@ void cellGcmSetDefaultCommandBuffer() // Other //------------------------------------------------------------------------ -int cellGcmSetFlipCommand(vm::ptr ctx, u32 id) +s32 cellGcmSetFlipCommand(vm::ptr ctx, u32 id) { cellGcmSys->Log("cellGcmSetFlipCommand(ctx_addr=0x%x, id=0x%x)", ctx.addr(), id); return cellGcmSetPrepareFlip(ctx, id); } -int cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, u32 label_index, u32 label_value) +s32 cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, u32 label_index, u32 label_value) { cellGcmSys->Log("cellGcmSetFlipCommandWithWaitLabel(ctx_addr=0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx.addr(), id, label_index, label_value); - int res = cellGcmSetPrepareFlip(ctx, id); + s32 res = cellGcmSetPrepareFlip(ctx, id); vm::write32(gcm_info.label_addr + 0x10 * label_index, label_value); return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; } -int cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) +s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) { cellGcmSys->Warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h index b7fad1b62f..82c53937f8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h @@ -18,22 +18,7 @@ struct CellGcmOffsetTable }; // Auxiliary functions -void InitOffsetTable(); -u32 gcmGetLocalMemorySize(); - -// libgcm functions -s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id); - -s32 cellGcmAddressToOffset(u64 address, vm::ptr> offset); -u32 cellGcmGetMaxIoMapSize(); -void cellGcmGetOffsetTable(vm::ptr table); -s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size); -s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags); -s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset); -s32 cellGcmReserveIoMapSize(u32 size); -s32 cellGcmUnmapEaIoAddress(u64 ea); -s32 cellGcmUnmapIoAddress(u64 io); -s32 cellGcmUnreserveIoMapSize(u32 size); +s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict); // Syscall s32 cellGcmCallback(vm::ptr context, u32 count); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index d509f4f6c7..eff513f66c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -376,7 +376,7 @@ s64 cellPngDecCreate(vm::ptr mainHandle, vm::ptrpngCodecVersion = PNGDEC_CODEC_VERSION; @@ -400,7 +400,7 @@ s64 cellPngDecExtCreate( mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr()); // create decoder - if (s32 res = pngDecCreate(mainHandle, threadInParam, extThreadInParam)) return res; + if (auto res = pngDecCreate(mainHandle, threadInParam, extThreadInParam)) return res; // set codec version threadOutParam->pngCodecVersion = PNGDEC_CODEC_VERSION; diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index d10da00a1f..ed9bbfbb85 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -11,13 +11,13 @@ Module *cellResc = nullptr; extern s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent); -extern int cellGcmSetFlipMode(u32 mode); +extern s32 cellGcmSetFlipMode(u32 mode); extern void cellGcmSetFlipHandler(vm::ptr handler); extern void cellGcmSetVBlankHandler(vm::ptr handler); -extern int cellGcmAddressToOffset(u64 address, vm::ptr> offset); -extern int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); -extern int cellGcmSetPrepareFlip(vm::ptr ctx, u32 id); -extern int cellGcmSetSecondVFrequency(u32 freq); +extern s32 cellGcmAddressToOffset(u32 address, vm::ptr> offset); +extern s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height); +extern s32 cellGcmSetPrepareFlip(vm::ptr ctx, u32 id); +extern s32 cellGcmSetSecondVFrequency(u32 freq); extern u32 cellGcmGetLabelAddress(u8 index); extern u32 cellGcmGetTiledPitchSize(u32 size); From 6909a1540028d1b594038db1f3e0cdf8dd81953b Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 15 Feb 2015 15:31:42 +0300 Subject: [PATCH 07/25] decode_x64_reg_op improved --- Utilities/Thread.cpp | 407 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 330 insertions(+), 77 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 926d49f8bd..2b447eeeab 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -51,52 +51,124 @@ void SetCurrentThreadDebugName(const char* threadName) enum x64_reg_t : u32 { - X64R_EAX, - X64R_ECX, - X64R_EDX, - X64R_EBX, - X64R_ESP, - X64R_EBP, - X64R_ESI, - X64R_EDI, - X64R_R8D, - X64R_R9D, - X64R_R10D, - X64R_R11D, - X64R_R12D, - X64R_R13D, - X64R_R14D, - X64R_R15D, - X64R32 = X64R_EAX, + X64R_RAX, + X64R_RCX, + X64R_RDX, + X64R_RBX, + X64R_RSP, + X64R_RBP, + X64R_RSI, + X64R_RDI, + X64R_R8, + X64R_R9, + X64R_R10, + X64R_R11, + X64R_R12, + X64R_R13, + X64R_R14, + X64R_R15, + X64R_XMM0, + X64R_XMM1, + X64R_XMM2, + X64R_XMM3, + X64R_XMM4, + X64R_XMM5, + X64R_XMM6, + X64R_XMM7, + X64R_XMM8, + X64R_XMM9, + X64R_XMM10, + X64R_XMM11, + X64R_XMM12, + X64R_XMM13, + X64R_XMM14, + X64R_XMM15, + + X64R_AL, + X64R_CL, + X64R_DL, + X64R_BL, + X64R_AH, + X64R_CH, + X64R_DH, + X64R_BH, + + X64_NOT_SET, + X64_IMM8, + X64_IMM16, X64_IMM32, + + X64R = X64R_RAX, + X64R_XMM = X64R_XMM0, + X64R_LH = X64R_AL, + X64R_ECX = X64R_CL, }; enum x64_op_t : u32 { + X64OP_NOP, X64OP_LOAD, // obtain and put the value into x64 register (from Memory.ReadMMIO32, for example) X64OP_STORE, // take the value from x64 register or an immediate and use it (pass in Memory.WriteMMIO32, for example) // example: add eax,[rax] -> X64OP_LOAD_ADD (add the value to x64 register) // example: add [rax],eax -> X64OP_LOAD_ADD_STORE (this will probably never happen for MMIO registers) + + X64OP_MOVS, + X64OP_XCHG, + X64OP_CMPXCHG, }; -void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_reg, size_t& decoded_size) +void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32& out_size, u32& out_length) { // simple analysis of x64 code allows to reinterpret MOV or other instructions in any desired way - decoded_size = 0; + out_length = 0; - u8 rex = 0; - u8 reg = 0; // set to 8 by REX prefix - u8 pg2 = 0; + u8 rex = 0, pg2 = 0; + + bool oso = false, lock = false, repne = false, repe = false; + + enum : u8 + { + LOCK = 0xf0, + REPNE = 0xf2, + REPE = 0xf3, + }; // check prefixes: - for (;; code++, decoded_size++) + for (;; code++, out_length++) { switch (const u8 prefix = *code) { - case 0xf0: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (LOCK prefix) found", (size_t)code - decoded_size, prefix); // group 1 - case 0xf2: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REPNE/REPNZ prefix) found", (size_t)code - decoded_size, prefix); // group 1 - case 0xf3: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REP/REPE/REPZ prefix) found", (size_t)code - decoded_size, prefix); // group 1 + case LOCK: // group 1 + { + if (lock) + { + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): LOCK prefix found twice", (size_t)code - out_length); + } + + lock = true; + continue; + } + case REPNE: // group 1 + { + if (repne) + { + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", (size_t)code - out_length); + } + + repne = true; + continue; + } + case REPE: // group 1 + { + if (repe) + { + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", (size_t)code - out_length); + } + + repe = true; + continue; + } case 0x2e: // group 2 case 0x36: @@ -105,19 +177,37 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_ case 0x64: case 0x65: { - if (!pg2) + if (pg2) { - pg2 = prefix; // probably, segment register - continue; + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", (size_t)code - out_length, prefix, pg2); } else { - throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", (size_t)code - decoded_size, prefix, pg2); + pg2 = prefix; // probably, segment register } + continue; } - case 0x66: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (operand-size override prefix) found", (size_t)code - decoded_size, prefix); // group 3 - case 0x67: throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (address-size override prefix) found", (size_t)code - decoded_size, prefix); // group 4 + case 0x66: // group 3 + { + if (oso) + { + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): operand-size override prefix found twice", (size_t)code - out_length); + } + + oso = true; + continue; + } + + case 0x67: // group 4 + { + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): address-size override prefix found", (size_t)code - out_length, prefix); + out_op = X64OP_NOP; + out_reg = X64_NOT_SET; + out_size = 0; + out_length = 0; + return; + } default: { @@ -125,17 +215,12 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_ { if (rex) { - throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", (size_t)code - decoded_size, prefix, rex); + LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", (size_t)code - out_length, prefix, rex); } - if (prefix & 0x80) // check REX.W bit + else { - throw fmt::format("decode_x64_reg_op(%016llxh): 0x%02x (REX.W bit) found", (size_t)code - decoded_size, prefix); + rex = prefix; } - if (prefix & 0x04) // check REX.R bit - { - reg = 8; - } - rex = prefix; continue; } } @@ -144,12 +229,27 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_ break; } - auto get_modRM_r32 = [](const u8* code, const u8 reg_base) -> x64_reg_t + auto get_modRM_reg = [](const u8* code, const u8 rex) -> x64_reg_t { - return (x64_reg_t)((((*code & 0x38) >> 3) | reg_base) + X64R32); + return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R); }; - auto get_modRM_size = [](const u8* code) -> size_t + auto get_modRM_reg_xmm = [](const u8* code, const u8 rex) -> x64_reg_t + { + return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R_XMM); + }; + + auto get_modRM_reg_lh = [](const u8* code) -> x64_reg_t + { + return (x64_reg_t)(((*code & 0x38) >> 3) + X64R_LH); + }; + + auto get_op_size = [](const u8 rex, const bool oso) -> u32 + { + return rex & 8 ? 8 : (oso ? 2 : 4); + }; + + auto get_modRM_size = [](const u8* code) -> u32 { switch (*code >> 6) // check Mod { @@ -160,38 +260,177 @@ void decode_x64_reg_op(const u8* code, x64_op_t& decoded_op, x64_reg_t& decoded_ } }; - decoded_size++; - switch (const u8 op1 = *code++) + const u8 op1 = (out_length++, *code++), op2 = code[0], op3 = code[1]; + + switch (op1) { - case 0x89: // MOV r/m32, r32 + case 0x0f: { - decoded_op = X64OP_STORE; - decoded_reg = get_modRM_r32(code, reg); - decoded_size += get_modRM_size(code); - return; + out_length++, code++; + + switch (op2) + { + case 0x7f: + { + if (repe && !oso) // MOVDQU xmm/m, xmm + { + out_op = X64OP_STORE; + out_reg = get_modRM_reg_xmm(code, rex); + out_size = 16; + out_length += get_modRM_size(code); + return; + } + break; + } + case 0xb0: + { + if (!oso) // CMPXCHG r8/m8, r8 + { + out_op = X64OP_CMPXCHG; + out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code); + out_size = 1; + out_length += get_modRM_size(code); + return; + } + break; + } + case 0xb1: + { + if (true) // CMPXCHG r/m, r (16, 32, 64) + { + out_op = X64OP_CMPXCHG; + out_reg = get_modRM_reg(code, rex); + out_size = get_op_size(rex, oso); + out_length += get_modRM_size(code); + return; + } + break; + } + } + + break; } - case 0x8b: // MOV r32, r/m32 + case 0x86: { - decoded_op = X64OP_LOAD; - decoded_reg = get_modRM_r32(code, reg); - decoded_size += get_modRM_size(code); - return; + if (!oso) // XCHG r8/m8, r8 + { + out_op = X64OP_XCHG; + out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code); + out_size = 1; + out_length += get_modRM_size(code); + return; + } + break; + } + case 0x87: + { + if (true) // XCHG r/m, r (16, 32, 64) + { + out_op = X64OP_XCHG; + out_reg = get_modRM_reg(code, rex); + out_size = get_op_size(rex, oso); + out_length += get_modRM_size(code); + return; + } + break; + } + case 0x88: + { + if (!lock && !oso) // MOV r8/m8, r8 + { + out_op = X64OP_STORE; + out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code); + out_size = 1; + out_length += get_modRM_size(code); + return; + } + break; + } + case 0x89: + { + if (!lock) // MOV r/m, r (16, 32, 64) + { + out_op = X64OP_STORE; + out_reg = get_modRM_reg(code, rex); + out_size = get_op_size(rex, oso); + out_length += get_modRM_size(code); + return; + } + break; + } + case 0x8a: + { + if (!lock && !oso) // MOV r8, r8/m8 + { + out_op = X64OP_LOAD; + out_reg = rex & 8 ? get_modRM_reg(code, rex) : get_modRM_reg_lh(code); + out_size = 1; + out_length += get_modRM_size(code); + return; + } + break; + } + case 0x8b: + { + if (!lock) // MOV r, r/m (16, 32, 64) + { + out_op = X64OP_LOAD; + out_reg = get_modRM_reg(code, rex); + out_size = get_op_size(rex, oso); + out_length += get_modRM_size(code); + return; + } + break; + } + case 0xa4: + { + if (!oso && !lock && !repe && !rex) // MOVS + { + out_op = X64OP_MOVS; + out_reg = X64_NOT_SET; + out_size = 1; + return; + } + if (!oso && !lock && repe) // REP MOVS + { + out_op = X64OP_MOVS; + out_reg = rex & 8 ? X64R_RCX : X64R_ECX; + out_size = 1; + return; + } + break; + } + case 0xc6: + { + if (!lock && !oso && get_modRM_reg(code, 0) == X64R_RAX) // MOV r8/m8, imm8 + { + out_op = X64OP_STORE; + out_reg = X64_IMM8; + out_size = 1; + out_length += get_modRM_size(code) + 1; + return; + } + break; } case 0xc7: { - if (get_modRM_r32(code, 0) == X64R_EAX) // MOV r/m32, imm32 (not tested) + if (!lock && get_modRM_reg(code, 0) == X64R_RAX) // MOV r/m, imm16/imm32 (16, 32, 64) { - decoded_op = X64OP_STORE; - decoded_reg = X64_IMM32; - decoded_size = get_modRM_size(code) + 4; + out_op = X64OP_STORE; + out_reg = oso ? X64_IMM16 : X64_IMM32; + out_size = get_op_size(rex, oso); + out_length += get_modRM_size(code) + (oso ? 2 : 4); return; } - } - default: - { - throw fmt::format("decode_x64_reg_op(%016llxh): unsupported opcode found (0x%02x, 0x%02x, 0x%02x)", (size_t)code - decoded_size, op1, code[0], code[1]); + break; } } + + LOG_WARNING(GENERAL, "decode_x64_reg_op(%016llxh): unsupported opcode found (%llX%llX)", (size_t)code - out_length, *(be_t*)(code - out_length), *(be_t*)(code - out_length + 8)); + out_op = X64OP_NOP; + out_reg = X64_NOT_SET; + out_size = 0; + out_length = 0; } #ifdef _WIN32 @@ -272,30 +511,39 @@ static const reg_table_t reg_table[17] = bool handle_access_violation(const u32 addr, bool is_writing, x64_context* context) { + x64_op_t op; + x64_reg_t reg; + u32 d_size; + u32 i_size; + + // decode single x64 instruction that causes memory access + decode_x64_reg_op((const u8*)(*X64REG(context, RIP)), op, reg, d_size, i_size); + // check if address is RawSPU MMIO register if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { - // one x64 instruction is manually decoded and interpreted - x64_op_t op; - x64_reg_t reg; - size_t size; - decode_x64_reg_op((const u8*)(*X64REG(context, RIP)), op, reg, size); + if (d_size != 4 || !i_size) + { + LOG_ERROR(GENERAL, "Invalid instruction (op=%d, reg=%d, d_size=0x%x, i_size=0x%x)", op, reg, d_size, i_size); + return false; + } // get x64 reg value (for store operations) u64 reg_value; - if (reg - X64R32 < 16) + if (reg - X64R < 16) { // load the value from x64 register - reg_value = (u32)*X64REG(context, reg - X64R32); + reg_value = (u32)*X64REG(context, reg - X64R); } else if (reg == X64_IMM32) { // load the immediate value (assuming it's at the end of the instruction) - reg_value = *(u32*)(*X64REG(context, RIP) + size - 4); + reg_value = *(u32*)(*X64REG(context, RIP) + i_size - 4); } else { - assert(!"Invalid x64_reg_t value"); + LOG_ERROR(GENERAL, "Invalid source (reg=%d)", reg); + return false; } bool save_reg = false; @@ -313,25 +561,30 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte Memory.WriteMMIO32(addr, re32((u32)reg_value)); break; } - default: assert(!"Invalid x64_op_t value"); + default: + { + LOG_ERROR(GENERAL, "Invalid operation (op=%d)", op); + return false; + } } // save x64 reg value (for load operations) if (save_reg) { - if (reg - X64R32 < 16) + if (reg - X64R < 16) { // store the value into x64 register - *X64REG(context, reg - X64R32) = (u32)reg_value; + *X64REG(context, reg - X64R) = (u32)reg_value; } else { - assert(!"Invalid x64_reg_t value (saving)"); + LOG_ERROR(GENERAL, "Invalid destination (reg=%d, reg_value=0x%llx)", reg, reg_value); + return false; } } // skip decoded instruction - *X64REG(context, RIP) += size; + *X64REG(context, RIP) += i_size; return true; } From 1189503b4d0f6240082c3892222aa44f13d5ffb4 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 15 Feb 2015 20:13:06 +0300 Subject: [PATCH 08/25] Some cleanup --- Utilities/Thread.cpp | 174 +++++++++++++++++++++++------------ rpcs3/Emu/Cell/SPUThread.cpp | 76 ++++----------- rpcs3/Emu/Memory/Memory.cpp | 15 ++- rpcs3/Emu/Memory/Memory.h | 4 +- 4 files changed, 143 insertions(+), 126 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 2b447eeeab..60c5182a8e 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -99,15 +99,12 @@ enum x64_reg_t : u32 X64_IMM16, X64_IMM32, - X64R = X64R_RAX, - X64R_XMM = X64R_XMM0, - X64R_LH = X64R_AL, X64R_ECX = X64R_CL, }; enum x64_op_t : u32 { - X64OP_NOP, + X64OP_NONE, X64OP_LOAD, // obtain and put the value into x64 register (from Memory.ReadMMIO32, for example) X64OP_STORE, // take the value from x64 register or an immediate and use it (pass in Memory.WriteMMIO32, for example) // example: add eax,[rax] -> X64OP_LOAD_ADD (add the value to x64 register) @@ -118,7 +115,7 @@ enum x64_op_t : u32 X64OP_CMPXCHG, }; -void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32& out_size, u32& out_length) +void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, size_t& out_size, size_t& out_length) { // simple analysis of x64 code allows to reinterpret MOV or other instructions in any desired way out_length = 0; @@ -202,7 +199,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32 case 0x67: // group 4 { LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): address-size override prefix found", (size_t)code - out_length, prefix); - out_op = X64OP_NOP; + out_op = X64OP_NONE; out_reg = X64_NOT_SET; out_size = 0; out_length = 0; @@ -231,25 +228,25 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32 auto get_modRM_reg = [](const u8* code, const u8 rex) -> x64_reg_t { - return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R); + return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R_RAX); }; auto get_modRM_reg_xmm = [](const u8* code, const u8 rex) -> x64_reg_t { - return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R_XMM); + return (x64_reg_t)(((*code & 0x38) >> 3 | (/* check REX.R bit */ rex & 4 ? 8 : 0)) + X64R_XMM0); }; auto get_modRM_reg_lh = [](const u8* code) -> x64_reg_t { - return (x64_reg_t)(((*code & 0x38) >> 3) + X64R_LH); + return (x64_reg_t)(((*code & 0x38) >> 3) + X64R_AL); }; - auto get_op_size = [](const u8 rex, const bool oso) -> u32 + auto get_op_size = [](const u8 rex, const bool oso) -> size_t { return rex & 8 ? 8 : (oso ? 2 : 4); }; - auto get_modRM_size = [](const u8* code) -> u32 + auto get_modRM_size = [](const u8* code) -> size_t { switch (*code >> 6) // check Mod { @@ -426,8 +423,8 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32 } } - LOG_WARNING(GENERAL, "decode_x64_reg_op(%016llxh): unsupported opcode found (%llX%llX)", (size_t)code - out_length, *(be_t*)(code - out_length), *(be_t*)(code - out_length + 8)); - out_op = X64OP_NOP; + LOG_WARNING(GENERAL, "decode_x64_reg_op(%016llxh): unsupported opcode found (%016llX%016llX)", (size_t)code - out_length, *(be_t*)(code - out_length), *(be_t*)(code - out_length + 8)); + out_op = X64OP_NONE; out_reg = X64_NOT_SET; out_size = 0; out_length = 0; @@ -437,13 +434,11 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, u32 typedef CONTEXT x64_context; -#define RIP 16 #define X64REG(context, reg) (&(&context->Rax)[reg]) #else typedef ucontext_t x64_context; -#define RIP 16 #ifdef __APPLE__ @@ -509,58 +504,134 @@ static const reg_table_t reg_table[17] = #endif +#define RAX(c) (*X64REG((c), 0)) +#define RCX(c) (*X64REG((c), 1)) +#define RDX(c) (*X64REG((c), 2)) +#define RSI(c) (*X64REG((c), 6)) +#define RDI(c) (*X64REG((c), 7)) +#define RIP(c) (*X64REG((c), 16)) + +bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_t i_size, u64& out_value) +{ + // get x64 reg value (for store operations) + if (reg - X64R_RAX < 16) + { + // load the value from x64 register + const u64 reg_value = *X64REG(context, reg - X64R_RAX); + + switch (d_size) + { + case 1: out_value = (u8)reg_value; return true; + case 2: out_value = (u16)reg_value; return true; + case 4: out_value = (u32)reg_value; return true; + case 8: out_value = reg_value; return true; + } + } + else if (reg - X64R_AL < 4 && d_size == 1) + { + out_value = (u8)(*X64REG(context, reg - X64R_AL)); + } + else if (reg - X64R_AH < 4 && d_size == 1) + { + out_value = (u8)(*X64REG(context, reg - X64R_AH) >> 8); + } + else if (reg == X64_IMM32) + { + // load the immediate value (assuming it's at the end of the instruction) + const s32 imm_value = *(s32*)(RIP(context) + i_size - 4); + + switch (d_size) + { + case 4: out_value = (u32)imm_value; return true; + case 8: out_value = (u64)imm_value; return true; // sign-extended + } + } + else if (reg == X64R_ECX) + { + out_value = (u32)RCX(context); + } + + LOG_ERROR(GENERAL, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size); + return false; +} + +bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 value) +{ + // save x64 reg value (for load operations) + if (reg - X64R_RAX < 16) + { + // store the value into x64 register + *X64REG(context, reg - X64R_RAX) = (u32)value; + return true; + } + + LOG_ERROR(GENERAL, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", reg, d_size, value); + return false; +} + +void fix_x64_reg_op(x64_context* context, x64_op_t& op, x64_reg_t& reg, size_t& d_size, size_t& i_size) +{ + if (op == X64OP_MOVS && reg != X64_NOT_SET) + { + u64 counter; + if (!get_x64_reg_value(context, reg, 8, i_size, counter)) + { + op = X64OP_NONE; + reg = X64_NOT_SET; + d_size = 0; + i_size = 0; + return; + } + + d_size *= counter; + } +} + bool handle_access_violation(const u32 addr, bool is_writing, x64_context* context) { + auto code = (const u8*)RIP(context); + x64_op_t op; x64_reg_t reg; - u32 d_size; - u32 i_size; + size_t d_size; + size_t i_size; // decode single x64 instruction that causes memory access - decode_x64_reg_op((const u8*)(*X64REG(context, RIP)), op, reg, d_size, i_size); + decode_x64_reg_op(code, op, reg, d_size, i_size); + fix_x64_reg_op(context, op, reg, d_size, i_size); // check if address is RawSPU MMIO register if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { if (d_size != 4 || !i_size) { - LOG_ERROR(GENERAL, "Invalid instruction (op=%d, reg=%d, d_size=0x%x, i_size=0x%x)", op, reg, d_size, i_size); + LOG_ERROR(GENERAL, "Invalid instruction (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size); return false; } - // get x64 reg value (for store operations) - u64 reg_value; - if (reg - X64R < 16) - { - // load the value from x64 register - reg_value = (u32)*X64REG(context, reg - X64R); - } - else if (reg == X64_IMM32) - { - // load the immediate value (assuming it's at the end of the instruction) - reg_value = *(u32*)(*X64REG(context, RIP) + i_size - 4); - } - else - { - LOG_ERROR(GENERAL, "Invalid source (reg=%d)", reg); - return false; - } - - bool save_reg = false; - switch (op) { case X64OP_LOAD: { - reg_value = re32(Memory.ReadMMIO32(addr)); - save_reg = true; + u32 value; + if (is_writing || !Memory.ReadMMIO32(addr, value) || !put_x64_reg_value(context, reg, d_size, re32(value))) + { + return false; + } + break; } case X64OP_STORE: { - Memory.WriteMMIO32(addr, re32((u32)reg_value)); + u64 reg_value; + if (!is_writing || !get_x64_reg_value(context, reg, d_size, i_size, reg_value) || !Memory.WriteMMIO32(addr, re32((u32)reg_value))) + { + return false; + } + break; } + case X64OP_MOVS: // TODO default: { LOG_ERROR(GENERAL, "Invalid operation (op=%d)", op); @@ -568,23 +639,8 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte } } - // save x64 reg value (for load operations) - if (save_reg) - { - if (reg - X64R < 16) - { - // store the value into x64 register - *X64REG(context, reg - X64R) = (u32)reg_value; - } - else - { - LOG_ERROR(GENERAL, "Invalid destination (reg=%d, reg_value=0x%llx)", reg, reg_value); - return false; - } - } - - // skip decoded instruction - *X64REG(context, RIP) += i_size; + // skip processed instruction + RIP(context) += i_size; return true; } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index e8a2a2ee18..963aa5ebf9 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -205,74 +205,36 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); - if (ea >= SYS_SPU_THREAD_BASE_LOW) + u32 eal = vm::cast(ea, "ea"); + + if (eal >= SYS_SPU_THREAD_BASE_LOW && group) // SPU Thread Group MMIO (LS and SNR) { - if (ea >= 0x100000000) - { - LOG_DMAC(LOG_ERROR, "Invalid external address"); - Emu.Pause(); - return; - } - else if (group) - { - // SPU Thread Group MMIO (LS and SNR) - u32 num = (ea & SYS_SPU_THREAD_BASE_MASK) / SYS_SPU_THREAD_OFFSET; // thread number in group - if (num >= group->list.size() || !group->list[num]) - { - LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); - Emu.Pause(); - return; - } + const u32 num = (eal & SYS_SPU_THREAD_BASE_MASK) / SYS_SPU_THREAD_OFFSET; // thread number in group + const u32 offset = (eal & SYS_SPU_THREAD_BASE_MASK) % SYS_SPU_THREAD_OFFSET; // LS offset or MMIO register - std::shared_ptr spu = Emu.GetCPU().GetThread(group->list[num]); + std::shared_ptr t; - u32 addr = (ea & SYS_SPU_THREAD_BASE_MASK) % SYS_SPU_THREAD_OFFSET; - if ((addr <= 0x3ffff) && (addr + size <= 0x40000)) + if (num < group->list.size() && group->list[num] && (t = Emu.GetCPU().GetThread(group->list[num])) && t->GetType() == CPU_THREAD_SPU) + { + SPUThread& spu = static_cast(*t); + + if (offset + size - 1 < 0x40000) // LS access { - // LS access - ea = ((SPUThread*)spu.get())->ls_offset + addr; + eal = spu.ls_offset + offset; // redirect access } - else if ((cmd & MFC_PUT_CMD) && size == 4 && (addr == SYS_SPU_THREAD_SNR1 || addr == SYS_SPU_THREAD_SNR2)) + else if ((cmd & MFC_PUT_CMD) && size == 4 && (offset == SYS_SPU_THREAD_SNR1 || offset == SYS_SPU_THREAD_SNR2)) { - ((SPUThread*)spu.get())->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, vm::read32(ls_offset + lsa)); + spu.WriteSNR(SYS_SPU_THREAD_SNR2 == offset, vm::read32(ls_offset + lsa)); return; } else { - LOG_DMAC(LOG_ERROR, "Invalid register (SPU Thread Group MMIO)"); - Emu.Pause(); - return; + LOG_DMAC(LOG_ERROR, "Invalid offset (SPU Thread Group MMIO)"); } } else { - LOG_DMAC(LOG_ERROR, "Thread group not set (SPU Thread Group MMIO)"); - Emu.Pause(); - return; - } - } - else if (ea >= RAW_SPU_BASE_ADDR && size == 4) - { - switch (cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) - { - case MFC_PUT_CMD: - { - vm::write32((u32)ea, ReadLS32(lsa)); - return; - } - - case MFC_GET_CMD: - { - WriteLS32(lsa, vm::read32((u32)ea)); - return; - } - - default: - { - LOG_DMAC(LOG_ERROR, "Unknown DMA command"); - Emu.Pause(); - return; - } + LOG_DMAC(LOG_ERROR, "Invalid thread (SPU Thread Group MMIO)"); } } @@ -280,13 +242,13 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { case MFC_PUT_CMD: { - memcpy(vm::get_ptr(vm::cast(ea)), vm::get_ptr(ls_offset + lsa), size); + memcpy(vm::get_ptr(eal), vm::get_ptr(ls_offset + lsa), size); return; } case MFC_GET_CMD: { - memcpy(vm::get_ptr(ls_offset + lsa), vm::get_ptr(vm::cast(ea)), size); + memcpy(vm::get_ptr(ls_offset + lsa), vm::get_ptr(eal), size); return; } @@ -299,7 +261,7 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) } } -#undef LOG_CMD +#undef LOG_DMAC void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFCArgs) { diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 64e50ae1ed..de4705a643 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -105,29 +105,28 @@ void MemoryBase::Close() MemoryBlocks.clear(); } -void MemoryBase::WriteMMIO32(u32 addr, const u32 data) +bool MemoryBase::WriteMMIO32(u32 addr, const u32 data) { LV2_LOCK(0); if (RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET] && ((RawSPUThread*)RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])->Write32(addr, data)) { - return; + return true; } - throw fmt::Format("%s(addr=0x%x, data=0x%x) failed", __FUNCTION__, addr, data); + return false; } -u32 MemoryBase::ReadMMIO32(u32 addr) +bool MemoryBase::ReadMMIO32(u32 addr, u32& result) { LV2_LOCK(0); - u32 res; - if (RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET] && ((RawSPUThread*)RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])->Read32(addr, &res)) + if (RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET] && ((RawSPUThread*)RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])->Read32(addr, &result)) { - return res; + return true; } - throw fmt::Format("%s(addr=0x%x) failed", __FUNCTION__, addr); + return false; } bool MemoryBase::Map(const u32 addr, const u32 size) diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 07151118ab..b17f8aa359 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -75,9 +75,9 @@ public: void Close(); - __noinline void WriteMMIO32(u32 addr, const u32 data); + bool WriteMMIO32(u32 addr, const u32 data); - __noinline u32 ReadMMIO32(u32 addr); + bool ReadMMIO32(u32 addr, u32& result); u32 GetUserMemTotalSize() { From e6c628caba8e29b1b772c859fcad5182f2163524 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 16 Feb 2015 04:53:53 +0300 Subject: [PATCH 09/25] Memory (unfinished) --- Utilities/Thread.cpp | 32 ++++++++++++++++++++++++-- rpcs3/Emu/Cell/SPUThread.cpp | 44 ++++++++++-------------------------- rpcs3/Emu/Memory/Memory.cpp | 6 ++--- rpcs3/Emu/Memory/vm.cpp | 28 ++++++++++++++++++++--- rpcs3/Emu/Memory/vm.h | 2 +- 5 files changed, 71 insertions(+), 41 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 60c5182a8e..f90accc485 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -530,10 +530,12 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_ else if (reg - X64R_AL < 4 && d_size == 1) { out_value = (u8)(*X64REG(context, reg - X64R_AL)); + return true; } else if (reg - X64R_AH < 4 && d_size == 1) { out_value = (u8)(*X64REG(context, reg - X64R_AH) >> 8); + return true; } else if (reg == X64_IMM32) { @@ -549,6 +551,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_ else if (reg == X64R_ECX) { out_value = (u32)RCX(context); + return true; } LOG_ERROR(GENERAL, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size); @@ -571,7 +574,7 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v void fix_x64_reg_op(x64_context* context, x64_op_t& op, x64_reg_t& reg, size_t& d_size, size_t& i_size) { - if (op == X64OP_MOVS && reg != X64_NOT_SET) + if (op == X64OP_MOVS && reg != X64_NOT_SET) // get "full" access size from RCX register { u64 counter; if (!get_x64_reg_value(context, reg, 8, i_size, counter)) @@ -584,6 +587,8 @@ void fix_x64_reg_op(x64_context* context, x64_op_t& op, x64_reg_t& reg, size_t& } d_size *= counter; + reg = X64_NOT_SET; + return; } } @@ -600,6 +605,29 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte decode_x64_reg_op(code, op, reg, d_size, i_size); fix_x64_reg_op(context, op, reg, d_size, i_size); + if (d_size + addr >= 0x100000000ull) + { + LOG_ERROR(GENERAL, "Invalid d_size (0x%llx)", d_size); + return false; + } + + if (op == X64OP_CMPXCHG) + { + // detect whether this instruction can't actually modify memory to avoid breaking reservation; + // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction + u64 cmp, exch; + if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) + { + return false; + } + + if (cmp == exch) + { + // could also be emulated without attempt to write memory + is_writing = false; + } + } + // check if address is RawSPU MMIO register if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { @@ -645,7 +673,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte } // check if fault is caused by reservation - if (vm::reservation_query(addr, is_writing)) + if (vm::reservation_query(addr, (u32)d_size, is_writing)) { return true; } diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 963aa5ebf9..b0785cfd16 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -203,7 +203,10 @@ void SPUThread::WriteSNR(bool number, u32 value) void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size) { - if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) _mm_mfence(); + if (cmd & (MFC_BARRIER_MASK | MFC_FENCE_MASK)) + { + _mm_mfence(); + } u32 eal = vm::cast(ea, "ea"); @@ -298,7 +301,7 @@ void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFC if (Ini.HLELogging.GetValue() || rec->s.data()) { - LOG_NOTICE(Log::SPU, "*** list element(%d/%d): s = 0x%x, ts = 0x%x, low ea = 0x%x (lsa = 0x%x)", i, list_size, rec->s, rec->ts, rec->ea, lsa | (addr & 0xf)); + LOG_NOTICE(Log::SPU, "*** list element(%d/%d): s=0x%x, ts=0x%x, eal=0x%x (lsa=0x%x)", i, list_size, rec->s, rec->ts, rec->ea, lsa | (addr & 0xf)); } if (size) @@ -346,7 +349,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) case MFC_PUTR_CMD: // ??? case MFC_GET_CMD: { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", + if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x, cmd=0x%x", (op & MFC_PUT_CMD ? "PUT" : "GET"), (op & MFC_RESULT_MASK ? "R" : ""), (op & MFC_BARRIER_MASK ? "B" : ""), @@ -362,7 +365,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) case MFC_PUTRL_CMD: // ??? case MFC_GETL_CMD: { - if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa = 0x%x, list = 0x%llx, tag = 0x%x, size = 0x%x, cmd = 0x%x", + if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "DMA %s%s%s%s: lsa=0x%x, list=0x%llx, tag=0x%x, size=0x%x, cmd=0x%x", (op & MFC_PUT_CMD ? "PUT" : "GET"), (op & MFC_RESULT_MASK ? "RL" : "L"), (op & MFC_BARRIER_MASK ? "B" : ""), @@ -378,39 +381,16 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) case MFC_PUTLLUC_CMD: case MFC_PUTQLLUC_CMD: { - if (Ini.HLELogging.GetValue() || size != 128) LOG_NOTICE(Log::SPU, "DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", + if (Ini.HLELogging.GetValue() || size != 128) LOG_NOTICE(Log::SPU, "DMA %s: lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x, cmd=0x%x", (op == MFC_GETLLAR_CMD ? "GETLLAR" : op == MFC_PUTLLC_CMD ? "PUTLLC" : op == MFC_PUTLLUC_CMD ? "PUTLLUC" : "PUTQLLUC"), lsa, ea, tag, size, cmd); - if ((u32)ea != ea) - { - LOG_ERROR(Log::SPU, "DMA %s: Invalid external address (0x%llx)", - (op == MFC_GETLLAR_CMD ? "GETLLAR" : - op == MFC_PUTLLC_CMD ? "PUTLLC" : - op == MFC_PUTLLUC_CMD ? "PUTLLUC" : "PUTQLLUC"), - ea); - Emu.Pause(); - return; - } - if (op == MFC_GETLLAR_CMD) // get reservation { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - vm::reservation_acquire(vm::get_ptr(ls_offset + lsa), vm::cast(ea), 128, [this]() { - //std::shared_ptr t = Emu.GetCPU().GetThread(tid); - - //if (t && (t->GetType() == CPU_THREAD_SPU || t->GetType() == CPU_THREAD_RAW_SPU)) - //{ - // SPUThread& spu = static_cast(*t); - - // spu.m_events |= SPU_EVENT_LR; // TODO: atomic op - // spu.Notify(); - //} - m_events |= SPU_EVENT_LR; // TODO: atomic op Notify(); }); @@ -448,16 +428,16 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs) } default: - LOG_ERROR(Log::SPU, "Unknown MFC cmd. (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", - op, cmd, lsa, ea, tag, size); + { + LOG_ERROR(Log::SPU, "Unknown MFC cmd (opcode=0x%x, cmd=0x%x, lsa=0x%x, ea=0x%llx, tag=0x%x, size=0x%x)", op, cmd, lsa, ea, tag, size); + Emu.Pause(); break; } + } } bool SPUThread::CheckEvents() { - // checks events: - return (m_events & m_event_mask) != 0; } diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index de4705a643..6db3ebe06e 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -297,7 +297,7 @@ bool DynamicMemoryBlockBase::AllocFixed(u32 addr, u32 size) for (u32 i = 0; i= m_allocated[i].addr && addr < m_allocated[i].addr + m_allocated[i].size) return false; + if (addr >= m_allocated[i].addr && addr <= m_allocated[i].addr + m_allocated[i].size - 1) return false; } AppendMem(addr, size); @@ -342,8 +342,8 @@ u32 DynamicMemoryBlockBase::AllocAlign(u32 size, u32 align) for (u32 i = 0; i= m_allocated[i].addr && addr < m_allocated[i].addr + m_allocated[i].size) || - (m_allocated[i].addr >= addr && m_allocated[i].addr < addr + exsize)) + if ((addr >= m_allocated[i].addr && addr <= m_allocated[i].addr + m_allocated[i].size - 1) || + (m_allocated[i].addr >= addr && m_allocated[i].addr <= addr + exsize - 1)) { is_good_addr = false; addr = m_allocated[i].addr + m_allocated[i].size; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 20b127ef19..8f50f1169a 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -271,7 +271,7 @@ namespace vm return true; } - bool reservation_query(u32 addr, bool is_writing) + bool reservation_query(u32 addr, u32 size, bool is_writing) { std::lock_guard lock(g_reservation_mutex); @@ -282,8 +282,30 @@ namespace vm if (is_writing) { - // break the reservation - _reservation_break(addr); + assert(size); + + if (addr + size - 1 >= g_reservation_addr && g_reservation_addr + g_reservation_size - 1 >= addr) + { + // break the reservation if writing access and reservation overlap + _reservation_break(addr); + } + else + { + // full-size check (isn't accurate enough) + if (!check_addr(addr, size)) + { + return false; + } + + // assume that the same memory page is accessed (isn't accurate enough) + if (g_reservation_addr >> 12 != addr >> 12) + { + return false; + } + + // write memory using "privileged" access to avoid breaking reservation + return false; + } } return true; diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 5f1d5a4338..e21d484be4 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -39,7 +39,7 @@ namespace vm // attempt to atomically update reserved memory bool reservation_update(u32 addr, const void* data, u32 size); // for internal use - bool reservation_query(u32 addr, bool is_writing); + bool reservation_query(u32 addr, u32 size, bool is_writing); // for internal use void reservation_free(); // perform complete operation From e7f278b5d2e479a164ed139e5671454160cdd9ea Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Mon, 16 Feb 2015 22:49:17 +0530 Subject: [PATCH 10/25] PPUJIT: Support exception based MMIO and reservations --- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 12157 ++++++++++++------------- rpcs3/Emu/Memory/vm.cpp | 5 + rpcs3/Emu/Memory/vm.h | 3 + 3 files changed, 6024 insertions(+), 6141 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index dedaf358bf..33994f0227 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1,6162 +1,6037 @@ -#include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Cell/PPULLVMRecompiler.h" -#include "Emu/Memory/Memory.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/CodeGen/MachineCodeInfo.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/Analysis/MemoryDependenceAnalysis.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/IR/Dominators.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Vectorize.h" -#include "llvm/MC/MCDisassembler.h" -#include "llvm/IR/Verifier.h" - -using namespace llvm; -using namespace ppu_recompiler_llvm; - -u64 Compiler::s_rotate_mask[64][64]; -bool Compiler::s_rotate_mask_inited = false; - -Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block) - : m_recompilation_engine(recompilation_engine) { - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - InitializeNativeTargetDisassembler(); - - m_llvm_context = new LLVMContext(); - m_ir_builder = new IRBuilder<>(*m_llvm_context); - m_module = new llvm::Module("Module", *m_llvm_context); - m_fpm = new FunctionPassManager(m_module); - - EngineBuilder engine_builder(m_module); - engine_builder.setMCPU(sys::getHostCPUName()); - engine_builder.setEngineKind(EngineKind::JIT); - engine_builder.setOptLevel(CodeGenOpt::Default); - m_execution_engine = engine_builder.create(); - - m_fpm->add(new DataLayoutPass(m_module)); - m_fpm->add(createNoAAPass()); - m_fpm->add(createBasicAliasAnalysisPass()); - m_fpm->add(createNoTargetTransformInfoPass()); - m_fpm->add(createEarlyCSEPass()); - m_fpm->add(createTailCallEliminationPass()); - m_fpm->add(createReassociatePass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(new DominatorTreeWrapperPass()); - m_fpm->add(new MemoryDependenceAnalysis()); - m_fpm->add(createGVNPass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(new MemoryDependenceAnalysis()); - m_fpm->add(createDeadStoreEliminationPass()); - m_fpm->add(new LoopInfo()); - m_fpm->add(new ScalarEvolution()); - m_fpm->add(createSLPVectorizerPass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(createCFGSimplificationPass()); - m_fpm->doInitialization(); - - std::vector arg_types; - arg_types.push_back(m_ir_builder->getInt8PtrTy()); - arg_types.push_back(m_ir_builder->getInt8PtrTy()); - arg_types.push_back(m_ir_builder->getInt64Ty()); - m_compiled_function_type = FunctionType::get(m_ir_builder->getInt32Ty(), arg_types, false); - - m_execute_unknown_function = (Function *)m_module->getOrInsertFunction("execute_unknown_function", m_compiled_function_type); - m_execute_unknown_function->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(m_execute_unknown_function, (void *)execute_unknown_function); - - m_execute_unknown_block = (Function *)m_module->getOrInsertFunction("execute_unknown_block", m_compiled_function_type); - m_execute_unknown_block->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(m_execute_unknown_block, (void *)execute_unknown_block); - - if (!s_rotate_mask_inited) { - InitRotateMask(); - s_rotate_mask_inited = true; - } -} - -Compiler::~Compiler() { - delete m_execution_engine; - delete m_fpm; - delete m_ir_builder; - delete m_llvm_context; -} - -Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & cfg, bool inline_all, bool generate_linkable_exits) { - auto compilation_start = std::chrono::high_resolution_clock::now(); - - m_state.cfg = &cfg; - m_state.inline_all = inline_all; - m_state.generate_linkable_exits = generate_linkable_exits; - - // Create the function - m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); - m_state.function->setCallingConv(CallingConv::X86_64_Win64); - auto arg_i = m_state.function->arg_begin(); - arg_i->setName("ppu_state"); - m_state.args[CompileTaskState::Args::State] = arg_i; - (++arg_i)->setName("context"); - m_state.args[CompileTaskState::Args::Context] = arg_i; - - // Create the entry block and add code to branch to the first instruction - m_ir_builder->SetInsertPoint(GetBasicBlockFromAddress(0)); - m_ir_builder->CreateBr(GetBasicBlockFromAddress(cfg.start_address)); - - // Convert each instruction in the CFG to LLVM IR - std::vector exit_instr_list; - for (auto instr_i = cfg.instruction_addresses.begin(); instr_i != cfg.instruction_addresses.end(); instr_i++) { - m_state.hit_branch_instruction = false; - m_state.current_instruction_address = *instr_i; - auto instr_bb = GetBasicBlockFromAddress(m_state.current_instruction_address); - m_ir_builder->SetInsertPoint(instr_bb); - - if (!inline_all && *instr_i != cfg.start_address) { - // Use an already compiled implementation of this block if available - auto ordinal = m_recompilation_engine.GetOrdinal(*instr_i); - if (ordinal != 0xFFFFFFFF) { - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - auto ret_i32 = IndirectCall(*instr_i, context_i64, false); - - auto switch_instr = m_ir_builder->CreateSwitch(ret_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); - auto branch_i = cfg.branches.find(*instr_i); - if (branch_i != cfg.branches.end()) { - for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { - switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); - } - } - } - } - - if (instr_bb->empty()) { - u32 instr = re32(vm::get_ref(m_state.current_instruction_address)); - Decode(instr); - if (!m_state.hit_branch_instruction) { - m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); - } - } - } - - // Generate exit logic for all empty blocks - auto default_exit_block_name = GetBasicBlockNameFromAddress(0xFFFFFFFF); - for (auto block_i = m_state.function->begin(); block_i != m_state.function->end(); block_i++) { - if (!block_i->getInstList().empty() || block_i->getName() == default_exit_block_name) { - continue; - } - - // Found an empty block - m_ir_builder->SetInsertPoint(block_i); - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - auto instr_address = GetAddressFromBasicBlockName(block_i->getName()); - SetPc(m_ir_builder->getInt32(instr_address)); - - if (generate_linkable_exits) { - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - auto ret_i32 = IndirectCall(instr_address, context_i64, false); - auto cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(instr_address, "then"); - auto merge_bb = GetBasicBlockFromAddress(instr_address, "merge"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - context_i64 = m_ir_builder->CreateZExt(ret_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else { - m_ir_builder->CreateRet(exit_instr_i32); - } - } - - // If the function has a default exit block then generate code for it - auto default_exit_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "", false); - if (default_exit_bb) { - m_ir_builder->SetInsertPoint(default_exit_bb); - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - if (generate_linkable_exits) { - auto cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then"); - auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else { - m_ir_builder->CreateRet(exit_instr_i32); - } - } - - // Add incoming values for all exit instr PHI nodes - for (auto exit_instr_i = exit_instr_list.begin(); exit_instr_i != exit_instr_list.end(); exit_instr_i++) { - auto block = (*exit_instr_i)->getParent(); - for (auto pred_i = pred_begin(block); pred_i != pred_end(block); pred_i++) { - auto pred_address = GetAddressFromBasicBlockName((*pred_i)->getName()); - (*exit_instr_i)->addIncoming(m_ir_builder->getInt32(pred_address), *pred_i); - } - } - -#ifdef _DEBUG - m_recompilation_engine.Log() << *m_state.function; - - std::string verify; - raw_string_ostream verify_ostream(verify); - if (verifyFunction(*m_state.function, &verify_ostream)) { - m_recompilation_engine.Log() << "Verification failed: " << verify << "\n"; - } -#endif - - auto ir_build_end = std::chrono::high_resolution_clock::now(); - m_stats.ir_build_time += std::chrono::duration_cast(ir_build_end - compilation_start); - - // Optimize this function - m_fpm->run(*m_state.function); - auto optimize_end = std::chrono::high_resolution_clock::now(); - m_stats.optimization_time += std::chrono::duration_cast(optimize_end - ir_build_end); - - // Translate to machine code - MachineCodeInfo mci; - m_execution_engine->runJITOnFunction(m_state.function, &mci); - auto translate_end = std::chrono::high_resolution_clock::now(); - m_stats.translation_time += std::chrono::duration_cast(translate_end - optimize_end); - -#ifdef _DEBUG - m_recompilation_engine.Log() << "\nDisassembly:\n"; - auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr); - for (size_t pc = 0; pc < mci.size();) { - char str[1024]; - - auto size = LLVMDisasmInstruction(disassembler, ((u8 *)mci.address()) + pc, mci.size() - pc, (uint64_t)(((u8 *)mci.address()) + pc), str, sizeof(str)); - m_recompilation_engine.Log() << fmt::Format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n'; - pc += size; - } - - LLVMDisasmDispose(disassembler); -#endif - - auto compilation_end = std::chrono::high_resolution_clock::now(); - m_stats.total_time += std::chrono::duration_cast(compilation_end - compilation_start); - - return (Executable)mci.address(); -} - -void Compiler::FreeExecutable(const std::string & name) { - auto function = m_module->getFunction(name); - if (function) { - m_execution_engine->freeMachineCodeForFunction(function); - function->eraseFromParent(); - } -} - -Compiler::Stats Compiler::GetStats() { - return m_stats; -} - -void Compiler::Decode(const u32 code) { - (*PPU_instr::main_list)(this, code); -} - -void Compiler::NULL_OP() { - CompilationError("NULL_OP"); -} - -void Compiler::NOP() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::TDI(u32 to, u32 ra, s32 simm16) { - CompilationError("TDI"); -} - -void Compiler::TWI(u32 to, u32 ra, s32 simm16) { - CompilationError("TWI"); -} - -void Compiler::MFVSCR(u32 vd) { - auto vscr_i32 = GetVscr(); - auto vscr_i128 = m_ir_builder->CreateZExt(vscr_i32, m_ir_builder->getIntNTy(128)); - SetVr(vd, vscr_i128); -} - -void Compiler::MTVSCR(u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto vscr_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(0)); - vscr_i32 = m_ir_builder->CreateAnd(vscr_i32, 0x00010001); - SetVscr(vscr_i32); -} - -void Compiler::VADDCUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - va_v4i32 = m_ir_builder->CreateNot(va_v4i32); - auto cmpv4i1 = m_ir_builder->CreateICmpULT(va_v4i32, vb_v4i32); - auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmpv4i32); -} - -void Compiler::VADDFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto sum_v4f32 = m_ir_builder->CreateFAdd(va_v4f32, vb_v4f32); - SetVr(vd, sum_v4f32); -} - -void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - // It looks like x86 does not have an instruction to add 32 bit intergers with signed/unsigned saturation. - // To implement add with saturation, we first determine what the result would be if the operation were to cause - // an overflow. If two -ve numbers are being added and cause an overflow, the result would be 0x80000000. - // If two +ve numbers are being added and cause an overflow, the result would be 0x7FFFFFFF. Addition of a -ve - // number and a +ve number cannot cause overflow. So the result in case of an overflow is 0x7FFFFFFF + sign bit - // of any one of the operands. - auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Next, we find if the addition can actually result in an overflow. Since an overflow can only happen if the operands - // have the same sign, we bitwise XOR both the operands. If the sign bit of the result is 0 then the operands have the - // same sign and so may cause an overflow. We invert the result so that the sign bit is 1 when the operands have the - // same sign. - auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); - tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); - - // Perform the sum. - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // If an overflow occurs, then the sign of the sum will be different from the sign of the operands. So, we xor the - // result with one of the operands. The sign bit of the result will be 1 if the sign bit of the sum and the sign bit of the - // result is different. This result is again ANDed with tmp3 (the sign bit of tmp3 is 1 only if the operands have the same - // sign and so can cause an overflow). - auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, sum_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set SAT -} - -void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateAdd(va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); -} - -void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); - - // TODO: Set SAT -} - -void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateAdd(va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); -} - -void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); - - // TODO: Set SAT -} - -void Compiler::VADDUWM(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - SetVr(vd, sum_v4i32); -} - -void Compiler::VADDUWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - auto cmp_v4i1 = m_ir_builder->CreateICmpULT(sum_v4i32, va_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateOr(sum_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set SAT -} - -void Compiler::VAND(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VANDC(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateNot(vb_v4i32); - auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VAVGSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateSExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto sum_v16i16 = m_ir_builder->CreateAdd(va_v16i16, vb_v16i16); - sum_v16i16 = m_ir_builder->CreateAdd(sum_v16i16, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt16(1))); - auto avg_v16i16 = m_ir_builder->CreateAShr(sum_v16i16, 1); - auto avg_v16i8 = m_ir_builder->CreateTrunc(avg_v16i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, avg_v16i8); -} - -void Compiler::VAVGSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto sum_v8i32 = m_ir_builder->CreateAdd(va_v8i32, vb_v8i32); - sum_v8i32 = m_ir_builder->CreateAdd(sum_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(1))); - auto avg_v8i32 = m_ir_builder->CreateAShr(sum_v8i32, 1); - auto avg_v8i16 = m_ir_builder->CreateTrunc(avg_v8i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, avg_v8i16); -} - -void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); - sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); - auto avg_v4i64 = m_ir_builder->CreateAShr(sum_v4i64, 1); - auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, avg_v4i32); -} - -void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8); - SetVr(vd, avg_v16i8); -} - -void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16); - SetVr(vd, avg_v8i16); -} - -void Compiler::VAVGUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto va_v4i64 = m_ir_builder->CreateZExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v4i64 = m_ir_builder->CreateZExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); - sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); - auto avg_v4i64 = m_ir_builder->CreateLShr(sum_v4i64, 1); - auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, avg_v4i32); -} - -void Compiler::VCFSX(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4f32 = m_ir_builder->CreateSIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); - - if (uimm5) { - float scale = (float)((u64)1 << uimm5); - res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); - } - - SetVr(vd, res_v4f32); -} - -void Compiler::VCFUX(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4f32 = m_ir_builder->CreateUIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); - - if (uimm5) { - float scale = (float)((u64)1 << uimm5); - res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); - } - - SetVr(vd, res_v4f32); -} - -void Compiler::VCMPBFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_gt_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); - vb_v4f32 = m_ir_builder->CreateFNeg(vb_v4f32); - auto cmp_lt_v4i1 = m_ir_builder->CreateFCmpOLT(va_v4f32, vb_v4f32); - auto cmp_gt_v4i32 = m_ir_builder->CreateZExt(cmp_gt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto cmp_lt_v4i32 = m_ir_builder->CreateZExt(cmp_lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - cmp_gt_v4i32 = m_ir_builder->CreateShl(cmp_gt_v4i32, 31); - cmp_lt_v4i32 = m_ir_builder->CreateShl(cmp_lt_v4i32, 30); - auto res_v4i32 = m_ir_builder->CreateOr(cmp_gt_v4i32, cmp_lt_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Implement NJ mode -} - -void Compiler::VCMPBFP_(u32 vd, u32 va, u32 vb) { - VCMPBFP(vd, va, vb); - - auto vd_v16i8 = GetVrAsIntVec(vd, 8); - u32 mask_v16i32[16] = {3, 7, 11, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - vd_v16i8 = m_ir_builder->CreateShuffleVector(vd_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - auto vd_v4i32 = m_ir_builder->CreateBitCast(vd_v16i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto vd_mask_i32 = m_ir_builder->CreateExtractElement(vd_v4i32, m_ir_builder->getInt32(0)); - auto cmp_i1 = m_ir_builder->CreateICmpEQ(vd_mask_i32, m_ir_builder->getInt32(0)); - SetCrField(6, nullptr, nullptr, cmp_i1, nullptr); -} - -void Compiler::VCMPEQFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOEQ(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPEQFP_(u32 vd, u32 va, u32 vb) { - VCMPEQFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpEQ(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPEQUB_(u32 vd, u32 va, u32 vb) { - VCMPEQUB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpEQ(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPEQUH_(u32 vd, u32 va, u32 vb) { - VCMPEQUH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpEQ(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPEQUW_(u32 vd, u32 va, u32 vb) { - VCMPEQUW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGEFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGEFP_(u32 vd, u32 va, u32 vb) { - VCMPGEFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTFP_(u32 vd, u32 va, u32 vb) { - VCMPGTFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpSGT(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPGTSB_(u32 vd, u32 va, u32 vb) { - VCMPGTSB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpSGT(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPGTSH_(u32 vd, u32 va, u32 vb) { - VCMPGTSH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpSGT(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTSW_(u32 vd, u32 va, u32 vb) { - VCMPGTSW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpUGT(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPGTUB_(u32 vd, u32 va, u32 vb) { - VCMPGTUB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpUGT(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPGTUH_(u32 vd, u32 va, u32 vb) { - VCMPGTUH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpUGT(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTUW_(u32 vd, u32 va, u32 vb) { - VCMPGTUW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCTSXS(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - if (uimm5) { - vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); - } - - auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_cvtps2dq), vb_v4f32); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0x7FFFFFFF))); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateXor(cmp_v4i32, res_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - if (uimm5) { - vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); - } - - auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0))); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu))); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VEXPTEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)), - m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VLOGEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::log2, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto vc_v4f32 = GetVrAsFloatVec(vc); - auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); - - u32 mask1_v4i32[4] = {0, 1, 2, 3}; - auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {4, 5, 6, 7}; - auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(0x4000))); - res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); - - u32 mask1_v4i32[4] = {0, 1, 2, 3}; - auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {4, 5, 6, 7}; - auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMINFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMINSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMINSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMINSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMINUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMINUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMINUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMLADDUHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - res_v8i16 = m_ir_builder->CreateAdd(res_v8i16, vc_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMRGHB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v16i32[16] = {24, 8, 25, 9, 26, 10, 27, 11, 28, 12, 29, 13, 30, 14, 31, 15}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VMRGHH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = {12, 4, 13, 5, 14, 6, 15, 7}; - auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VMRGHW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - u32 mask_v4i32[4] = {6, 2, 7, 3}; - auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VMRGLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v16i32[16] = {16, 0, 17, 1, 18, 2, 19, 3, 20, 4, 21, 5, 22, 6, 23, 7}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VMRGLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = {8, 0, 9, 1, 10, 2, 11, 3}; - auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VMRGLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - u32 mask_v4i32[4] = {4, 0, 5, 1}; - auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); - - auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); - u32 mask1_v4i32[4] = {0, 4, 8, 12}; - auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp1_v4i32 = m_ir_builder->CreateSExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask2_v4i32[4] = {1, 5, 9, 13}; - auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto tmp2_v4i32 = m_ir_builder->CreateSExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask3_v4i32[4] = {2, 6, 10, 14}; - auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto tmp3_v4i32 = m_ir_builder->CreateSExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask4_v4i32[4] = {3, 7, 11, 15}; - auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto tmp4_v4i32 = m_ir_builder->CreateSExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); - - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto tmp2_v4i32 = m_ir_builder->CreateXor(vc_v4i32, res_v4i32); - tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); - auto sum_v4i32 = m_ir_builder->CreateAdd(vc_v4i32, res_v4i32); - auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto tmp3_v4i32 = m_ir_builder->CreateXor(vc_v4i32, sum_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMSUMUBM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateZExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); - - auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); - u32 mask1_v4i32[4] = {0, 4, 8, 12}; - auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp1_v4i32 = m_ir_builder->CreateZExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask2_v4i32[4] = {1, 5, 9, 13}; - auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto tmp2_v4i32 = m_ir_builder->CreateZExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask3_v4i32[4] = {2, 6, 10, 14}; - auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto tmp3_v4i32 = m_ir_builder->CreateZExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask4_v4i32[4] = {3, 7, 11, 15}; - auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto tmp4_v4i32 = m_ir_builder->CreateZExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMUHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - - auto undef_v8i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)); - u32 mask1_v4i32[4] = {0, 2, 4, 6}; - auto tmp1_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {1, 3, 5, 7}; - auto tmp2_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMUHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - auto tmp_v8i64 = m_ir_builder->CreateZExt(tmp_v8i32, VectorType::get(m_ir_builder->getInt64Ty(), 8)); - - u32 mask1_v4i32[4] = {0, 2, 4, 6}; - u32 mask2_v4i32[4] = {1, 3, 5, 7}; - auto tmp1_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp2_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto vc_v4i64 = m_ir_builder->CreateZExt(vc_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto res_v4i64 = m_ir_builder->CreateAdd(tmp1_v4i64, tmp2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vc_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpUGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF))); - auto gt_v4i64 = m_ir_builder->CreateSExt(gt_v4i1, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - res_v4i64 = m_ir_builder->CreateOr(res_v4i64, gt_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMULESB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULESH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULEUB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULEUH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULOSB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); - va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULOSH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); - va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULOUB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); - va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULOUH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); - va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto vc_v4f32 = GetVrAsFloatVec(vc); - vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VNOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); - res_v8i16 = m_ir_builder->CreateNot(res_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto vc_v16i8 = GetVrAsIntVec(vc, 8); - - auto thrity_one_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(31)); - vc_v16i8 = m_ir_builder->CreateAnd(vc_v16i8, thrity_one_v16i8); - - auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15)); - auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8); - auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8); - - auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8); - auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8); - auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8); - auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8); - - auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VPKPX(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto tmpa_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); - tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); - tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); - tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); - tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); - auto tmpa_v8i16 = m_ir_builder->CreateBitCast(tmpa_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - auto tmpb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); - tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); - tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); - tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); - tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); - auto tmpb_v8i16 = m_ir_builder->CreateBitCast(tmpb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - u32 mask_v8i32[8] = {1, 3, 5, 7, 9, 11, 13, 15}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(tmpb_v8i16, tmpa_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - SetVr(vd, res_v8i16); - - // TODO: Implement with pext on CPUs with BMI -} - -void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16); - SetVr(vd, res_v16i8); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16); - SetVr(vd, res_v16i8); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32); - SetVr(vd, res_v8i16); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32); - SetVr(vd, res_v8i16); - - // TODO: VSCR.SAT -} - -void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - - u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, res_v16i8); -} - -void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); - vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); - auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, res_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - - u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, res_v8i16); -} - -void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); - vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); - auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VREFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIM(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::floor, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIN(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::nearbyint, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ceil, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIZ(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::trunc, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(7))); - auto tmp1_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); - vb_v16i8 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(8)), vb_v16i8); - auto tmp2_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); - auto res_v16i8 = m_ir_builder->CreateOr(tmp1_v16i8, tmp2_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VRLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto tmp1_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); - vb_v8i16 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0x10)), vb_v8i16); - auto tmp2_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); - auto res_v8i16 = m_ir_builder->CreateOr(tmp1_v8i16, tmp2_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VRLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto tmp1_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); - vb_v4i32 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x20)), vb_v4i32); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); - auto res_v4i32 = m_ir_builder->CreateOr(tmp1_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VRSQRTEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), res_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VSEL(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, vc_v4i32); - vc_v4i32 = m_ir_builder->CreateNot(vc_v4i32); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vc_v4i32); - auto vd_v4i32 = m_ir_builder->CreateOr(va_v4i32, vb_v4i32); - SetVr(vd, vd_v4i32); -} - -void Compiler::VSL(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSLDOI(u32 vd, u32 va, u32 vb, u32 sh) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - sh = 16 - sh; - u32 mask_v16i32[16] = {sh, sh + 1, sh + 2, sh + 3, sh + 4, sh + 5, sh + 6, sh + 7, sh + 8, sh + 9, sh + 10, sh + 11, sh + 12, sh + 13, sh + 14, sh + 15}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VSLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSLO(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSPLTB(u32 vd, u32 uimm5, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto undef_v16i8 = UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto mask_v16i32 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt32(15 - uimm5)); - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, undef_v16i8, mask_v16i32); - SetVr(vd, res_v16i8); -} - -void Compiler::VSPLTH(u32 vd, u32 uimm5, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto undef_v8i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)); - auto mask_v8i32 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(7 - uimm5)); - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, undef_v8i16, mask_v8i32); - SetVr(vd, res_v8i16); -} - -void Compiler::VSPLTISB(u32 vd, s32 simm5) { - auto vd_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8((s8)simm5)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VSPLTISH(u32 vd, s32 simm5) { - auto vd_v8i16 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16((s16)simm5)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VSPLTISW(u32 vd, s32 simm5) { - auto vd_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32((s32)simm5)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VSPLTW(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto undef_v4i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto mask_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3 - uimm5)); - auto res_v4i32 = m_ir_builder->CreateShuffleVector(vb_v4i32, undef_v4i32, mask_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSR(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSRAB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateAShr(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSRAH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateAShr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSRAW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateAShr(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSRB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSRH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSRO(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSRW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSUBCUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto cmpv4i1 = m_ir_builder->CreateICmpUGE(va_v4i32, vb_v4i32); - auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmpv4i32); -} - -void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto diff_v4f32 = m_ir_builder->CreateFSub(va_v4f32, vb_v4f32); - SetVr(vd, diff_v4f32); -} - -void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - // See the comments for VADDSWS for a detailed description of how this works - - // Find the result in case of an overflow - auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Find the elements that can overflow (elements with opposite sign bits) - auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); - - // Perform the sub - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - auto diff_v16i8 = m_ir_builder->CreateBitCast(diff_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Find the elements that overflowed - auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, diff_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set SAT -} - -void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateSub(va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); -} - -void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); - - // TODO: Set SAT -} - -void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateSub(va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); -} - -void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); - - // TODO: Set SAT -} - -void Compiler::VSUBUWM(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - SetVr(vd, diff_v4i32); -} - -void Compiler::VSUBUWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - auto cmp_v4i1 = m_ir_builder->CreateICmpULE(diff_v4i32, va_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateAnd(diff_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set SAT -} - -void Compiler::VSUMSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto res_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(3)); - auto res_i64 = m_ir_builder->CreateSExt(res_i32, m_ir_builder->getInt64Ty()); - for (auto i = 0; i < 4; i++) { - auto va_i32 = m_ir_builder->CreateExtractElement(va_v4i32, m_ir_builder->getInt32(i)); - auto va_i64 = m_ir_builder->CreateSExt(va_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateAdd(res_i64, va_i64); - } - - auto gt_i1 = m_ir_builder->CreateICmpSGT(res_i64, m_ir_builder->getInt64(0x7FFFFFFFull)); - auto lt_i1 = m_ir_builder->CreateICmpSLT(res_i64, m_ir_builder->getInt64(0xFFFFFFFF80000000ull)); - res_i64 = m_ir_builder->CreateSelect(gt_i1, m_ir_builder->getInt64(0x7FFFFFFFull), res_i64); - res_i64 = m_ir_builder->CreateSelect(lt_i1, m_ir_builder->getInt64(0xFFFFFFFF80000000ull), res_i64); - auto res_i128 = m_ir_builder->CreateZExt(res_i64, m_ir_builder->getIntNTy(128)); - - SetVr(vd, res_i128); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM2SWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v2i32[2] = { 0, 2 }; - u32 mask2_v2i32[2] = { 1, 3 }; - auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto va1_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); - auto va2_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v2i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v2i64 = m_ir_builder->CreateShuffleVector(vb_v4i64, UndefValue::get(vb_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); - - auto res_v2i64 = m_ir_builder->CreateAdd(va1_v2i64, va2_v2i64); - res_v2i64 = m_ir_builder->CreateAdd(res_v2i64, vb_v2i64); - auto gt_v2i1 = m_ir_builder->CreateICmpSGT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v2i1 = m_ir_builder->CreateICmpSLT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v2i64 = m_ir_builder->CreateSelect(gt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v2i64); - res_v2i64 = m_ir_builder->CreateSelect(lt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x80000000ull)), res_v2i64); - SetVr(vd, res_v2i64); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4SBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; - u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; - u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; - u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; - auto va_v16i64 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt64Ty(), 16)); - auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto va3_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto va4_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - - auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va3_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va4_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); - res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4SHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 2, 4, 6 }; - u32 mask2_v4i32[4] = { 1, 3, 5, 7 }; - auto va_v8i64 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt64Ty(), 8)); - auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - - auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); - res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4UBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; - u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; - u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; - u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; - auto va1_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va1_v4i32 = m_ir_builder->CreateZExt(va1_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va2_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto va2_v4i32 = m_ir_builder->CreateZExt(va2_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va3_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto va3_v4i32 = m_ir_builder->CreateZExt(va3_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va4_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto va4_v4i32 = m_ir_builder->CreateZExt(va4_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto res_v4i32 = m_ir_builder->CreateAdd(va1_v4i32, va2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vb_v4i32); - auto lt_v4i1 = m_ir_builder->CreateICmpULT(res_v4i32, vb_v4i32); - auto lt_v4i32 = m_ir_builder->CreateSExt(lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateOr(lt_v4i32, res_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VUPKHPX(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = { 4, 4, 5, 5, 6, 6, 7, 7 }; - vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); - tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); - auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKHSB(u32 vd, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v8i32[8] = { 8, 9, 10, 11, 12, 13, 14, 15 }; - auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, res_v8i16); -} - -void Compiler::VUPKHSH(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v4i32[4] = { 4, 5, 6, 7 }; - auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKLPX(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = { 0, 0, 1, 1, 2, 2, 3, 3 }; - vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); - tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); - auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKLSB(u32 vd, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v8i32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, res_v8i16); -} - -void Compiler::VUPKLSH(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v4i32[4] = { 0, 1, 2, 3 }; - auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); -} - -void Compiler::VXOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateXor(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::MULLI(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - auto res_i64 = m_ir_builder->CreateMul(ra_i64, m_ir_builder->getInt64((s64)simm16)); - SetGpr(rd, res_i64); -} - -void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNeg(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16)); - auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, diff_i64); - SetXerCa(carry_i1); -} - -void Compiler::CMPLI(u32 crfd, u32 l, u32 ra, u32 uimm16) { - Value * ra_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - } - - SetCrFieldUnsignedCmp(crfd, ra_i64, m_ir_builder->getInt64(uimm16)); -} - -void Compiler::CMPI(u32 crfd, u32 l, u32 ra, s32 simm16) { - Value * ra_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - } - - SetCrFieldSignedCmp(crfd, ra_i64, m_ir_builder->getInt64((s64)simm16)); -} - -void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); -} - -void Compiler::ADDIC_(u32 rd, u32 ra, s32 simm16) { - ADDIC(rd, ra, simm16); - SetCrFieldSignedCmp(0, GetGpr(rd), m_ir_builder->getInt64(0)); -} - -void Compiler::ADDI(u32 rd, u32 ra, s32 simm16) { - if (ra == 0) { - SetGpr(rd, m_ir_builder->getInt64((s64)simm16)); - } else { - auto ra_i64 = GetGpr(ra); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16)); - SetGpr(rd, sum_i64); - } -} - -void Compiler::ADDIS(u32 rd, u32 ra, s32 simm16) { - if (ra == 0) { - SetGpr(rd, m_ir_builder->getInt64((s64)simm16 << 16)); - } else { - auto ra_i64 = GetGpr(ra); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16 << 16)); - SetGpr(rd, sum_i64); - } -} - -void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { - auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, bd)); - auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); -} - -void Compiler::SC(u32 lev) { - switch (lev) { - case 0: - Call("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); - break; - case 2: - Call("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute, - m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32)); - break; - case 3: - Call("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]); - break; - default: - CompilationError(fmt::Format("SC %u", lev)); - break; - } -} - -void Compiler::B(s32 ll, u32 aa, u32 lk) { - auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, ll)); - auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); - CreateBranch(nullptr, target_i32, lk ? true : false); -} - -void Compiler::MCRF(u32 crfd, u32 crfs) { - if (crfd != crfs) { - auto cr_i32 = GetCr(); - auto crf_i32 = GetNibble(cr_i32, crfs); - cr_i32 = SetNibble(cr_i32, crfd, crf_i32); - SetCr(cr_i32); - } -} - -void Compiler::BCLR(u32 bo, u32 bi, u32 bh, u32 lk) { - auto lr_i64 = GetLr(); - lr_i64 = m_ir_builder->CreateAnd(lr_i64, ~0x3ULL); - auto lr_i32 = m_ir_builder->CreateTrunc(lr_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), lr_i32, lk ? true : false, true); -} - -void Compiler::CRNOR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRANDC(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); - res_i32 = m_ir_builder->CreateAnd(ba_i32, res_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::ISYNC() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::CRXOR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::DCBI(u32 ra, u32 rb) { - // TODO: See if this can be translated to cache flush - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::CRNAND(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRAND(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CREQV(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRORC(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); - res_i32 = m_ir_builder->CreateOr(ba_i32, res_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CROR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { - auto ctr_i64 = GetCtr(); - ctr_i64 = m_ir_builder->CreateAnd(ctr_i64, ~0x3ULL); - auto ctr_i32 = m_ir_builder->CreateTrunc(ctr_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), ctr_i32, lk ? true : false); -} - -void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto ra_i64 = GetGpr(ra); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - u64 mask = s_rotate_mask[32 + mb][32 + me]; - res_i64 = m_ir_builder->CreateAnd(res_i64, mask); - ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); - res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto rb_i64 = GetGpr(rb); - auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x1F); - auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(32), shl_i64); - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); - auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ORI(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, uimm16); - SetGpr(ra, res_i64); -} - -void Compiler::ORIS(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); -} - -void Compiler::XORI(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, uimm16); - SetGpr(ra, res_i64); -} - -void Compiler::XORIS(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); -} - -void Compiler::ANDI_(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, uimm16); - SetGpr(ra, res_i64); - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); -} - -void Compiler::ANDIS_(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); -} - -void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63 - sh]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto ra_i64 = GetGpr(ra); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - u64 mask = s_rotate_mask[mb][63 - sh]; - res_i64 = m_ir_builder->CreateAnd(res_i64, mask); - ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); - res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x3F); - auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(64), shl_i64); - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); - auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - - if (is_r) { - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][m_eb]); - } else { - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[m_eb][63]); - } - - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CMP(u32 crfd, u32 l, u32 ra, u32 rb) { - Value * ra_i64; - Value * rb_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - rb_i64 = m_ir_builder->CreateSExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - rb_i64 = GetGpr(rb); - } - - SetCrFieldSignedCmp(crfd, ra_i64, rb_i64); -} - -void Compiler::TW(u32 to, u32 ra, u32 rb) { - CompilationError("TW"); -} - -void Compiler::LVSL(u32 vd, u32 ra, u32 rb) { - static const u128 s_lvsl_values[] = { - {0x08090A0B0C0D0E0F, 0x0001020304050607}, - {0x090A0B0C0D0E0F10, 0x0102030405060708}, - {0x0A0B0C0D0E0F1011, 0x0203040506070809}, - {0x0B0C0D0E0F101112, 0x030405060708090A}, - {0x0C0D0E0F10111213, 0x0405060708090A0B}, - {0x0D0E0F1011121314, 0x05060708090A0B0C}, - {0x0E0F101112131415, 0x060708090A0B0C0D}, - {0x0F10111213141516, 0x0708090A0B0C0D0E}, - {0x1011121314151617, 0x08090A0B0C0D0E0F}, - {0x1112131415161718, 0x090A0B0C0D0E0F10}, - {0x1213141516171819, 0x0A0B0C0D0E0F1011}, - {0x131415161718191A, 0x0B0C0D0E0F101112}, - {0x1415161718191A1B, 0x0C0D0E0F10111213}, - {0x15161718191A1B1C, 0x0D0E0F1011121314}, - {0x161718191A1B1C1D, 0x0E0F101112131415}, - {0x1718191A1B1C1D1E, 0x0F10111213141516}, - }; - +#include "stdafx.h" +#include "Utilities/Log.h" +#include "Emu/Cell/PPULLVMRecompiler.h" +#include "Emu/Memory/Memory.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/CodeGen/MachineCodeInfo.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/IR/Dominators.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Vectorize.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/IR/Verifier.h" + +using namespace llvm; +using namespace ppu_recompiler_llvm; + +u64 Compiler::s_rotate_mask[64][64]; +bool Compiler::s_rotate_mask_inited = false; + +Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block) + : m_recompilation_engine(recompilation_engine) { + InitializeNativeTarget(); + InitializeNativeTargetAsmPrinter(); + InitializeNativeTargetDisassembler(); + + m_llvm_context = new LLVMContext(); + m_ir_builder = new IRBuilder<>(*m_llvm_context); + m_module = new llvm::Module("Module", *m_llvm_context); + m_fpm = new FunctionPassManager(m_module); + + EngineBuilder engine_builder(m_module); + engine_builder.setMCPU(sys::getHostCPUName()); + engine_builder.setEngineKind(EngineKind::JIT); + engine_builder.setOptLevel(CodeGenOpt::Default); + m_execution_engine = engine_builder.create(); + + m_fpm->add(new DataLayoutPass(m_module)); + m_fpm->add(createNoAAPass()); + m_fpm->add(createBasicAliasAnalysisPass()); + m_fpm->add(createNoTargetTransformInfoPass()); + m_fpm->add(createEarlyCSEPass()); + m_fpm->add(createTailCallEliminationPass()); + m_fpm->add(createReassociatePass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(new DominatorTreeWrapperPass()); + m_fpm->add(new MemoryDependenceAnalysis()); + m_fpm->add(createGVNPass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(new MemoryDependenceAnalysis()); + m_fpm->add(createDeadStoreEliminationPass()); + m_fpm->add(new LoopInfo()); + m_fpm->add(new ScalarEvolution()); + m_fpm->add(createSLPVectorizerPass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(createCFGSimplificationPass()); + m_fpm->doInitialization(); + + std::vector arg_types; + arg_types.push_back(m_ir_builder->getInt8PtrTy()); + arg_types.push_back(m_ir_builder->getInt8PtrTy()); + arg_types.push_back(m_ir_builder->getInt64Ty()); + m_compiled_function_type = FunctionType::get(m_ir_builder->getInt32Ty(), arg_types, false); + + m_execute_unknown_function = (Function *)m_module->getOrInsertFunction("execute_unknown_function", m_compiled_function_type); + m_execute_unknown_function->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(m_execute_unknown_function, (void *)execute_unknown_function); + + m_execute_unknown_block = (Function *)m_module->getOrInsertFunction("execute_unknown_block", m_compiled_function_type); + m_execute_unknown_block->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(m_execute_unknown_block, (void *)execute_unknown_block); + + if (!s_rotate_mask_inited) { + InitRotateMask(); + s_rotate_mask_inited = true; + } +} + +Compiler::~Compiler() { + delete m_execution_engine; + delete m_fpm; + delete m_ir_builder; + delete m_llvm_context; +} + +Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & cfg, bool inline_all, bool generate_linkable_exits) { + auto compilation_start = std::chrono::high_resolution_clock::now(); + + m_state.cfg = &cfg; + m_state.inline_all = inline_all; + m_state.generate_linkable_exits = generate_linkable_exits; + + // Create the function + m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); + m_state.function->setCallingConv(CallingConv::X86_64_Win64); + auto arg_i = m_state.function->arg_begin(); + arg_i->setName("ppu_state"); + m_state.args[CompileTaskState::Args::State] = arg_i; + (++arg_i)->setName("context"); + m_state.args[CompileTaskState::Args::Context] = arg_i; + + // Create the entry block and add code to branch to the first instruction + m_ir_builder->SetInsertPoint(GetBasicBlockFromAddress(0)); + m_ir_builder->CreateBr(GetBasicBlockFromAddress(cfg.start_address)); + + // Convert each instruction in the CFG to LLVM IR + std::vector exit_instr_list; + for (auto instr_i = cfg.instruction_addresses.begin(); instr_i != cfg.instruction_addresses.end(); instr_i++) { + m_state.hit_branch_instruction = false; + m_state.current_instruction_address = *instr_i; + auto instr_bb = GetBasicBlockFromAddress(m_state.current_instruction_address); + m_ir_builder->SetInsertPoint(instr_bb); + + if (!inline_all && *instr_i != cfg.start_address) { + // Use an already compiled implementation of this block if available + auto ordinal = m_recompilation_engine.GetOrdinal(*instr_i); + if (ordinal != 0xFFFFFFFF) { + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + auto ret_i32 = IndirectCall(*instr_i, context_i64, false); + + auto switch_instr = m_ir_builder->CreateSwitch(ret_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); + auto branch_i = cfg.branches.find(*instr_i); + if (branch_i != cfg.branches.end()) { + for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { + switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); + } + } + } + } + + if (instr_bb->empty()) { + u32 instr = re32(vm::get_ref(m_state.current_instruction_address)); + Decode(instr); + if (!m_state.hit_branch_instruction) { + m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); + } + } + } + + // Generate exit logic for all empty blocks + auto default_exit_block_name = GetBasicBlockNameFromAddress(0xFFFFFFFF); + for (auto block_i = m_state.function->begin(); block_i != m_state.function->end(); block_i++) { + if (!block_i->getInstList().empty() || block_i->getName() == default_exit_block_name) { + continue; + } + + // Found an empty block + m_ir_builder->SetInsertPoint(block_i); + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + auto instr_address = GetAddressFromBasicBlockName(block_i->getName()); + SetPc(m_ir_builder->getInt32(instr_address)); + + if (generate_linkable_exits) { + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + auto ret_i32 = IndirectCall(instr_address, context_i64, false); + auto cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); + auto then_bb = GetBasicBlockFromAddress(instr_address, "then"); + auto merge_bb = GetBasicBlockFromAddress(instr_address, "merge"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + + m_ir_builder->SetInsertPoint(then_bb); + context_i64 = m_ir_builder->CreateZExt(ret_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); + m_ir_builder->CreateBr(merge_bb); + + m_ir_builder->SetInsertPoint(merge_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else { + m_ir_builder->CreateRet(exit_instr_i32); + } + } + + // If the function has a default exit block then generate code for it + auto default_exit_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "", false); + if (default_exit_bb) { + m_ir_builder->SetInsertPoint(default_exit_bb); + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + if (generate_linkable_exits) { + auto cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); + auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then"); + auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + + m_ir_builder->SetInsertPoint(then_bb); + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); + m_ir_builder->CreateBr(merge_bb); + + m_ir_builder->SetInsertPoint(merge_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else { + m_ir_builder->CreateRet(exit_instr_i32); + } + } + + // Add incoming values for all exit instr PHI nodes + for (auto exit_instr_i = exit_instr_list.begin(); exit_instr_i != exit_instr_list.end(); exit_instr_i++) { + auto block = (*exit_instr_i)->getParent(); + for (auto pred_i = pred_begin(block); pred_i != pred_end(block); pred_i++) { + auto pred_address = GetAddressFromBasicBlockName((*pred_i)->getName()); + (*exit_instr_i)->addIncoming(m_ir_builder->getInt32(pred_address), *pred_i); + } + } + +#ifdef _DEBUG + m_recompilation_engine.Log() << *m_state.function; + + std::string verify; + raw_string_ostream verify_ostream(verify); + if (verifyFunction(*m_state.function, &verify_ostream)) { + m_recompilation_engine.Log() << "Verification failed: " << verify << "\n"; + } +#endif + + auto ir_build_end = std::chrono::high_resolution_clock::now(); + m_stats.ir_build_time += std::chrono::duration_cast(ir_build_end - compilation_start); + + // Optimize this function + m_fpm->run(*m_state.function); + auto optimize_end = std::chrono::high_resolution_clock::now(); + m_stats.optimization_time += std::chrono::duration_cast(optimize_end - ir_build_end); + + // Translate to machine code + MachineCodeInfo mci; + m_execution_engine->runJITOnFunction(m_state.function, &mci); + auto translate_end = std::chrono::high_resolution_clock::now(); + m_stats.translation_time += std::chrono::duration_cast(translate_end - optimize_end); + +#ifdef _DEBUG + m_recompilation_engine.Log() << "\nDisassembly:\n"; + auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr); + for (size_t pc = 0; pc < mci.size();) { + char str[1024]; + + auto size = LLVMDisasmInstruction(disassembler, ((u8 *)mci.address()) + pc, mci.size() - pc, (uint64_t)(((u8 *)mci.address()) + pc), str, sizeof(str)); + m_recompilation_engine.Log() << fmt::Format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n'; + pc += size; + } + + LLVMDisasmDispose(disassembler); +#endif + + auto compilation_end = std::chrono::high_resolution_clock::now(); + m_stats.total_time += std::chrono::duration_cast(compilation_end - compilation_start); + + return (Executable)mci.address(); +} + +void Compiler::FreeExecutable(const std::string & name) { + auto function = m_module->getFunction(name); + if (function) { + m_execution_engine->freeMachineCodeForFunction(function); + function->eraseFromParent(); + } +} + +Compiler::Stats Compiler::GetStats() { + return m_stats; +} + +void Compiler::Decode(const u32 code) { + (*PPU_instr::main_list)(this, code); +} + +void Compiler::NULL_OP() { + CompilationError("NULL_OP"); +} + +void Compiler::NOP() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::TDI(u32 to, u32 ra, s32 simm16) { + CompilationError("TDI"); +} + +void Compiler::TWI(u32 to, u32 ra, s32 simm16) { + CompilationError("TWI"); +} + +void Compiler::MFVSCR(u32 vd) { + auto vscr_i32 = GetVscr(); + auto vscr_i128 = m_ir_builder->CreateZExt(vscr_i32, m_ir_builder->getIntNTy(128)); + SetVr(vd, vscr_i128); +} + +void Compiler::MTVSCR(u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto vscr_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(0)); + vscr_i32 = m_ir_builder->CreateAnd(vscr_i32, 0x00010001); + SetVscr(vscr_i32); +} + +void Compiler::VADDCUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + va_v4i32 = m_ir_builder->CreateNot(va_v4i32); + auto cmpv4i1 = m_ir_builder->CreateICmpULT(va_v4i32, vb_v4i32); + auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmpv4i32); +} + +void Compiler::VADDFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto sum_v4f32 = m_ir_builder->CreateFAdd(va_v4f32, vb_v4f32); + SetVr(vd, sum_v4f32); +} + +void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + // It looks like x86 does not have an instruction to add 32 bit intergers with signed/unsigned saturation. + // To implement add with saturation, we first determine what the result would be if the operation were to cause + // an overflow. If two -ve numbers are being added and cause an overflow, the result would be 0x80000000. + // If two +ve numbers are being added and cause an overflow, the result would be 0x7FFFFFFF. Addition of a -ve + // number and a +ve number cannot cause overflow. So the result in case of an overflow is 0x7FFFFFFF + sign bit + // of any one of the operands. + auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Next, we find if the addition can actually result in an overflow. Since an overflow can only happen if the operands + // have the same sign, we bitwise XOR both the operands. If the sign bit of the result is 0 then the operands have the + // same sign and so may cause an overflow. We invert the result so that the sign bit is 1 when the operands have the + // same sign. + auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); + tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); + + // Perform the sum. + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // If an overflow occurs, then the sign of the sum will be different from the sign of the operands. So, we xor the + // result with one of the operands. The sign bit of the result will be 1 if the sign bit of the sum and the sign bit of the + // result is different. This result is again ANDed with tmp3 (the sign bit of tmp3 is 1 only if the operands have the same + // sign and so can cause an overflow). + auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, sum_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set SAT +} + +void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateAdd(va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); +} + +void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); + + // TODO: Set SAT +} + +void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateAdd(va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); +} + +void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); + + // TODO: Set SAT +} + +void Compiler::VADDUWM(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + SetVr(vd, sum_v4i32); +} + +void Compiler::VADDUWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + auto cmp_v4i1 = m_ir_builder->CreateICmpULT(sum_v4i32, va_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateOr(sum_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set SAT +} + +void Compiler::VAND(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VANDC(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateNot(vb_v4i32); + auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VAVGSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateSExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto sum_v16i16 = m_ir_builder->CreateAdd(va_v16i16, vb_v16i16); + sum_v16i16 = m_ir_builder->CreateAdd(sum_v16i16, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt16(1))); + auto avg_v16i16 = m_ir_builder->CreateAShr(sum_v16i16, 1); + auto avg_v16i8 = m_ir_builder->CreateTrunc(avg_v16i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, avg_v16i8); +} + +void Compiler::VAVGSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto sum_v8i32 = m_ir_builder->CreateAdd(va_v8i32, vb_v8i32); + sum_v8i32 = m_ir_builder->CreateAdd(sum_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(1))); + auto avg_v8i32 = m_ir_builder->CreateAShr(sum_v8i32, 1); + auto avg_v8i16 = m_ir_builder->CreateTrunc(avg_v8i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, avg_v8i16); +} + +void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); + sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); + auto avg_v4i64 = m_ir_builder->CreateAShr(sum_v4i64, 1); + auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, avg_v4i32); +} + +void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8); + SetVr(vd, avg_v16i8); +} + +void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16); + SetVr(vd, avg_v8i16); +} + +void Compiler::VAVGUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto va_v4i64 = m_ir_builder->CreateZExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v4i64 = m_ir_builder->CreateZExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); + sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); + auto avg_v4i64 = m_ir_builder->CreateLShr(sum_v4i64, 1); + auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, avg_v4i32); +} + +void Compiler::VCFSX(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4f32 = m_ir_builder->CreateSIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); + + if (uimm5) { + float scale = (float)((u64)1 << uimm5); + res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); + } + + SetVr(vd, res_v4f32); +} + +void Compiler::VCFUX(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4f32 = m_ir_builder->CreateUIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); + + if (uimm5) { + float scale = (float)((u64)1 << uimm5); + res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); + } + + SetVr(vd, res_v4f32); +} + +void Compiler::VCMPBFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_gt_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); + vb_v4f32 = m_ir_builder->CreateFNeg(vb_v4f32); + auto cmp_lt_v4i1 = m_ir_builder->CreateFCmpOLT(va_v4f32, vb_v4f32); + auto cmp_gt_v4i32 = m_ir_builder->CreateZExt(cmp_gt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto cmp_lt_v4i32 = m_ir_builder->CreateZExt(cmp_lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + cmp_gt_v4i32 = m_ir_builder->CreateShl(cmp_gt_v4i32, 31); + cmp_lt_v4i32 = m_ir_builder->CreateShl(cmp_lt_v4i32, 30); + auto res_v4i32 = m_ir_builder->CreateOr(cmp_gt_v4i32, cmp_lt_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Implement NJ mode +} + +void Compiler::VCMPBFP_(u32 vd, u32 va, u32 vb) { + VCMPBFP(vd, va, vb); + + auto vd_v16i8 = GetVrAsIntVec(vd, 8); + u32 mask_v16i32[16] = {3, 7, 11, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + vd_v16i8 = m_ir_builder->CreateShuffleVector(vd_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + auto vd_v4i32 = m_ir_builder->CreateBitCast(vd_v16i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto vd_mask_i32 = m_ir_builder->CreateExtractElement(vd_v4i32, m_ir_builder->getInt32(0)); + auto cmp_i1 = m_ir_builder->CreateICmpEQ(vd_mask_i32, m_ir_builder->getInt32(0)); + SetCrField(6, nullptr, nullptr, cmp_i1, nullptr); +} + +void Compiler::VCMPEQFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOEQ(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPEQFP_(u32 vd, u32 va, u32 vb) { + VCMPEQFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpEQ(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPEQUB_(u32 vd, u32 va, u32 vb) { + VCMPEQUB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpEQ(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPEQUH_(u32 vd, u32 va, u32 vb) { + VCMPEQUH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpEQ(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPEQUW_(u32 vd, u32 va, u32 vb) { + VCMPEQUW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGEFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGEFP_(u32 vd, u32 va, u32 vb) { + VCMPGEFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTFP_(u32 vd, u32 va, u32 vb) { + VCMPGTFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpSGT(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPGTSB_(u32 vd, u32 va, u32 vb) { + VCMPGTSB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpSGT(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPGTSH_(u32 vd, u32 va, u32 vb) { + VCMPGTSH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpSGT(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTSW_(u32 vd, u32 va, u32 vb) { + VCMPGTSW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpUGT(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPGTUB_(u32 vd, u32 va, u32 vb) { + VCMPGTUB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpUGT(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPGTUH_(u32 vd, u32 va, u32 vb) { + VCMPGTUH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpUGT(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTUW_(u32 vd, u32 va, u32 vb) { + VCMPGTUW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCTSXS(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + if (uimm5) { + vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); + } + + auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_cvtps2dq), vb_v4f32); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0x7FFFFFFF))); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateXor(cmp_v4i32, res_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + if (uimm5) { + vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); + } + + auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0))); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu))); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VEXPTEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)), + m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VLOGEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::log2, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto vc_v4f32 = GetVrAsFloatVec(vc); + auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); + + u32 mask1_v4i32[4] = {0, 1, 2, 3}; + auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {4, 5, 6, 7}; + auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(0x4000))); + res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); + + u32 mask1_v4i32[4] = {0, 1, 2, 3}; + auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {4, 5, 6, 7}; + auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMINFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMINSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMINSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMINSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMINUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMINUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMINUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMLADDUHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + res_v8i16 = m_ir_builder->CreateAdd(res_v8i16, vc_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMRGHB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v16i32[16] = {24, 8, 25, 9, 26, 10, 27, 11, 28, 12, 29, 13, 30, 14, 31, 15}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VMRGHH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = {12, 4, 13, 5, 14, 6, 15, 7}; + auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VMRGHW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + u32 mask_v4i32[4] = {6, 2, 7, 3}; + auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VMRGLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v16i32[16] = {16, 0, 17, 1, 18, 2, 19, 3, 20, 4, 21, 5, 22, 6, 23, 7}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VMRGLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = {8, 0, 9, 1, 10, 2, 11, 3}; + auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VMRGLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + u32 mask_v4i32[4] = {4, 0, 5, 1}; + auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); + + auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); + u32 mask1_v4i32[4] = {0, 4, 8, 12}; + auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp1_v4i32 = m_ir_builder->CreateSExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask2_v4i32[4] = {1, 5, 9, 13}; + auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto tmp2_v4i32 = m_ir_builder->CreateSExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask3_v4i32[4] = {2, 6, 10, 14}; + auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto tmp3_v4i32 = m_ir_builder->CreateSExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask4_v4i32[4] = {3, 7, 11, 15}; + auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto tmp4_v4i32 = m_ir_builder->CreateSExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); + + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto tmp2_v4i32 = m_ir_builder->CreateXor(vc_v4i32, res_v4i32); + tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); + auto sum_v4i32 = m_ir_builder->CreateAdd(vc_v4i32, res_v4i32); + auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto tmp3_v4i32 = m_ir_builder->CreateXor(vc_v4i32, sum_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMSUMUBM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateZExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); + + auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); + u32 mask1_v4i32[4] = {0, 4, 8, 12}; + auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp1_v4i32 = m_ir_builder->CreateZExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask2_v4i32[4] = {1, 5, 9, 13}; + auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto tmp2_v4i32 = m_ir_builder->CreateZExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask3_v4i32[4] = {2, 6, 10, 14}; + auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto tmp3_v4i32 = m_ir_builder->CreateZExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask4_v4i32[4] = {3, 7, 11, 15}; + auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto tmp4_v4i32 = m_ir_builder->CreateZExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMUHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + + auto undef_v8i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)); + u32 mask1_v4i32[4] = {0, 2, 4, 6}; + auto tmp1_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {1, 3, 5, 7}; + auto tmp2_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMUHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + auto tmp_v8i64 = m_ir_builder->CreateZExt(tmp_v8i32, VectorType::get(m_ir_builder->getInt64Ty(), 8)); + + u32 mask1_v4i32[4] = {0, 2, 4, 6}; + u32 mask2_v4i32[4] = {1, 3, 5, 7}; + auto tmp1_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp2_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto vc_v4i64 = m_ir_builder->CreateZExt(vc_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto res_v4i64 = m_ir_builder->CreateAdd(tmp1_v4i64, tmp2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vc_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpUGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF))); + auto gt_v4i64 = m_ir_builder->CreateSExt(gt_v4i1, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + res_v4i64 = m_ir_builder->CreateOr(res_v4i64, gt_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMULESB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULESH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULEUB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULEUH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULOSB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); + va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULOSH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); + va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULOUB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); + va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULOUH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); + va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto vc_v4f32 = GetVrAsFloatVec(vc); + vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VNOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); + res_v8i16 = m_ir_builder->CreateNot(res_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto vc_v16i8 = GetVrAsIntVec(vc, 8); + + auto thrity_one_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(31)); + vc_v16i8 = m_ir_builder->CreateAnd(vc_v16i8, thrity_one_v16i8); + + auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15)); + auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8); + auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8); + + auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8); + auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8); + auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8); + auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8); + + auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VPKPX(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto tmpa_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); + tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); + tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); + tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); + tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); + auto tmpa_v8i16 = m_ir_builder->CreateBitCast(tmpa_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + auto tmpb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); + tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); + tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); + tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); + tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); + auto tmpb_v8i16 = m_ir_builder->CreateBitCast(tmpb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + u32 mask_v8i32[8] = {1, 3, 5, 7, 9, 11, 13, 15}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(tmpb_v8i16, tmpa_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + SetVr(vd, res_v8i16); + + // TODO: Implement with pext on CPUs with BMI +} + +void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16); + SetVr(vd, res_v16i8); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16); + SetVr(vd, res_v16i8); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32); + SetVr(vd, res_v8i16); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32); + SetVr(vd, res_v8i16); + + // TODO: VSCR.SAT +} + +void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + + u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, res_v16i8); +} + +void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); + vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); + auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, res_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + + u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, res_v8i16); +} + +void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); + vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); + auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VREFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIM(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::floor, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIN(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::nearbyint, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ceil, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIZ(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::trunc, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(7))); + auto tmp1_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); + vb_v16i8 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(8)), vb_v16i8); + auto tmp2_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); + auto res_v16i8 = m_ir_builder->CreateOr(tmp1_v16i8, tmp2_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VRLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto tmp1_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); + vb_v8i16 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0x10)), vb_v8i16); + auto tmp2_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); + auto res_v8i16 = m_ir_builder->CreateOr(tmp1_v8i16, tmp2_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VRLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto tmp1_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); + vb_v4i32 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x20)), vb_v4i32); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); + auto res_v4i32 = m_ir_builder->CreateOr(tmp1_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VRSQRTEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), res_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VSEL(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, vc_v4i32); + vc_v4i32 = m_ir_builder->CreateNot(vc_v4i32); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vc_v4i32); + auto vd_v4i32 = m_ir_builder->CreateOr(va_v4i32, vb_v4i32); + SetVr(vd, vd_v4i32); +} + +void Compiler::VSL(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSLDOI(u32 vd, u32 va, u32 vb, u32 sh) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + sh = 16 - sh; + u32 mask_v16i32[16] = {sh, sh + 1, sh + 2, sh + 3, sh + 4, sh + 5, sh + 6, sh + 7, sh + 8, sh + 9, sh + 10, sh + 11, sh + 12, sh + 13, sh + 14, sh + 15}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VSLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSLO(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSPLTB(u32 vd, u32 uimm5, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto undef_v16i8 = UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto mask_v16i32 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt32(15 - uimm5)); + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, undef_v16i8, mask_v16i32); + SetVr(vd, res_v16i8); +} + +void Compiler::VSPLTH(u32 vd, u32 uimm5, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto undef_v8i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)); + auto mask_v8i32 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(7 - uimm5)); + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, undef_v8i16, mask_v8i32); + SetVr(vd, res_v8i16); +} + +void Compiler::VSPLTISB(u32 vd, s32 simm5) { + auto vd_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8((s8)simm5)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VSPLTISH(u32 vd, s32 simm5) { + auto vd_v8i16 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16((s16)simm5)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VSPLTISW(u32 vd, s32 simm5) { + auto vd_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32((s32)simm5)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VSPLTW(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto undef_v4i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto mask_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3 - uimm5)); + auto res_v4i32 = m_ir_builder->CreateShuffleVector(vb_v4i32, undef_v4i32, mask_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSR(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSRAB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateAShr(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSRAH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateAShr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSRAW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateAShr(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSRB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSRH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSRO(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSRW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSUBCUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto cmpv4i1 = m_ir_builder->CreateICmpUGE(va_v4i32, vb_v4i32); + auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmpv4i32); +} + +void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto diff_v4f32 = m_ir_builder->CreateFSub(va_v4f32, vb_v4f32); + SetVr(vd, diff_v4f32); +} + +void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + // See the comments for VADDSWS for a detailed description of how this works + + // Find the result in case of an overflow + auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Find the elements that can overflow (elements with opposite sign bits) + auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); + + // Perform the sub + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + auto diff_v16i8 = m_ir_builder->CreateBitCast(diff_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Find the elements that overflowed + auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, diff_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set SAT +} + +void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateSub(va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); +} + +void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); + + // TODO: Set SAT +} + +void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateSub(va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); +} + +void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); + + // TODO: Set SAT +} + +void Compiler::VSUBUWM(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + SetVr(vd, diff_v4i32); +} + +void Compiler::VSUBUWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + auto cmp_v4i1 = m_ir_builder->CreateICmpULE(diff_v4i32, va_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateAnd(diff_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set SAT +} + +void Compiler::VSUMSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto res_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(3)); + auto res_i64 = m_ir_builder->CreateSExt(res_i32, m_ir_builder->getInt64Ty()); + for (auto i = 0; i < 4; i++) { + auto va_i32 = m_ir_builder->CreateExtractElement(va_v4i32, m_ir_builder->getInt32(i)); + auto va_i64 = m_ir_builder->CreateSExt(va_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateAdd(res_i64, va_i64); + } + + auto gt_i1 = m_ir_builder->CreateICmpSGT(res_i64, m_ir_builder->getInt64(0x7FFFFFFFull)); + auto lt_i1 = m_ir_builder->CreateICmpSLT(res_i64, m_ir_builder->getInt64(0xFFFFFFFF80000000ull)); + res_i64 = m_ir_builder->CreateSelect(gt_i1, m_ir_builder->getInt64(0x7FFFFFFFull), res_i64); + res_i64 = m_ir_builder->CreateSelect(lt_i1, m_ir_builder->getInt64(0xFFFFFFFF80000000ull), res_i64); + auto res_i128 = m_ir_builder->CreateZExt(res_i64, m_ir_builder->getIntNTy(128)); + + SetVr(vd, res_i128); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM2SWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v2i32[2] = { 0, 2 }; + u32 mask2_v2i32[2] = { 1, 3 }; + auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto va1_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); + auto va2_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v2i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v2i64 = m_ir_builder->CreateShuffleVector(vb_v4i64, UndefValue::get(vb_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); + + auto res_v2i64 = m_ir_builder->CreateAdd(va1_v2i64, va2_v2i64); + res_v2i64 = m_ir_builder->CreateAdd(res_v2i64, vb_v2i64); + auto gt_v2i1 = m_ir_builder->CreateICmpSGT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v2i1 = m_ir_builder->CreateICmpSLT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v2i64 = m_ir_builder->CreateSelect(gt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v2i64); + res_v2i64 = m_ir_builder->CreateSelect(lt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x80000000ull)), res_v2i64); + SetVr(vd, res_v2i64); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4SBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; + u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; + u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; + u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; + auto va_v16i64 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt64Ty(), 16)); + auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto va3_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto va4_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + + auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va3_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va4_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); + res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4SHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 2, 4, 6 }; + u32 mask2_v4i32[4] = { 1, 3, 5, 7 }; + auto va_v8i64 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt64Ty(), 8)); + auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + + auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); + res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4UBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; + u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; + u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; + u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; + auto va1_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va1_v4i32 = m_ir_builder->CreateZExt(va1_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va2_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto va2_v4i32 = m_ir_builder->CreateZExt(va2_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va3_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto va3_v4i32 = m_ir_builder->CreateZExt(va3_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va4_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto va4_v4i32 = m_ir_builder->CreateZExt(va4_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto res_v4i32 = m_ir_builder->CreateAdd(va1_v4i32, va2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vb_v4i32); + auto lt_v4i1 = m_ir_builder->CreateICmpULT(res_v4i32, vb_v4i32); + auto lt_v4i32 = m_ir_builder->CreateSExt(lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateOr(lt_v4i32, res_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VUPKHPX(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = { 4, 4, 5, 5, 6, 6, 7, 7 }; + vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); + tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); + auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKHSB(u32 vd, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v8i32[8] = { 8, 9, 10, 11, 12, 13, 14, 15 }; + auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, res_v8i16); +} + +void Compiler::VUPKHSH(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v4i32[4] = { 4, 5, 6, 7 }; + auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKLPX(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = { 0, 0, 1, 1, 2, 2, 3, 3 }; + vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); + tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); + auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKLSB(u32 vd, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v8i32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, res_v8i16); +} + +void Compiler::VUPKLSH(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v4i32[4] = { 0, 1, 2, 3 }; + auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); +} + +void Compiler::VXOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateXor(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::MULLI(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + auto res_i64 = m_ir_builder->CreateMul(ra_i64, m_ir_builder->getInt64((s64)simm16)); + SetGpr(rd, res_i64); +} + +void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNeg(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16)); + auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, diff_i64); + SetXerCa(carry_i1); +} + +void Compiler::CMPLI(u32 crfd, u32 l, u32 ra, u32 uimm16) { + Value * ra_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + } + + SetCrFieldUnsignedCmp(crfd, ra_i64, m_ir_builder->getInt64(uimm16)); +} + +void Compiler::CMPI(u32 crfd, u32 l, u32 ra, s32 simm16) { + Value * ra_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + } + + SetCrFieldSignedCmp(crfd, ra_i64, m_ir_builder->getInt64((s64)simm16)); +} + +void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); +} + +void Compiler::ADDIC_(u32 rd, u32 ra, s32 simm16) { + ADDIC(rd, ra, simm16); + SetCrFieldSignedCmp(0, GetGpr(rd), m_ir_builder->getInt64(0)); +} + +void Compiler::ADDI(u32 rd, u32 ra, s32 simm16) { + if (ra == 0) { + SetGpr(rd, m_ir_builder->getInt64((s64)simm16)); + } else { + auto ra_i64 = GetGpr(ra); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16)); + SetGpr(rd, sum_i64); + } +} + +void Compiler::ADDIS(u32 rd, u32 ra, s32 simm16) { + if (ra == 0) { + SetGpr(rd, m_ir_builder->getInt64((s64)simm16 << 16)); + } else { + auto ra_i64 = GetGpr(ra); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16 << 16)); + SetGpr(rd, sum_i64); + } +} + +void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { + auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, bd)); + auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); +} + +void Compiler::SC(u32 lev) { + switch (lev) { + case 0: + Call("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); + break; + case 2: + Call("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute, + m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32)); + break; + case 3: + Call("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]); + break; + default: + CompilationError(fmt::Format("SC %u", lev)); + break; + } +} + +void Compiler::B(s32 ll, u32 aa, u32 lk) { + auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, ll)); + auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); + CreateBranch(nullptr, target_i32, lk ? true : false); +} + +void Compiler::MCRF(u32 crfd, u32 crfs) { + if (crfd != crfs) { + auto cr_i32 = GetCr(); + auto crf_i32 = GetNibble(cr_i32, crfs); + cr_i32 = SetNibble(cr_i32, crfd, crf_i32); + SetCr(cr_i32); + } +} + +void Compiler::BCLR(u32 bo, u32 bi, u32 bh, u32 lk) { + auto lr_i64 = GetLr(); + lr_i64 = m_ir_builder->CreateAnd(lr_i64, ~0x3ULL); + auto lr_i32 = m_ir_builder->CreateTrunc(lr_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), lr_i32, lk ? true : false, true); +} + +void Compiler::CRNOR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRANDC(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); + res_i32 = m_ir_builder->CreateAnd(ba_i32, res_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::ISYNC() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::CRXOR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::DCBI(u32 ra, u32 rb) { + // TODO: See if this can be translated to cache flush + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::CRNAND(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRAND(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CREQV(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRORC(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); + res_i32 = m_ir_builder->CreateOr(ba_i32, res_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CROR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { + auto ctr_i64 = GetCtr(); + ctr_i64 = m_ir_builder->CreateAnd(ctr_i64, ~0x3ULL); + auto ctr_i32 = m_ir_builder->CreateTrunc(ctr_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), ctr_i32, lk ? true : false); +} + +void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto ra_i64 = GetGpr(ra); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + u64 mask = s_rotate_mask[32 + mb][32 + me]; + res_i64 = m_ir_builder->CreateAnd(res_i64, mask); + ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); + res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto rb_i64 = GetGpr(rb); + auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x1F); + auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(32), shl_i64); + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); + auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ORI(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, uimm16); + SetGpr(ra, res_i64); +} + +void Compiler::ORIS(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); +} + +void Compiler::XORI(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, uimm16); + SetGpr(ra, res_i64); +} + +void Compiler::XORIS(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); +} + +void Compiler::ANDI_(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, uimm16); + SetGpr(ra, res_i64); + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); +} + +void Compiler::ANDIS_(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); +} + +void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63 - sh]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto ra_i64 = GetGpr(ra); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + u64 mask = s_rotate_mask[mb][63 - sh]; + res_i64 = m_ir_builder->CreateAnd(res_i64, mask); + ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); + res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x3F); + auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(64), shl_i64); + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); + auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + + if (is_r) { + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][m_eb]); + } else { + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[m_eb][63]); + } + + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CMP(u32 crfd, u32 l, u32 ra, u32 rb) { + Value * ra_i64; + Value * rb_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + rb_i64 = m_ir_builder->CreateSExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + rb_i64 = GetGpr(rb); + } + + SetCrFieldSignedCmp(crfd, ra_i64, rb_i64); +} + +void Compiler::TW(u32 to, u32 ra, u32 rb) { + CompilationError("TW"); +} + +void Compiler::LVSL(u32 vd, u32 ra, u32 rb) { + static const u128 s_lvsl_values[] = { + {0x08090A0B0C0D0E0F, 0x0001020304050607}, + {0x090A0B0C0D0E0F10, 0x0102030405060708}, + {0x0A0B0C0D0E0F1011, 0x0203040506070809}, + {0x0B0C0D0E0F101112, 0x030405060708090A}, + {0x0C0D0E0F10111213, 0x0405060708090A0B}, + {0x0D0E0F1011121314, 0x05060708090A0B0C}, + {0x0E0F101112131415, 0x060708090A0B0C0D}, + {0x0F10111213141516, 0x0708090A0B0C0D0E}, + {0x1011121314151617, 0x08090A0B0C0D0E0F}, + {0x1112131415161718, 0x090A0B0C0D0E0F10}, + {0x1213141516171819, 0x0A0B0C0D0E0F1011}, + {0x131415161718191A, 0x0B0C0D0E0F101112}, + {0x1415161718191A1B, 0x0C0D0E0F10111213}, + {0x15161718191A1B1C, 0x0D0E0F1011121314}, + {0x161718191A1B1C1D, 0x0E0F101112131415}, + {0x1718191A1B1C1D1E, 0x0F10111213141516}, + }; + + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + auto lvsl_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsl_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); + lvsl_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsl_values_v16i8_ptr, index_i64); + auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsl_values_v16i8_ptr, 16); + SetVr(vd, val_v16i8); +} + +void Compiler::LVEBX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto val_i8 = ReadMemory(addr_i64, 8); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); + auto vd_v16i8 = GetVrAsIntVec(vd, 8); + vd_v16i8 = m_ir_builder->CreateInsertElement(vd_v16i8, val_i8, index_i64); + SetVr(vd, vd_v16i8); +} + +void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNeg(ra_i64); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); + auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, diff_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFCO"); + } +} + +void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + } +} + +void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128)); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128)); + auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); + prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); + auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateZExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + prod_i64 = m_ir_builder->CreateLShr(prod_i64, 32); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MFOCRF(u32 a, u32 rd, u32 crm) { + auto cr_i32 = GetCr(); + auto cr_i64 = m_ir_builder->CreateZExt(cr_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, cr_i64); +} + +void Compiler::LWARX(u32 rd, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - auto lvsl_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsl_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); - lvsl_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsl_values_v16i8_ptr, index_i64); - auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsl_values_v16i8_ptr, 16); - SetVr(vd, val_v16i8); -} - -void Compiler::LVEBX(u32 vd, u32 ra, u32 rb) { + + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); + auto val_i32_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt32Ty()); + val_i32_ptr->setAlignment(4); + Call("vm.reservation_acquire_no_cb", vm::reservation_acquire_no_cb, m_ir_builder->CreateBitCast(val_i32_ptr, m_ir_builder->getInt8PtrTy()), addr_i32, m_ir_builder->getInt32(4)); + auto val_i32 = (Value *)m_ir_builder->CreateLoad(val_i32_ptr); + val_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_i32); + auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, val_i64); +} + +void Compiler::LDX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); +} + +void Compiler::LWZX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateShl(rs_i64, rb_i64); + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false)); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateShl(rs_i128, rb_i128); + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::AND(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { + Value * ra_i64; + Value * rb_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + rb_i64 = m_ir_builder->CreateZExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + rb_i64 = GetGpr(rb); + } + + SetCrFieldUnsignedCmp(crfd, ra_i64, rb_i64); +} + +void Compiler::LVSR(u32 vd, u32 ra, u32 rb) { + static const u128 s_lvsr_values[] = { + {0x18191A1B1C1D1E1F, 0x1011121314151617}, + {0x1718191A1B1C1D1E, 0x0F10111213141516}, + {0x161718191A1B1C1D, 0x0E0F101112131415}, + {0x15161718191A1B1C, 0x0D0E0F1011121314}, + {0x1415161718191A1B, 0x0C0D0E0F10111213}, + {0x131415161718191A, 0x0B0C0D0E0F101112}, + {0x1213141516171819, 0x0A0B0C0D0E0F1011}, + {0x1112131415161718, 0x090A0B0C0D0E0F10}, + {0x1011121314151617, 0x08090A0B0C0D0E0F}, + {0x0F10111213141516, 0x0708090A0B0C0D0E}, + {0x0E0F101112131415, 0x060708090A0B0C0D}, + {0x0D0E0F1011121314, 0x05060708090A0B0C}, + {0x0C0D0E0F10111213, 0x0405060708090A0B}, + {0x0B0C0D0E0F101112, 0x030405060708090A}, + {0x0A0B0C0D0E0F1011, 0x0203040506070809}, + {0x090A0B0C0D0E0F10, 0x0102030405060708}, + }; + + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + auto lvsr_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsr_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); + lvsr_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsr_values_v16i8_ptr, index_i64); + auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsr_values_v16i8_ptr, 16); + SetVr(vd, val_v16i8); +} + +void Compiler::LVEHX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); + auto val_i16 = ReadMemory(addr_i64, 16, 2); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 1); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); + auto vd_v8i16 = GetVrAsIntVec(vd, 16); + vd_v8i16 = m_ir_builder->CreateInsertElement(vd_v8i16, val_i16, index_i64); + SetVr(vd, vd_v8i16); +} + +void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto diff_i64 = m_ir_builder->CreateSub(rb_i64, ra_i64); + SetGpr(rd, diff_i64); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFO"); + } +} + +void Compiler::LDUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::DCBST(u32 ra, u32 rb) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false)); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + rb_i64 = m_ir_builder->CreateNot(rb_i64); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::TD(u32 to, u32 ra, u32 rb) { + CompilationError("TD"); +} + +void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); + auto val_i32 = ReadMemory(addr_i64, 32, 4); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 2); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); + auto vd_v4i32 = GetVrAsIntVec(vd, 32); + vd_v4i32 = m_ir_builder->CreateInsertElement(vd_v4i32, val_i32, index_i64); + SetVr(vd, vd_v4i32); +} + +void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128)); + auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128)); + auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); + prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); + auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MULHW(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + prod_i64 = m_ir_builder->CreateAShr(prod_i64, 32); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LDARX(u32 rd, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - - auto val_i8 = ReadMemory(addr_i64, 8); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); - auto vd_v16i8 = GetVrAsIntVec(vd, 8); - vd_v16i8 = m_ir_builder->CreateInsertElement(vd_v16i8, val_i8, index_i64); - SetVr(vd, vd_v16i8); -} - -void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNeg(ra_i64); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); - auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, diff_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); + auto val_i64_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt64Ty()); + val_i64_ptr->setAlignment(8); + Call("vm.reservation_acquire_no_cb", vm::reservation_acquire_no_cb, m_ir_builder->CreateBitCast(val_i64_ptr, m_ir_builder->getInt8PtrTy()), addr_i32, m_ir_builder->getInt32(8)); + auto val_i64 = (Value *)m_ir_builder->CreateLoad(val_i64_ptr); + val_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt64Ty()), val_i64); + SetGpr(rd, val_i64); +} + +void Compiler::DCBF(u32 ra, u32 rb) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LBZX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LVX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + SetVr(vd, mem_i128); +} + +void Compiler::NEG(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto diff_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(0), ra_i64); + SetGpr(rd, diff_i64); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("NEGO"); + } +} + +void Compiler::LBZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::NOR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateXor(res_i64, (s64)-1); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVEBX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); + auto vs_v16i8 = GetVrAsIntVec(vs, 8); + auto val_i8 = m_ir_builder->CreateExtractElement(vs_v16i8, index_i64); + WriteMemory(addr_i64, val_i8); +} + +void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFEO"); + } +} + +void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDEO"); + } +} + +void Compiler::MTOCRF(u32 l, u32 crm, u32 rs) { + auto rs_i32 = GetGpr(rs, 32); + auto cr_i32 = GetCr(); + u32 mask = 0; + + for (u32 i = 0; i < 8; i++) { + if (crm & (1 << i)) { + mask |= 0xF << ((7 - i) * 4); + if (l) { + break; + } + } + } + + cr_i32 = m_ir_builder->CreateAnd(cr_i32, ~mask); + rs_i32 = m_ir_builder->CreateAnd(rs_i32, ~mask); + cr_i32 = m_ir_builder->CreateOr(cr_i32, rs_i32); + SetCr(cr_i32); +} + +void Compiler::STDX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 64)); +} + +void Compiler::STWCX_(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFCO"); - } -} - -void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - } -} - -void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128)); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128)); - auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); - prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); - auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateZExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - prod_i64 = m_ir_builder->CreateLShr(prod_i64, 32); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MFOCRF(u32 a, u32 rd, u32 crm) { + + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); + auto rs_i32 = GetGpr(rs, 32); + rs_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), rs_i32); + auto rs_i32_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt32Ty()); + rs_i32_ptr->setAlignment(4); + m_ir_builder->CreateStore(rs_i32, rs_i32_ptr); + auto success_i1 = Call("vm.reservation_update", vm::reservation_update, addr_i32, m_ir_builder->CreateBitCast(rs_i32_ptr, m_ir_builder->getInt8PtrTy()), m_ir_builder->getInt32(4)); + auto cr_i32 = GetCr(); - auto cr_i64 = m_ir_builder->CreateZExt(cr_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, cr_i64); -} - -void Compiler::LWARX(u32 rd, u32 ra, u32 rb) { - throw __FUNCTION__; - - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto resv_addr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_ADDR)); - //auto resv_addr_i64_ptr = m_ir_builder->CreateBitCast(resv_addr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //m_ir_builder->CreateAlignedStore(addr_i64, resv_addr_i64_ptr, 8); - - //auto resv_val_i32 = ReadMemory(addr_i64, 32, 4, false, false); - //auto resv_val_i64 = m_ir_builder->CreateZExt(resv_val_i32, m_ir_builder->getInt64Ty()); - //auto resv_val_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_VALUE)); - //auto resv_val_i64_ptr = m_ir_builder->CreateBitCast(resv_val_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //m_ir_builder->CreateAlignedStore(resv_val_i64, resv_val_i64_ptr, 8); - - //resv_val_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), resv_val_i32); - //resv_val_i64 = m_ir_builder->CreateZExt(resv_val_i32, m_ir_builder->getInt64Ty()); - //SetGpr(rd, resv_val_i64); -} - -void Compiler::LDX(u32 rd, u32 ra, u32 rb) { + cr_i32 = SetBit(cr_i32, 2, success_i1); + SetCr(cr_i32); +} + +void Compiler::STWX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STVEHX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 1); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); + auto vs_v8i16 = GetVrAsIntVec(vs, 16); + auto val_i16 = m_ir_builder->CreateExtractElement(vs_v8i16, index_i64); + WriteMemory(addr_i64, val_i16, 2); +} + +void Compiler::STDUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 64)); + SetGpr(ra, addr_i64); +} + +void Compiler::STWUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 32)); + SetGpr(ra, addr_i64); +} + +void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 2); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); + auto vs_v4i32 = GetVrAsIntVec(vs, 32); + auto val_i32 = m_ir_builder->CreateExtractElement(vs_v4i32, index_i64); + WriteMemory(addr_i64, val_i32, 4); +} + +void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto ca_i64 = GetXerCa(); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDZEO"); + } +} + +void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto ca_i64 = GetXerCa(); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFZEO"); + } +} + +void Compiler::STDCX_(u32 rs, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); -} - -void Compiler::LWZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateShl(rs_i64, rb_i64); - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false)); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateShl(rs_i128, rb_i128); - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::AND(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { - Value * ra_i64; - Value * rb_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - rb_i64 = m_ir_builder->CreateZExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - rb_i64 = GetGpr(rb); - } - - SetCrFieldUnsignedCmp(crfd, ra_i64, rb_i64); -} - -void Compiler::LVSR(u32 vd, u32 ra, u32 rb) { - static const u128 s_lvsr_values[] = { - {0x18191A1B1C1D1E1F, 0x1011121314151617}, - {0x1718191A1B1C1D1E, 0x0F10111213141516}, - {0x161718191A1B1C1D, 0x0E0F101112131415}, - {0x15161718191A1B1C, 0x0D0E0F1011121314}, - {0x1415161718191A1B, 0x0C0D0E0F10111213}, - {0x131415161718191A, 0x0B0C0D0E0F101112}, - {0x1213141516171819, 0x0A0B0C0D0E0F1011}, - {0x1112131415161718, 0x090A0B0C0D0E0F10}, - {0x1011121314151617, 0x08090A0B0C0D0E0F}, - {0x0F10111213141516, 0x0708090A0B0C0D0E}, - {0x0E0F101112131415, 0x060708090A0B0C0D}, - {0x0D0E0F1011121314, 0x05060708090A0B0C}, - {0x0C0D0E0F10111213, 0x0405060708090A0B}, - {0x0B0C0D0E0F101112, 0x030405060708090A}, - {0x0A0B0C0D0E0F1011, 0x0203040506070809}, - {0x090A0B0C0D0E0F10, 0x0102030405060708}, - }; - - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - auto lvsr_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsr_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); - lvsr_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsr_values_v16i8_ptr, index_i64); - auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsr_values_v16i8_ptr, 16); - SetVr(vd, val_v16i8); -} - -void Compiler::LVEHX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); - auto val_i16 = ReadMemory(addr_i64, 16, 2); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 1); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); - auto vd_v8i16 = GetVrAsIntVec(vd, 16); - vd_v8i16 = m_ir_builder->CreateInsertElement(vd_v8i16, val_i16, index_i64); - SetVr(vd, vd_v8i16); -} - -void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto diff_i64 = m_ir_builder->CreateSub(rb_i64, ra_i64); - SetGpr(rd, diff_i64); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFO"); - } -} - -void Compiler::LDUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::DCBST(u32 ra, u32 rb) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false)); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - rb_i64 = m_ir_builder->CreateNot(rb_i64); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::TD(u32 to, u32 ra, u32 rb) { - CompilationError("TD"); -} - -void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); - auto val_i32 = ReadMemory(addr_i64, 32, 4); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 2); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); - auto vd_v4i32 = GetVrAsIntVec(vd, 32); - vd_v4i32 = m_ir_builder->CreateInsertElement(vd_v4i32, val_i32, index_i64); - SetVr(vd, vd_v4i32); -} - -void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128)); - auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128)); - auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); - prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); - auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MULHW(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - prod_i64 = m_ir_builder->CreateAShr(prod_i64, 32); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LDARX(u32 rd, u32 ra, u32 rb) { - throw __FUNCTION__; - - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto resv_addr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_ADDR)); - //auto resv_addr_i64_ptr = m_ir_builder->CreateBitCast(resv_addr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //m_ir_builder->CreateAlignedStore(addr_i64, resv_addr_i64_ptr, 8); - - //auto resv_val_i64 = ReadMemory(addr_i64, 64, 8, false); - //auto resv_val_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_VALUE)); - //auto resv_val_i64_ptr = m_ir_builder->CreateBitCast(resv_val_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //m_ir_builder->CreateAlignedStore(resv_val_i64, resv_val_i64_ptr, 8); - - //resv_val_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt64Ty()), resv_val_i64); - //SetGpr(rd, resv_val_i64); -} - -void Compiler::DCBF(u32 ra, u32 rb) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LBZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LVX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - SetVr(vd, mem_i128); -} - -void Compiler::NEG(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto diff_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(0), ra_i64); - SetGpr(rd, diff_i64); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("NEGO"); - } -} - -void Compiler::LBZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::NOR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateXor(res_i64, (s64)-1); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVEBX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); - auto vs_v16i8 = GetVrAsIntVec(vs, 8); - auto val_i8 = m_ir_builder->CreateExtractElement(vs_v16i8, index_i64); - WriteMemory(addr_i64, val_i8); -} - -void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFEO"); - } -} - -void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDEO"); - } -} - -void Compiler::MTOCRF(u32 l, u32 crm, u32 rs) { - auto rs_i32 = GetGpr(rs, 32); + + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); + auto rs_i64 = GetGpr(rs); + rs_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt64Ty()), rs_i64); + auto rs_i64_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt64Ty()); + rs_i64_ptr->setAlignment(8); + m_ir_builder->CreateStore(rs_i64, rs_i64_ptr); + auto success_i1 = Call("vm.reservation_update", vm::reservation_update, addr_i32, m_ir_builder->CreateBitCast(rs_i64_ptr, m_ir_builder->getInt8PtrTy()), m_ir_builder->getInt32(8)); + auto cr_i32 = GetCr(); - u32 mask = 0; - - for (u32 i = 0; i < 8; i++) { - if (crm & (1 << i)) { - mask |= 0xF << ((7 - i) * 4); - if (l) { - break; - } - } - } - - cr_i32 = m_ir_builder->CreateAnd(cr_i32, ~mask); - rs_i32 = m_ir_builder->CreateAnd(rs_i32, ~mask); - cr_i32 = m_ir_builder->CreateOr(cr_i32, rs_i32); + cr_i32 = SetBit(cr_i32, 2, success_i1); SetCr(cr_i32); -} - -void Compiler::STDX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 64)); -} - -void Compiler::STWCX_(u32 rs, u32 ra, u32 rb) { - throw __FUNCTION__; - - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto resv_addr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_ADDR)); - //auto resv_addr_i64_ptr = m_ir_builder->CreateBitCast(resv_addr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //auto resv_addr_i64 = (Value *)m_ir_builder->CreateAlignedLoad(resv_addr_i64_ptr, 8); - //auto cmp_i1 = m_ir_builder->CreateICmpEQ(addr_i64, resv_addr_i64); - - //auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then"); - //auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "else"); - //auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge"); - //m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); - - //m_ir_builder->SetInsertPoint(then_bb); - //auto rs_i32 = GetGpr(rs, 32); - //rs_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, rs_i32->getType()), rs_i32); - //resv_addr_i64 = m_ir_builder->CreateAdd(resv_addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - //auto resv_addr_val_i32_ptr = m_ir_builder->CreateIntToPtr(resv_addr_i64, m_ir_builder->getInt32Ty()->getPointerTo()); - //auto resv_val_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_VALUE)); - //auto resv_val_i32_ptr = m_ir_builder->CreateBitCast(resv_val_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - //auto resv_val_i32 = m_ir_builder->CreateAlignedLoad(resv_val_i32_ptr, 8); - - //auto res_s = m_ir_builder->CreateAtomicCmpXchg(resv_addr_val_i32_ptr, resv_val_i32, rs_i32, AtomicOrdering::AcquireRelease, AtomicOrdering::Monotonic); - //auto success_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - //auto cr_i32 = GetCr(); - //cr_i32 = SetBit(cr_i32, 2, success_i1); - //SetCr(cr_i32); - //m_ir_builder->CreateAlignedStore(m_ir_builder->getInt64(0), resv_addr_i64_ptr, 8); - //m_ir_builder->CreateBr(merge_bb); - - //m_ir_builder->SetInsertPoint(else_bb); - //cr_i32 = GetCr(); - //cr_i32 = ClrBit(cr_i32, 2); - //SetCr(cr_i32); - //m_ir_builder->CreateBr(merge_bb); - //m_ir_builder->SetInsertPoint(merge_bb); -} - -void Compiler::STWX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STVEHX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 1); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); - auto vs_v8i16 = GetVrAsIntVec(vs, 16); - auto val_i16 = m_ir_builder->CreateExtractElement(vs_v8i16, index_i64); - WriteMemory(addr_i64, val_i16, 2); -} - -void Compiler::STDUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 64)); - SetGpr(ra, addr_i64); -} - -void Compiler::STWUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 32)); - SetGpr(ra, addr_i64); -} - -void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 2); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); - auto vs_v4i32 = GetVrAsIntVec(vs, 32); - auto val_i32 = m_ir_builder->CreateExtractElement(vs_v4i32, index_i64); - WriteMemory(addr_i64, val_i32, 4); -} - -void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto ca_i64 = GetXerCa(); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDZEO"); - } -} - -void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto ca_i64 = GetXerCa(); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFZEO"); - } -} - -void Compiler::STDCX_(u32 rs, u32 ra, u32 rb) { - throw __FUNCTION__; - - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto resv_addr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_ADDR)); - //auto resv_addr_i64_ptr = m_ir_builder->CreateBitCast(resv_addr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //auto resv_addr_i64 = (Value *)m_ir_builder->CreateAlignedLoad(resv_addr_i64_ptr, 8); - //auto cmp_i1 = m_ir_builder->CreateICmpEQ(addr_i64, resv_addr_i64); - - //auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then"); - //auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "else"); - //auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge"); - //m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); - - //m_ir_builder->SetInsertPoint(then_bb); - //auto rs_i64 = GetGpr(rs, 64); - //rs_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, rs_i64->getType()), rs_i64); - //resv_addr_i64 = m_ir_builder->CreateAdd(resv_addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - //auto resv_addr_val_i64_ptr = m_ir_builder->CreateIntToPtr(resv_addr_i64, m_ir_builder->getInt64Ty()->getPointerTo()); - //auto resv_val_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, R_VALUE)); - //auto resv_val_i64_ptr = m_ir_builder->CreateBitCast(resv_val_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - //auto resv_val_i64 = m_ir_builder->CreateAlignedLoad(resv_val_i64_ptr, 8); - - //auto res_s = m_ir_builder->CreateAtomicCmpXchg(resv_addr_val_i64_ptr, resv_val_i64, rs_i64, AtomicOrdering::AcquireRelease, AtomicOrdering::Monotonic); - //auto success_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - //auto cr_i32 = GetCr(); - //cr_i32 = SetBit(cr_i32, 2, success_i1); - //SetCr(cr_i32); - //m_ir_builder->CreateAlignedStore(m_ir_builder->getInt64(0), resv_addr_i64_ptr, 8); - //m_ir_builder->CreateBr(merge_bb); - - //m_ir_builder->SetInsertPoint(else_bb); - //cr_i32 = GetCr(); - //cr_i32 = ClrBit(cr_i32, 2); - //SetCr(cr_i32); - //m_ir_builder->CreateBr(merge_bb); - //m_ir_builder->SetInsertPoint(merge_bb); -} - -void Compiler::STBX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 8)); -} - -void Compiler::STVX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - WriteMemory(addr_i64, GetVr(vs), 16); -} - -void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFMEO"); - } -} - -void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("MULLDO"); - } -} - -void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDMEO"); - } -} - -void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("MULLWO"); - } -} - -void Compiler::DCBTST(u32 ra, u32 rb, u32 th) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::STBUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 8)); - SetGpr(ra, addr_i64); -} - -void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, rb_i64); - SetGpr(rd, sum_i64); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDO"); - } -} - -void Compiler::DCBT(u32 ra, u32 rb, u32 th) { - // TODO: Implement this using prefetch - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateNot(res_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) { - throw __FUNCTION__; - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto mem_i32 = ReadMemory(addr_i64, 32); - //auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - //SetGpr(rd, mem_i64); -} - -void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::XOR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MFSPR(u32 rd, u32 spr) { - Value * rd_i64; - auto n = (spr >> 5) | ((spr & 0x1f) << 5); - - switch (n) { - case 0x001: - rd_i64 = GetXer(); - break; - case 0x008: - rd_i64 = GetLr(); - break; - case 0x009: - rd_i64 = GetCtr(); - break; - case 0x100: - rd_i64 = GetVrsave(); - break; - case 0x10C: - rd_i64 = Call("get_time", get_time); - break; - case 0x10D: - rd_i64 = Call("get_time", get_time); - rd_i64 = m_ir_builder->CreateLShr(rd_i64, 32); - break; - default: - assert(0); - break; - } - - SetGpr(rd, rd_i64); -} - -void Compiler::LWAX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::DST(u32 ra, u32 rb, u32 strm, u32 t) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHAX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LVXL(u32 vd, u32 ra, u32 rb) { - LVX(vd, ra, rb); -} - -void Compiler::MFTB(u32 rd, u32 spr) { - auto tb_i64 = Call("get_time", get_time); - - u32 n = (spr >> 5) | ((spr & 0x1f) << 5); - if (n == 0x10D) { - tb_i64 = m_ir_builder->CreateLShr(tb_i64, 32); - } - - SetGpr(rd, tb_i64); -} - -void Compiler::LWAUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::DSTST(u32 ra, u32 rb, u32 strm, u32 t) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHAUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STHX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16)); -} - -void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - rb_i64 = m_ir_builder->CreateNot(rb_i64); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) { - throw __FUNCTION__; - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STHUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 16)); - SetGpr(ra, addr_i64); -} - -void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateUDiv(ra_i64, rb_i64); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVDUO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto res_i32 = m_ir_builder->CreateUDiv(ra_i32, rb_i32); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVWUO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::MTSPR(u32 spr, u32 rs) { - auto rs_i64 = GetGpr(rs); - auto n = (spr >> 5) | ((spr & 0x1f) << 5); - - switch (n) { - case 0x001: - SetXer(rs_i64); - break; - case 0x008: - SetLr(rs_i64); - break; - case 0x009: - SetCtr(rs_i64); - break; - case 0x100: - SetVrsave(rs_i64); - break; - default: - assert(0); - break; - } - -} - -void Compiler::NAND(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateNot(res_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVXL(u32 vs, u32 ra, u32 rb) { - STVX(vs, ra, rb); -} - -void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateSDiv(ra_i64, rb_i64); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVDO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto res_i32 = m_ir_builder->CreateSDiv(ra_i32, rb_i32); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVWO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::LVLX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto eb_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); - auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - mem_i128 = m_ir_builder->CreateShl(mem_i128, eb_i128); - SetVr(vd, mem_i128); -} - -void Compiler::LDBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64, 0, false); - SetGpr(rd, mem_i64); -} - -void Compiler::LSWX(u32 rd, u32 ra, u32 rb) { - CompilationError("LSWX"); -} - -void Compiler::LWBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32, 0, false); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LFSX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); -} - -void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateLShr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateLShr(rs_i128, rb_i128); - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LVRX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto eb_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), addr_i64); - eb_i64 = m_ir_builder->CreateAnd(eb_i64, 0xF); - eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); - auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - mem_i128 = m_ir_builder->CreateLShr(mem_i128, eb_i128); - auto cmp_i1 = m_ir_builder->CreateICmpNE(eb_i64, m_ir_builder->getInt64(0)); - auto cmp_i128 = m_ir_builder->CreateSExt(cmp_i1, m_ir_builder->getIntNTy(128)); - mem_i128 = m_ir_builder->CreateAnd(mem_i128, cmp_i128); - SetVr(vd, mem_i128); -} - -void Compiler::LSWI(u32 rd, u32 ra, u32 nb) { - auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); - - nb = nb ? nb : 32; - for (u32 i = 0; i < nb; i += 4) { - auto val_i32 = ReadMemory(addr_i64, 32, 0, true, false); - - if (i + 4 <= nb) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } else { - u32 mask = 0xFFFFFFFF << ((4 - (nb - i)) * 8); - val_i32 = m_ir_builder->CreateAnd(val_i32, mask); - } - - auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, val_i64); - rd = (rd + 1) % 32; - } -} - -void Compiler::LFSUX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::SYNC(u32 l) { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::LFDX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); -} - -void Compiler::LFDUX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STVLX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - auto size_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), index_i64); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - auto vs_i128 = GetVr(vs); - vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); - auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); - vs_i128_ptr->setAlignment(16); - m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); - auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); - - Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), - addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); -} - -void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs), 0, false); -} - -void Compiler::STSWX(u32 rs, u32 ra, u32 rb) { - CompilationError("STSWX"); -} - -void Compiler::STWBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32), 0, false); -} - -void Compiler::STFSX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::STVRX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto size_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - auto index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), size_i64); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFF0); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - auto vs_i128 = GetVr(vs); - vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); - auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); - vs_i128_ptr->setAlignment(16); - m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); - auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); - vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64); - - Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), - addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); -} - -void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::STSWI(u32 rd, u32 ra, u32 nb) { - auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); - - nb = nb ? nb : 32; - for (u32 i = 0; i < nb; i += 4) { - auto val_i32 = GetGpr(rd, 32); - - if (i + 4 <= nb) { - WriteMemory(addr_i64, val_i32, 0, true, false); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - rd = (rd + 1) % 32; - } else { - u32 n = nb - i; - if (n >= 2) { - auto val_i16 = m_ir_builder->CreateLShr(val_i32, 16); - val_i16 = m_ir_builder->CreateTrunc(val_i16, m_ir_builder->getInt16Ty()); - WriteMemory(addr_i64, val_i16); - - if (n == 3) { - auto val_i8 = m_ir_builder->CreateLShr(val_i32, 8); - val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(2)); - WriteMemory(addr_i64, val_i8); - } - } else { - auto val_i8 = m_ir_builder->CreateLShr(val_i32, 24); - val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); - WriteMemory(addr_i64, val_i8); - } - } - } -} - -void Compiler::STFDX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); -} - -void Compiler::STFDUX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LVLXL(u32 vd, u32 ra, u32 rb) { - LVLX(vd, ra, rb); -} - -void Compiler::LHBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16, 0, false); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateAShr(rs_i64, rb_i64); - auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); - SetGpr(ra, ra_i64); - - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateAShr(rs_i128, rb_i128); - auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); - auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, ra_i64); - - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LVRXL(u32 vd, u32 ra, u32 rb) { - LVRX(vd, ra, rb); -} - -void Compiler::DSS(u32 strm, u32 a) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); - auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh); - auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); - SetGpr(ra, ra_i64); - - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); - auto res_i128 = m_ir_builder->CreateAShr(rs_i128, sh); - auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); - auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, ra_i64); - - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { - SRADI1(ra, rs, sh, rc); -} - -void Compiler::EIEIO() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::STVLXL(u32 vs, u32 ra, u32 rb) { - STVLX(vs, ra, rb); -} - -void Compiler::STHBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16), 0, false); -} - -void Compiler::EXTSH(u32 ra, u32 rs, bool rc) { - auto rs_i16 = GetGpr(rs, 16); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i16, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVRXL(u32 vs, u32 ra, u32 rb) { - STVRX(vs, ra, rb); -} - -void Compiler::EXTSB(u32 ra, u32 rs, bool rc) { - auto rs_i8 = GetGpr(rs, 8); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i8, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STFIWX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - auto frs_i32 = m_ir_builder->CreateTrunc(frs_i64, m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::EXTSW(u32 ra, u32 rs, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ICBI(u32 ra, u32 rs) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::DCBZ(u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, ~(127ULL)); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - std::vector types = {(Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty()}; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types), - addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true)); -} - -void Compiler::LWZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LWZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LBZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LBZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STW(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STWU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 32)); - SetGpr(ra, addr_i64); -} - -void Compiler::STB(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 8)); -} - -void Compiler::STBU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 8)); - SetGpr(ra, addr_i64); -} - -void Compiler::LHZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LHZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LHA(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LHAU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STH(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16)); -} - -void Compiler::STHU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 16)); - SetGpr(ra, addr_i64); -} - -void Compiler::LMW(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); - } - - for (u32 i = rd; i < 32; i++) { - auto val_i32 = ReadMemory(addr_i64, 32); - auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); - SetGpr(i, val_i64); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } -} - -void Compiler::STMW(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); - } - - for (u32 i = rs; i < 32; i++) { - auto val_i32 = GetGpr(i, 32); - WriteMemory(addr_i64, val_i32); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } -} - -void Compiler::LFS(u32 frd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); -} - -void Compiler::LFSU(u32 frd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::LFD(u32 frd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); -} - -void Compiler::LFDU(u32 frd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STFS(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::STFSU(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::STFD(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); -} - -void Compiler::STFDU(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LD(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); -} - -void Compiler::LDU(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LWA(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FDIVS."); - } - - // TODO: Set flags -} - -void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FADDS."); - } - - // TODO: Set flags -} - -void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FSQRTS."); - } - - // TODO: Set flags -} - -void Compiler::FRES(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FRES."); - } - - // TODO: Set flags -} - -void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMULS."); - } - - // TODO: Set flags -} - -void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMADDS."); - } - - // TODO: Set flags -} - -void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FNMSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FNMADDS."); - } - - // TODO: Set flags -} - -void Compiler::STD(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 64)); -} - -void Compiler::STDU(u32 rs, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 64)); - SetGpr(ra, addr_i64); -} - -void Compiler::MTFSB1(u32 crbd, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSB1."); - } -} - -void Compiler::MCRFS(u32 crbd, u32 crbs) { - auto fpscr_i32 = GetFpscr(); - auto val_i32 = GetNibble(fpscr_i32, crbs); - SetCrField(crbd, val_i32); - - switch (crbs) { - case 0: - fpscr_i32 = ClrBit(fpscr_i32, 0); - fpscr_i32 = ClrBit(fpscr_i32, 3); - break; - case 1: - fpscr_i32 = ClrNibble(fpscr_i32, 1); - break; - case 2: - fpscr_i32 = ClrNibble(fpscr_i32, 2); - break; - case 3: - fpscr_i32 = ClrBit(fpscr_i32, 12); - break; - case 5: - fpscr_i32 = ClrBit(fpscr_i32, 21); - fpscr_i32 = ClrBit(fpscr_i32, 22); - fpscr_i32 = ClrBit(fpscr_i32, 23); - break; - default: - break; - } - - SetFpscr(fpscr_i32); -} - -void Compiler::MTFSB0(u32 crbd, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = ClrBit(fpscr_i32, crbd); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSB0."); - } -} - -void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF)); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSFI."); - } -} - -void Compiler::MFFS(u32 frd, bool rc) { - auto fpscr_i32 = GetFpscr(); - auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty()); - SetFpr(frd, fpscr_i64); - - if (rc) { - // TODO: Implement this - CompilationError("MFFS."); - } -} - -void Compiler::MTFSF(u32 flm, u32 frb, bool rc) { - u32 mask = 0; - for(u32 i = 0; i < 8; i++) { - if (flm & (1 << i)) { - mask |= 0xF << (i * 4); - } - } - - auto rb_i32 = GetFpr(frb, 32, true); - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = m_ir_builder->CreateAnd(fpscr_i32, ~mask); - rb_i32 = m_ir_builder->CreateAnd(rb_i32, mask); - fpscr_i32 = m_ir_builder->CreateOr(fpscr_i32, rb_i32); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSF."); - } -} - -void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); - auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); - auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); - SetCr(cr_i32); - - // TODO: Set flags / Handle NaN -} - -void Compiler::FRSP(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f32 = m_ir_builder->CreateFPTrunc(rb_f64, m_ir_builder->getFloatTy()); - auto res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy()); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FRSP."); - } - - // TODO: Revisit this - // TODO: Set flags -} - -void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); - auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIW."); - } - - // TODO: Set flags / Implement rounding modes -} - -void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); - auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIWZ."); - } - - // TODO: Set flags -} - -void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FDIV."); - } - - // TODO: Set flags -} - -void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSUB."); - } - - // TODO: Set flags -} - -void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FADD."); - } - - // TODO: Set flags -} - -void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSQRT."); - } - - // TODO: Set flags -} - -void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto cmp_i1 = m_ir_builder->CreateFCmpOGE(ra_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0.0)); - auto res_f64 = m_ir_builder->CreateSelect(cmp_i1, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSEL."); - } - - // TODO: Set flags -} - -void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMUL."); - } - - // TODO: Set flags -} - -void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), res_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FRSQRTE."); - } -} - -void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMSUB."); - } - - // TODO: Set flags -} - -void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMADD."); - } - - // TODO: Set flags -} - -void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rc_f64 = m_ir_builder->CreateFNeg(rc_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNMSUB."); - } - - // TODO: Set flags -} - -void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - rc_f64 = m_ir_builder->CreateFNeg(rc_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNMADD."); - } - - // TODO: Set flags -} - -void Compiler::FCMPO(u32 crfd, u32 fra, u32 frb) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); - auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); - auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); - SetCr(cr_i32); - - // TODO: Set flags / Handle NaN -} - -void Compiler::FNEG(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - SetFpr(frd, rb_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNEG."); - } - - // TODO: Set flags -} - -void Compiler::FMR(u32 frd, u32 frb, bool rc) { - SetFpr(frd, GetFpr(frb)); - - if (rc) { - // TODO: Implement this - CompilationError("FMR."); - } - - // TODO: Set flags -} - -void Compiler::FNABS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNABS."); - } - - // TODO: Set flags -} - -void Compiler::FABS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FABS."); - } - - // TODO: Set flags -} - -void Compiler::FCTID(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); - auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTID."); - } - - // TODO: Set flags / Implement rounding modes -} - -void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); - auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIDZ."); - } - - // TODO: Set flags -} - -void Compiler::FCFID(u32 frd, u32 frb, bool rc) { - auto rb_i64 = GetFpr(frb, 64, true); - auto res_f64 = m_ir_builder->CreateSIToFP(rb_i64, m_ir_builder->getDoubleTy()); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FCFID."); - } - - // TODO: Set flags -} - -void Compiler::UNK(const u32 code, const u32 opcode, const u32 gcode) { - CompilationError(fmt::Format("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode)); -} - -std::string Compiler::GetBasicBlockNameFromAddress(u32 address, const std::string & suffix) const { - std::string name; - - if (address == 0) { - name = "entry"; - } else if (address == 0xFFFFFFFF) { - name = "default_exit"; - } else { - name = fmt::Format("instr_0x%08X", address); - } - - if (suffix != "") { - name += "_" + suffix; - } - - return name; -} - -u32 Compiler::GetAddressFromBasicBlockName(const std::string & name) const { - if (name.compare(0, 6, "instr_") == 0) { - return strtoul(name.c_str() + 6, nullptr, 0); - } else if (name == GetBasicBlockNameFromAddress(0)) { - return 0; - } else if (name == GetBasicBlockNameFromAddress(0xFFFFFFFF)) { - return 0xFFFFFFFF; - } - - return 0; -} - -BasicBlock * Compiler::GetBasicBlockFromAddress(u32 address, const std::string & suffix, bool create_if_not_exist) { - auto block_name = GetBasicBlockNameFromAddress(address, suffix); - BasicBlock * block = nullptr; - BasicBlock * next_block = nullptr; - for (auto i = m_state.function->begin(); i != m_state.function->end(); i++) { - if (i->getName() == block_name) { - block = &(*i); - break; - } - -#ifdef _DEBUG - auto block_address = GetAddressFromBasicBlockName(i->getName()); - if (block_address > address) { - next_block = &(*i); - break; - } -#endif - } - - if (!block && create_if_not_exist) { - block = BasicBlock::Create(m_ir_builder->getContext(), block_name, m_state.function, next_block); - } - - return block; -} - -Value * Compiler::GetBit(Value * val, u32 n) { - Value * bit; - -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - if (val->getType()->isIntegerTy(32)) { - bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31- n))); - } else if (val->getType()->isIntegerTy(64)) { - bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n))); - } else { -#endif - if (val->getType()->getIntegerBitWidth() != (n + 1)) { - bit = m_ir_builder->CreateLShr(val, val->getType()->getIntegerBitWidth() - n - 1); - } - - bit = m_ir_builder->CreateAnd(bit, 1); -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - } -#endif - - return bit; -} - -Value * Compiler::ClrBit(Value * val, u32 n) { - return m_ir_builder->CreateAnd(val, ~((u64)1 << (val->getType()->getIntegerBitWidth() - n - 1))); -} - -Value * Compiler::SetBit(Value * val, u32 n, Value * bit, bool doClear) { - if (doClear) { - val = ClrBit(val, n); - } - - if (bit->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { - bit = m_ir_builder->CreateZExt(bit, val->getType()); - } else if (bit->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { - bit = m_ir_builder->CreateTrunc(bit, val->getType()); - } - - if (val->getType()->getIntegerBitWidth() != (n + 1)) { - bit = m_ir_builder->CreateShl(bit, bit->getType()->getIntegerBitWidth() - n - 1); - } - - return m_ir_builder->CreateOr(val, bit); -} - -Value * Compiler::GetNibble(Value * val, u32 n) { - Value * nibble; - -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - if (val->getType()->isIntegerTy(32)) { - nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4))); - } else if (val->getType()->isIntegerTy(64)) { - nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4))); - } else { -#endif - if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { - val = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); - } - - nibble = m_ir_builder->CreateAnd(val, 0xF); -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - } -#endif - - return nibble; -} - -Value * Compiler::ClrNibble(Value * val, u32 n) { - return m_ir_builder->CreateAnd(val, ~((u64)0xF << ((((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4))); -} - -Value * Compiler::SetNibble(Value * val, u32 n, Value * nibble, bool doClear) { - if (doClear) { - val = ClrNibble(val, n); - } - - if (nibble->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { - nibble = m_ir_builder->CreateZExt(nibble, val->getType()); - } else if (nibble->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { - nibble = m_ir_builder->CreateTrunc(nibble, val->getType()); - } - - if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { - nibble = m_ir_builder->CreateShl(nibble, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); - } - - return m_ir_builder->CreateOr(val, nibble); -} - -Value * Compiler::SetNibble(Value * val, u32 n, Value * b0, Value * b1, Value * b2, Value * b3, bool doClear) { - if (doClear) { - val = ClrNibble(val, n); - } - - if (b0) { - val = SetBit(val, n * 4, b0, false); - } - - if (b1) { - val = SetBit(val, (n * 4) + 1, b1, false); - } - - if (b2) { - val = SetBit(val, (n * 4) + 2, b2, false); - } - - if (b3) { - val = SetBit(val, (n * 4) + 3, b3, false); - } - - return val; -} - -Value * Compiler::GetPc() { - auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); - auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(pc_i32_ptr, 4); -} - -void Compiler::SetPc(Value * val_ix) { - auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); - auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_ix, m_ir_builder->getInt32Ty()); - m_ir_builder->CreateAlignedStore(val_i32, pc_i32_ptr, 4); -} - -Value * Compiler::GetGpr(u32 r, u32 num_bits) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); - auto r_ix_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getIntNTy(num_bits)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(r_ix_ptr, 8); -} - -void Compiler::SetGpr(u32 r, Value * val_x64) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); - auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - m_ir_builder->CreateAlignedStore(val_i64, r_i64_ptr, 8); -} - -Value * Compiler::GetCr() { - auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); - auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(cr_i32_ptr, 4); -} - -Value * Compiler::GetCrField(u32 n) { - return GetNibble(GetCr(), n); -} - -void Compiler::SetCr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); - auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, cr_i32_ptr, 4); -} - -void Compiler::SetCrField(u32 n, Value * field) { - SetCr(SetNibble(GetCr(), n, field)); -} - -void Compiler::SetCrField(u32 n, Value * b0, Value * b1, Value * b2, Value * b3) { - SetCr(SetNibble(GetCr(), n, b0, b1, b2, b3)); -} - -void Compiler::SetCrFieldSignedCmp(u32 n, Value * a, Value * b) { - auto lt_i1 = m_ir_builder->CreateICmpSLT(a, b); - auto gt_i1 = m_ir_builder->CreateICmpSGT(a, b); - auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); - SetCr(cr_i32); -} - -void Compiler::SetCrFieldUnsignedCmp(u32 n, Value * a, Value * b) { - auto lt_i1 = m_ir_builder->CreateICmpULT(a, b); - auto gt_i1 = m_ir_builder->CreateICmpUGT(a, b); - auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); - SetCr(cr_i32); -} - -void Compiler::SetCr6AfterVectorCompare(u32 vr) { - auto vr_v16i8 = GetVrAsIntVec(vr, 8); - auto vr_mask_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmovmskb_128), vr_v16i8); - auto cmp0_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0)); - auto cmp1_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0xFFFF)); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, 6, cmp1_i1, nullptr, cmp0_i1, nullptr); - SetCr(cr_i32); -} - -Value * Compiler::GetLr() { - auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); - auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(lr_i64_ptr, 8); -} - -void Compiler::SetLr(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); - auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, lr_i64_ptr, 8); -} - -Value * Compiler::GetCtr() { - auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); - auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(ctr_i64_ptr, 8); -} - -void Compiler::SetCtr(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); - auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, ctr_i64_ptr, 8); -} - -Value * Compiler::GetXer() { - auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); - auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(xer_i64_ptr, 8); -} - -Value * Compiler::GetXerCa() { - return GetBit(GetXer(), 34); -} - -Value * Compiler::GetXerSo() { - return GetBit(GetXer(), 32); -} - -void Compiler::SetXer(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); - auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, xer_i64_ptr, 8); -} - -void Compiler::SetXerCa(Value * ca) { - auto xer_i64 = GetXer(); - xer_i64 = SetBit(xer_i64, 34, ca); - SetXer(xer_i64); -} - -void Compiler::SetXerSo(Value * so) { - auto xer_i64 = GetXer(); - xer_i64 = SetBit(xer_i64, 32, so); - SetXer(xer_i64); -} - -Value * Compiler::GetVrsave() { - auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); - auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4); - return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty()); -} - -void Compiler::SetVrsave(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty()); - auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); - auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8); -} - -Value * Compiler::GetFpscr() { - auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); - auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4); -} - -void Compiler::SetFpscr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); - auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4); -} - -Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); - if (!as_int) { - auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); - auto r_f64 = m_ir_builder->CreateAlignedLoad(r_f64_ptr, 8); - if (bits == 32) { - return m_ir_builder->CreateFPTrunc(r_f64, m_ir_builder->getFloatTy()); - } else { - return r_f64; - } - } else { - auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - auto r_i64 = m_ir_builder->CreateAlignedLoad(r_i64_ptr, 8); - if (bits == 32) { - return m_ir_builder->CreateTrunc(r_i64, m_ir_builder->getInt32Ty()); - } else { - return r_i64; - } - } -} - -void Compiler::SetFpr(u32 r, Value * val) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); - auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); - - Value* val_f64; - if (val->getType()->isDoubleTy() || val->getType()->isIntegerTy(64)) { - val_f64 = m_ir_builder->CreateBitCast(val, m_ir_builder->getDoubleTy()); - } else if (val->getType()->isFloatTy() || val->getType()->isIntegerTy(32)) { - auto val_f32 = m_ir_builder->CreateBitCast(val, m_ir_builder->getFloatTy()); - val_f64 = m_ir_builder->CreateFPExt(val_f32, m_ir_builder->getDoubleTy()); - } else { - assert(0); - } - - m_ir_builder->CreateAlignedStore(val_f64, r_f64_ptr, 8); -} - -Value * Compiler::GetVscr() { - auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); - auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vscr_i32_ptr, 4); -} - -void Compiler::SetVscr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); - auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, vscr_i32_ptr, 4); -} - -Value * Compiler::GetVr(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_i128_ptr, 16); -} - -Value * Compiler::GetVrAsIntVec(u32 vr, u32 vec_elt_num_bits) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_vec_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getIntNTy(vec_elt_num_bits), 128 / vec_elt_num_bits)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_vec_ptr, 16); -} - -Value * Compiler::GetVrAsFloatVec(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_v4f32_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getFloatTy(), 4)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_v4f32_ptr, 16); -} - -Value * Compiler::GetVrAsDoubleVec(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_v2f64_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getDoubleTy(), 2)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_v2f64_ptr, 16); -} - -void Compiler::SetVr(u32 vr, Value * val_x128) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto val_i128 = m_ir_builder->CreateBitCast(val_x128, m_ir_builder->getIntNTy(128)); - m_ir_builder->CreateAlignedStore(val_i128, vr_i128_ptr, 16); -} - -Value * Compiler::CheckBranchCondition(u32 bo, u32 bi) { - bool bo0 = bo & 0x10 ? true : false; - bool bo1 = bo & 0x08 ? true : false; - bool bo2 = bo & 0x04 ? true : false; - bool bo3 = bo & 0x02 ? true : false; - - auto ctr_i64 = GetCtr(); - if (!bo2) { - ctr_i64 = m_ir_builder->CreateSub(ctr_i64, m_ir_builder->getInt64(1)); - SetCtr(ctr_i64); - } - - Value * ctr_ok_i1 = nullptr; - if (!bo2) { - // TODO: Check if we should compare all bits or just the lower 32 bits. This depends on MSR[SF]. Not sure what it is for PS3. - ctr_ok_i1 = m_ir_builder->CreateICmpNE(ctr_i64, m_ir_builder->getInt64(0)); - if (bo3) { - ctr_ok_i1 = m_ir_builder->CreateXor(ctr_ok_i1, m_ir_builder->getInt1(bo3)); - } - } - - Value * cond_ok_i1 = nullptr; - if (!bo0) { - auto cr_bi_i32 = GetBit(GetCr(), bi); - cond_ok_i1 = m_ir_builder->CreateTrunc(cr_bi_i32, m_ir_builder->getInt1Ty()); - if (!bo1) { - cond_ok_i1 = m_ir_builder->CreateXor(cond_ok_i1, m_ir_builder->getInt1(!bo1)); - } - } - - Value * cmp_i1 = nullptr; - if (ctr_ok_i1 && cond_ok_i1) { - cmp_i1 = m_ir_builder->CreateAnd(ctr_ok_i1, cond_ok_i1); - } else if (ctr_ok_i1) { - cmp_i1 = ctr_ok_i1; - } else if (cond_ok_i1) { - cmp_i1 = cond_ok_i1; - } - - return cmp_i1; -} - -void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool lk, bool target_is_lr) { - if (lk) { - SetLr(m_ir_builder->getInt64(m_state.current_instruction_address + 4)); - } - - auto current_block = m_ir_builder->GetInsertBlock(); - - BasicBlock * target_block = nullptr; - if (dyn_cast(target_i32)) { - // Target address is an immediate value. - u32 target_address = (u32)(dyn_cast(target_i32)->getLimitedValue()); - if (lk) { - // Function call - if (cmp_i1) { // There is no need to create a new block for an unconditional jump - target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); - m_ir_builder->SetInsertPoint(target_block); - } - - SetPc(target_i32); - IndirectCall(target_address, m_ir_builder->getInt64(0), true); - m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); - } else { - // Local branch - target_block = GetBasicBlockFromAddress(target_address); - } - } else { - // Target address is in a register - if (cmp_i1) { // There is no need to create a new block for an unconditional jump - target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); - m_ir_builder->SetInsertPoint(target_block); - } - - SetPc(target_i32); - if (target_is_lr && !lk) { - // Return from this function - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else if (lk) { - auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); - auto unknown_function_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "unknown_function"); - - auto switch_instr = m_ir_builder->CreateSwitch(target_i32, unknown_function_block); - m_ir_builder->SetInsertPoint(unknown_function_block); - m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); - m_ir_builder->CreateBr(next_block); - - auto call_i = m_state.cfg->calls.find(m_state.current_instruction_address); - if (call_i != m_state.cfg->calls.end()) { - for (auto function_i = call_i->second.begin(); function_i != call_i->second.end(); function_i++) { - auto block = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("0x%08X", *function_i)); - m_ir_builder->SetInsertPoint(block); - IndirectCall(*function_i, m_ir_builder->getInt64(0), true); - m_ir_builder->CreateBr(next_block); - switch_instr->addCase(m_ir_builder->getInt32(*function_i), block); - } - } - } else { - auto switch_instr = m_ir_builder->CreateSwitch(target_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); - auto branch_i = m_state.cfg->branches.find(m_state.current_instruction_address); - if (branch_i != m_state.cfg->branches.end()) { - for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { - switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); - } - } - } - } - - if (cmp_i1) { - // Conditional branch - auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); - m_ir_builder->SetInsertPoint(current_block); - m_ir_builder->CreateCondBr(cmp_i1, target_block, next_block); - } else { - // Unconditional branch - if (target_block) { - m_ir_builder->SetInsertPoint(current_block); - m_ir_builder->CreateBr(target_block); - } - } - - m_state.hit_branch_instruction = true; -} - -Value * Compiler::ReadMemory(Value * addr_i64, u32 bits, u32 alignment, bool bswap, bool could_be_mmio) { - if (bits != 32 || could_be_mmio == false) { - auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getIntNTy(bits)->getPointerTo()); - auto val_ix = (Value *)m_ir_builder->CreateLoad(eaddr_ix_ptr, alignment); - if (bits > 8 && bswap) { - val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getIntNTy(bits)), val_ix); - } - - return val_ix; - } else { - static u32 next_basic_block_id = 0; - - next_basic_block_id++; - auto cmp_i1 = m_ir_builder->CreateICmpULT(addr_i64, m_ir_builder->getInt64(RAW_SPU_BASE_ADDR)); - auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("then_%u", next_basic_block_id)); - auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("else_%u", next_basic_block_id)); - auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("merge_%u", next_basic_block_id)); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); - - m_ir_builder->SetInsertPoint(then_bb); - auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto eaddr_i32_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getInt32Ty()->getPointerTo()); - auto val_then_i32 = (Value *)m_ir_builder->CreateAlignedLoad(eaddr_i32_ptr, alignment); - if (bswap) { - val_then_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_then_i32); - } - - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(else_bb); - auto val_else_i32 = Call("vm.read32", (u32(*)(u64))vm::read32, addr_i64); - if (!bswap) { - val_else_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_else_i32); - } - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - auto phi = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 2); - phi->addIncoming(val_then_i32, then_bb); - phi->addIncoming(val_else_i32, else_bb); - return phi; - } -} - -void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool bswap, bool could_be_mmio) { - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); - if (val_ix->getType()->getIntegerBitWidth() != 32 || could_be_mmio == false) { - if (val_ix->getType()->getIntegerBitWidth() > 8 && bswap) { - val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, val_ix->getType()), val_ix); - } - - auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, val_ix->getType()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_ix, eaddr_ix_ptr, alignment); - } else { - static u32 next_basic_block_id; - - next_basic_block_id++; - auto cmp_i1 = m_ir_builder->CreateICmpULT(addr_i64, m_ir_builder->getInt64(RAW_SPU_BASE_ADDR)); - auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("then_%u", next_basic_block_id)); - auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("else_%u", next_basic_block_id)); - auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("merge_%u", next_basic_block_id)); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); - - m_ir_builder->SetInsertPoint(then_bb); - Value * val_then_i32 = val_ix; - if (bswap) { - val_then_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_then_i32); - } - - auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto eaddr_i32_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_then_i32, eaddr_i32_ptr, alignment); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(else_bb); - Value * val_else_i32 = val_ix; - if (!bswap) { - val_else_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_else_i32); - } - - Call("vm.write32", (void(*)(u32, u32))vm::write32, addr_i64, val_else_i32); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - } -} - -template -Type * Compiler::CppToLlvmType() { - if (std::is_void::value) { - return m_ir_builder->getVoidTy(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt64Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt32Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt16Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt8Ty(); - } else if (std::is_same::value) { - return m_ir_builder->getFloatTy(); - } else if (std::is_same::value) { - return m_ir_builder->getDoubleTy(); - } else if (std::is_pointer::value) { - return m_ir_builder->getInt8PtrTy(); - } else { - assert(0); - } - - return nullptr; -} - -template -Value * Compiler::Call(const char * name, Func function, Args... args) { - auto fn = m_module->getFunction(name); - if (!fn) { - std::vector fn_args_type = {args->getType()...}; - auto fn_type = FunctionType::get(CppToLlvmType(), fn_args_type, false); - fn = cast(m_module->getOrInsertFunction(name, fn_type)); - fn->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(fn, (void *&)function); - } - - std::vector fn_args = {args...}; - return m_ir_builder->CreateCall(fn, fn_args); -} - -llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_function) { - auto ordinal = m_recompilation_engine.AllocateOrdinal(address, is_function); - auto location_i64 = m_ir_builder->getInt64(m_recompilation_engine.GetAddressOfExecutableLookup() + (ordinal * sizeof(u64))); - auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); - auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); - auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); - return m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); -} - -void Compiler::CompilationError(const std::string & error) { - LOG_ERROR(PPU, "[0x%08X] %s", m_state.current_instruction_address, error.c_str()); - Emu.Pause(); -} - -void Compiler::InitRotateMask() { - for (u32 mb = 0; mb < 64; mb++) { - for (u32 me = 0; me < 64; me++) { - u64 mask = ((u64)-1 >> mb) ^ ((me >= 63) ? 0 : (u64)-1 >> (me + 1)); - s_rotate_mask[mb][me] = mb > me ? ~mask : mask; - } - } -} - -std::mutex RecompilationEngine::s_mutex; -std::shared_ptr RecompilationEngine::s_the_instance = nullptr; - -RecompilationEngine::RecompilationEngine() - : ThreadBase("PPU Recompilation Engine") - , m_log(nullptr) - , m_next_ordinal(0) - , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn) { - m_compiler.RunAllTests(); -} - -RecompilationEngine::~RecompilationEngine() { - Stop(); -} - -u32 RecompilationEngine::AllocateOrdinal(u32 address, bool is_function) { - std::lock_guard lock(m_address_to_ordinal_lock); - - auto i = m_address_to_ordinal.find(address); - if (i == m_address_to_ordinal.end()) { - assert(m_next_ordinal < (sizeof(m_executable_lookup) / sizeof(m_executable_lookup[0]))); - - m_executable_lookup[m_next_ordinal] = is_function ? ExecutionEngine::ExecuteFunction : ExecutionEngine::ExecuteTillReturn; - std::atomic_thread_fence(std::memory_order_release); - i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, m_next_ordinal++)); - } - - return i->second; -} - -u32 RecompilationEngine::GetOrdinal(u32 address) const { - std::lock_guard lock(m_address_to_ordinal_lock); - - auto i = m_address_to_ordinal.find(address); - if (i != m_address_to_ordinal.end()) { - return i->second; - } else { - return 0xFFFFFFFF; - } -} - -const Executable RecompilationEngine::GetExecutable(u32 ordinal) const { - std::atomic_thread_fence(std::memory_order_acquire); - return m_executable_lookup[ordinal]; -} - -u64 RecompilationEngine::GetAddressOfExecutableLookup() const { - return (u64)m_executable_lookup; -} - -void RecompilationEngine::NotifyTrace(ExecutionTrace * execution_trace) { - { - std::lock_guard lock(m_pending_execution_traces_lock); - m_pending_execution_traces.push_back(execution_trace); - } - - if (!IsAlive()) { - Start(); - } - - Notify(); - // TODO: Increase the priority of the recompilation engine thread -} - -raw_fd_ostream & RecompilationEngine::Log() { - if (!m_log) { - std::string error; - m_log = new raw_fd_ostream("PPULLVMRecompiler.log", error, sys::fs::F_Text); - m_log->SetUnbuffered(); - } - - return *m_log; -} - -void RecompilationEngine::Task() { - bool is_idling = false; - std::chrono::nanoseconds idling_time(0); - std::chrono::nanoseconds recompiling_time(0); - - auto start = std::chrono::high_resolution_clock::now(); - while (!TestDestroy() && !Emu.IsStopped()) { - bool work_done_this_iteration = false; - ExecutionTrace * execution_trace = nullptr; - - { - std::lock_guard lock(m_pending_execution_traces_lock); - - auto i = m_pending_execution_traces.begin(); - if (i != m_pending_execution_traces.end()) { - execution_trace = *i; - m_pending_execution_traces.erase(i); - } - } - - if (execution_trace) { - ProcessExecutionTrace(*execution_trace); - delete execution_trace; - work_done_this_iteration = true; - } - - if (!work_done_this_iteration) { - // TODO: Reduce the priority of the recompilation engine thread if its set to high priority - } else { - is_idling = false; - } - - if (is_idling) { - auto recompiling_start = std::chrono::high_resolution_clock::now(); - - // Recompile the function whose CFG has changed the most since the last time it was compiled - auto candidate = (BlockEntry *)nullptr; - size_t max_diff = 0; - for (auto block : m_block_table) { - if (block->IsFunction() && block->is_compiled) { - auto diff = block->cfg.GetSize() - block->last_compiled_cfg_size; - if (diff > max_diff) { - candidate = block; - max_diff = diff; - } - } - } - - if (candidate != nullptr) { - Log() << "Recompiling: " << candidate->ToString() << "\n"; - CompileBlock(*candidate); - work_done_this_iteration = true; - } - - auto recompiling_end = std::chrono::high_resolution_clock::now(); - recompiling_time += std::chrono::duration_cast(recompiling_end - recompiling_start); - } - - if (!work_done_this_iteration) { - is_idling = true; - - // Wait a few ms for something to happen - auto idling_start = std::chrono::high_resolution_clock::now(); - WaitForAnySignal(250); - auto idling_end = std::chrono::high_resolution_clock::now(); - idling_time += std::chrono::duration_cast(idling_end - idling_start); - } - } - - std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); - auto total_time = std::chrono::duration_cast(end - start); - auto compiler_stats = m_compiler.GetStats(); - - Log() << "Total time = " << total_time.count() / 1000000 << "ms\n"; - Log() << " Time spent compiling = " << compiler_stats.total_time.count() / 1000000 << "ms\n"; - Log() << " Time spent building IR = " << compiler_stats.ir_build_time.count() / 1000000 << "ms\n"; - Log() << " Time spent optimizing = " << compiler_stats.optimization_time.count() / 1000000 << "ms\n"; - Log() << " Time spent translating = " << compiler_stats.translation_time.count() / 1000000 << "ms\n"; - Log() << " Time spent recompiling = " << recompiling_time.count() / 1000000 << "ms\n"; - Log() << " Time spent idling = " << idling_time.count() / 1000000 << "ms\n"; - Log() << " Time spent doing misc tasks = " << (total_time.count() - idling_time.count() - compiler_stats.total_time.count()) / 1000000 << "ms\n"; - Log() << "Ordinals allocated = " << m_next_ordinal << "\n"; - - LOG_NOTICE(PPU, "PPU LLVM Recompilation thread exiting."); - s_the_instance = nullptr; // Can cause deadlock if this is the last instance. Need to fix this. -} - -void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution_trace) { - auto execution_trace_id = execution_trace.GetId(); - auto processed_execution_trace_i = m_processed_execution_traces.find(execution_trace_id); - if (processed_execution_trace_i == m_processed_execution_traces.end()) { -#ifdef _DEBUG - Log() << "Trace: " << execution_trace.ToString() << "\n"; -#endif - // Find the function block - BlockEntry key(execution_trace.function_address, execution_trace.function_address); - auto block_i = m_block_table.find(&key); - if (block_i == m_block_table.end()) { - block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); - } - - auto function_block = *block_i; - block_i = m_block_table.end(); - auto split_trace = false; - std::vector tmp_block_list; - for (auto trace_i = execution_trace.entries.begin(); trace_i != execution_trace.entries.end(); trace_i++) { - if (trace_i->type == ExecutionTraceEntry::Type::CompiledBlock) { - block_i = m_block_table.end(); - split_trace = true; - } - - if (block_i == m_block_table.end()) { - BlockEntry key(trace_i->GetPrimaryAddress(), execution_trace.function_address); - block_i = m_block_table.find(&key); - if (block_i == m_block_table.end()) { - block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); - } - - tmp_block_list.push_back(*block_i); - } - - const ExecutionTraceEntry * next_trace = nullptr; - if (trace_i + 1 != execution_trace.entries.end()) { - next_trace = &(*(trace_i + 1)); - } else if (!split_trace && execution_trace.type == ExecutionTrace::Type::Loop) { - next_trace = &(*(execution_trace.entries.begin())); - } - - UpdateControlFlowGraph((*block_i)->cfg, *trace_i, next_trace); - if (*block_i != function_block) { - UpdateControlFlowGraph(function_block->cfg, *trace_i, next_trace); - } - } - - processed_execution_trace_i = m_processed_execution_traces.insert(m_processed_execution_traces.end(), std::make_pair(execution_trace_id, std::move(tmp_block_list))); - } - - for (auto i = processed_execution_trace_i->second.begin(); i != processed_execution_trace_i->second.end(); i++) { - if (!(*i)->is_compiled) { - (*i)->num_hits++; - if ((*i)->num_hits >= 1000) { // TODO: Make this configurable - CompileBlock(*(*i)); - } - } - } - - std::remove_if(processed_execution_trace_i->second.begin(), processed_execution_trace_i->second.end(), [](const BlockEntry * b)->bool { return b->is_compiled; }); -} - -void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry) { - if (this_entry.type == ExecutionTraceEntry::Type::Instruction) { - cfg.instruction_addresses.insert(this_entry.GetPrimaryAddress()); - - if (next_entry) { - if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { - if (next_entry->GetPrimaryAddress() != (this_entry.GetPrimaryAddress() + 4)) { - cfg.branches[this_entry.GetPrimaryAddress()].insert(next_entry->GetPrimaryAddress()); - } - } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { - cfg.calls[this_entry.data.instruction.address].insert(next_entry->GetPrimaryAddress()); - } - } - } else if (this_entry.type == ExecutionTraceEntry::Type::CompiledBlock) { - if (next_entry) { - if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { - cfg.branches[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); - } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { - cfg.calls[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); - } - } - } -} - -void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { -#ifdef _DEBUG - Log() << "Compile: " << block_entry.ToString() << "\n"; - Log() << "CFG: " << block_entry.cfg.ToString() << "\n"; -#endif - - auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction()); - auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), block_entry.cfg, true, - block_entry.IsFunction() ? true : false /*generate_linkable_exits*/); - m_executable_lookup[ordinal] = executable; - block_entry.last_compiled_cfg_size = block_entry.cfg.GetSize(); - block_entry.is_compiled = true; -} - -std::shared_ptr RecompilationEngine::GetInstance() { - std::lock_guard lock(s_mutex); - - if (s_the_instance == nullptr) { - s_the_instance = std::shared_ptr(new RecompilationEngine()); - } - - return s_the_instance; -} - -Tracer::Tracer() - : m_recompilation_engine(RecompilationEngine::GetInstance()) { - m_stack.reserve(100); -} - -Tracer::~Tracer() { - Terminate(); -} - -void Tracer::Trace(TraceType trace_type, u32 arg1, u32 arg2) { - ExecutionTrace * execution_trace = nullptr; - - switch (trace_type) { - case TraceType::CallFunction: - // arg1 is address of the function - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::FunctionCall, arg1)); - break; - case TraceType::EnterFunction: - // arg1 is address of the function - m_stack.push_back(new ExecutionTrace(arg1)); - break; - case TraceType::ExitFromCompiledFunction: - // arg1 is address of function. - // arg2 is the address of the exit instruction. - if (arg2) { - m_stack.push_back(new ExecutionTrace(arg1)); - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); - } - break; - case TraceType::Return: - // No args used - execution_trace = m_stack.back(); - execution_trace->type = ExecutionTrace::Type::Linear; - m_stack.pop_back(); - break; - case TraceType::Instruction: - // arg1 is the address of the instruction - for (int i = (int)m_stack.back()->entries.size() - 1; i >= 0; i--) { - if ((m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::Instruction && m_stack.back()->entries[i].data.instruction.address == arg1) || - (m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::CompiledBlock && m_stack.back()->entries[i].data.compiled_block.entry_address == arg1)) { - // Found a loop - execution_trace = new ExecutionTrace(m_stack.back()->function_address); - execution_trace->type = ExecutionTrace::Type::Loop; - std::copy(m_stack.back()->entries.begin() + i, m_stack.back()->entries.end(), std::back_inserter(execution_trace->entries)); - m_stack.back()->entries.erase(m_stack.back()->entries.begin() + i + 1, m_stack.back()->entries.end()); - break; - } - } - - if (!execution_trace) { - // A loop was not found - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::Instruction, arg1)); - } - break; - case TraceType::ExitFromCompiledBlock: - // arg1 is address of the compiled block. - // arg2 is the address of the exit instruction. - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); - - if (arg2 == 0) { - // Return from function - execution_trace = m_stack.back(); - execution_trace->type = ExecutionTrace::Type::Linear; - m_stack.pop_back(); - } - break; - default: - assert(0); - break; - } - - if (execution_trace) { - m_recompilation_engine->NotifyTrace(execution_trace); - } -} - -void Tracer::Terminate() { - // TODO: Notify recompilation engine -} - -ppu_recompiler_llvm::ExecutionEngine::ExecutionEngine(PPUThread & ppu) - : m_ppu(ppu) - , m_interpreter(new PPUInterpreter(ppu)) - , m_decoder(m_interpreter) - , m_last_cache_clear_time(std::chrono::high_resolution_clock::now()) +} + +void Compiler::STBX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 8)); +} + +void Compiler::STVX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + WriteMemory(addr_i64, GetVr(vs), 16); +} + +void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFMEO"); + } +} + +void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("MULLDO"); + } +} + +void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDMEO"); + } +} + +void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("MULLWO"); + } +} + +void Compiler::DCBTST(u32 ra, u32 rb, u32 th) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::STBUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 8)); + SetGpr(ra, addr_i64); +} + +void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, rb_i64); + SetGpr(rd, sum_i64); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDO"); + } +} + +void Compiler::DCBT(u32 ra, u32 rb, u32 th) { + // TODO: Implement this using prefetch + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHZX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateNot(res_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) { + CompilationError("ECIWX"); + //auto addr_i64 = GetGpr(rb); + //if (ra) { + // auto ra_i64 = GetGpr(ra); + // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + //} + + //auto mem_i32 = ReadMemory(addr_i64, 32); + //auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + //SetGpr(rd, mem_i64); +} + +void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::XOR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MFSPR(u32 rd, u32 spr) { + Value * rd_i64; + auto n = (spr >> 5) | ((spr & 0x1f) << 5); + + switch (n) { + case 0x001: + rd_i64 = GetXer(); + break; + case 0x008: + rd_i64 = GetLr(); + break; + case 0x009: + rd_i64 = GetCtr(); + break; + case 0x100: + rd_i64 = GetVrsave(); + break; + case 0x10C: + rd_i64 = Call("get_time", get_time); + break; + case 0x10D: + rd_i64 = Call("get_time", get_time); + rd_i64 = m_ir_builder->CreateLShr(rd_i64, 32); + break; + default: + assert(0); + break; + } + + SetGpr(rd, rd_i64); +} + +void Compiler::LWAX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::DST(u32 ra, u32 rb, u32 strm, u32 t) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHAX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LVXL(u32 vd, u32 ra, u32 rb) { + LVX(vd, ra, rb); +} + +void Compiler::MFTB(u32 rd, u32 spr) { + auto tb_i64 = Call("get_time", get_time); + + u32 n = (spr >> 5) | ((spr & 0x1f) << 5); + if (n == 0x10D) { + tb_i64 = m_ir_builder->CreateLShr(tb_i64, 32); + } + + SetGpr(rd, tb_i64); +} + +void Compiler::LWAUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::DSTST(u32 ra, u32 rb, u32 strm, u32 t) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHAUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STHX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16)); +} + +void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + rb_i64 = m_ir_builder->CreateNot(rb_i64); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) { + CompilationError("ECOWX"); + //auto addr_i64 = GetGpr(rb); + //if (ra) { + // auto ra_i64 = GetGpr(ra); + // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + //} + + //WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STHUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 16)); + SetGpr(ra, addr_i64); +} + +void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateUDiv(ra_i64, rb_i64); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVDUO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto res_i32 = m_ir_builder->CreateUDiv(ra_i32, rb_i32); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVWUO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::MTSPR(u32 spr, u32 rs) { + auto rs_i64 = GetGpr(rs); + auto n = (spr >> 5) | ((spr & 0x1f) << 5); + + switch (n) { + case 0x001: + SetXer(rs_i64); + break; + case 0x008: + SetLr(rs_i64); + break; + case 0x009: + SetCtr(rs_i64); + break; + case 0x100: + SetVrsave(rs_i64); + break; + default: + assert(0); + break; + } + +} + +void Compiler::NAND(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateNot(res_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVXL(u32 vs, u32 ra, u32 rb) { + STVX(vs, ra, rb); +} + +void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateSDiv(ra_i64, rb_i64); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVDO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto res_i32 = m_ir_builder->CreateSDiv(ra_i32, rb_i32); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVWO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::LVLX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto eb_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); + auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + mem_i128 = m_ir_builder->CreateShl(mem_i128, eb_i128); + SetVr(vd, mem_i128); +} + +void Compiler::LDBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64, 0, false); + SetGpr(rd, mem_i64); +} + +void Compiler::LSWX(u32 rd, u32 ra, u32 rb) { + CompilationError("LSWX"); +} + +void Compiler::LWBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32, 0, false); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LFSX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); +} + +void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateLShr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateLShr(rs_i128, rb_i128); + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LVRX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto eb_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), addr_i64); + eb_i64 = m_ir_builder->CreateAnd(eb_i64, 0xF); + eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); + auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + mem_i128 = m_ir_builder->CreateLShr(mem_i128, eb_i128); + auto cmp_i1 = m_ir_builder->CreateICmpNE(eb_i64, m_ir_builder->getInt64(0)); + auto cmp_i128 = m_ir_builder->CreateSExt(cmp_i1, m_ir_builder->getIntNTy(128)); + mem_i128 = m_ir_builder->CreateAnd(mem_i128, cmp_i128); + SetVr(vd, mem_i128); +} + +void Compiler::LSWI(u32 rd, u32 ra, u32 nb) { + auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); + + nb = nb ? nb : 32; + for (u32 i = 0; i < nb; i += 4) { + auto val_i32 = ReadMemory(addr_i64, 32, 0, true, false); + + if (i + 4 <= nb) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } else { + u32 mask = 0xFFFFFFFF << ((4 - (nb - i)) * 8); + val_i32 = m_ir_builder->CreateAnd(val_i32, mask); + } + + auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, val_i64); + rd = (rd + 1) % 32; + } +} + +void Compiler::LFSUX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::SYNC(u32 l) { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::LFDX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); +} + +void Compiler::LFDUX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STVLX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + auto size_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), index_i64); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + auto vs_i128 = GetVr(vs); + vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); + auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); + vs_i128_ptr->setAlignment(16); + m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); + auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); + + Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), + addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); +} + +void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs), 0, false); +} + +void Compiler::STSWX(u32 rs, u32 ra, u32 rb) { + CompilationError("STSWX"); +} + +void Compiler::STWBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 32), 0, false); +} + +void Compiler::STFSX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::STVRX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto size_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + auto index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), size_i64); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFF0); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + auto vs_i128 = GetVr(vs); + vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); + auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); + vs_i128_ptr->setAlignment(16); + m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); + auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); + vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64); + + Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), + addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); +} + +void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::STSWI(u32 rd, u32 ra, u32 nb) { + auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); + + nb = nb ? nb : 32; + for (u32 i = 0; i < nb; i += 4) { + auto val_i32 = GetGpr(rd, 32); + + if (i + 4 <= nb) { + WriteMemory(addr_i64, val_i32, 0, true, false); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + rd = (rd + 1) % 32; + } else { + u32 n = nb - i; + if (n >= 2) { + auto val_i16 = m_ir_builder->CreateLShr(val_i32, 16); + val_i16 = m_ir_builder->CreateTrunc(val_i16, m_ir_builder->getInt16Ty()); + WriteMemory(addr_i64, val_i16); + + if (n == 3) { + auto val_i8 = m_ir_builder->CreateLShr(val_i32, 8); + val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(2)); + WriteMemory(addr_i64, val_i8); + } + } else { + auto val_i8 = m_ir_builder->CreateLShr(val_i32, 24); + val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); + WriteMemory(addr_i64, val_i8); + } + } + } +} + +void Compiler::STFDX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); +} + +void Compiler::STFDUX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LVLXL(u32 vd, u32 ra, u32 rb) { + LVLX(vd, ra, rb); +} + +void Compiler::LHBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16, 0, false); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateAShr(rs_i64, rb_i64); + auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); + SetGpr(ra, ra_i64); + + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateAShr(rs_i128, rb_i128); + auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); + auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, ra_i64); + + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LVRXL(u32 vd, u32 ra, u32 rb) { + LVRX(vd, ra, rb); +} + +void Compiler::DSS(u32 strm, u32 a) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); + auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh); + auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); + SetGpr(ra, ra_i64); + + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); + auto res_i128 = m_ir_builder->CreateAShr(rs_i128, sh); + auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); + auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, ra_i64); + + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { + SRADI1(ra, rs, sh, rc); +} + +void Compiler::EIEIO() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::STVLXL(u32 vs, u32 ra, u32 rb) { + STVLX(vs, ra, rb); +} + +void Compiler::STHBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16), 0, false); +} + +void Compiler::EXTSH(u32 ra, u32 rs, bool rc) { + auto rs_i16 = GetGpr(rs, 16); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i16, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVRXL(u32 vs, u32 ra, u32 rb) { + STVRX(vs, ra, rb); +} + +void Compiler::EXTSB(u32 ra, u32 rs, bool rc) { + auto rs_i8 = GetGpr(rs, 8); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i8, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STFIWX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + auto frs_i32 = m_ir_builder->CreateTrunc(frs_i64, m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::EXTSW(u32 ra, u32 rs, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ICBI(u32 ra, u32 rs) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::DCBZ(u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, ~(127ULL)); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + std::vector types = {(Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty()}; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types), + addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true)); +} + +void Compiler::LWZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LWZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LBZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LBZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STW(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STWU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 32)); + SetGpr(ra, addr_i64); +} + +void Compiler::STB(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 8)); +} + +void Compiler::STBU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 8)); + SetGpr(ra, addr_i64); +} + +void Compiler::LHZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LHZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LHA(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LHAU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STH(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16)); +} + +void Compiler::STHU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 16)); + SetGpr(ra, addr_i64); +} + +void Compiler::LMW(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); + } + + for (u32 i = rd; i < 32; i++) { + auto val_i32 = ReadMemory(addr_i64, 32); + auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); + SetGpr(i, val_i64); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } +} + +void Compiler::STMW(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); + } + + for (u32 i = rs; i < 32; i++) { + auto val_i32 = GetGpr(i, 32); + WriteMemory(addr_i64, val_i32); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } +} + +void Compiler::LFS(u32 frd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); +} + +void Compiler::LFSU(u32 frd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::LFD(u32 frd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); +} + +void Compiler::LFDU(u32 frd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STFS(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::STFSU(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::STFD(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); +} + +void Compiler::STFDU(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LD(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); +} + +void Compiler::LDU(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LWA(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FDIVS."); + } + + // TODO: Set flags +} + +void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FADDS."); + } + + // TODO: Set flags +} + +void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FSQRTS."); + } + + // TODO: Set flags +} + +void Compiler::FRES(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FRES."); + } + + // TODO: Set flags +} + +void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMULS."); + } + + // TODO: Set flags +} + +void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMADDS."); + } + + // TODO: Set flags +} + +void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FNMSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FNMADDS."); + } + + // TODO: Set flags +} + +void Compiler::STD(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 64)); +} + +void Compiler::STDU(u32 rs, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 64)); + SetGpr(ra, addr_i64); +} + +void Compiler::MTFSB1(u32 crbd, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSB1."); + } +} + +void Compiler::MCRFS(u32 crbd, u32 crbs) { + auto fpscr_i32 = GetFpscr(); + auto val_i32 = GetNibble(fpscr_i32, crbs); + SetCrField(crbd, val_i32); + + switch (crbs) { + case 0: + fpscr_i32 = ClrBit(fpscr_i32, 0); + fpscr_i32 = ClrBit(fpscr_i32, 3); + break; + case 1: + fpscr_i32 = ClrNibble(fpscr_i32, 1); + break; + case 2: + fpscr_i32 = ClrNibble(fpscr_i32, 2); + break; + case 3: + fpscr_i32 = ClrBit(fpscr_i32, 12); + break; + case 5: + fpscr_i32 = ClrBit(fpscr_i32, 21); + fpscr_i32 = ClrBit(fpscr_i32, 22); + fpscr_i32 = ClrBit(fpscr_i32, 23); + break; + default: + break; + } + + SetFpscr(fpscr_i32); +} + +void Compiler::MTFSB0(u32 crbd, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = ClrBit(fpscr_i32, crbd); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSB0."); + } +} + +void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF)); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSFI."); + } +} + +void Compiler::MFFS(u32 frd, bool rc) { + auto fpscr_i32 = GetFpscr(); + auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty()); + SetFpr(frd, fpscr_i64); + + if (rc) { + // TODO: Implement this + CompilationError("MFFS."); + } +} + +void Compiler::MTFSF(u32 flm, u32 frb, bool rc) { + u32 mask = 0; + for(u32 i = 0; i < 8; i++) { + if (flm & (1 << i)) { + mask |= 0xF << (i * 4); + } + } + + auto rb_i32 = GetFpr(frb, 32, true); + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = m_ir_builder->CreateAnd(fpscr_i32, ~mask); + rb_i32 = m_ir_builder->CreateAnd(rb_i32, mask); + fpscr_i32 = m_ir_builder->CreateOr(fpscr_i32, rb_i32); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSF."); + } +} + +void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); + auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); + auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); + SetCr(cr_i32); + + // TODO: Set flags / Handle NaN +} + +void Compiler::FRSP(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f32 = m_ir_builder->CreateFPTrunc(rb_f64, m_ir_builder->getFloatTy()); + auto res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy()); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FRSP."); + } + + // TODO: Revisit this + // TODO: Set flags +} + +void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); + auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIW."); + } + + // TODO: Set flags / Implement rounding modes +} + +void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); + auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIWZ."); + } + + // TODO: Set flags +} + +void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FDIV."); + } + + // TODO: Set flags +} + +void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSUB."); + } + + // TODO: Set flags +} + +void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FADD."); + } + + // TODO: Set flags +} + +void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSQRT."); + } + + // TODO: Set flags +} + +void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto cmp_i1 = m_ir_builder->CreateFCmpOGE(ra_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0.0)); + auto res_f64 = m_ir_builder->CreateSelect(cmp_i1, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSEL."); + } + + // TODO: Set flags +} + +void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMUL."); + } + + // TODO: Set flags +} + +void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), res_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FRSQRTE."); + } +} + +void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMSUB."); + } + + // TODO: Set flags +} + +void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMADD."); + } + + // TODO: Set flags +} + +void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rc_f64 = m_ir_builder->CreateFNeg(rc_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNMSUB."); + } + + // TODO: Set flags +} + +void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + rc_f64 = m_ir_builder->CreateFNeg(rc_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNMADD."); + } + + // TODO: Set flags +} + +void Compiler::FCMPO(u32 crfd, u32 fra, u32 frb) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); + auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); + auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); + SetCr(cr_i32); + + // TODO: Set flags / Handle NaN +} + +void Compiler::FNEG(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + SetFpr(frd, rb_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNEG."); + } + + // TODO: Set flags +} + +void Compiler::FMR(u32 frd, u32 frb, bool rc) { + SetFpr(frd, GetFpr(frb)); + + if (rc) { + // TODO: Implement this + CompilationError("FMR."); + } + + // TODO: Set flags +} + +void Compiler::FNABS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNABS."); + } + + // TODO: Set flags +} + +void Compiler::FABS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FABS."); + } + + // TODO: Set flags +} + +void Compiler::FCTID(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); + auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTID."); + } + + // TODO: Set flags / Implement rounding modes +} + +void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); + auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIDZ."); + } + + // TODO: Set flags +} + +void Compiler::FCFID(u32 frd, u32 frb, bool rc) { + auto rb_i64 = GetFpr(frb, 64, true); + auto res_f64 = m_ir_builder->CreateSIToFP(rb_i64, m_ir_builder->getDoubleTy()); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FCFID."); + } + + // TODO: Set flags +} + +void Compiler::UNK(const u32 code, const u32 opcode, const u32 gcode) { + CompilationError(fmt::Format("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode)); +} + +std::string Compiler::GetBasicBlockNameFromAddress(u32 address, const std::string & suffix) const { + std::string name; + + if (address == 0) { + name = "entry"; + } else if (address == 0xFFFFFFFF) { + name = "default_exit"; + } else { + name = fmt::Format("instr_0x%08X", address); + } + + if (suffix != "") { + name += "_" + suffix; + } + + return name; +} + +u32 Compiler::GetAddressFromBasicBlockName(const std::string & name) const { + if (name.compare(0, 6, "instr_") == 0) { + return strtoul(name.c_str() + 6, nullptr, 0); + } else if (name == GetBasicBlockNameFromAddress(0)) { + return 0; + } else if (name == GetBasicBlockNameFromAddress(0xFFFFFFFF)) { + return 0xFFFFFFFF; + } + + return 0; +} + +BasicBlock * Compiler::GetBasicBlockFromAddress(u32 address, const std::string & suffix, bool create_if_not_exist) { + auto block_name = GetBasicBlockNameFromAddress(address, suffix); + BasicBlock * block = nullptr; + BasicBlock * next_block = nullptr; + for (auto i = m_state.function->begin(); i != m_state.function->end(); i++) { + if (i->getName() == block_name) { + block = &(*i); + break; + } + +#ifdef _DEBUG + auto block_address = GetAddressFromBasicBlockName(i->getName()); + if (block_address > address) { + next_block = &(*i); + break; + } +#endif + } + + if (!block && create_if_not_exist) { + block = BasicBlock::Create(m_ir_builder->getContext(), block_name, m_state.function, next_block); + } + + return block; +} + +Value * Compiler::GetBit(Value * val, u32 n) { + Value * bit; + +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + if (val->getType()->isIntegerTy(32)) { + bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31- n))); + } else if (val->getType()->isIntegerTy(64)) { + bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n))); + } else { +#endif + if (val->getType()->getIntegerBitWidth() != (n + 1)) { + bit = m_ir_builder->CreateLShr(val, val->getType()->getIntegerBitWidth() - n - 1); + } + + bit = m_ir_builder->CreateAnd(bit, 1); +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + } +#endif + + return bit; +} + +Value * Compiler::ClrBit(Value * val, u32 n) { + return m_ir_builder->CreateAnd(val, ~((u64)1 << (val->getType()->getIntegerBitWidth() - n - 1))); +} + +Value * Compiler::SetBit(Value * val, u32 n, Value * bit, bool doClear) { + if (doClear) { + val = ClrBit(val, n); + } + + if (bit->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { + bit = m_ir_builder->CreateZExt(bit, val->getType()); + } else if (bit->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { + bit = m_ir_builder->CreateTrunc(bit, val->getType()); + } + + if (val->getType()->getIntegerBitWidth() != (n + 1)) { + bit = m_ir_builder->CreateShl(bit, bit->getType()->getIntegerBitWidth() - n - 1); + } + + return m_ir_builder->CreateOr(val, bit); +} + +Value * Compiler::GetNibble(Value * val, u32 n) { + Value * nibble; + +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + if (val->getType()->isIntegerTy(32)) { + nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4))); + } else if (val->getType()->isIntegerTy(64)) { + nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4))); + } else { +#endif + if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { + val = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); + } + + nibble = m_ir_builder->CreateAnd(val, 0xF); +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + } +#endif + + return nibble; +} + +Value * Compiler::ClrNibble(Value * val, u32 n) { + return m_ir_builder->CreateAnd(val, ~((u64)0xF << ((((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4))); +} + +Value * Compiler::SetNibble(Value * val, u32 n, Value * nibble, bool doClear) { + if (doClear) { + val = ClrNibble(val, n); + } + + if (nibble->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { + nibble = m_ir_builder->CreateZExt(nibble, val->getType()); + } else if (nibble->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { + nibble = m_ir_builder->CreateTrunc(nibble, val->getType()); + } + + if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { + nibble = m_ir_builder->CreateShl(nibble, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); + } + + return m_ir_builder->CreateOr(val, nibble); +} + +Value * Compiler::SetNibble(Value * val, u32 n, Value * b0, Value * b1, Value * b2, Value * b3, bool doClear) { + if (doClear) { + val = ClrNibble(val, n); + } + + if (b0) { + val = SetBit(val, n * 4, b0, false); + } + + if (b1) { + val = SetBit(val, (n * 4) + 1, b1, false); + } + + if (b2) { + val = SetBit(val, (n * 4) + 2, b2, false); + } + + if (b3) { + val = SetBit(val, (n * 4) + 3, b3, false); + } + + return val; +} + +Value * Compiler::GetPc() { + auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); + auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(pc_i32_ptr, 4); +} + +void Compiler::SetPc(Value * val_ix) { + auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); + auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_ix, m_ir_builder->getInt32Ty()); + m_ir_builder->CreateAlignedStore(val_i32, pc_i32_ptr, 4); +} + +Value * Compiler::GetGpr(u32 r, u32 num_bits) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); + auto r_ix_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getIntNTy(num_bits)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(r_ix_ptr, 8); +} + +void Compiler::SetGpr(u32 r, Value * val_x64) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); + auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + m_ir_builder->CreateAlignedStore(val_i64, r_i64_ptr, 8); +} + +Value * Compiler::GetCr() { + auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); + auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(cr_i32_ptr, 4); +} + +Value * Compiler::GetCrField(u32 n) { + return GetNibble(GetCr(), n); +} + +void Compiler::SetCr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); + auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, cr_i32_ptr, 4); +} + +void Compiler::SetCrField(u32 n, Value * field) { + SetCr(SetNibble(GetCr(), n, field)); +} + +void Compiler::SetCrField(u32 n, Value * b0, Value * b1, Value * b2, Value * b3) { + SetCr(SetNibble(GetCr(), n, b0, b1, b2, b3)); +} + +void Compiler::SetCrFieldSignedCmp(u32 n, Value * a, Value * b) { + auto lt_i1 = m_ir_builder->CreateICmpSLT(a, b); + auto gt_i1 = m_ir_builder->CreateICmpSGT(a, b); + auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); + SetCr(cr_i32); +} + +void Compiler::SetCrFieldUnsignedCmp(u32 n, Value * a, Value * b) { + auto lt_i1 = m_ir_builder->CreateICmpULT(a, b); + auto gt_i1 = m_ir_builder->CreateICmpUGT(a, b); + auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); + SetCr(cr_i32); +} + +void Compiler::SetCr6AfterVectorCompare(u32 vr) { + auto vr_v16i8 = GetVrAsIntVec(vr, 8); + auto vr_mask_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmovmskb_128), vr_v16i8); + auto cmp0_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0)); + auto cmp1_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0xFFFF)); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, 6, cmp1_i1, nullptr, cmp0_i1, nullptr); + SetCr(cr_i32); +} + +Value * Compiler::GetLr() { + auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); + auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(lr_i64_ptr, 8); +} + +void Compiler::SetLr(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); + auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, lr_i64_ptr, 8); +} + +Value * Compiler::GetCtr() { + auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); + auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(ctr_i64_ptr, 8); +} + +void Compiler::SetCtr(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); + auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, ctr_i64_ptr, 8); +} + +Value * Compiler::GetXer() { + auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); + auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(xer_i64_ptr, 8); +} + +Value * Compiler::GetXerCa() { + return GetBit(GetXer(), 34); +} + +Value * Compiler::GetXerSo() { + return GetBit(GetXer(), 32); +} + +void Compiler::SetXer(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); + auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, xer_i64_ptr, 8); +} + +void Compiler::SetXerCa(Value * ca) { + auto xer_i64 = GetXer(); + xer_i64 = SetBit(xer_i64, 34, ca); + SetXer(xer_i64); +} + +void Compiler::SetXerSo(Value * so) { + auto xer_i64 = GetXer(); + xer_i64 = SetBit(xer_i64, 32, so); + SetXer(xer_i64); +} + +Value * Compiler::GetVrsave() { + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4); + return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty()); +} + +void Compiler::SetVrsave(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty()); + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8); +} + +Value * Compiler::GetFpscr() { + auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); + auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4); +} + +void Compiler::SetFpscr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); + auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4); +} + +Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); + if (!as_int) { + auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); + auto r_f64 = m_ir_builder->CreateAlignedLoad(r_f64_ptr, 8); + if (bits == 32) { + return m_ir_builder->CreateFPTrunc(r_f64, m_ir_builder->getFloatTy()); + } else { + return r_f64; + } + } else { + auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + auto r_i64 = m_ir_builder->CreateAlignedLoad(r_i64_ptr, 8); + if (bits == 32) { + return m_ir_builder->CreateTrunc(r_i64, m_ir_builder->getInt32Ty()); + } else { + return r_i64; + } + } +} + +void Compiler::SetFpr(u32 r, Value * val) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); + auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); + + Value* val_f64; + if (val->getType()->isDoubleTy() || val->getType()->isIntegerTy(64)) { + val_f64 = m_ir_builder->CreateBitCast(val, m_ir_builder->getDoubleTy()); + } else if (val->getType()->isFloatTy() || val->getType()->isIntegerTy(32)) { + auto val_f32 = m_ir_builder->CreateBitCast(val, m_ir_builder->getFloatTy()); + val_f64 = m_ir_builder->CreateFPExt(val_f32, m_ir_builder->getDoubleTy()); + } else { + assert(0); + } + + m_ir_builder->CreateAlignedStore(val_f64, r_f64_ptr, 8); +} + +Value * Compiler::GetVscr() { + auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); + auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vscr_i32_ptr, 4); +} + +void Compiler::SetVscr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); + auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, vscr_i32_ptr, 4); +} + +Value * Compiler::GetVr(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_i128_ptr, 16); +} + +Value * Compiler::GetVrAsIntVec(u32 vr, u32 vec_elt_num_bits) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_vec_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getIntNTy(vec_elt_num_bits), 128 / vec_elt_num_bits)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_vec_ptr, 16); +} + +Value * Compiler::GetVrAsFloatVec(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_v4f32_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getFloatTy(), 4)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_v4f32_ptr, 16); +} + +Value * Compiler::GetVrAsDoubleVec(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_v2f64_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getDoubleTy(), 2)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_v2f64_ptr, 16); +} + +void Compiler::SetVr(u32 vr, Value * val_x128) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto val_i128 = m_ir_builder->CreateBitCast(val_x128, m_ir_builder->getIntNTy(128)); + m_ir_builder->CreateAlignedStore(val_i128, vr_i128_ptr, 16); +} + +Value * Compiler::CheckBranchCondition(u32 bo, u32 bi) { + bool bo0 = bo & 0x10 ? true : false; + bool bo1 = bo & 0x08 ? true : false; + bool bo2 = bo & 0x04 ? true : false; + bool bo3 = bo & 0x02 ? true : false; + + auto ctr_i64 = GetCtr(); + if (!bo2) { + ctr_i64 = m_ir_builder->CreateSub(ctr_i64, m_ir_builder->getInt64(1)); + SetCtr(ctr_i64); + } + + Value * ctr_ok_i1 = nullptr; + if (!bo2) { + // TODO: Check if we should compare all bits or just the lower 32 bits. This depends on MSR[SF]. Not sure what it is for PS3. + ctr_ok_i1 = m_ir_builder->CreateICmpNE(ctr_i64, m_ir_builder->getInt64(0)); + if (bo3) { + ctr_ok_i1 = m_ir_builder->CreateXor(ctr_ok_i1, m_ir_builder->getInt1(bo3)); + } + } + + Value * cond_ok_i1 = nullptr; + if (!bo0) { + auto cr_bi_i32 = GetBit(GetCr(), bi); + cond_ok_i1 = m_ir_builder->CreateTrunc(cr_bi_i32, m_ir_builder->getInt1Ty()); + if (!bo1) { + cond_ok_i1 = m_ir_builder->CreateXor(cond_ok_i1, m_ir_builder->getInt1(!bo1)); + } + } + + Value * cmp_i1 = nullptr; + if (ctr_ok_i1 && cond_ok_i1) { + cmp_i1 = m_ir_builder->CreateAnd(ctr_ok_i1, cond_ok_i1); + } else if (ctr_ok_i1) { + cmp_i1 = ctr_ok_i1; + } else if (cond_ok_i1) { + cmp_i1 = cond_ok_i1; + } + + return cmp_i1; +} + +void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool lk, bool target_is_lr) { + if (lk) { + SetLr(m_ir_builder->getInt64(m_state.current_instruction_address + 4)); + } + + auto current_block = m_ir_builder->GetInsertBlock(); + + BasicBlock * target_block = nullptr; + if (dyn_cast(target_i32)) { + // Target address is an immediate value. + u32 target_address = (u32)(dyn_cast(target_i32)->getLimitedValue()); + if (lk) { + // Function call + if (cmp_i1) { // There is no need to create a new block for an unconditional jump + target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); + m_ir_builder->SetInsertPoint(target_block); + } + + SetPc(target_i32); + IndirectCall(target_address, m_ir_builder->getInt64(0), true); + m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); + } else { + // Local branch + target_block = GetBasicBlockFromAddress(target_address); + } + } else { + // Target address is in a register + if (cmp_i1) { // There is no need to create a new block for an unconditional jump + target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); + m_ir_builder->SetInsertPoint(target_block); + } + + SetPc(target_i32); + if (target_is_lr && !lk) { + // Return from this function + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else if (lk) { + auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); + auto unknown_function_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "unknown_function"); + + auto switch_instr = m_ir_builder->CreateSwitch(target_i32, unknown_function_block); + m_ir_builder->SetInsertPoint(unknown_function_block); + m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); + m_ir_builder->CreateBr(next_block); + + auto call_i = m_state.cfg->calls.find(m_state.current_instruction_address); + if (call_i != m_state.cfg->calls.end()) { + for (auto function_i = call_i->second.begin(); function_i != call_i->second.end(); function_i++) { + auto block = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("0x%08X", *function_i)); + m_ir_builder->SetInsertPoint(block); + IndirectCall(*function_i, m_ir_builder->getInt64(0), true); + m_ir_builder->CreateBr(next_block); + switch_instr->addCase(m_ir_builder->getInt32(*function_i), block); + } + } + } else { + auto switch_instr = m_ir_builder->CreateSwitch(target_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); + auto branch_i = m_state.cfg->branches.find(m_state.current_instruction_address); + if (branch_i != m_state.cfg->branches.end()) { + for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { + switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); + } + } + } + } + + if (cmp_i1) { + // Conditional branch + auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); + m_ir_builder->SetInsertPoint(current_block); + m_ir_builder->CreateCondBr(cmp_i1, target_block, next_block); + } else { + // Unconditional branch + if (target_block) { + m_ir_builder->SetInsertPoint(current_block); + m_ir_builder->CreateBr(target_block); + } + } + + m_state.hit_branch_instruction = true; +} + +Value * Compiler::ReadMemory(Value * addr_i64, u32 bits, u32 alignment, bool bswap, bool could_be_mmio) { + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); + auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getIntNTy(bits)->getPointerTo()); + auto val_ix = (Value *)m_ir_builder->CreateLoad(eaddr_ix_ptr, alignment); + if (bits > 8 && bswap) { + val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getIntNTy(bits)), val_ix); + } + + return val_ix; +} + +void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool bswap, bool could_be_mmio) { + if (val_ix->getType()->getIntegerBitWidth() > 8 && bswap) { + val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, val_ix->getType()), val_ix); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); + auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, val_ix->getType()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_ix, eaddr_ix_ptr, alignment); +} + +template +Type * Compiler::CppToLlvmType() { + if (std::is_void::value) { + return m_ir_builder->getVoidTy(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt64Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt32Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt16Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt8Ty(); + } else if (std::is_same::value) { + return m_ir_builder->getFloatTy(); + } else if (std::is_same::value) { + return m_ir_builder->getDoubleTy(); + } else if (std::is_same::value) { + return m_ir_builder->getInt1Ty(); + } else if (std::is_pointer::value) { + return m_ir_builder->getInt8PtrTy(); + } else { + assert(0); + } + + return nullptr; +} + +template +Value * Compiler::Call(const char * name, Func function, Args... args) { + auto fn = m_module->getFunction(name); + if (!fn) { + std::vector fn_args_type = {args->getType()...}; + auto fn_type = FunctionType::get(CppToLlvmType(), fn_args_type, false); + fn = cast(m_module->getOrInsertFunction(name, fn_type)); + fn->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(fn, (void *&)function); + } + + std::vector fn_args = {args...}; + return m_ir_builder->CreateCall(fn, fn_args); +} + +llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_function) { + auto ordinal = m_recompilation_engine.AllocateOrdinal(address, is_function); + auto location_i64 = m_ir_builder->getInt64(m_recompilation_engine.GetAddressOfExecutableLookup() + (ordinal * sizeof(u64))); + auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); + auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); + auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); + return m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); +} + +void Compiler::CompilationError(const std::string & error) { + LOG_ERROR(PPU, "[0x%08X] %s", m_state.current_instruction_address, error.c_str()); + Emu.Pause(); +} + +void Compiler::InitRotateMask() { + for (u32 mb = 0; mb < 64; mb++) { + for (u32 me = 0; me < 64; me++) { + u64 mask = ((u64)-1 >> mb) ^ ((me >= 63) ? 0 : (u64)-1 >> (me + 1)); + s_rotate_mask[mb][me] = mb > me ? ~mask : mask; + } + } +} + +std::mutex RecompilationEngine::s_mutex; +std::shared_ptr RecompilationEngine::s_the_instance = nullptr; + +RecompilationEngine::RecompilationEngine() + : ThreadBase("PPU Recompilation Engine") + , m_log(nullptr) + , m_next_ordinal(0) + , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn) { + m_compiler.RunAllTests(); +} + +RecompilationEngine::~RecompilationEngine() { + Stop(); +} + +u32 RecompilationEngine::AllocateOrdinal(u32 address, bool is_function) { + std::lock_guard lock(m_address_to_ordinal_lock); + + auto i = m_address_to_ordinal.find(address); + if (i == m_address_to_ordinal.end()) { + assert(m_next_ordinal < (sizeof(m_executable_lookup) / sizeof(m_executable_lookup[0]))); + + m_executable_lookup[m_next_ordinal] = is_function ? ExecutionEngine::ExecuteFunction : ExecutionEngine::ExecuteTillReturn; + std::atomic_thread_fence(std::memory_order_release); + i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, m_next_ordinal++)); + } + + return i->second; +} + +u32 RecompilationEngine::GetOrdinal(u32 address) const { + std::lock_guard lock(m_address_to_ordinal_lock); + + auto i = m_address_to_ordinal.find(address); + if (i != m_address_to_ordinal.end()) { + return i->second; + } else { + return 0xFFFFFFFF; + } +} + +const Executable RecompilationEngine::GetExecutable(u32 ordinal) const { + std::atomic_thread_fence(std::memory_order_acquire); + return m_executable_lookup[ordinal]; +} + +u64 RecompilationEngine::GetAddressOfExecutableLookup() const { + return (u64)m_executable_lookup; +} + +void RecompilationEngine::NotifyTrace(ExecutionTrace * execution_trace) { + { + std::lock_guard lock(m_pending_execution_traces_lock); + m_pending_execution_traces.push_back(execution_trace); + } + + if (!IsAlive()) { + Start(); + } + + Notify(); + // TODO: Increase the priority of the recompilation engine thread +} + +raw_fd_ostream & RecompilationEngine::Log() { + if (!m_log) { + std::string error; + m_log = new raw_fd_ostream("PPULLVMRecompiler.log", error, sys::fs::F_Text); + m_log->SetUnbuffered(); + } + + return *m_log; +} + +void RecompilationEngine::Task() { + bool is_idling = false; + std::chrono::nanoseconds idling_time(0); + std::chrono::nanoseconds recompiling_time(0); + + auto start = std::chrono::high_resolution_clock::now(); + while (!TestDestroy() && !Emu.IsStopped()) { + bool work_done_this_iteration = false; + ExecutionTrace * execution_trace = nullptr; + + { + std::lock_guard lock(m_pending_execution_traces_lock); + + auto i = m_pending_execution_traces.begin(); + if (i != m_pending_execution_traces.end()) { + execution_trace = *i; + m_pending_execution_traces.erase(i); + } + } + + if (execution_trace) { + ProcessExecutionTrace(*execution_trace); + delete execution_trace; + work_done_this_iteration = true; + } + + if (!work_done_this_iteration) { + // TODO: Reduce the priority of the recompilation engine thread if its set to high priority + } else { + is_idling = false; + } + + if (is_idling) { + auto recompiling_start = std::chrono::high_resolution_clock::now(); + + // Recompile the function whose CFG has changed the most since the last time it was compiled + auto candidate = (BlockEntry *)nullptr; + size_t max_diff = 0; + for (auto block : m_block_table) { + if (block->IsFunction() && block->is_compiled) { + auto diff = block->cfg.GetSize() - block->last_compiled_cfg_size; + if (diff > max_diff) { + candidate = block; + max_diff = diff; + } + } + } + + if (candidate != nullptr) { + Log() << "Recompiling: " << candidate->ToString() << "\n"; + CompileBlock(*candidate); + work_done_this_iteration = true; + } + + auto recompiling_end = std::chrono::high_resolution_clock::now(); + recompiling_time += std::chrono::duration_cast(recompiling_end - recompiling_start); + } + + if (!work_done_this_iteration) { + is_idling = true; + + // Wait a few ms for something to happen + auto idling_start = std::chrono::high_resolution_clock::now(); + WaitForAnySignal(250); + auto idling_end = std::chrono::high_resolution_clock::now(); + idling_time += std::chrono::duration_cast(idling_end - idling_start); + } + } + + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); + auto total_time = std::chrono::duration_cast(end - start); + auto compiler_stats = m_compiler.GetStats(); + + Log() << "Total time = " << total_time.count() / 1000000 << "ms\n"; + Log() << " Time spent compiling = " << compiler_stats.total_time.count() / 1000000 << "ms\n"; + Log() << " Time spent building IR = " << compiler_stats.ir_build_time.count() / 1000000 << "ms\n"; + Log() << " Time spent optimizing = " << compiler_stats.optimization_time.count() / 1000000 << "ms\n"; + Log() << " Time spent translating = " << compiler_stats.translation_time.count() / 1000000 << "ms\n"; + Log() << " Time spent recompiling = " << recompiling_time.count() / 1000000 << "ms\n"; + Log() << " Time spent idling = " << idling_time.count() / 1000000 << "ms\n"; + Log() << " Time spent doing misc tasks = " << (total_time.count() - idling_time.count() - compiler_stats.total_time.count()) / 1000000 << "ms\n"; + Log() << "Ordinals allocated = " << m_next_ordinal << "\n"; + + LOG_NOTICE(PPU, "PPU LLVM Recompilation thread exiting."); + s_the_instance = nullptr; // Can cause deadlock if this is the last instance. Need to fix this. +} + +void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution_trace) { + auto execution_trace_id = execution_trace.GetId(); + auto processed_execution_trace_i = m_processed_execution_traces.find(execution_trace_id); + if (processed_execution_trace_i == m_processed_execution_traces.end()) { +#ifdef _DEBUG + Log() << "Trace: " << execution_trace.ToString() << "\n"; +#endif + // Find the function block + BlockEntry key(execution_trace.function_address, execution_trace.function_address); + auto block_i = m_block_table.find(&key); + if (block_i == m_block_table.end()) { + block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); + } + + auto function_block = *block_i; + block_i = m_block_table.end(); + auto split_trace = false; + std::vector tmp_block_list; + for (auto trace_i = execution_trace.entries.begin(); trace_i != execution_trace.entries.end(); trace_i++) { + if (trace_i->type == ExecutionTraceEntry::Type::CompiledBlock) { + block_i = m_block_table.end(); + split_trace = true; + } + + if (block_i == m_block_table.end()) { + BlockEntry key(trace_i->GetPrimaryAddress(), execution_trace.function_address); + block_i = m_block_table.find(&key); + if (block_i == m_block_table.end()) { + block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); + } + + tmp_block_list.push_back(*block_i); + } + + const ExecutionTraceEntry * next_trace = nullptr; + if (trace_i + 1 != execution_trace.entries.end()) { + next_trace = &(*(trace_i + 1)); + } else if (!split_trace && execution_trace.type == ExecutionTrace::Type::Loop) { + next_trace = &(*(execution_trace.entries.begin())); + } + + UpdateControlFlowGraph((*block_i)->cfg, *trace_i, next_trace); + if (*block_i != function_block) { + UpdateControlFlowGraph(function_block->cfg, *trace_i, next_trace); + } + } + + processed_execution_trace_i = m_processed_execution_traces.insert(m_processed_execution_traces.end(), std::make_pair(execution_trace_id, std::move(tmp_block_list))); + } + + for (auto i = processed_execution_trace_i->second.begin(); i != processed_execution_trace_i->second.end(); i++) { + if (!(*i)->is_compiled) { + (*i)->num_hits++; + if ((*i)->num_hits >= 1000) { // TODO: Make this configurable + CompileBlock(*(*i)); + } + } + } + + std::remove_if(processed_execution_trace_i->second.begin(), processed_execution_trace_i->second.end(), [](const BlockEntry * b)->bool { return b->is_compiled; }); +} + +void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry) { + if (this_entry.type == ExecutionTraceEntry::Type::Instruction) { + cfg.instruction_addresses.insert(this_entry.GetPrimaryAddress()); + + if (next_entry) { + if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { + if (next_entry->GetPrimaryAddress() != (this_entry.GetPrimaryAddress() + 4)) { + cfg.branches[this_entry.GetPrimaryAddress()].insert(next_entry->GetPrimaryAddress()); + } + } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { + cfg.calls[this_entry.data.instruction.address].insert(next_entry->GetPrimaryAddress()); + } + } + } else if (this_entry.type == ExecutionTraceEntry::Type::CompiledBlock) { + if (next_entry) { + if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { + cfg.branches[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); + } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { + cfg.calls[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); + } + } + } +} + +void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { +#ifdef _DEBUG + Log() << "Compile: " << block_entry.ToString() << "\n"; + Log() << "CFG: " << block_entry.cfg.ToString() << "\n"; +#endif + + auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction()); + auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), block_entry.cfg, true, + block_entry.IsFunction() ? true : false /*generate_linkable_exits*/); + m_executable_lookup[ordinal] = executable; + block_entry.last_compiled_cfg_size = block_entry.cfg.GetSize(); + block_entry.is_compiled = true; +} + +std::shared_ptr RecompilationEngine::GetInstance() { + std::lock_guard lock(s_mutex); + + if (s_the_instance == nullptr) { + s_the_instance = std::shared_ptr(new RecompilationEngine()); + } + + return s_the_instance; +} + +Tracer::Tracer() + : m_recompilation_engine(RecompilationEngine::GetInstance()) { + m_stack.reserve(100); +} + +Tracer::~Tracer() { + Terminate(); +} + +void Tracer::Trace(TraceType trace_type, u32 arg1, u32 arg2) { + ExecutionTrace * execution_trace = nullptr; + + switch (trace_type) { + case TraceType::CallFunction: + // arg1 is address of the function + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::FunctionCall, arg1)); + break; + case TraceType::EnterFunction: + // arg1 is address of the function + m_stack.push_back(new ExecutionTrace(arg1)); + break; + case TraceType::ExitFromCompiledFunction: + // arg1 is address of function. + // arg2 is the address of the exit instruction. + if (arg2) { + m_stack.push_back(new ExecutionTrace(arg1)); + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); + } + break; + case TraceType::Return: + // No args used + execution_trace = m_stack.back(); + execution_trace->type = ExecutionTrace::Type::Linear; + m_stack.pop_back(); + break; + case TraceType::Instruction: + // arg1 is the address of the instruction + for (int i = (int)m_stack.back()->entries.size() - 1; i >= 0; i--) { + if ((m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::Instruction && m_stack.back()->entries[i].data.instruction.address == arg1) || + (m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::CompiledBlock && m_stack.back()->entries[i].data.compiled_block.entry_address == arg1)) { + // Found a loop + execution_trace = new ExecutionTrace(m_stack.back()->function_address); + execution_trace->type = ExecutionTrace::Type::Loop; + std::copy(m_stack.back()->entries.begin() + i, m_stack.back()->entries.end(), std::back_inserter(execution_trace->entries)); + m_stack.back()->entries.erase(m_stack.back()->entries.begin() + i + 1, m_stack.back()->entries.end()); + break; + } + } + + if (!execution_trace) { + // A loop was not found + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::Instruction, arg1)); + } + break; + case TraceType::ExitFromCompiledBlock: + // arg1 is address of the compiled block. + // arg2 is the address of the exit instruction. + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); + + if (arg2 == 0) { + // Return from function + execution_trace = m_stack.back(); + execution_trace->type = ExecutionTrace::Type::Linear; + m_stack.pop_back(); + } + break; + default: + assert(0); + break; + } + + if (execution_trace) { + m_recompilation_engine->NotifyTrace(execution_trace); + } +} + +void Tracer::Terminate() { + // TODO: Notify recompilation engine +} + +ppu_recompiler_llvm::ExecutionEngine::ExecutionEngine(PPUThread & ppu) + : m_ppu(ppu) + , m_interpreter(new PPUInterpreter(ppu)) + , m_decoder(m_interpreter) + , m_last_cache_clear_time(std::chrono::high_resolution_clock::now()) , m_recompilation_engine(RecompilationEngine::GetInstance()) { -} +} + +ppu_recompiler_llvm::ExecutionEngine::~ExecutionEngine() { -ppu_recompiler_llvm::ExecutionEngine::~ExecutionEngine() { - -} - -u32 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) { - ExecuteFunction(&m_ppu, 0); - return 0; -} - -void ppu_recompiler_llvm::ExecutionEngine::RemoveUnusedEntriesFromCache() const { - auto now = std::chrono::high_resolution_clock::now(); - if (std::chrono::duration_cast(now - m_last_cache_clear_time).count() > 10000) { - for (auto i = m_address_to_ordinal.begin(); i != m_address_to_ordinal.end();) { - auto tmp = i; - i++; - if (tmp->second.second == 0) { - m_address_to_ordinal.erase(tmp); - } else { - tmp->second.second = 0; - } - } - - m_last_cache_clear_time = now; - } -} - -Executable ppu_recompiler_llvm::ExecutionEngine::GetExecutable(u32 address, Executable default_executable) const { - // Find the ordinal for the specified address and insert it to the cache - auto i = m_address_to_ordinal.find(address); - if (i == m_address_to_ordinal.end()) { - auto ordinal = m_recompilation_engine->GetOrdinal(address); - if (ordinal != 0xFFFFFFFF) { - i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, std::make_pair(ordinal, 0))); - } - } - - Executable executable = default_executable; - if (i != m_address_to_ordinal.end()) { - i->second.second++; - executable = m_recompilation_engine->GetExecutable(i->second.first); - } - - RemoveUnusedEntriesFromCache(); - return executable; -} - -u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteFunction(PPUThread * ppu_state, u64 context) { - auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); - execution_engine->m_tracer.Trace(Tracer::TraceType::EnterFunction, ppu_state->PC, 0); - return ExecuteTillReturn(ppu_state, 0); -} - -u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_state, u64 context) { - auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); - auto terminate = false; - auto branch_type = BranchType::NonBranch; - - if (context) { - execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledFunction, context >> 32, context & 0xFFFFFFFF); - } - - while (!terminate && !Emu.IsStopped()) { - if (Emu.IsPaused()) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - continue; - } - - auto executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteTillReturn); - if (executable != ExecuteTillReturn && executable != ExecuteFunction) { - auto entry = ppu_state->PC; - auto exit = (u32)executable(ppu_state, 0); - execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledBlock, entry, exit); - if (exit == 0) { - terminate = true; - } - } else { - execution_engine->m_tracer.Trace(Tracer::TraceType::Instruction, ppu_state->PC, 0); - auto instruction = re32(vm::get_ref(ppu_state->PC)); - execution_engine->m_decoder.Decode(instruction); - branch_type = ppu_state->m_is_branch ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; - ppu_state->NextPc(4); - - switch (branch_type) { - case BranchType::Return: - execution_engine->m_tracer.Trace(Tracer::TraceType::Return, 0, 0); - terminate = true; - break; - case BranchType::FunctionCall: - execution_engine->m_tracer.Trace(Tracer::TraceType::CallFunction, ppu_state->PC, 0); - executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteFunction); - executable(ppu_state, 0); - break; - case BranchType::LocalBranch: - break; - case BranchType::NonBranch: - break; - default: - assert(0); - break; - } - } - } - - return 0; -} - -BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { - auto type = BranchType::NonBranch; - auto field1 = instruction >> 26; - auto lk = instruction & 1; - - if (field1 == 16 || field1 == 18) { - type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; - } else if (field1 == 19) { - u32 field2 = (instruction >> 1) & 0x3FF; - if (field2 == 16) { - type = lk ? BranchType::FunctionCall : BranchType::Return; - } else if (field2 == 528) { - type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; - } - } - - return type; -} +} + +u32 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) { + ExecuteFunction(&m_ppu, 0); + return 0; +} + +void ppu_recompiler_llvm::ExecutionEngine::RemoveUnusedEntriesFromCache() const { + auto now = std::chrono::high_resolution_clock::now(); + if (std::chrono::duration_cast(now - m_last_cache_clear_time).count() > 10000) { + for (auto i = m_address_to_ordinal.begin(); i != m_address_to_ordinal.end();) { + auto tmp = i; + i++; + if (tmp->second.second == 0) { + m_address_to_ordinal.erase(tmp); + } else { + tmp->second.second = 0; + } + } + + m_last_cache_clear_time = now; + } +} + +Executable ppu_recompiler_llvm::ExecutionEngine::GetExecutable(u32 address, Executable default_executable) const { + // Find the ordinal for the specified address and insert it to the cache + auto i = m_address_to_ordinal.find(address); + if (i == m_address_to_ordinal.end()) { + auto ordinal = m_recompilation_engine->GetOrdinal(address); + if (ordinal != 0xFFFFFFFF) { + i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, std::make_pair(ordinal, 0))); + } + } + + Executable executable = default_executable; + if (i != m_address_to_ordinal.end()) { + i->second.second++; + executable = m_recompilation_engine->GetExecutable(i->second.first); + } + + RemoveUnusedEntriesFromCache(); + return executable; +} + +u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteFunction(PPUThread * ppu_state, u64 context) { + auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); + execution_engine->m_tracer.Trace(Tracer::TraceType::EnterFunction, ppu_state->PC, 0); + return ExecuteTillReturn(ppu_state, 0); +} + +u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_state, u64 context) { + auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); + auto terminate = false; + auto branch_type = BranchType::NonBranch; + + if (context) { + execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledFunction, context >> 32, context & 0xFFFFFFFF); + } + + while (!terminate && !Emu.IsStopped()) { + if (Emu.IsPaused()) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + continue; + } + + auto executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteTillReturn); + if (executable != ExecuteTillReturn && executable != ExecuteFunction) { + auto entry = ppu_state->PC; + auto exit = (u32)executable(ppu_state, 0); + execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledBlock, entry, exit); + if (exit == 0) { + terminate = true; + } + } else { + execution_engine->m_tracer.Trace(Tracer::TraceType::Instruction, ppu_state->PC, 0); + auto instruction = re32(vm::get_ref(ppu_state->PC)); + execution_engine->m_decoder.Decode(instruction); + branch_type = ppu_state->m_is_branch ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; + ppu_state->NextPc(4); + + switch (branch_type) { + case BranchType::Return: + execution_engine->m_tracer.Trace(Tracer::TraceType::Return, 0, 0); + terminate = true; + break; + case BranchType::FunctionCall: + execution_engine->m_tracer.Trace(Tracer::TraceType::CallFunction, ppu_state->PC, 0); + executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteFunction); + executable(ppu_state, 0); + break; + case BranchType::LocalBranch: + break; + case BranchType::NonBranch: + break; + default: + assert(0); + break; + } + } + } + + return 0; +} + +BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { + auto type = BranchType::NonBranch; + auto field1 = instruction >> 26; + auto lk = instruction & 1; + + if (field1 == 16 || field1 == 18) { + type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; + } else if (field1 == 19) { + u32 field2 = (instruction >> 1) & 0x3FF; + if (field2 == 16) { + type = lk ? BranchType::FunctionCall : BranchType::Return; + } else if (field2 == 528) { + type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; + } + } + + return type; +} diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 20b127ef19..edbb7c5d9d 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -242,6 +242,11 @@ namespace vm return broken; } + bool reservation_acquire_no_cb(void* data, u32 addr, u32 size) + { + return reservation_acquire(data, addr, size); + } + bool reservation_update(u32 addr, const void* data, u32 size) { assert(size == 1 || size == 2 || size == 4 || size == 8 || size == 128); diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 5f1d5a4338..833faf8478 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -36,6 +36,9 @@ namespace vm bool reservation_break(u32 addr); // read memory and reserve it for further atomic update, return true if the previous reservation was broken bool reservation_acquire(void* data, u32 addr, u32 size, const std::function& callback = nullptr); + // same as reservation_acquire but does not have the callback argument + // used by the PPU LLVM JIT since creating a std::function object in LLVM IR is too complicated + bool reservation_acquire_no_cb(void* data, u32 addr, u32 size); // attempt to atomically update reserved memory bool reservation_update(u32 addr, const void* data, u32 size); // for internal use From 3a2b13c02b39d49439c21924a0299b9430c15992 Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Mon, 16 Feb 2015 23:00:41 +0530 Subject: [PATCH 11/25] PPUJIT: Fix unit tests --- rpcs3/Emu/Cell/PPULLVMRecompiler.h | 4 +- rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp | 1082 ++++++++++----------- 2 files changed, 543 insertions(+), 543 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 40a9472e1e..588d9a1c47 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -923,8 +923,8 @@ namespace ppu_recompiler_llvm { llvm::Value * IndirectCall(u32 address, llvm::Value * context_i64, bool is_function); /// Test an instruction against the interpreter - template - void VerifyInstructionAgainstInterpreter(const char * name, PPULLVMRecompilerFn recomp_fn, PPUInterpreterFn interp_fn, PPUState & input_state, Args... args); + template + void VerifyInstructionAgainstInterpreter(const char * name, void (Compiler::*recomp_fn)(Args...), void (PPUInterpreter::*interp_fn)(Args...), PPUState & input_state, Args... args); /// Excute a test void RunTest(const char * name, std::function test_case, std::function input, std::function check_result); diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp index 511125e233..56f68885b2 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp @@ -189,8 +189,8 @@ static PPUThread * s_ppu_state = nullptr; static PPUInterpreter * s_interpreter = nullptr; #endif // PPU_LLVM_RECOMPILER_UNIT_TESTS -template -void Compiler::VerifyInstructionAgainstInterpreter(const char * name, CompilerFn recomp_fn, PPUInterpreterFn interp_fn, PPUState & input_state, Args... args) { +template +void Compiler::VerifyInstructionAgainstInterpreter(const char * name, void (Compiler::*recomp_fn)(Args...), void (PPUInterpreter::*interp_fn)(Args...), PPUState & input_state, Args... args) { #ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS auto test_case = [&]() { (this->*recomp_fn)(args...); @@ -308,403 +308,403 @@ void Compiler::RunAllTests() { m_recompilation_engine.Log() << "Starting Unit Tests\n"; - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFVSCR, 0, 5, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTVSCR, 0, 5, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDCUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSHS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUBM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUHM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUHS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUWM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAND, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VANDC, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFSX, 0, 5, 0, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFSX, 5, 5, 0, 3, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFUX, 0, 5, 0, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFUX, 5, 5, 0, 2, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 5, 5, 0, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 0, 5, 0, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 5, 5, 0, 3, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 0, 5, 0, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 5, 5, 0, 3, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VEXPTEFP, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VLOGEFP, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMADDFP, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHADDSHS, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHRADDSHS, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMLADDUHM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMMBM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHS, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUBM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHS, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNMSUBFP, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNOR, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VOR, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPERM, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKPX, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHSS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHUS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWSS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWUS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VREFP, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIM, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIN, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIP, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIZ, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRSQRTEFP, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSEL, 0, 5, 0, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSL, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLDOI, 0, 5, 0, 1, 2, 6); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLO, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTB, 0, 5, 0, 3, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTH, 0, 5, 0, 3, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISB, 0, 5, 0, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISH, 0, 5, 0, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISW, 0, 5, 0, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTW, 0, 5, 0, 3, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSR, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRB, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRH, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRO, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRW, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBFP, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSHS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUBM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWM, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUMSWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM2SWS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SHS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4UBS, 0, 5, 0, 1, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHPX, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSB, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSH, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLPX, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSB, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSH, 0, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VXOR, 0, 5, 0, 1, 2); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFVSCR, 0, 5, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTVSCR, 0, 5, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDCUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSHS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDSWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUBM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUHM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUHS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUWM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VADDUWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAND, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VANDC, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGSW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VAVGUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFSX, 0, 5, 0u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFSX, 5, 5, 0u, 3u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFUX, 0, 5, 0u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCFUX, 5, 5, 0u, 2u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPBFP_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQFP_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUB_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUH_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPEQUW_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGEFP_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTFP_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSB_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSH_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTSW_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUB_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUH_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCMPGTUW_, 5, 5, 0u, 1u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 0, 5, 0u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTSXS, 5, 5, 0u, 3u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 0, 5, 0u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VCTUXS, 5, 5, 0u, 3u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VEXPTEFP, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VLOGEFP, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMADDFP, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXSW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMAXUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHADDSHS, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMHRADDSHS, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINSW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMINUW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMLADDUHM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGHW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMRGLW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMMBM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMSHS, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUBM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMSUMUHS, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULESH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULEUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOSH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VMULOUH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNMSUBFP, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VNOR, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VOR, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPERM, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKPX, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHSS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSHUS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWSS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKSWUS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUHUS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VPKUWUS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VREFP, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIM, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIN, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIP, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRFIZ, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRLW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VRSQRTEFP, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSEL, 0, 5, 0u, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSL, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLDOI, 0, 5, 0u, 1u, 2u, 6u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLO, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSLW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTB, 0, 5, 0u, 3u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTH, 0, 5, 0u, 3u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISB, 0, 5, 0u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISH, 0, 5, 0u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTISW, 0, 5, 0u, -12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSPLTW, 0, 5, 0u, 3u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSR, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRAW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRB, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRH, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRO, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSRW, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBFP, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSHS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBSWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUBM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUHS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWM, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUBUWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUMSWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM2SWS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4SHS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VSUM4UBS, 0, 5, 0u, 1u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHPX, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSB, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKHSH, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLPX, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSB, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VUPKLSH, 0, 5, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(VXOR, 0, 5, 0u, 1u, 2u); // TODO: Rest of the vector instructions - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLI, 0, 5, 1, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFIC, 0, 5, 1, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPLI, 0, 5, 1, 0, 7, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPLI, 5, 5, 1, 1, 7, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPI, 0, 5, 5, 0, 7, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPI, 5, 5, 5, 1, 7, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIC, 0, 5, 1, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIC_, 0, 5, 1, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDI, 0, 5, 1, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDI, 5, 5, 0, 2, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIS, 0, 5, 1, 2, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIS, 5, 5, 0, 2, -12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLI, 0, 5, 1u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFIC, 0, 5, 1u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPLI, 0, 5, 1u, 0u, 7u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPLI, 5, 5, 1u, 1u, 7u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPI, 0, 5, 5u, 0u, 7u, -12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPI, 5, 5, 5u, 1u, 7u, -12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIC, 0, 5, 1u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIC_, 0, 5, 1u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDI, 0, 5, 1u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDI, 5, 5, 0u, 2u, 12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIS, 0, 5, 1u, 2u, -12345); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDIS, 5, 5, 0u, 2u, -12345); // TODO: BC // TODO: SC // TODO: B - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRF, 0, 5, 0, 7); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRF, 5, 5, 6, 2); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRF, 0, 5, 0u, 7u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRF, 5, 5, 6u, 2u); // TODO: BCLR - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNOR, 0, 5, 0, 7, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRANDC, 0, 5, 5, 6, 7); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNOR, 0, 5, 0u, 7u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRANDC, 0, 5, 5u, 6u, 7u); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ISYNC, 0, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRXOR, 0, 5, 7, 7, 7); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNAND, 0, 5, 3, 4, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRAND, 0, 5, 1, 2, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CREQV, 0, 5, 2, 1, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRORC, 0, 5, 3, 4, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CROR, 0, 5, 6, 7, 0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRXOR, 0, 5, 7u, 7u, 7u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRNAND, 0, 5, 3u, 4u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRAND, 0, 5, 1u, 2u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CREQV, 0, 5, 2u, 1u, 0u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CRORC, 0, 5, 3u, 4u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CROR, 0, 5, 6u, 7u, 0u); // TODO: BCCTR - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWIMI, 0, 5, 7, 8, 9, 12, 25, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWIMI, 5, 5, 21, 22, 21, 18, 24, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWINM, 0, 5, 7, 8, 9, 12, 25, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWINM, 5, 5, 21, 22, 21, 18, 24, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWNM, 0, 5, 7, 8, 9, 12, 25, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWNM, 5, 5, 21, 22, 21, 18, 24, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORI, 0, 5, 25, 29, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORIS, 0, 5, 7, 31, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XORI, 0, 5, 0, 19, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XORIS, 0, 5, 3, 14, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDI_, 0, 5, 16, 7, 12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDIS_, 0, 5, 23, 21, -12345); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICL, 0, 5, 7, 8, 9, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICL, 5, 5, 21, 22, 43, 43, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICR, 0, 5, 7, 8, 0, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICR, 5, 5, 21, 22, 63, 43, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIC, 0, 5, 7, 8, 9, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIC, 5, 5, 21, 22, 23, 43, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 0, 5, 7, 8, 9, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 5, 5, 21, 22, 23, 43, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 0, 5, 7, 8, 9, 12, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 5, 5, 21, 22, 23, 43, 1, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 0, 5, 3, 0, 9, 31); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 5, 5, 6, 1, 23, 14); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 0, 5, 0, 1, 2, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 5, 5, 0, 1, 2, 0, true); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 0, 5, 0, 1, 2, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 5, 5, 0, 1, 2, 0, true); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 5, 5, 21, 22, 23, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWIMI, 0, 5, 7u, 8u, 9u, 12u, 25u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWIMI, 5, 5, 21u, 22u, 21u, 18u, 24u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWINM, 0, 5, 7u, 8u, 9u, 12u, 25u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWINM, 5, 5, 21u, 22u, 21u, 18u, 24u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWNM, 0, 5, 7u, 8u, 9u, 12u, 25u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLWNM, 5, 5, 21u, 22u, 21u, 18u, 24u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORI, 0, 5, 25u, 29u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORIS, 0, 5, 7u, 31u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XORI, 0, 5, 0u, 19u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XORIS, 0, 5, 3u, 14u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDI_, 0, 5, 16u, 7u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDIS_, 0, 5, 23u, 21u, 12345u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICL, 0, 5, 7u, 8u, 9u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICL, 5, 5, 21u, 22u, 43u, 43u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICR, 0, 5, 7u, 8u, 0u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDICR, 5, 5, 21u, 22u, 63u, 43u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIC, 0, 5, 7u, 8u, 9u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIC, 5, 5, 21u, 22u, 23u, 43u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 0, 5, 7u, 8u, 9u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDIMI, 5, 5, 21u, 22u, 23u, 43u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 0, 5, 7u, 8u, 9u, 12u, false, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(RLDC_LR, 5, 5, 21u, 22u, 23u, 43u, true, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 0, 5, 3u, 0u, 9u, 31u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMP, 5, 5, 6u, 1u, 23u, 14u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 0, 5, 0u, 1u, 2u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFC, 5, 5, 0u, 1u, 2u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 0, 5, 0u, 1u, 2u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDC, 5, 5, 0u, 1u, 2u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHDU, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHWU, 5, 5, 21u, 22u, 23u, true); // TODO: MFOCRF - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 0, 5, 5, 6, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5, 6, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 0, 5, 3, 0, 9, 31); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 5, 5, 6, 1, 23, 14); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5, 6, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5, 6, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 0, 5, 7, 8, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 5, 5, 21, 22, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 5, 5, 21, 22, 23, 0, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 0, 5, 5u, 6u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5u, 6u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(AND, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 0, 5, 3u, 0u, 9u, 31u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CMPL, 5, 5, 6u, 1u, 23u, 14u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBF, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5u, 6u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5u, 6u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHD, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULHW, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 0, 5, 7u, 8u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NEG, 5, 5, 21u, 22u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NOR, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFE, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDE, 5, 5, 21u, 22u, 23u, 0u, true); // TODO: MTOCRF - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 0, 5, 7, 8, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 5, 5, 21, 22, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 0, 5, 7, 8, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 5, 5, 21, 22, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 0, 5, 7, 8, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 5, 5, 21, 22, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 0, 5, 7, 8, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 5, 5, 21, 22, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 0, 5, 5, 0x20); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 5, 5, 5, 0x100); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5, 0x120); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5, 0x8); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 0, 5, 7u, 8u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDZE, 5, 5, 21u, 22u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 0, 5, 7u, 8u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFZE, 5, 5, 21u, 22u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 0, 5, 7u, 8u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SUBFME, 5, 5, 21u, 22u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLD, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 0, 5, 7u, 8u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADDME, 5, 5, 21u, 22u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MULLW, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ADD, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EQV, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(XOR, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 0, 5, 5u, 0x20u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 5, 5, 5u, 0x100u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5u, 0x120u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5u, 0x8u); // TODO: MFTB - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 0, 5, 0x20, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 5, 5, 0x100, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 10, 5, 0x120, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 15, 5, 0x8, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 0, 5, 7, 8, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 5, 5, 21, 22, 23, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 0, 5, 7, 8, 9, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 5, 5, 21, 22, 23, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 5, 5, 5, 6, 7, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ORC, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(OR, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVDU, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVWU, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 0, 5, 0x20u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 5, 5, 0x100u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 10, 5, 0x120u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTSPR, 15, 5, 0x8u, 5u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 0, 5, 7u, 8u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(NAND, 5, 5, 21u, 22u, 23u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVD, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 0, 5, 7u, 8u, 9u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(DIVW, 5, 5, 21u, 22u, 23u, 0u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 5, 5, 5u, 6u, 7u, true); // TODO: SYNC - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 0, 5, 5, 6, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 5, 5, 5, 6, 7, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 0, 5, 5, 6, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 5, 5, 5, 6, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 10, 5, 5, 6, 22, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 15, 5, 5, 6, 31, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 0, 5, 5, 6, 0, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 5, 5, 5, 6, 12, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 10, 5, 5, 6, 48, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 15, 5, 5, 6, 63, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 0, 5, 5u, 6u, 7u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 5, 5, 5u, 6u, 7u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 0, 5, 5u, 6u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 5, 5, 5u, 6u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 10, 5, 5u, 6u, 22u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 15, 5, 5u, 6u, 31u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 0, 5, 5u, 6u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 5, 5, 5u, 6u, 12u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 10, 5, 5u, 6u, 48u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 15, 5, 5u, 6u, 63u, true); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EIEIO, 0, 5); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 0, 5, 6, 9, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 5, 5, 6, 9, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 0, 5, 3, 5, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 5, 5, 3, 5, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 0, 5, 25, 29, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 5, 5, 25, 29, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 0, 5, 6u, 9u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSH, 5, 5, 6u, 9u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 0, 5, 3u, 5u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSB, 5, 5, 3u, 5u, true); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 0, 5, 25u, 29u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EXTSW, 5, 5, 25u, 29u, true); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIVS, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUBS, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADDS, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRTS, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRES, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMULS, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADDS, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUBS, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUBS, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADDS, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 0, 5, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 5, 5, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 10, 5, 25, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 15, 5, 31, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 0, 5, 0, 7); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 5, 5, 7, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 10, 5, 5, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 15, 5, 5, 3); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 0, 5, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 5, 5, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 10, 5, 25, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 15, 5, 31, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 5, 5, 2, 6, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 10, 5, 5, 11, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 15, 5, 7, 14, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFFS, 0, 5, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 0, 5, 0, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 5, 5, 2, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 10, 5, 5, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 15, 5, 7, 0, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPU, 0, 5, 5, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSP, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIW, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIWZ, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIV, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUB, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRT, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSEL, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMUL, 0, 5, 0, 1, 2, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSQRTE, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUB, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADD, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUB, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADD, 0, 5, 0, 1, 2, 3, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPO, 0, 5, 3, 0, 1); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNEG, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMR, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNABS, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FABS, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTID, 0, 5, 0, 1, false); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCFID, 0, 5, 0, 1, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIVS, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUBS, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADDS, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRTS, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRES, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMULS, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADDS, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUBS, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUBS, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADDS, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 0, 5, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 5, 5, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 10, 5, 25u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB1, 15, 5, 31u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 0, 5, 0u, 7u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 5, 5, 7u, 0u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 10, 5, 5u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MCRFS, 15, 5, 5u, 3u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 0, 5, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 5, 5, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 10, 5, 25u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSB0, 15, 5, 31u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 5, 5, 2u, 6u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 10, 5, 5u, 11u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSFI, 15, 5, 7u, 14u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFFS, 0, 5, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 0, 5, 0u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 5, 5, 2u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 10, 5, 5u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MTFSF, 15, 5, 7u, 0u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPU, 0, 5, 5u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSP, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIW, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIWZ, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIV, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUB, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRT, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSEL, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMUL, 0, 5, 0u, 1u, 2u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FRSQRTE, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMSUB, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMADD, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMSUB, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNMADD, 0, 5, 0u, 1u, 2u, 3u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCMPO, 0, 5, 3u, 0u, 1u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNEG, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FMR, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FNABS, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FABS, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTID, 0, 5, 0u, 1u, false); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCFID, 0, 5, 0u, 1u, false); PPUState input; input.SetRandom(0x10000); @@ -713,163 +713,163 @@ void Compiler::RunAllTests() { input.GPR[23] = 0x10000; input.mem_block[0] = 0x8877665544332211; - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZ, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZ, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5, 14, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 0, input, 5, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5, 0, 0x100F0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5, 14, 0x100F0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAU, 0, input, 5, 14, 0x100F0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHBRX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZ, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZ, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWA, 0, input, 5, 0, 0x100F0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWA, 1, input, 5, 14, 0x100F0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWBRX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LD, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LD, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDBRX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFS, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFS, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSUX, 0, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFD, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFD, 1, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDU, 0, input, 5, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDUX, 0, input, 5, 14, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWARX, 0, input, 5, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWARX, 1, input, 5, 14, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDARX, 0, input, 5, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDARX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 0, input, 5, 23, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 1, input, 5, 23, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 2, input, 5, 23, 7); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 3, input, 5, 23, 25); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LMW, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LMW, 1, input, 16, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 2, input, 5, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 2, input, 5, 21, 23); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZ, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZ, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5u, 14u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 0, input, 5u, 0u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5u, 0u, 0x100F0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5u, 14u, 0x100F0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAU, 0, input, 5u, 14u, 0x100F0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHAUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHBRX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZ, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZ, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWZUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWA, 0, input, 5u, 0u, 0x100F0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWA, 1, input, 5u, 14u, 0x100F0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWAUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWBRX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LD, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LD, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDBRX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFS, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFS, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFSUX, 0, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFD, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFD, 1, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDU, 0, input, 5u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LFDUX, 0, input, 5u, 14u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWARX, 0, input, 5u, 0u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LWARX, 1, input, 5u, 14u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDARX, 0, input, 5u, 0u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LDARX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 0, input, 5u, 23u, 0u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 1, input, 5u, 23u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 2, input, 5u, 23u, 7u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LSWI, 3, input, 5u, 23u, 25u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LMW, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LMW, 1, input, 16u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 2, input, 5u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVRX, 2, input, 5u, 21u, 23u); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBU, 0, input, 3, 14, 0x10000); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 0, input, 3, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STH, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STH, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3, 14, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 0, input, 3, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWU, 0, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 0, input, 0, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 1, input, 0, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 2, input, 0, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWBRX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDU, 0, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 1, input, 3, 14, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 0, input, 3, 0, 23); - //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSU, 0, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 0, input, 0, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 1, input, 0, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 2, input, 0, 21, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 0, input, 3, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 1, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDU, 0, input, 3, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDX, 0, input, 3, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDX, 1, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDUX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFIWX, 0, input, 3, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEBX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEBX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEHX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEHX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEWX, 0, input, 5, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEWX, 1, input, 5, 14, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STMW, 0, input, 5, 0, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STMW, 1, input, 16, 14, 0x10000); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 0, input, 5, 23, 0); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 1, input, 5, 23, 2); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 2, input, 5, 23, 7); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 3, input, 5, 23, 25); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0, 23); - VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14, 23); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDCX_, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STBUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STH, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STH, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3u, 14u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 0, input, 3u, 0u, 23u); + //VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 0, input, 0u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 1, input, 0u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVLX, 2, input, 0u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWBRX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STD, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STWCX_, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STDUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFS, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 0, input, 0u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 1, input, 0u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVRX, 2, input, 0u, 21u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFSUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 0, input, 3u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFD, 1, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDU, 0, input, 3u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDX, 0, input, 3u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDX, 1, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFDUX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STFIWX, 0, input, 3u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEBX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEBX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEHX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEHX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEWX, 0, input, 5u, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVEWX, 1, input, 5u, 14u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STMW, 0, input, 5u, 0u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STMW, 1, input, 16u, 14u, 0x10000); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 0, input, 5u, 23u, 0u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 1, input, 5u, 23u, 2u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 2, input, 5u, 23u, 7u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 3, input, 5u, 23u, 25u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0u, 23u); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14u, 23u); m_recompilation_engine.Log() << "Finished Unit Tests\n"; #endif // PPU_LLVM_RECOMPILER_UNIT_TESTS From 1365c830b232f98fcc21db87291e7dcc2379725f Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Mon, 16 Feb 2015 23:07:22 +0530 Subject: [PATCH 12/25] PPUJIT: Fix EOL issues --- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 11924 ++++++++++++------------- 1 file changed, 5962 insertions(+), 5962 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 33994f0227..7bcb074901 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1,2474 +1,2474 @@ -#include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/Cell/PPULLVMRecompiler.h" -#include "Emu/Memory/Memory.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/CodeGen/MachineCodeInfo.h" -#include "llvm/ExecutionEngine/GenericValue.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/TargetTransformInfo.h" -#include "llvm/Analysis/MemoryDependenceAnalysis.h" -#include "llvm/Analysis/LoopInfo.h" -#include "llvm/Analysis/ScalarEvolution.h" -#include "llvm/IR/Dominators.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm/Transforms/Vectorize.h" -#include "llvm/MC/MCDisassembler.h" -#include "llvm/IR/Verifier.h" - -using namespace llvm; -using namespace ppu_recompiler_llvm; - -u64 Compiler::s_rotate_mask[64][64]; -bool Compiler::s_rotate_mask_inited = false; - -Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block) - : m_recompilation_engine(recompilation_engine) { - InitializeNativeTarget(); - InitializeNativeTargetAsmPrinter(); - InitializeNativeTargetDisassembler(); - - m_llvm_context = new LLVMContext(); - m_ir_builder = new IRBuilder<>(*m_llvm_context); - m_module = new llvm::Module("Module", *m_llvm_context); - m_fpm = new FunctionPassManager(m_module); - - EngineBuilder engine_builder(m_module); - engine_builder.setMCPU(sys::getHostCPUName()); - engine_builder.setEngineKind(EngineKind::JIT); - engine_builder.setOptLevel(CodeGenOpt::Default); - m_execution_engine = engine_builder.create(); - - m_fpm->add(new DataLayoutPass(m_module)); - m_fpm->add(createNoAAPass()); - m_fpm->add(createBasicAliasAnalysisPass()); - m_fpm->add(createNoTargetTransformInfoPass()); - m_fpm->add(createEarlyCSEPass()); - m_fpm->add(createTailCallEliminationPass()); - m_fpm->add(createReassociatePass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(new DominatorTreeWrapperPass()); - m_fpm->add(new MemoryDependenceAnalysis()); - m_fpm->add(createGVNPass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(new MemoryDependenceAnalysis()); - m_fpm->add(createDeadStoreEliminationPass()); - m_fpm->add(new LoopInfo()); - m_fpm->add(new ScalarEvolution()); - m_fpm->add(createSLPVectorizerPass()); - m_fpm->add(createInstructionCombiningPass()); - m_fpm->add(createCFGSimplificationPass()); - m_fpm->doInitialization(); - - std::vector arg_types; - arg_types.push_back(m_ir_builder->getInt8PtrTy()); - arg_types.push_back(m_ir_builder->getInt8PtrTy()); - arg_types.push_back(m_ir_builder->getInt64Ty()); - m_compiled_function_type = FunctionType::get(m_ir_builder->getInt32Ty(), arg_types, false); - - m_execute_unknown_function = (Function *)m_module->getOrInsertFunction("execute_unknown_function", m_compiled_function_type); - m_execute_unknown_function->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(m_execute_unknown_function, (void *)execute_unknown_function); - - m_execute_unknown_block = (Function *)m_module->getOrInsertFunction("execute_unknown_block", m_compiled_function_type); - m_execute_unknown_block->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(m_execute_unknown_block, (void *)execute_unknown_block); - - if (!s_rotate_mask_inited) { - InitRotateMask(); - s_rotate_mask_inited = true; - } -} - -Compiler::~Compiler() { - delete m_execution_engine; - delete m_fpm; - delete m_ir_builder; - delete m_llvm_context; -} - -Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & cfg, bool inline_all, bool generate_linkable_exits) { - auto compilation_start = std::chrono::high_resolution_clock::now(); - - m_state.cfg = &cfg; - m_state.inline_all = inline_all; - m_state.generate_linkable_exits = generate_linkable_exits; - - // Create the function - m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); - m_state.function->setCallingConv(CallingConv::X86_64_Win64); - auto arg_i = m_state.function->arg_begin(); - arg_i->setName("ppu_state"); - m_state.args[CompileTaskState::Args::State] = arg_i; - (++arg_i)->setName("context"); - m_state.args[CompileTaskState::Args::Context] = arg_i; - - // Create the entry block and add code to branch to the first instruction - m_ir_builder->SetInsertPoint(GetBasicBlockFromAddress(0)); - m_ir_builder->CreateBr(GetBasicBlockFromAddress(cfg.start_address)); - - // Convert each instruction in the CFG to LLVM IR - std::vector exit_instr_list; - for (auto instr_i = cfg.instruction_addresses.begin(); instr_i != cfg.instruction_addresses.end(); instr_i++) { - m_state.hit_branch_instruction = false; - m_state.current_instruction_address = *instr_i; - auto instr_bb = GetBasicBlockFromAddress(m_state.current_instruction_address); - m_ir_builder->SetInsertPoint(instr_bb); - - if (!inline_all && *instr_i != cfg.start_address) { - // Use an already compiled implementation of this block if available - auto ordinal = m_recompilation_engine.GetOrdinal(*instr_i); - if (ordinal != 0xFFFFFFFF) { - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - auto ret_i32 = IndirectCall(*instr_i, context_i64, false); - - auto switch_instr = m_ir_builder->CreateSwitch(ret_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); - auto branch_i = cfg.branches.find(*instr_i); - if (branch_i != cfg.branches.end()) { - for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { - switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); - } - } - } - } - - if (instr_bb->empty()) { - u32 instr = re32(vm::get_ref(m_state.current_instruction_address)); - Decode(instr); - if (!m_state.hit_branch_instruction) { - m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); - } - } - } - - // Generate exit logic for all empty blocks - auto default_exit_block_name = GetBasicBlockNameFromAddress(0xFFFFFFFF); - for (auto block_i = m_state.function->begin(); block_i != m_state.function->end(); block_i++) { - if (!block_i->getInstList().empty() || block_i->getName() == default_exit_block_name) { - continue; - } - - // Found an empty block - m_ir_builder->SetInsertPoint(block_i); - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - auto instr_address = GetAddressFromBasicBlockName(block_i->getName()); - SetPc(m_ir_builder->getInt32(instr_address)); - - if (generate_linkable_exits) { - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - auto ret_i32 = IndirectCall(instr_address, context_i64, false); - auto cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(instr_address, "then"); - auto merge_bb = GetBasicBlockFromAddress(instr_address, "merge"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - context_i64 = m_ir_builder->CreateZExt(ret_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else { - m_ir_builder->CreateRet(exit_instr_i32); - } - } - - // If the function has a default exit block then generate code for it - auto default_exit_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "", false); - if (default_exit_bb) { - m_ir_builder->SetInsertPoint(default_exit_bb); - auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); - exit_instr_list.push_back(exit_instr_i32); - - if (generate_linkable_exits) { - auto cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then"); - auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge"); - m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); - - m_ir_builder->SetInsertPoint(then_bb); - auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); - context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); - m_ir_builder->CreateBr(merge_bb); - - m_ir_builder->SetInsertPoint(merge_bb); - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else { - m_ir_builder->CreateRet(exit_instr_i32); - } - } - - // Add incoming values for all exit instr PHI nodes - for (auto exit_instr_i = exit_instr_list.begin(); exit_instr_i != exit_instr_list.end(); exit_instr_i++) { - auto block = (*exit_instr_i)->getParent(); - for (auto pred_i = pred_begin(block); pred_i != pred_end(block); pred_i++) { - auto pred_address = GetAddressFromBasicBlockName((*pred_i)->getName()); - (*exit_instr_i)->addIncoming(m_ir_builder->getInt32(pred_address), *pred_i); - } - } - -#ifdef _DEBUG - m_recompilation_engine.Log() << *m_state.function; - - std::string verify; - raw_string_ostream verify_ostream(verify); - if (verifyFunction(*m_state.function, &verify_ostream)) { - m_recompilation_engine.Log() << "Verification failed: " << verify << "\n"; - } -#endif - - auto ir_build_end = std::chrono::high_resolution_clock::now(); - m_stats.ir_build_time += std::chrono::duration_cast(ir_build_end - compilation_start); - - // Optimize this function - m_fpm->run(*m_state.function); - auto optimize_end = std::chrono::high_resolution_clock::now(); - m_stats.optimization_time += std::chrono::duration_cast(optimize_end - ir_build_end); - - // Translate to machine code - MachineCodeInfo mci; - m_execution_engine->runJITOnFunction(m_state.function, &mci); - auto translate_end = std::chrono::high_resolution_clock::now(); - m_stats.translation_time += std::chrono::duration_cast(translate_end - optimize_end); - -#ifdef _DEBUG - m_recompilation_engine.Log() << "\nDisassembly:\n"; - auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr); - for (size_t pc = 0; pc < mci.size();) { - char str[1024]; - - auto size = LLVMDisasmInstruction(disassembler, ((u8 *)mci.address()) + pc, mci.size() - pc, (uint64_t)(((u8 *)mci.address()) + pc), str, sizeof(str)); - m_recompilation_engine.Log() << fmt::Format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n'; - pc += size; - } - - LLVMDisasmDispose(disassembler); -#endif - - auto compilation_end = std::chrono::high_resolution_clock::now(); - m_stats.total_time += std::chrono::duration_cast(compilation_end - compilation_start); - - return (Executable)mci.address(); -} - -void Compiler::FreeExecutable(const std::string & name) { - auto function = m_module->getFunction(name); - if (function) { - m_execution_engine->freeMachineCodeForFunction(function); - function->eraseFromParent(); - } -} - -Compiler::Stats Compiler::GetStats() { - return m_stats; -} - -void Compiler::Decode(const u32 code) { - (*PPU_instr::main_list)(this, code); -} - -void Compiler::NULL_OP() { - CompilationError("NULL_OP"); -} - -void Compiler::NOP() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::TDI(u32 to, u32 ra, s32 simm16) { - CompilationError("TDI"); -} - -void Compiler::TWI(u32 to, u32 ra, s32 simm16) { - CompilationError("TWI"); -} - -void Compiler::MFVSCR(u32 vd) { - auto vscr_i32 = GetVscr(); - auto vscr_i128 = m_ir_builder->CreateZExt(vscr_i32, m_ir_builder->getIntNTy(128)); - SetVr(vd, vscr_i128); -} - -void Compiler::MTVSCR(u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto vscr_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(0)); - vscr_i32 = m_ir_builder->CreateAnd(vscr_i32, 0x00010001); - SetVscr(vscr_i32); -} - -void Compiler::VADDCUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - va_v4i32 = m_ir_builder->CreateNot(va_v4i32); - auto cmpv4i1 = m_ir_builder->CreateICmpULT(va_v4i32, vb_v4i32); - auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmpv4i32); -} - -void Compiler::VADDFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto sum_v4f32 = m_ir_builder->CreateFAdd(va_v4f32, vb_v4f32); - SetVr(vd, sum_v4f32); -} - -void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - // It looks like x86 does not have an instruction to add 32 bit intergers with signed/unsigned saturation. - // To implement add with saturation, we first determine what the result would be if the operation were to cause - // an overflow. If two -ve numbers are being added and cause an overflow, the result would be 0x80000000. - // If two +ve numbers are being added and cause an overflow, the result would be 0x7FFFFFFF. Addition of a -ve - // number and a +ve number cannot cause overflow. So the result in case of an overflow is 0x7FFFFFFF + sign bit - // of any one of the operands. - auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Next, we find if the addition can actually result in an overflow. Since an overflow can only happen if the operands - // have the same sign, we bitwise XOR both the operands. If the sign bit of the result is 0 then the operands have the - // same sign and so may cause an overflow. We invert the result so that the sign bit is 1 when the operands have the - // same sign. - auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); - tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); - - // Perform the sum. - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // If an overflow occurs, then the sign of the sum will be different from the sign of the operands. So, we xor the - // result with one of the operands. The sign bit of the result will be 1 if the sign bit of the sum and the sign bit of the - // result is different. This result is again ANDed with tmp3 (the sign bit of tmp3 is 1 only if the operands have the same - // sign and so can cause an overflow). - auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, sum_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set SAT -} - -void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateAdd(va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); -} - -void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8); - SetVr(vd, sum_v16i8); - - // TODO: Set SAT -} - -void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateAdd(va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); -} - -void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16); - SetVr(vd, sum_v8i16); - - // TODO: Set SAT -} - -void Compiler::VADDUWM(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - SetVr(vd, sum_v4i32); -} - -void Compiler::VADDUWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); - auto cmp_v4i1 = m_ir_builder->CreateICmpULT(sum_v4i32, va_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateOr(sum_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set SAT -} - -void Compiler::VAND(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VANDC(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateNot(vb_v4i32); - auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VAVGSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateSExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto sum_v16i16 = m_ir_builder->CreateAdd(va_v16i16, vb_v16i16); - sum_v16i16 = m_ir_builder->CreateAdd(sum_v16i16, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt16(1))); - auto avg_v16i16 = m_ir_builder->CreateAShr(sum_v16i16, 1); - auto avg_v16i8 = m_ir_builder->CreateTrunc(avg_v16i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, avg_v16i8); -} - -void Compiler::VAVGSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto sum_v8i32 = m_ir_builder->CreateAdd(va_v8i32, vb_v8i32); - sum_v8i32 = m_ir_builder->CreateAdd(sum_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(1))); - auto avg_v8i32 = m_ir_builder->CreateAShr(sum_v8i32, 1); - auto avg_v8i16 = m_ir_builder->CreateTrunc(avg_v8i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, avg_v8i16); -} - -void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); - sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); - auto avg_v4i64 = m_ir_builder->CreateAShr(sum_v4i64, 1); - auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, avg_v4i32); -} - -void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8); - SetVr(vd, avg_v16i8); -} - -void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16); - SetVr(vd, avg_v8i16); -} - -void Compiler::VAVGUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto va_v4i64 = m_ir_builder->CreateZExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v4i64 = m_ir_builder->CreateZExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); - sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); - auto avg_v4i64 = m_ir_builder->CreateLShr(sum_v4i64, 1); - auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, avg_v4i32); -} - -void Compiler::VCFSX(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4f32 = m_ir_builder->CreateSIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); - - if (uimm5) { - float scale = (float)((u64)1 << uimm5); - res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); - } - - SetVr(vd, res_v4f32); -} - -void Compiler::VCFUX(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4f32 = m_ir_builder->CreateUIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); - - if (uimm5) { - float scale = (float)((u64)1 << uimm5); - res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); - } - - SetVr(vd, res_v4f32); -} - -void Compiler::VCMPBFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_gt_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); - vb_v4f32 = m_ir_builder->CreateFNeg(vb_v4f32); - auto cmp_lt_v4i1 = m_ir_builder->CreateFCmpOLT(va_v4f32, vb_v4f32); - auto cmp_gt_v4i32 = m_ir_builder->CreateZExt(cmp_gt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto cmp_lt_v4i32 = m_ir_builder->CreateZExt(cmp_lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - cmp_gt_v4i32 = m_ir_builder->CreateShl(cmp_gt_v4i32, 31); - cmp_lt_v4i32 = m_ir_builder->CreateShl(cmp_lt_v4i32, 30); - auto res_v4i32 = m_ir_builder->CreateOr(cmp_gt_v4i32, cmp_lt_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Implement NJ mode -} - -void Compiler::VCMPBFP_(u32 vd, u32 va, u32 vb) { - VCMPBFP(vd, va, vb); - - auto vd_v16i8 = GetVrAsIntVec(vd, 8); - u32 mask_v16i32[16] = {3, 7, 11, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - vd_v16i8 = m_ir_builder->CreateShuffleVector(vd_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - auto vd_v4i32 = m_ir_builder->CreateBitCast(vd_v16i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto vd_mask_i32 = m_ir_builder->CreateExtractElement(vd_v4i32, m_ir_builder->getInt32(0)); - auto cmp_i1 = m_ir_builder->CreateICmpEQ(vd_mask_i32, m_ir_builder->getInt32(0)); - SetCrField(6, nullptr, nullptr, cmp_i1, nullptr); -} - -void Compiler::VCMPEQFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOEQ(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPEQFP_(u32 vd, u32 va, u32 vb) { - VCMPEQFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpEQ(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPEQUB_(u32 vd, u32 va, u32 vb) { - VCMPEQUB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpEQ(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPEQUH_(u32 vd, u32 va, u32 vb) { - VCMPEQUH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPEQUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpEQ(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPEQUW_(u32 vd, u32 va, u32 vb) { - VCMPEQUW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGEFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGEFP_(u32 vd, u32 va, u32 vb) { - VCMPGEFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTFP_(u32 vd, u32 va, u32 vb) { - VCMPGTFP(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpSGT(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPGTSB_(u32 vd, u32 va, u32 vb) { - VCMPGTSB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpSGT(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPGTSH_(u32 vd, u32 va, u32 vb) { - VCMPGTSH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpSGT(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTSW_(u32 vd, u32 va, u32 vb) { - VCMPGTSW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto cmp_v16i1 = m_ir_builder->CreateICmpUGT(va_v16i8, vb_v16i8); - auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - SetVr(vd, cmp_v16i8); -} - -void Compiler::VCMPGTUB_(u32 vd, u32 va, u32 vb) { - VCMPGTUB(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto cmp_v8i1 = m_ir_builder->CreateICmpUGT(va_v8i16, vb_v8i16); - auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, cmp_v8i16); -} - -void Compiler::VCMPGTUH_(u32 vd, u32 va, u32 vb) { - VCMPGTUH(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCMPGTUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto cmp_v4i1 = m_ir_builder->CreateICmpUGT(va_v4i32, vb_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmp_v4i32); -} - -void Compiler::VCMPGTUW_(u32 vd, u32 va, u32 vb) { - VCMPGTUW(vd, va, vb); - SetCr6AfterVectorCompare(vd); -} - -void Compiler::VCTSXS(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - if (uimm5) { - vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); - } - - auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_cvtps2dq), vb_v4f32); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0x7FFFFFFF))); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateXor(cmp_v4i32, res_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - if (uimm5) { - vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); - } - - auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0))); - auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu))); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VEXPTEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)), - m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VLOGEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::log2, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto vc_v4f32 = GetVrAsFloatVec(vc); - auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); - - u32 mask1_v4i32[4] = {0, 1, 2, 3}; - auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {4, 5, 6, 7}; - auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(0x4000))); - res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); - res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); - - u32 mask1_v4i32[4] = {0, 1, 2, 3}; - auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {4, 5, 6, 7}; - auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMINFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VMINSB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMINSH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMINSW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMINUB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VMINUH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMINUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMLADDUHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v8i16 = GetVrAsIntVec(vc, 16); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - res_v8i16 = m_ir_builder->CreateAdd(res_v8i16, vc_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMRGHB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v16i32[16] = {24, 8, 25, 9, 26, 10, 27, 11, 28, 12, 29, 13, 30, 14, 31, 15}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VMRGHH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = {12, 4, 13, 5, 14, 6, 15, 7}; - auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VMRGHW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - u32 mask_v4i32[4] = {6, 2, 7, 3}; - auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VMRGLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v16i32[16] = {16, 0, 17, 1, 18, 2, 19, 3, 20, 4, 21, 5, 22, 6, 23, 7}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VMRGLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = {8, 0, 9, 1, 10, 2, 11, 3}; - auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VMRGLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - u32 mask_v4i32[4] = {4, 0, 5, 1}; - auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); - - auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); - u32 mask1_v4i32[4] = {0, 4, 8, 12}; - auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp1_v4i32 = m_ir_builder->CreateSExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask2_v4i32[4] = {1, 5, 9, 13}; - auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto tmp2_v4i32 = m_ir_builder->CreateSExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask3_v4i32[4] = {2, 6, 10, 14}; - auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto tmp3_v4i32 = m_ir_builder->CreateSExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask4_v4i32[4] = {3, 7, 11, 15}; - auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto tmp4_v4i32 = m_ir_builder->CreateSExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); - - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto tmp2_v4i32 = m_ir_builder->CreateXor(vc_v4i32, res_v4i32); - tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); - auto sum_v4i32 = m_ir_builder->CreateAdd(vc_v4i32, res_v4i32); - auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto tmp3_v4i32 = m_ir_builder->CreateXor(vc_v4i32, sum_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMSUMUBM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto va_v16i16 = m_ir_builder->CreateZExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); - auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); - - auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); - u32 mask1_v4i32[4] = {0, 4, 8, 12}; - auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp1_v4i32 = m_ir_builder->CreateZExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask2_v4i32[4] = {1, 5, 9, 13}; - auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto tmp2_v4i32 = m_ir_builder->CreateZExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask3_v4i32[4] = {2, 6, 10, 14}; - auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto tmp3_v4i32 = m_ir_builder->CreateZExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - u32 mask4_v4i32[4] = {3, 7, 11, 15}; - auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto tmp4_v4i32 = m_ir_builder->CreateZExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMUHM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - - auto undef_v8i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)); - u32 mask1_v4i32[4] = {0, 2, 4, 6}; - auto tmp1_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - u32 mask2_v4i32[4] = {1, 3, 5, 7}; - auto tmp2_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); - - SetVr(vd, res_v4i32); - - // TODO: Try to optimize with horizontal add -} - -void Compiler::VMSUMUHS(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); - auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); - auto tmp_v8i64 = m_ir_builder->CreateZExt(tmp_v8i32, VectorType::get(m_ir_builder->getInt64Ty(), 8)); - - u32 mask1_v4i32[4] = {0, 2, 4, 6}; - u32 mask2_v4i32[4] = {1, 3, 5, 7}; - auto tmp1_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto tmp2_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - auto vc_v4i64 = m_ir_builder->CreateZExt(vc_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto res_v4i64 = m_ir_builder->CreateAdd(tmp1_v4i64, tmp2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vc_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpUGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF))); - auto gt_v4i64 = m_ir_builder->CreateSExt(gt_v4i1, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - res_v4i64 = m_ir_builder->CreateOr(res_v4i64, gt_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VMULESB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULESH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULEUB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULEUH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULOSB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); - va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULOSH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); - va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VMULOUB(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); - va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); - vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); - auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VMULOUH(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); - va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); - vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); - auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto vc_v4f32 = GetVrAsFloatVec(vc); - vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32); - auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VNOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); - res_v8i16 = m_ir_builder->CreateNot(res_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto vc_v16i8 = GetVrAsIntVec(vc, 8); - - auto thrity_one_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(31)); - vc_v16i8 = m_ir_builder->CreateAnd(vc_v16i8, thrity_one_v16i8); - - auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15)); - auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8); - auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8); - - auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8); - auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8); - auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8); - auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8); - - auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VPKPX(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto tmpa_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); - tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); - tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); - tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); - va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); - tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); - auto tmpa_v8i16 = m_ir_builder->CreateBitCast(tmpa_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - auto tmpb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); - tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); - tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); - tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); - vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); - tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); - auto tmpb_v8i16 = m_ir_builder->CreateBitCast(tmpb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - u32 mask_v8i32[8] = {1, 3, 5, 7, 9, 11, 13, 15}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(tmpb_v8i16, tmpa_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - SetVr(vd, res_v8i16); - - // TODO: Implement with pext on CPUs with BMI -} - -void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16); - SetVr(vd, res_v16i8); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16); - SetVr(vd, res_v16i8); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32); - SetVr(vd, res_v8i16); - - // TODO: VSCR.SAT -} - -void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32); - SetVr(vd, res_v8i16); - - // TODO: VSCR.SAT -} - -void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - - u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, res_v16i8); -} - -void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); - vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); - auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, res_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - - u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, res_v8i16); -} - -void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); - vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); - auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - - u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - SetVr(vd, res_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VREFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIM(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::floor, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIN(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::nearbyint, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ceil, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRFIZ(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::trunc, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VRLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(7))); - auto tmp1_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); - vb_v16i8 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(8)), vb_v16i8); - auto tmp2_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); - auto res_v16i8 = m_ir_builder->CreateOr(tmp1_v16i8, tmp2_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VRLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto tmp1_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); - vb_v8i16 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0x10)), vb_v8i16); - auto tmp2_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); - auto res_v8i16 = m_ir_builder->CreateOr(tmp1_v8i16, tmp2_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VRLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto tmp1_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); - vb_v4i32 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x20)), vb_v4i32); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); - auto res_v4i32 = m_ir_builder->CreateOr(tmp1_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VRSQRTEFP(u32 vd, u32 vb) { - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); - res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), res_v4f32); - SetVr(vd, res_v4f32); -} - -void Compiler::VSEL(u32 vd, u32 va, u32 vb, u32 vc) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto vc_v4i32 = GetVrAsIntVec(vc, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, vc_v4i32); - vc_v4i32 = m_ir_builder->CreateNot(vc_v4i32); - va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vc_v4i32); - auto vd_v4i32 = m_ir_builder->CreateOr(va_v4i32, vb_v4i32); - SetVr(vd, vd_v4i32); -} - -void Compiler::VSL(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSLB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSLDOI(u32 vd, u32 va, u32 vb, u32 sh) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - sh = 16 - sh; - u32 mask_v16i32[16] = {sh, sh + 1, sh + 2, sh + 3, sh + 4, sh + 5, sh + 6, sh + 7, sh + 8, sh + 9, sh + 10, sh + 11, sh + 12, sh + 13, sh + 14, sh + 15}; - auto vd_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VSLH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSLO(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSLW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSPLTB(u32 vd, u32 uimm5, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto undef_v16i8 = UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)); - auto mask_v16i32 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt32(15 - uimm5)); - auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, undef_v16i8, mask_v16i32); - SetVr(vd, res_v16i8); -} - -void Compiler::VSPLTH(u32 vd, u32 uimm5, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto undef_v8i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)); - auto mask_v8i32 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(7 - uimm5)); - auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, undef_v8i16, mask_v8i32); - SetVr(vd, res_v8i16); -} - -void Compiler::VSPLTISB(u32 vd, s32 simm5) { - auto vd_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8((s8)simm5)); - SetVr(vd, vd_v16i8); -} - -void Compiler::VSPLTISH(u32 vd, s32 simm5) { - auto vd_v8i16 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16((s16)simm5)); - SetVr(vd, vd_v8i16); -} - -void Compiler::VSPLTISW(u32 vd, s32 simm5) { - auto vd_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32((s32)simm5)); - SetVr(vd, vd_v4i32); -} - -void Compiler::VSPLTW(u32 vd, u32 uimm5, u32 vb) { - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto undef_v4i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto mask_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3 - uimm5)); - auto res_v4i32 = m_ir_builder->CreateShuffleVector(vb_v4i32, undef_v4i32, mask_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSR(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSRAB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateAShr(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSRAH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateAShr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSRAW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateAShr(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSRB(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); - auto res_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); - SetVr(vd, res_v16i8); -} - -void Compiler::VSRH(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); - auto res_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::VSRO(u32 vd, u32 va, u32 vb) { - auto va_i128 = GetVr(va); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); - sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); - auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); - va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); - SetVr(vd, va_i128); -} - -void Compiler::VSRW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); - auto res_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VSUBCUW(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto cmpv4i1 = m_ir_builder->CreateICmpUGE(va_v4i32, vb_v4i32); - auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, cmpv4i32); -} - -void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) { - auto va_v4f32 = GetVrAsFloatVec(va); - auto vb_v4f32 = GetVrAsFloatVec(vb); - auto diff_v4f32 = m_ir_builder->CreateFSub(va_v4f32, vb_v4f32); - SetVr(vd, diff_v4f32); -} - -void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - // See the comments for VADDSWS for a detailed description of how this works - - // Find the result in case of an overflow - auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); - tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); - auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Find the elements that can overflow (elements with opposite sign bits) - auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); - - // Perform the sub - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - auto diff_v16i8 = m_ir_builder->CreateBitCast(diff_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // Find the elements that overflowed - auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, diff_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); - tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); - auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); - - // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. - auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8); - SetVr(vd, res_v16i8); - - // TODO: Set SAT -} - -void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateSub(va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); -} - -void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8); - SetVr(vd, diff_v16i8); - - // TODO: Set SAT -} - -void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateSub(va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); -} - -void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16); - SetVr(vd, diff_v8i16); - - // TODO: Set SAT -} - -void Compiler::VSUBUWM(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - SetVr(vd, diff_v4i32); -} - -void Compiler::VSUBUWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); - auto cmp_v4i1 = m_ir_builder->CreateICmpULE(diff_v4i32, va_v4i32); - auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto res_v4i32 = m_ir_builder->CreateAnd(diff_v4i32, cmp_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set SAT -} - -void Compiler::VSUMSWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - auto res_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(3)); - auto res_i64 = m_ir_builder->CreateSExt(res_i32, m_ir_builder->getInt64Ty()); - for (auto i = 0; i < 4; i++) { - auto va_i32 = m_ir_builder->CreateExtractElement(va_v4i32, m_ir_builder->getInt32(i)); - auto va_i64 = m_ir_builder->CreateSExt(va_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateAdd(res_i64, va_i64); - } - - auto gt_i1 = m_ir_builder->CreateICmpSGT(res_i64, m_ir_builder->getInt64(0x7FFFFFFFull)); - auto lt_i1 = m_ir_builder->CreateICmpSLT(res_i64, m_ir_builder->getInt64(0xFFFFFFFF80000000ull)); - res_i64 = m_ir_builder->CreateSelect(gt_i1, m_ir_builder->getInt64(0x7FFFFFFFull), res_i64); - res_i64 = m_ir_builder->CreateSelect(lt_i1, m_ir_builder->getInt64(0xFFFFFFFF80000000ull), res_i64); - auto res_i128 = m_ir_builder->CreateZExt(res_i64, m_ir_builder->getIntNTy(128)); - - SetVr(vd, res_i128); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM2SWS(u32 vd, u32 va, u32 vb) { - auto va_v4i32 = GetVrAsIntVec(va, 32); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v2i32[2] = { 0, 2 }; - u32 mask2_v2i32[2] = { 1, 3 }; - auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto va1_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); - auto va2_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v2i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - auto vb_v2i64 = m_ir_builder->CreateShuffleVector(vb_v4i64, UndefValue::get(vb_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); - - auto res_v2i64 = m_ir_builder->CreateAdd(va1_v2i64, va2_v2i64); - res_v2i64 = m_ir_builder->CreateAdd(res_v2i64, vb_v2i64); - auto gt_v2i1 = m_ir_builder->CreateICmpSGT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v2i1 = m_ir_builder->CreateICmpSLT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v2i64 = m_ir_builder->CreateSelect(gt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v2i64); - res_v2i64 = m_ir_builder->CreateSelect(lt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x80000000ull)), res_v2i64); - SetVr(vd, res_v2i64); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4SBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; - u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; - u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; - u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; - auto va_v16i64 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt64Ty(), 16)); - auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto va3_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto va4_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - - auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va3_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va4_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); - res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4SHS(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 2, 4, 6 }; - u32 mask2_v4i32[4] = { 1, 3, 5, 7 }; - auto va_v8i64 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt64Ty(), 8)); - auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); - - auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); - res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); - auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); - auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); - res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); - res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); - auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VSUM4UBS(u32 vd, u32 va, u32 vb) { - auto va_v16i8 = GetVrAsIntVec(va, 8); - auto vb_v4i32 = GetVrAsIntVec(vb, 32); - - u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; - u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; - u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; - u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; - auto va1_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); - auto va1_v4i32 = m_ir_builder->CreateZExt(va1_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va2_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); - auto va2_v4i32 = m_ir_builder->CreateZExt(va2_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va3_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); - auto va3_v4i32 = m_ir_builder->CreateZExt(va3_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - auto va4_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); - auto va4_v4i32 = m_ir_builder->CreateZExt(va4_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - - auto res_v4i32 = m_ir_builder->CreateAdd(va1_v4i32, va2_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va3_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va4_v4i32); - res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vb_v4i32); - auto lt_v4i1 = m_ir_builder->CreateICmpULT(res_v4i32, vb_v4i32); - auto lt_v4i32 = m_ir_builder->CreateSExt(lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - res_v4i32 = m_ir_builder->CreateOr(lt_v4i32, res_v4i32); - SetVr(vd, res_v4i32); - - // TODO: Set VSCR.SAT -} - -void Compiler::VUPKHPX(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = { 4, 4, 5, 5, 6, 6, 7, 7 }; - vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); - tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); - auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKHSB(u32 vd, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v8i32[8] = { 8, 9, 10, 11, 12, 13, 14, 15 }; - auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, res_v8i16); -} - -void Compiler::VUPKHSH(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v4i32[4] = { 4, 5, 6, 7 }; - auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKLPX(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v8i32[8] = { 0, 0, 1, 1, 2, 2, 3, 3 }; - vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - - auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); - auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); - tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); - auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); - tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); - auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); - res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); - SetVr(vd, res_v4i32); -} - -void Compiler::VUPKLSB(u32 vd, u32 vb) { - auto vb_v16i8 = GetVrAsIntVec(vb, 8); - u32 mask_v8i32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); - auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); - SetVr(vd, res_v8i16); -} - -void Compiler::VUPKLSH(u32 vd, u32 vb) { - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - u32 mask_v4i32[4] = { 0, 1, 2, 3 }; - auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); - auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); - SetVr(vd, res_v4i32); -} - -void Compiler::VXOR(u32 vd, u32 va, u32 vb) { - auto va_v8i16 = GetVrAsIntVec(va, 16); - auto vb_v8i16 = GetVrAsIntVec(vb, 16); - auto res_v8i16 = m_ir_builder->CreateXor(va_v8i16, vb_v8i16); - SetVr(vd, res_v8i16); -} - -void Compiler::MULLI(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - auto res_i64 = m_ir_builder->CreateMul(ra_i64, m_ir_builder->getInt64((s64)simm16)); - SetGpr(rd, res_i64); -} - -void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNeg(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16)); - auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, diff_i64); - SetXerCa(carry_i1); -} - -void Compiler::CMPLI(u32 crfd, u32 l, u32 ra, u32 uimm16) { - Value * ra_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - } - - SetCrFieldUnsignedCmp(crfd, ra_i64, m_ir_builder->getInt64(uimm16)); -} - -void Compiler::CMPI(u32 crfd, u32 l, u32 ra, s32 simm16) { - Value * ra_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - } - - SetCrFieldSignedCmp(crfd, ra_i64, m_ir_builder->getInt64((s64)simm16)); -} - -void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) { - auto ra_i64 = GetGpr(ra); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); -} - -void Compiler::ADDIC_(u32 rd, u32 ra, s32 simm16) { - ADDIC(rd, ra, simm16); - SetCrFieldSignedCmp(0, GetGpr(rd), m_ir_builder->getInt64(0)); -} - -void Compiler::ADDI(u32 rd, u32 ra, s32 simm16) { - if (ra == 0) { - SetGpr(rd, m_ir_builder->getInt64((s64)simm16)); - } else { - auto ra_i64 = GetGpr(ra); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16)); - SetGpr(rd, sum_i64); - } -} - -void Compiler::ADDIS(u32 rd, u32 ra, s32 simm16) { - if (ra == 0) { - SetGpr(rd, m_ir_builder->getInt64((s64)simm16 << 16)); - } else { - auto ra_i64 = GetGpr(ra); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16 << 16)); - SetGpr(rd, sum_i64); - } -} - -void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { - auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, bd)); - auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); -} - -void Compiler::SC(u32 lev) { - switch (lev) { - case 0: - Call("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); - break; - case 2: - Call("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute, - m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32)); - break; - case 3: - Call("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]); - break; - default: - CompilationError(fmt::Format("SC %u", lev)); - break; - } -} - -void Compiler::B(s32 ll, u32 aa, u32 lk) { - auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, ll)); - auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); - CreateBranch(nullptr, target_i32, lk ? true : false); -} - -void Compiler::MCRF(u32 crfd, u32 crfs) { - if (crfd != crfs) { - auto cr_i32 = GetCr(); - auto crf_i32 = GetNibble(cr_i32, crfs); - cr_i32 = SetNibble(cr_i32, crfd, crf_i32); - SetCr(cr_i32); - } -} - -void Compiler::BCLR(u32 bo, u32 bi, u32 bh, u32 lk) { - auto lr_i64 = GetLr(); - lr_i64 = m_ir_builder->CreateAnd(lr_i64, ~0x3ULL); - auto lr_i32 = m_ir_builder->CreateTrunc(lr_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), lr_i32, lk ? true : false, true); -} - -void Compiler::CRNOR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRANDC(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); - res_i32 = m_ir_builder->CreateAnd(ba_i32, res_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::ISYNC() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::CRXOR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::DCBI(u32 ra, u32 rb) { - // TODO: See if this can be translated to cache flush - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::CRNAND(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRAND(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CREQV(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); - res_i32 = m_ir_builder->CreateXor(res_i32, 1); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CRORC(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); - res_i32 = m_ir_builder->CreateOr(ba_i32, res_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::CROR(u32 crbd, u32 crba, u32 crbb) { - auto cr_i32 = GetCr(); - auto ba_i32 = GetBit(cr_i32, crba); - auto bb_i32 = GetBit(cr_i32, crbb); - auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); - cr_i32 = SetBit(cr_i32, crbd, res_i32); - SetCr(cr_i32); -} - -void Compiler::BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { - auto ctr_i64 = GetCtr(); - ctr_i64 = m_ir_builder->CreateAnd(ctr_i64, ~0x3ULL); - auto ctr_i32 = m_ir_builder->CreateTrunc(ctr_i64, m_ir_builder->getInt32Ty()); - CreateBranch(CheckBranchCondition(bo, bi), ctr_i32, lk ? true : false); -} - -void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto ra_i64 = GetGpr(ra); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - u64 mask = s_rotate_mask[32 + mb][32 + me]; - res_i64 = m_ir_builder->CreateAnd(res_i64, mask); - ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); - res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); - rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); - auto rb_i64 = GetGpr(rb); - auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x1F); - auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(32), shl_i64); - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); - auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ORI(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, uimm16); - SetGpr(ra, res_i64); -} - -void Compiler::ORIS(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); -} - -void Compiler::XORI(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, uimm16); - SetGpr(ra, res_i64); -} - -void Compiler::XORIS(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); -} - -void Compiler::ANDI_(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, uimm16); - SetGpr(ra, res_i64); - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); -} - -void Compiler::ANDIS_(u32 ra, u32 rs, u32 uimm16) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, (u64)uimm16 << 16); - SetGpr(ra, res_i64); - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); -} - -void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][me]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63 - sh]); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto ra_i64 = GetGpr(ra); - auto res_i64 = rs_i64; - if (sh) { - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); - res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - } - - u64 mask = s_rotate_mask[mb][63 - sh]; - res_i64 = m_ir_builder->CreateAnd(res_i64, mask); - ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); - res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x3F); - auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(64), shl_i64); - auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); - auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); - auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); - - if (is_r) { - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][m_eb]); - } else { - res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[m_eb][63]); - } - - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CMP(u32 crfd, u32 l, u32 ra, u32 rb) { - Value * ra_i64; - Value * rb_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - rb_i64 = m_ir_builder->CreateSExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - rb_i64 = GetGpr(rb); - } - - SetCrFieldSignedCmp(crfd, ra_i64, rb_i64); -} - -void Compiler::TW(u32 to, u32 ra, u32 rb) { - CompilationError("TW"); -} - -void Compiler::LVSL(u32 vd, u32 ra, u32 rb) { - static const u128 s_lvsl_values[] = { - {0x08090A0B0C0D0E0F, 0x0001020304050607}, - {0x090A0B0C0D0E0F10, 0x0102030405060708}, - {0x0A0B0C0D0E0F1011, 0x0203040506070809}, - {0x0B0C0D0E0F101112, 0x030405060708090A}, - {0x0C0D0E0F10111213, 0x0405060708090A0B}, - {0x0D0E0F1011121314, 0x05060708090A0B0C}, - {0x0E0F101112131415, 0x060708090A0B0C0D}, - {0x0F10111213141516, 0x0708090A0B0C0D0E}, - {0x1011121314151617, 0x08090A0B0C0D0E0F}, - {0x1112131415161718, 0x090A0B0C0D0E0F10}, - {0x1213141516171819, 0x0A0B0C0D0E0F1011}, - {0x131415161718191A, 0x0B0C0D0E0F101112}, - {0x1415161718191A1B, 0x0C0D0E0F10111213}, - {0x15161718191A1B1C, 0x0D0E0F1011121314}, - {0x161718191A1B1C1D, 0x0E0F101112131415}, - {0x1718191A1B1C1D1E, 0x0F10111213141516}, - }; - - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - auto lvsl_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsl_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); - lvsl_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsl_values_v16i8_ptr, index_i64); - auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsl_values_v16i8_ptr, 16); - SetVr(vd, val_v16i8); -} - -void Compiler::LVEBX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto val_i8 = ReadMemory(addr_i64, 8); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); - auto vd_v16i8 = GetVrAsIntVec(vd, 8); - vd_v16i8 = m_ir_builder->CreateInsertElement(vd_v16i8, val_i8, index_i64); - SetVr(vd, vd_v16i8); -} - -void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNeg(ra_i64); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); - auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, diff_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFCO"); - } -} - -void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - } -} - -void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128)); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128)); - auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); - prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); - auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateZExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - prod_i64 = m_ir_builder->CreateLShr(prod_i64, 32); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MFOCRF(u32 a, u32 rd, u32 crm) { - auto cr_i32 = GetCr(); - auto cr_i64 = m_ir_builder->CreateZExt(cr_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, cr_i64); -} - -void Compiler::LWARX(u32 rd, u32 ra, u32 rb) { +#include "stdafx.h" +#include "Utilities/Log.h" +#include "Emu/Cell/PPULLVMRecompiler.h" +#include "Emu/Memory/Memory.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/CodeGen/MachineCodeInfo.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/IR/Dominators.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/Vectorize.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/IR/Verifier.h" + +using namespace llvm; +using namespace ppu_recompiler_llvm; + +u64 Compiler::s_rotate_mask[64][64]; +bool Compiler::s_rotate_mask_inited = false; + +Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block) + : m_recompilation_engine(recompilation_engine) { + InitializeNativeTarget(); + InitializeNativeTargetAsmPrinter(); + InitializeNativeTargetDisassembler(); + + m_llvm_context = new LLVMContext(); + m_ir_builder = new IRBuilder<>(*m_llvm_context); + m_module = new llvm::Module("Module", *m_llvm_context); + m_fpm = new FunctionPassManager(m_module); + + EngineBuilder engine_builder(m_module); + engine_builder.setMCPU(sys::getHostCPUName()); + engine_builder.setEngineKind(EngineKind::JIT); + engine_builder.setOptLevel(CodeGenOpt::Default); + m_execution_engine = engine_builder.create(); + + m_fpm->add(new DataLayoutPass(m_module)); + m_fpm->add(createNoAAPass()); + m_fpm->add(createBasicAliasAnalysisPass()); + m_fpm->add(createNoTargetTransformInfoPass()); + m_fpm->add(createEarlyCSEPass()); + m_fpm->add(createTailCallEliminationPass()); + m_fpm->add(createReassociatePass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(new DominatorTreeWrapperPass()); + m_fpm->add(new MemoryDependenceAnalysis()); + m_fpm->add(createGVNPass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(new MemoryDependenceAnalysis()); + m_fpm->add(createDeadStoreEliminationPass()); + m_fpm->add(new LoopInfo()); + m_fpm->add(new ScalarEvolution()); + m_fpm->add(createSLPVectorizerPass()); + m_fpm->add(createInstructionCombiningPass()); + m_fpm->add(createCFGSimplificationPass()); + m_fpm->doInitialization(); + + std::vector arg_types; + arg_types.push_back(m_ir_builder->getInt8PtrTy()); + arg_types.push_back(m_ir_builder->getInt8PtrTy()); + arg_types.push_back(m_ir_builder->getInt64Ty()); + m_compiled_function_type = FunctionType::get(m_ir_builder->getInt32Ty(), arg_types, false); + + m_execute_unknown_function = (Function *)m_module->getOrInsertFunction("execute_unknown_function", m_compiled_function_type); + m_execute_unknown_function->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(m_execute_unknown_function, (void *)execute_unknown_function); + + m_execute_unknown_block = (Function *)m_module->getOrInsertFunction("execute_unknown_block", m_compiled_function_type); + m_execute_unknown_block->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(m_execute_unknown_block, (void *)execute_unknown_block); + + if (!s_rotate_mask_inited) { + InitRotateMask(); + s_rotate_mask_inited = true; + } +} + +Compiler::~Compiler() { + delete m_execution_engine; + delete m_fpm; + delete m_ir_builder; + delete m_llvm_context; +} + +Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & cfg, bool inline_all, bool generate_linkable_exits) { + auto compilation_start = std::chrono::high_resolution_clock::now(); + + m_state.cfg = &cfg; + m_state.inline_all = inline_all; + m_state.generate_linkable_exits = generate_linkable_exits; + + // Create the function + m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); + m_state.function->setCallingConv(CallingConv::X86_64_Win64); + auto arg_i = m_state.function->arg_begin(); + arg_i->setName("ppu_state"); + m_state.args[CompileTaskState::Args::State] = arg_i; + (++arg_i)->setName("context"); + m_state.args[CompileTaskState::Args::Context] = arg_i; + + // Create the entry block and add code to branch to the first instruction + m_ir_builder->SetInsertPoint(GetBasicBlockFromAddress(0)); + m_ir_builder->CreateBr(GetBasicBlockFromAddress(cfg.start_address)); + + // Convert each instruction in the CFG to LLVM IR + std::vector exit_instr_list; + for (auto instr_i = cfg.instruction_addresses.begin(); instr_i != cfg.instruction_addresses.end(); instr_i++) { + m_state.hit_branch_instruction = false; + m_state.current_instruction_address = *instr_i; + auto instr_bb = GetBasicBlockFromAddress(m_state.current_instruction_address); + m_ir_builder->SetInsertPoint(instr_bb); + + if (!inline_all && *instr_i != cfg.start_address) { + // Use an already compiled implementation of this block if available + auto ordinal = m_recompilation_engine.GetOrdinal(*instr_i); + if (ordinal != 0xFFFFFFFF) { + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + auto ret_i32 = IndirectCall(*instr_i, context_i64, false); + + auto switch_instr = m_ir_builder->CreateSwitch(ret_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); + auto branch_i = cfg.branches.find(*instr_i); + if (branch_i != cfg.branches.end()) { + for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { + switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); + } + } + } + } + + if (instr_bb->empty()) { + u32 instr = re32(vm::get_ref(m_state.current_instruction_address)); + Decode(instr); + if (!m_state.hit_branch_instruction) { + m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); + } + } + } + + // Generate exit logic for all empty blocks + auto default_exit_block_name = GetBasicBlockNameFromAddress(0xFFFFFFFF); + for (auto block_i = m_state.function->begin(); block_i != m_state.function->end(); block_i++) { + if (!block_i->getInstList().empty() || block_i->getName() == default_exit_block_name) { + continue; + } + + // Found an empty block + m_ir_builder->SetInsertPoint(block_i); + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + auto instr_address = GetAddressFromBasicBlockName(block_i->getName()); + SetPc(m_ir_builder->getInt32(instr_address)); + + if (generate_linkable_exits) { + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + auto ret_i32 = IndirectCall(instr_address, context_i64, false); + auto cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); + auto then_bb = GetBasicBlockFromAddress(instr_address, "then"); + auto merge_bb = GetBasicBlockFromAddress(instr_address, "merge"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + + m_ir_builder->SetInsertPoint(then_bb); + context_i64 = m_ir_builder->CreateZExt(ret_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); + m_ir_builder->CreateBr(merge_bb); + + m_ir_builder->SetInsertPoint(merge_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else { + m_ir_builder->CreateRet(exit_instr_i32); + } + } + + // If the function has a default exit block then generate code for it + auto default_exit_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "", false); + if (default_exit_bb) { + m_ir_builder->SetInsertPoint(default_exit_bb); + auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); + exit_instr_list.push_back(exit_instr_i32); + + if (generate_linkable_exits) { + auto cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); + auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then"); + auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + + m_ir_builder->SetInsertPoint(then_bb); + auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); + context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); + m_ir_builder->CreateCall2(m_execute_unknown_block, m_state.args[CompileTaskState::Args::State], context_i64); + m_ir_builder->CreateBr(merge_bb); + + m_ir_builder->SetInsertPoint(merge_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else { + m_ir_builder->CreateRet(exit_instr_i32); + } + } + + // Add incoming values for all exit instr PHI nodes + for (auto exit_instr_i = exit_instr_list.begin(); exit_instr_i != exit_instr_list.end(); exit_instr_i++) { + auto block = (*exit_instr_i)->getParent(); + for (auto pred_i = pred_begin(block); pred_i != pred_end(block); pred_i++) { + auto pred_address = GetAddressFromBasicBlockName((*pred_i)->getName()); + (*exit_instr_i)->addIncoming(m_ir_builder->getInt32(pred_address), *pred_i); + } + } + +#ifdef _DEBUG + m_recompilation_engine.Log() << *m_state.function; + + std::string verify; + raw_string_ostream verify_ostream(verify); + if (verifyFunction(*m_state.function, &verify_ostream)) { + m_recompilation_engine.Log() << "Verification failed: " << verify << "\n"; + } +#endif + + auto ir_build_end = std::chrono::high_resolution_clock::now(); + m_stats.ir_build_time += std::chrono::duration_cast(ir_build_end - compilation_start); + + // Optimize this function + m_fpm->run(*m_state.function); + auto optimize_end = std::chrono::high_resolution_clock::now(); + m_stats.optimization_time += std::chrono::duration_cast(optimize_end - ir_build_end); + + // Translate to machine code + MachineCodeInfo mci; + m_execution_engine->runJITOnFunction(m_state.function, &mci); + auto translate_end = std::chrono::high_resolution_clock::now(); + m_stats.translation_time += std::chrono::duration_cast(translate_end - optimize_end); + +#ifdef _DEBUG + m_recompilation_engine.Log() << "\nDisassembly:\n"; + auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr); + for (size_t pc = 0; pc < mci.size();) { + char str[1024]; + + auto size = LLVMDisasmInstruction(disassembler, ((u8 *)mci.address()) + pc, mci.size() - pc, (uint64_t)(((u8 *)mci.address()) + pc), str, sizeof(str)); + m_recompilation_engine.Log() << fmt::Format("0x%08X: ", (u64)(((u8 *)mci.address()) + pc)) << str << '\n'; + pc += size; + } + + LLVMDisasmDispose(disassembler); +#endif + + auto compilation_end = std::chrono::high_resolution_clock::now(); + m_stats.total_time += std::chrono::duration_cast(compilation_end - compilation_start); + + return (Executable)mci.address(); +} + +void Compiler::FreeExecutable(const std::string & name) { + auto function = m_module->getFunction(name); + if (function) { + m_execution_engine->freeMachineCodeForFunction(function); + function->eraseFromParent(); + } +} + +Compiler::Stats Compiler::GetStats() { + return m_stats; +} + +void Compiler::Decode(const u32 code) { + (*PPU_instr::main_list)(this, code); +} + +void Compiler::NULL_OP() { + CompilationError("NULL_OP"); +} + +void Compiler::NOP() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::TDI(u32 to, u32 ra, s32 simm16) { + CompilationError("TDI"); +} + +void Compiler::TWI(u32 to, u32 ra, s32 simm16) { + CompilationError("TWI"); +} + +void Compiler::MFVSCR(u32 vd) { + auto vscr_i32 = GetVscr(); + auto vscr_i128 = m_ir_builder->CreateZExt(vscr_i32, m_ir_builder->getIntNTy(128)); + SetVr(vd, vscr_i128); +} + +void Compiler::MTVSCR(u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto vscr_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(0)); + vscr_i32 = m_ir_builder->CreateAnd(vscr_i32, 0x00010001); + SetVscr(vscr_i32); +} + +void Compiler::VADDCUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + va_v4i32 = m_ir_builder->CreateNot(va_v4i32); + auto cmpv4i1 = m_ir_builder->CreateICmpULT(va_v4i32, vb_v4i32); + auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmpv4i32); +} + +void Compiler::VADDFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto sum_v4f32 = m_ir_builder->CreateFAdd(va_v4f32, vb_v4f32); + SetVr(vd, sum_v4f32); +} + +void Compiler::VADDSBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_b), va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VADDSHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_padds_w), va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VADDSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + // It looks like x86 does not have an instruction to add 32 bit intergers with signed/unsigned saturation. + // To implement add with saturation, we first determine what the result would be if the operation were to cause + // an overflow. If two -ve numbers are being added and cause an overflow, the result would be 0x80000000. + // If two +ve numbers are being added and cause an overflow, the result would be 0x7FFFFFFF. Addition of a -ve + // number and a +ve number cannot cause overflow. So the result in case of an overflow is 0x7FFFFFFF + sign bit + // of any one of the operands. + auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Next, we find if the addition can actually result in an overflow. Since an overflow can only happen if the operands + // have the same sign, we bitwise XOR both the operands. If the sign bit of the result is 0 then the operands have the + // same sign and so may cause an overflow. We invert the result so that the sign bit is 1 when the operands have the + // same sign. + auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); + tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); + + // Perform the sum. + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // If an overflow occurs, then the sign of the sum will be different from the sign of the operands. So, we xor the + // result with one of the operands. The sign bit of the result will be 1 if the sign bit of the sum and the sign bit of the + // result is different. This result is again ANDed with tmp3 (the sign bit of tmp3 is 1 only if the operands have the same + // sign and so can cause an overflow). + auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, sum_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set SAT +} + +void Compiler::VADDUBM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateAdd(va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); +} + +void Compiler::VADDUBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sum_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_b), va_v16i8, vb_v16i8); + SetVr(vd, sum_v16i8); + + // TODO: Set SAT +} + +void Compiler::VADDUHM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateAdd(va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); +} + +void Compiler::VADDUHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto sum_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_paddus_w), va_v8i16, vb_v8i16); + SetVr(vd, sum_v8i16); + + // TODO: Set SAT +} + +void Compiler::VADDUWM(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + SetVr(vd, sum_v4i32); +} + +void Compiler::VADDUWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto sum_v4i32 = m_ir_builder->CreateAdd(va_v4i32, vb_v4i32); + auto cmp_v4i1 = m_ir_builder->CreateICmpULT(sum_v4i32, va_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateOr(sum_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set SAT +} + +void Compiler::VAND(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VANDC(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateNot(vb_v4i32); + auto res_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VAVGSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateSExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto sum_v16i16 = m_ir_builder->CreateAdd(va_v16i16, vb_v16i16); + sum_v16i16 = m_ir_builder->CreateAdd(sum_v16i16, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt16(1))); + auto avg_v16i16 = m_ir_builder->CreateAShr(sum_v16i16, 1); + auto avg_v16i8 = m_ir_builder->CreateTrunc(avg_v16i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, avg_v16i8); +} + +void Compiler::VAVGSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto sum_v8i32 = m_ir_builder->CreateAdd(va_v8i32, vb_v8i32); + sum_v8i32 = m_ir_builder->CreateAdd(sum_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(1))); + auto avg_v8i32 = m_ir_builder->CreateAShr(sum_v8i32, 1); + auto avg_v8i16 = m_ir_builder->CreateTrunc(avg_v8i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, avg_v8i16); +} + +void Compiler::VAVGSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); + sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); + auto avg_v4i64 = m_ir_builder->CreateAShr(sum_v4i64, 1); + auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, avg_v4i32); +} + +void Compiler::VAVGUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto avg_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_b), va_v16i8, vb_v16i8); + SetVr(vd, avg_v16i8); +} + +void Compiler::VAVGUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto avg_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pavg_w), va_v8i16, vb_v8i16); + SetVr(vd, avg_v8i16); +} + +void Compiler::VAVGUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto va_v4i64 = m_ir_builder->CreateZExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v4i64 = m_ir_builder->CreateZExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto sum_v4i64 = m_ir_builder->CreateAdd(va_v4i64, vb_v4i64); + sum_v4i64 = m_ir_builder->CreateAdd(sum_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(1))); + auto avg_v4i64 = m_ir_builder->CreateLShr(sum_v4i64, 1); + auto avg_v4i32 = m_ir_builder->CreateTrunc(avg_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, avg_v4i32); +} + +void Compiler::VCFSX(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4f32 = m_ir_builder->CreateSIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); + + if (uimm5) { + float scale = (float)((u64)1 << uimm5); + res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); + } + + SetVr(vd, res_v4f32); +} + +void Compiler::VCFUX(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4f32 = m_ir_builder->CreateUIToFP(vb_v4i32, VectorType::get(m_ir_builder->getFloatTy(), 4)); + + if (uimm5) { + float scale = (float)((u64)1 << uimm5); + res_v4f32 = m_ir_builder->CreateFDiv(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), scale))); + } + + SetVr(vd, res_v4f32); +} + +void Compiler::VCMPBFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_gt_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); + vb_v4f32 = m_ir_builder->CreateFNeg(vb_v4f32); + auto cmp_lt_v4i1 = m_ir_builder->CreateFCmpOLT(va_v4f32, vb_v4f32); + auto cmp_gt_v4i32 = m_ir_builder->CreateZExt(cmp_gt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto cmp_lt_v4i32 = m_ir_builder->CreateZExt(cmp_lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + cmp_gt_v4i32 = m_ir_builder->CreateShl(cmp_gt_v4i32, 31); + cmp_lt_v4i32 = m_ir_builder->CreateShl(cmp_lt_v4i32, 30); + auto res_v4i32 = m_ir_builder->CreateOr(cmp_gt_v4i32, cmp_lt_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Implement NJ mode +} + +void Compiler::VCMPBFP_(u32 vd, u32 va, u32 vb) { + VCMPBFP(vd, va, vb); + + auto vd_v16i8 = GetVrAsIntVec(vd, 8); + u32 mask_v16i32[16] = {3, 7, 11, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + vd_v16i8 = m_ir_builder->CreateShuffleVector(vd_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + auto vd_v4i32 = m_ir_builder->CreateBitCast(vd_v16i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto vd_mask_i32 = m_ir_builder->CreateExtractElement(vd_v4i32, m_ir_builder->getInt32(0)); + auto cmp_i1 = m_ir_builder->CreateICmpEQ(vd_mask_i32, m_ir_builder->getInt32(0)); + SetCrField(6, nullptr, nullptr, cmp_i1, nullptr); +} + +void Compiler::VCMPEQFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOEQ(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPEQFP_(u32 vd, u32 va, u32 vb) { + VCMPEQFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpEQ(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPEQUB_(u32 vd, u32 va, u32 vb) { + VCMPEQUB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpEQ(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPEQUH_(u32 vd, u32 va, u32 vb) { + VCMPEQUH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPEQUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpEQ(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPEQUW_(u32 vd, u32 va, u32 vb) { + VCMPEQUW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGEFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGEFP_(u32 vd, u32 va, u32 vb) { + VCMPGEFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGT(va_v4f32, vb_v4f32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTFP_(u32 vd, u32 va, u32 vb) { + VCMPGTFP(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpSGT(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPGTSB_(u32 vd, u32 va, u32 vb) { + VCMPGTSB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpSGT(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPGTSH_(u32 vd, u32 va, u32 vb) { + VCMPGTSH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpSGT(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTSW_(u32 vd, u32 va, u32 vb) { + VCMPGTSW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto cmp_v16i1 = m_ir_builder->CreateICmpUGT(va_v16i8, vb_v16i8); + auto cmp_v16i8 = m_ir_builder->CreateSExt(cmp_v16i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + SetVr(vd, cmp_v16i8); +} + +void Compiler::VCMPGTUB_(u32 vd, u32 va, u32 vb) { + VCMPGTUB(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto cmp_v8i1 = m_ir_builder->CreateICmpUGT(va_v8i16, vb_v8i16); + auto cmp_v8i16 = m_ir_builder->CreateSExt(cmp_v8i1, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, cmp_v8i16); +} + +void Compiler::VCMPGTUH_(u32 vd, u32 va, u32 vb) { + VCMPGTUH(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCMPGTUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto cmp_v4i1 = m_ir_builder->CreateICmpUGT(va_v4i32, vb_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmp_v4i32); +} + +void Compiler::VCMPGTUW_(u32 vd, u32 va, u32 vb) { + VCMPGTUW(vd, va, vb); + SetCr6AfterVectorCompare(vd); +} + +void Compiler::VCTSXS(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + if (uimm5) { + vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); + } + + auto res_v4i32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_cvtps2dq), vb_v4f32); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0x7FFFFFFF))); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateXor(cmp_v4i32, res_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VCTUXS(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + if (uimm5) { + vb_v4f32 = m_ir_builder->CreateFMul(vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 1 << uimm5))); + } + + auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), vb_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0))); + auto cmp_v4i1 = m_ir_builder->CreateFCmpOGE(res_v4f32, m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 0xFFFFFFFFu))); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateFPToUI(res_v4f32, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VEXPTEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::pow, VectorType::get(m_ir_builder->getFloatTy(), 4)), + m_ir_builder->CreateVectorSplat(4, ConstantFP::get(m_ir_builder->getFloatTy(), 2.0f)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VLOGEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::log2, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMADDFP(u32 vd, u32 va, u32 vc, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto vc_v4f32 = GetVrAsFloatVec(vc); + auto res_v4f32 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMAXFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_max_ps), va_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMAXSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsb), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMAXSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxs_w), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMAXSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxsd), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMAXUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmaxu_b), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMAXUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxuw), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMAXUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pmaxud), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMHADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); + + u32 mask1_v4i32[4] = {0, 1, 2, 3}; + auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {4, 5, 6, 7}; + auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMHRADDSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto va_v8i32 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateSExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vc_v8i32 = m_ir_builder->CreateSExt(vc_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto res_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(0x4000))); + res_v8i32 = m_ir_builder->CreateAShr(res_v8i32, 15); + res_v8i32 = m_ir_builder->CreateAdd(res_v8i32, vc_v8i32); + + u32 mask1_v4i32[4] = {0, 1, 2, 3}; + auto res1_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {4, 5, 6, 7}; + auto res2_v4i32 = m_ir_builder->CreateShuffleVector(res_v8i32, UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), res1_v4i32, res2_v4i32); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMINFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_min_ps), va_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VMINSB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsb), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMINSH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmins_w), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMINSW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminsd), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMINUB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pminu_b), va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VMINUH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMINUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMLADDUHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v8i16 = GetVrAsIntVec(vc, 16); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + res_v8i16 = m_ir_builder->CreateAdd(res_v8i16, vc_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMRGHB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v16i32[16] = {24, 8, 25, 9, 26, 10, 27, 11, 28, 12, 29, 13, 30, 14, 31, 15}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VMRGHH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = {12, 4, 13, 5, 14, 6, 15, 7}; + auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VMRGHW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + u32 mask_v4i32[4] = {6, 2, 7, 3}; + auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VMRGLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v16i32[16] = {16, 0, 17, 1, 18, 2, 19, 3, 20, 4, 21, 5, 22, 6, 23, 7}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(va_v16i8, vb_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VMRGLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = {8, 0, 9, 1, 10, 2, 11, 3}; + auto vd_v8i16 = m_ir_builder->CreateShuffleVector(va_v8i16, vb_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VMRGLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + u32 mask_v4i32[4] = {4, 0, 5, 1}; + auto vd_v4i32 = m_ir_builder->CreateShuffleVector(va_v4i32, vb_v4i32, ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VMSUMMBM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); + + auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); + u32 mask1_v4i32[4] = {0, 4, 8, 12}; + auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp1_v4i32 = m_ir_builder->CreateSExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask2_v4i32[4] = {1, 5, 9, 13}; + auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto tmp2_v4i32 = m_ir_builder->CreateSExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask3_v4i32[4] = {2, 6, 10, 14}; + auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto tmp3_v4i32 = m_ir_builder->CreateSExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask4_v4i32[4] = {3, 7, 11, 15}; + auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto tmp4_v4i32 = m_ir_builder->CreateSExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMSHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMSUMSHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = (Value *)m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmadd_wd), va_v8i16, vb_v8i16); + + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vc_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto tmp2_v4i32 = m_ir_builder->CreateXor(vc_v4i32, res_v4i32); + tmp2_v4i32 = m_ir_builder->CreateNot(tmp2_v4i32); + auto sum_v4i32 = m_ir_builder->CreateAdd(vc_v4i32, res_v4i32); + auto sum_v16i8 = m_ir_builder->CreateBitCast(sum_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto tmp3_v4i32 = m_ir_builder->CreateXor(vc_v4i32, sum_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), sum_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMSUMUBM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto va_v16i16 = m_ir_builder->CreateZExt(va_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto vb_v16i16 = m_ir_builder->CreateZExt(vb_v16i8, VectorType::get(m_ir_builder->getInt16Ty(), 16)); + auto tmp_v16i16 = m_ir_builder->CreateMul(va_v16i16, vb_v16i16); + + auto undef_v16i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 16)); + u32 mask1_v4i32[4] = {0, 4, 8, 12}; + auto tmp1_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp1_v4i32 = m_ir_builder->CreateZExt(tmp1_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask2_v4i32[4] = {1, 5, 9, 13}; + auto tmp2_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto tmp2_v4i32 = m_ir_builder->CreateZExt(tmp2_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask3_v4i32[4] = {2, 6, 10, 14}; + auto tmp3_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto tmp3_v4i32 = m_ir_builder->CreateZExt(tmp3_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + u32 mask4_v4i32[4] = {3, 7, 11, 15}; + auto tmp4_v4i16 = m_ir_builder->CreateShuffleVector(tmp_v16i16, undef_v16i16, ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto tmp4_v4i32 = m_ir_builder->CreateZExt(tmp4_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, tmp4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMUHM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + + auto undef_v8i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 8)); + u32 mask1_v4i32[4] = {0, 2, 4, 6}; + auto tmp1_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + u32 mask2_v4i32[4] = {1, 3, 5, 7}; + auto tmp2_v4i32 = m_ir_builder->CreateShuffleVector(tmp_v8i32, undef_v8i32, ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto res_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, tmp2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vc_v4i32); + + SetVr(vd, res_v4i32); + + // TODO: Try to optimize with horizontal add +} + +void Compiler::VMSUMUHS(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto va_v8i32 = m_ir_builder->CreateZExt(va_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto vb_v8i32 = m_ir_builder->CreateZExt(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 8)); + auto tmp_v8i32 = m_ir_builder->CreateMul(va_v8i32, vb_v8i32); + auto tmp_v8i64 = m_ir_builder->CreateZExt(tmp_v8i32, VectorType::get(m_ir_builder->getInt64Ty(), 8)); + + u32 mask1_v4i32[4] = {0, 2, 4, 6}; + u32 mask2_v4i32[4] = {1, 3, 5, 7}; + auto tmp1_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto tmp2_v4i64 = m_ir_builder->CreateShuffleVector(tmp_v8i64, UndefValue::get(tmp_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + auto vc_v4i64 = m_ir_builder->CreateZExt(vc_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto res_v4i64 = m_ir_builder->CreateAdd(tmp1_v4i64, tmp2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vc_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpUGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF))); + auto gt_v4i64 = m_ir_builder->CreateSExt(gt_v4i1, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + res_v4i64 = m_ir_builder->CreateOr(res_v4i64, gt_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VMULESB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULESH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULEUB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULEUH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULOSB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); + va_v8i16 = m_ir_builder->CreateAShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateAShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULOSH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); + va_v4i32 = m_ir_builder->CreateAShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VMULOUB(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateShl(va_v8i16, 8); + va_v8i16 = m_ir_builder->CreateLShr(va_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateShl(vb_v8i16, 8); + vb_v8i16 = m_ir_builder->CreateLShr(vb_v8i16, 8); + auto res_v8i16 = m_ir_builder->CreateMul(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VMULOUH(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, 16); + va_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, 16); + vb_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, 16); + auto res_v4i32 = m_ir_builder->CreateMul(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VNMSUBFP(u32 vd, u32 va, u32 vc, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto vc_v4f32 = GetVrAsFloatVec(vc); + vc_v4f32 = m_ir_builder->CreateFNeg(vc_v4f32); + auto res_v4f32 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, VectorType::get(m_ir_builder->getFloatTy(), 4)), va_v4f32, vc_v4f32, vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VNOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); + res_v8i16 = m_ir_builder->CreateNot(res_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateOr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VPERM(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto vc_v16i8 = GetVrAsIntVec(vc, 8); + + auto thrity_one_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(31)); + vc_v16i8 = m_ir_builder->CreateAnd(vc_v16i8, thrity_one_v16i8); + + auto fifteen_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(15)); + auto vc_le15_v16i8 = m_ir_builder->CreateSub(fifteen_v16i8, vc_v16i8); + auto res_va_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), va_v16i8, vc_le15_v16i8); + + auto vc_gt15_v16i8 = m_ir_builder->CreateSub(thrity_one_v16i8, vc_v16i8); + auto cmp_i1 = m_ir_builder->CreateICmpUGT(vc_gt15_v16i8, fifteen_v16i8); + auto cmp_i8 = m_ir_builder->CreateSExt(cmp_i1, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + vc_gt15_v16i8 = m_ir_builder->CreateOr(cmp_i8, vc_gt15_v16i8); + auto res_vb_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_ssse3_pshuf_b_128), vb_v16i8, vc_gt15_v16i8); + + auto res_v16i8 = m_ir_builder->CreateOr(res_vb_v16i8, res_va_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VPKPX(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto tmpa_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); + tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); + tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); + tmpa_v4i32 = m_ir_builder->CreateAnd(tmpa_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); + va_v4i32 = m_ir_builder->CreateShl(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); + tmpa_v4i32 = m_ir_builder->CreateOr(tmpa_v4i32, va_v4i32); + auto tmpa_v8i16 = m_ir_builder->CreateBitCast(tmpa_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + auto tmpb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(7))); + tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFC000000))); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFC000000))); + tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); + tmpb_v4i32 = m_ir_builder->CreateAnd(tmpb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFE00000))); + vb_v4i32 = m_ir_builder->CreateShl(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(~0xFFE00000))); + tmpb_v4i32 = m_ir_builder->CreateOr(tmpb_v4i32, vb_v4i32); + auto tmpb_v8i16 = m_ir_builder->CreateBitCast(tmpb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + u32 mask_v8i32[8] = {1, 3, 5, 7, 9, 11, 13, 15}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(tmpb_v8i16, tmpa_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + SetVr(vd, res_v8i16); + + // TODO: Implement with pext on CPUs with BMI +} + +void Compiler::VPKSHSS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packsswb_128), vb_v8i16, va_v8i16); + SetVr(vd, res_v16i8); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSHUS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packuswb_128), vb_v8i16, va_v8i16); + SetVr(vd, res_v16i8); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSWSS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_packssdw_128), vb_v4i32, va_v4i32); + SetVr(vd, res_v8i16); + + // TODO: VSCR.SAT +} + +void Compiler::VPKSWUS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto res_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_packusdw), vb_v4i32, va_v4i32); + SetVr(vd, res_v8i16); + + // TODO: VSCR.SAT +} + +void Compiler::VPKUHUM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + + u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, res_v16i8); +} + +void Compiler::VPKUHUS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + va_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), va_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); + vb_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminuw), vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xFF))); + auto va_v16i8 = m_ir_builder->CreateBitCast(va_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto vb_v16i8 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + u32 mask_v16i32[16] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, res_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VPKUWUM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + + u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, res_v8i16); +} + +void Compiler::VPKUWUS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + va_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), va_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); + vb_v4i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pminud), vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFFFF))); + auto va_v8i16 = m_ir_builder->CreateBitCast(va_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + auto vb_v8i16 = m_ir_builder->CreateBitCast(vb_v4i32, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + + u32 mask_v8i32[8] = {0, 2, 4, 6, 8, 10, 12, 14}; + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, va_v8i16, ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + SetVr(vd, res_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VREFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIM(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::floor, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIN(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::nearbyint, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::ceil, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRFIZ(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::trunc, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VRLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(7))); + auto tmp1_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); + vb_v16i8 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(8)), vb_v16i8); + auto tmp2_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); + auto res_v16i8 = m_ir_builder->CreateOr(tmp1_v16i8, tmp2_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VRLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto tmp1_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); + vb_v8i16 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0x10)), vb_v8i16); + auto tmp2_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); + auto res_v8i16 = m_ir_builder->CreateOr(tmp1_v8i16, tmp2_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VRLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto tmp1_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); + vb_v4i32 = m_ir_builder->CreateSub(m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x20)), vb_v4i32); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); + auto res_v4i32 = m_ir_builder->CreateOr(tmp1_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VRSQRTEFP(u32 vd, u32 vb) { + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, VectorType::get(m_ir_builder->getFloatTy(), 4)), vb_v4f32); + res_v4f32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse_rcp_ps), res_v4f32); + SetVr(vd, res_v4f32); +} + +void Compiler::VSEL(u32 vd, u32 va, u32 vb, u32 vc) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto vc_v4i32 = GetVrAsIntVec(vc, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, vc_v4i32); + vc_v4i32 = m_ir_builder->CreateNot(vc_v4i32); + va_v4i32 = m_ir_builder->CreateAnd(va_v4i32, vc_v4i32); + auto vd_v4i32 = m_ir_builder->CreateOr(va_v4i32, vb_v4i32); + SetVr(vd, vd_v4i32); +} + +void Compiler::VSL(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSLB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateShl(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSLDOI(u32 vd, u32 va, u32 vb, u32 sh) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + sh = 16 - sh; + u32 mask_v16i32[16] = {sh, sh + 1, sh + 2, sh + 3, sh + 4, sh + 5, sh + 6, sh + 7, sh + 8, sh + 9, sh + 10, sh + 11, sh + 12, sh + 13, sh + 14, sh + 15}; + auto vd_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, va_v16i8, ConstantDataVector::get(m_ir_builder->getContext(), mask_v16i32)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VSLH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateShl(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSLO(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateShl(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSLW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateShl(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSPLTB(u32 vd, u32 uimm5, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto undef_v16i8 = UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)); + auto mask_v16i32 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt32(15 - uimm5)); + auto res_v16i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, undef_v16i8, mask_v16i32); + SetVr(vd, res_v16i8); +} + +void Compiler::VSPLTH(u32 vd, u32 uimm5, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto undef_v8i16 = UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)); + auto mask_v8i32 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt32(7 - uimm5)); + auto res_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, undef_v8i16, mask_v8i32); + SetVr(vd, res_v8i16); +} + +void Compiler::VSPLTISB(u32 vd, s32 simm5) { + auto vd_v16i8 = m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8((s8)simm5)); + SetVr(vd, vd_v16i8); +} + +void Compiler::VSPLTISH(u32 vd, s32 simm5) { + auto vd_v8i16 = m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16((s16)simm5)); + SetVr(vd, vd_v8i16); +} + +void Compiler::VSPLTISW(u32 vd, s32 simm5) { + auto vd_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32((s32)simm5)); + SetVr(vd, vd_v4i32); +} + +void Compiler::VSPLTW(u32 vd, u32 uimm5, u32 vb) { + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto undef_v4i32 = UndefValue::get(VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto mask_v4i32 = m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3 - uimm5)); + auto res_v4i32 = m_ir_builder->CreateShuffleVector(vb_v4i32, undef_v4i32, mask_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSR(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x7); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSRAB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateAShr(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSRAH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateAShr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSRAW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateAShr(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSRB(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + vb_v16i8 = m_ir_builder->CreateAnd(vb_v16i8, m_ir_builder->CreateVectorSplat(16, m_ir_builder->getInt8(0x7))); + auto res_v16i8 = m_ir_builder->CreateLShr(va_v16i8, vb_v16i8); + SetVr(vd, res_v16i8); +} + +void Compiler::VSRH(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + vb_v8i16 = m_ir_builder->CreateAnd(vb_v8i16, m_ir_builder->CreateVectorSplat(8, m_ir_builder->getInt16(0xF))); + auto res_v8i16 = m_ir_builder->CreateLShr(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::VSRO(u32 vd, u32 va, u32 vb) { + auto va_i128 = GetVr(va); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto sh_i8 = m_ir_builder->CreateExtractElement(vb_v16i8, m_ir_builder->getInt8(0)); + sh_i8 = m_ir_builder->CreateAnd(sh_i8, 0x78); + auto sh_i128 = m_ir_builder->CreateZExt(sh_i8, m_ir_builder->getIntNTy(128)); + va_i128 = m_ir_builder->CreateLShr(va_i128, sh_i128); + SetVr(vd, va_i128); +} + +void Compiler::VSRW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + vb_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x1F))); + auto res_v4i32 = m_ir_builder->CreateLShr(va_v4i32, vb_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VSUBCUW(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto cmpv4i1 = m_ir_builder->CreateICmpUGE(va_v4i32, vb_v4i32); + auto cmpv4i32 = m_ir_builder->CreateZExt(cmpv4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, cmpv4i32); +} + +void Compiler::VSUBFP(u32 vd, u32 va, u32 vb) { + auto va_v4f32 = GetVrAsFloatVec(va); + auto vb_v4f32 = GetVrAsFloatVec(vb); + auto diff_v4f32 = m_ir_builder->CreateFSub(va_v4f32, vb_v4f32); + SetVr(vd, diff_v4f32); +} + +void Compiler::VSUBSBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_b), va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUBSHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubs_w), va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUBSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + // See the comments for VADDSWS for a detailed description of how this works + + // Find the result in case of an overflow + auto tmp1_v4i32 = m_ir_builder->CreateLShr(va_v4i32, 31); + tmp1_v4i32 = m_ir_builder->CreateAdd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x7FFFFFFF))); + auto tmp1_v16i8 = m_ir_builder->CreateBitCast(tmp1_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Find the elements that can overflow (elements with opposite sign bits) + auto tmp2_v4i32 = m_ir_builder->CreateXor(va_v4i32, vb_v4i32); + + // Perform the sub + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + auto diff_v16i8 = m_ir_builder->CreateBitCast(diff_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // Find the elements that overflowed + auto tmp3_v4i32 = m_ir_builder->CreateXor(va_v4i32, diff_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, tmp3_v4i32); + tmp3_v4i32 = m_ir_builder->CreateAShr(tmp3_v4i32, 31); + auto tmp3_v16i8 = m_ir_builder->CreateBitCast(tmp3_v4i32, VectorType::get(m_ir_builder->getInt8Ty(), 16)); + + // tmp4 is equal to 0xFFFFFFFF if an overflow occured and 0x00000000 otherwise. + auto res_v16i8 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse41_pblendvb), diff_v16i8, tmp1_v16i8, tmp3_v16i8); + SetVr(vd, res_v16i8); + + // TODO: Set SAT +} + +void Compiler::VSUBUBM(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateSub(va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); +} + +void Compiler::VSUBUBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + auto diff_v16i8 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_b), va_v16i8, vb_v16i8); + SetVr(vd, diff_v16i8); + + // TODO: Set SAT +} + +void Compiler::VSUBUHM(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateSub(va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); +} + +void Compiler::VSUBUHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto diff_v8i16 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_psubus_w), va_v8i16, vb_v8i16); + SetVr(vd, diff_v8i16); + + // TODO: Set SAT +} + +void Compiler::VSUBUWM(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + SetVr(vd, diff_v4i32); +} + +void Compiler::VSUBUWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + auto diff_v4i32 = m_ir_builder->CreateSub(va_v4i32, vb_v4i32); + auto cmp_v4i1 = m_ir_builder->CreateICmpULE(diff_v4i32, va_v4i32); + auto cmp_v4i32 = m_ir_builder->CreateSExt(cmp_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto res_v4i32 = m_ir_builder->CreateAnd(diff_v4i32, cmp_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set SAT +} + +void Compiler::VSUMSWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + auto res_i32 = m_ir_builder->CreateExtractElement(vb_v4i32, m_ir_builder->getInt32(3)); + auto res_i64 = m_ir_builder->CreateSExt(res_i32, m_ir_builder->getInt64Ty()); + for (auto i = 0; i < 4; i++) { + auto va_i32 = m_ir_builder->CreateExtractElement(va_v4i32, m_ir_builder->getInt32(i)); + auto va_i64 = m_ir_builder->CreateSExt(va_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateAdd(res_i64, va_i64); + } + + auto gt_i1 = m_ir_builder->CreateICmpSGT(res_i64, m_ir_builder->getInt64(0x7FFFFFFFull)); + auto lt_i1 = m_ir_builder->CreateICmpSLT(res_i64, m_ir_builder->getInt64(0xFFFFFFFF80000000ull)); + res_i64 = m_ir_builder->CreateSelect(gt_i1, m_ir_builder->getInt64(0x7FFFFFFFull), res_i64); + res_i64 = m_ir_builder->CreateSelect(lt_i1, m_ir_builder->getInt64(0xFFFFFFFF80000000ull), res_i64); + auto res_i128 = m_ir_builder->CreateZExt(res_i64, m_ir_builder->getIntNTy(128)); + + SetVr(vd, res_i128); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM2SWS(u32 vd, u32 va, u32 vb) { + auto va_v4i32 = GetVrAsIntVec(va, 32); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v2i32[2] = { 0, 2 }; + u32 mask2_v2i32[2] = { 1, 3 }; + auto va_v4i64 = m_ir_builder->CreateSExt(va_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto va1_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); + auto va2_v2i64 = m_ir_builder->CreateShuffleVector(va_v4i64, UndefValue::get(va_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v2i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + auto vb_v2i64 = m_ir_builder->CreateShuffleVector(vb_v4i64, UndefValue::get(vb_v4i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v2i32)); + + auto res_v2i64 = m_ir_builder->CreateAdd(va1_v2i64, va2_v2i64); + res_v2i64 = m_ir_builder->CreateAdd(res_v2i64, vb_v2i64); + auto gt_v2i1 = m_ir_builder->CreateICmpSGT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v2i1 = m_ir_builder->CreateICmpSLT(res_v2i64, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v2i64 = m_ir_builder->CreateSelect(gt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v2i64); + res_v2i64 = m_ir_builder->CreateSelect(lt_v2i1, m_ir_builder->CreateVectorSplat(2, m_ir_builder->getInt64(0x80000000ull)), res_v2i64); + SetVr(vd, res_v2i64); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4SBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; + u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; + u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; + u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; + auto va_v16i64 = m_ir_builder->CreateSExt(va_v16i8, VectorType::get(m_ir_builder->getInt64Ty(), 16)); + auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto va3_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto va4_v4i64 = m_ir_builder->CreateShuffleVector(va_v16i64, UndefValue::get(va_v16i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + + auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va3_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, va4_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); + res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4SHS(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 2, 4, 6 }; + u32 mask2_v4i32[4] = { 1, 3, 5, 7 }; + auto va_v8i64 = m_ir_builder->CreateSExt(va_v8i16, VectorType::get(m_ir_builder->getInt64Ty(), 8)); + auto va1_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va2_v4i64 = m_ir_builder->CreateShuffleVector(va_v8i64, UndefValue::get(va_v8i64->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto vb_v4i64 = m_ir_builder->CreateSExt(vb_v4i32, VectorType::get(m_ir_builder->getInt64Ty(), 4)); + + auto res_v4i64 = m_ir_builder->CreateAdd(va1_v4i64, va2_v4i64); + res_v4i64 = m_ir_builder->CreateAdd(res_v4i64, vb_v4i64); + auto gt_v4i1 = m_ir_builder->CreateICmpSGT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull))); + auto lt_v4i1 = m_ir_builder->CreateICmpSLT(res_v4i64, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0xFFFFFFFF80000000ull))); + res_v4i64 = m_ir_builder->CreateSelect(gt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x7FFFFFFFull)), res_v4i64); + res_v4i64 = m_ir_builder->CreateSelect(lt_v4i1, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt64(0x80000000ull)), res_v4i64); + auto res_v4i32 = m_ir_builder->CreateTrunc(res_v4i64, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VSUM4UBS(u32 vd, u32 va, u32 vb) { + auto va_v16i8 = GetVrAsIntVec(va, 8); + auto vb_v4i32 = GetVrAsIntVec(vb, 32); + + u32 mask1_v4i32[4] = { 0, 4, 8, 12 }; + u32 mask2_v4i32[4] = { 1, 5, 9, 13 }; + u32 mask3_v4i32[4] = { 2, 6, 10, 14 }; + u32 mask4_v4i32[4] = { 3, 7, 11, 15 }; + auto va1_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask1_v4i32)); + auto va1_v4i32 = m_ir_builder->CreateZExt(va1_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va2_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask2_v4i32)); + auto va2_v4i32 = m_ir_builder->CreateZExt(va2_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va3_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask3_v4i32)); + auto va3_v4i32 = m_ir_builder->CreateZExt(va3_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + auto va4_v4i8 = m_ir_builder->CreateShuffleVector(va_v16i8, UndefValue::get(va_v16i8->getType()), ConstantDataVector::get(m_ir_builder->getContext(), mask4_v4i32)); + auto va4_v4i32 = m_ir_builder->CreateZExt(va4_v4i8, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + + auto res_v4i32 = m_ir_builder->CreateAdd(va1_v4i32, va2_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va3_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, va4_v4i32); + res_v4i32 = m_ir_builder->CreateAdd(res_v4i32, vb_v4i32); + auto lt_v4i1 = m_ir_builder->CreateICmpULT(res_v4i32, vb_v4i32); + auto lt_v4i32 = m_ir_builder->CreateSExt(lt_v4i1, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + res_v4i32 = m_ir_builder->CreateOr(lt_v4i32, res_v4i32); + SetVr(vd, res_v4i32); + + // TODO: Set VSCR.SAT +} + +void Compiler::VUPKHPX(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = { 4, 4, 5, 5, 6, 6, 7, 7 }; + vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); + tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); + auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKHSB(u32 vd, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v8i32[8] = { 8, 9, 10, 11, 12, 13, 14, 15 }; + auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, res_v8i16); +} + +void Compiler::VUPKHSH(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v4i32[4] = { 4, 5, 6, 7 }; + auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKLPX(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v8i32[8] = { 0, 0, 1, 1, 2, 2, 3, 3 }; + vb_v8i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + + auto vb_v4i32 = m_ir_builder->CreateBitCast(vb_v8i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + vb_v4i32 = m_ir_builder->CreateAShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(10))); + auto tmp1_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(3))); + tmp1_v4i32 = m_ir_builder->CreateAnd(tmp1_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x00001F00))); + auto tmp2_v4i32 = m_ir_builder->CreateLShr(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(6))); + tmp2_v4i32 = m_ir_builder->CreateAnd(tmp2_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0x0000001F))); + auto res_v4i32 = m_ir_builder->CreateAnd(vb_v4i32, m_ir_builder->CreateVectorSplat(4, m_ir_builder->getInt32(0xFF1F0000))); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp1_v4i32); + res_v4i32 = m_ir_builder->CreateOr(res_v4i32, tmp2_v4i32); + SetVr(vd, res_v4i32); +} + +void Compiler::VUPKLSB(u32 vd, u32 vb) { + auto vb_v16i8 = GetVrAsIntVec(vb, 8); + u32 mask_v8i32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + auto vb_v8i8 = m_ir_builder->CreateShuffleVector(vb_v16i8, UndefValue::get(VectorType::get(m_ir_builder->getInt8Ty(), 16)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v8i32)); + auto res_v8i16 = m_ir_builder->CreateSExt(vb_v8i8, VectorType::get(m_ir_builder->getInt16Ty(), 8)); + SetVr(vd, res_v8i16); +} + +void Compiler::VUPKLSH(u32 vd, u32 vb) { + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + u32 mask_v4i32[4] = { 0, 1, 2, 3 }; + auto vb_v4i16 = m_ir_builder->CreateShuffleVector(vb_v8i16, UndefValue::get(VectorType::get(m_ir_builder->getInt16Ty(), 8)), ConstantDataVector::get(m_ir_builder->getContext(), mask_v4i32)); + auto res_v4i32 = m_ir_builder->CreateSExt(vb_v4i16, VectorType::get(m_ir_builder->getInt32Ty(), 4)); + SetVr(vd, res_v4i32); +} + +void Compiler::VXOR(u32 vd, u32 va, u32 vb) { + auto va_v8i16 = GetVrAsIntVec(va, 16); + auto vb_v8i16 = GetVrAsIntVec(vb, 16); + auto res_v8i16 = m_ir_builder->CreateXor(va_v8i16, vb_v8i16); + SetVr(vd, res_v8i16); +} + +void Compiler::MULLI(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + auto res_i64 = m_ir_builder->CreateMul(ra_i64, m_ir_builder->getInt64((s64)simm16)); + SetGpr(rd, res_i64); +} + +void Compiler::SUBFIC(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNeg(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, m_ir_builder->getInt64((s64)simm16)); + auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, diff_i64); + SetXerCa(carry_i1); +} + +void Compiler::CMPLI(u32 crfd, u32 l, u32 ra, u32 uimm16) { + Value * ra_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + } + + SetCrFieldUnsignedCmp(crfd, ra_i64, m_ir_builder->getInt64(uimm16)); +} + +void Compiler::CMPI(u32 crfd, u32 l, u32 ra, s32 simm16) { + Value * ra_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + } + + SetCrFieldSignedCmp(crfd, ra_i64, m_ir_builder->getInt64((s64)simm16)); +} + +void Compiler::ADDIC(u32 rd, u32 ra, s32 simm16) { + auto ra_i64 = GetGpr(ra); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), m_ir_builder->getInt64((s64)simm16), ra_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); +} + +void Compiler::ADDIC_(u32 rd, u32 ra, s32 simm16) { + ADDIC(rd, ra, simm16); + SetCrFieldSignedCmp(0, GetGpr(rd), m_ir_builder->getInt64(0)); +} + +void Compiler::ADDI(u32 rd, u32 ra, s32 simm16) { + if (ra == 0) { + SetGpr(rd, m_ir_builder->getInt64((s64)simm16)); + } else { + auto ra_i64 = GetGpr(ra); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16)); + SetGpr(rd, sum_i64); + } +} + +void Compiler::ADDIS(u32 rd, u32 ra, s32 simm16) { + if (ra == 0) { + SetGpr(rd, m_ir_builder->getInt64((s64)simm16 << 16)); + } else { + auto ra_i64 = GetGpr(ra); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, m_ir_builder->getInt64((s64)simm16 << 16)); + SetGpr(rd, sum_i64); + } +} + +void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { + auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, bd)); + auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); +} + +void Compiler::SC(u32 lev) { + switch (lev) { + case 0: + Call("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); + break; + case 2: + Call("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute, + m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32)); + break; + case 3: + Call("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]); + break; + default: + CompilationError(fmt::Format("SC %u", lev)); + break; + } +} + +void Compiler::B(s32 ll, u32 aa, u32 lk) { + auto target_i64 = m_ir_builder->getInt64(branchTarget(aa ? 0 : m_state.current_instruction_address, ll)); + auto target_i32 = m_ir_builder->CreateTrunc(target_i64, m_ir_builder->getInt32Ty()); + CreateBranch(nullptr, target_i32, lk ? true : false); +} + +void Compiler::MCRF(u32 crfd, u32 crfs) { + if (crfd != crfs) { + auto cr_i32 = GetCr(); + auto crf_i32 = GetNibble(cr_i32, crfs); + cr_i32 = SetNibble(cr_i32, crfd, crf_i32); + SetCr(cr_i32); + } +} + +void Compiler::BCLR(u32 bo, u32 bi, u32 bh, u32 lk) { + auto lr_i64 = GetLr(); + lr_i64 = m_ir_builder->CreateAnd(lr_i64, ~0x3ULL); + auto lr_i32 = m_ir_builder->CreateTrunc(lr_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), lr_i32, lk ? true : false, true); +} + +void Compiler::CRNOR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRANDC(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); + res_i32 = m_ir_builder->CreateAnd(ba_i32, res_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::ISYNC() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::CRXOR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::DCBI(u32 ra, u32 rb) { + // TODO: See if this can be translated to cache flush + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::CRNAND(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRAND(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateAnd(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CREQV(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(ba_i32, bb_i32); + res_i32 = m_ir_builder->CreateXor(res_i32, 1); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CRORC(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateXor(bb_i32, 1); + res_i32 = m_ir_builder->CreateOr(ba_i32, res_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::CROR(u32 crbd, u32 crba, u32 crbb) { + auto cr_i32 = GetCr(); + auto ba_i32 = GetBit(cr_i32, crba); + auto bb_i32 = GetBit(cr_i32, crbb); + auto res_i32 = m_ir_builder->CreateOr(ba_i32, bb_i32); + cr_i32 = SetBit(cr_i32, crbd, res_i32); + SetCr(cr_i32); +} + +void Compiler::BCCTR(u32 bo, u32 bi, u32 bh, u32 lk) { + auto ctr_i64 = GetCtr(); + ctr_i64 = m_ir_builder->CreateAnd(ctr_i64, ~0x3ULL); + auto ctr_i32 = m_ir_builder->CreateTrunc(ctr_i64, m_ir_builder->getInt32Ty()); + CreateBranch(CheckBranchCondition(bo, bi), ctr_i32, lk ? true : false); +} + +void Compiler::RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto ra_i64 = GetGpr(ra); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + u64 mask = s_rotate_mask[32 + mb][32 + me]; + res_i64 = m_ir_builder->CreateAnd(res_i64, mask); + ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); + res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLWINM(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLWNM(u32 ra, u32 rs, u32 rb, u32 mb, u32 me, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rsh_i64 = m_ir_builder->CreateShl(rs_i64, 32); + rs_i64 = m_ir_builder->CreateOr(rs_i64, rsh_i64); + auto rb_i64 = GetGpr(rb); + auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x1F); + auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(32), shl_i64); + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); + auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[32 + mb][32 + me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ORI(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, uimm16); + SetGpr(ra, res_i64); +} + +void Compiler::ORIS(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); +} + +void Compiler::XORI(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, uimm16); + SetGpr(ra, res_i64); +} + +void Compiler::XORIS(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); +} + +void Compiler::ANDI_(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, uimm16); + SetGpr(ra, res_i64); + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); +} + +void Compiler::ANDIS_(u32 ra, u32 rs, u32 uimm16) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, (u64)uimm16 << 16); + SetGpr(ra, res_i64); + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); +} + +void Compiler::RLDICL(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDICR(u32 ra, u32 rs, u32 sh, u32 me, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][me]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDIC(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[mb][63 - sh]); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDIMI(u32 ra, u32 rs, u32 sh, u32 mb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto ra_i64 = GetGpr(ra); + auto res_i64 = rs_i64; + if (sh) { + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, 64 - sh); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, sh); + res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + } + + u64 mask = s_rotate_mask[mb][63 - sh]; + res_i64 = m_ir_builder->CreateAnd(res_i64, mask); + ra_i64 = m_ir_builder->CreateAnd(ra_i64, ~mask); + res_i64 = m_ir_builder->CreateOr(res_i64, ra_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::RLDC_LR(u32 ra, u32 rs, u32 rb, u32 m_eb, bool is_r, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto shl_i64 = m_ir_builder->CreateAnd(rb_i64, 0x3F); + auto shr_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(64), shl_i64); + auto resl_i64 = m_ir_builder->CreateLShr(rs_i64, shr_i64); + auto resh_i64 = m_ir_builder->CreateShl(rs_i64, shl_i64); + auto res_i64 = m_ir_builder->CreateOr(resh_i64, resl_i64); + + if (is_r) { + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[0][m_eb]); + } else { + res_i64 = m_ir_builder->CreateAnd(res_i64, s_rotate_mask[m_eb][63]); + } + + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CMP(u32 crfd, u32 l, u32 ra, u32 rb) { + Value * ra_i64; + Value * rb_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateSExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + rb_i64 = m_ir_builder->CreateSExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + rb_i64 = GetGpr(rb); + } + + SetCrFieldSignedCmp(crfd, ra_i64, rb_i64); +} + +void Compiler::TW(u32 to, u32 ra, u32 rb) { + CompilationError("TW"); +} + +void Compiler::LVSL(u32 vd, u32 ra, u32 rb) { + static const u128 s_lvsl_values[] = { + {0x08090A0B0C0D0E0F, 0x0001020304050607}, + {0x090A0B0C0D0E0F10, 0x0102030405060708}, + {0x0A0B0C0D0E0F1011, 0x0203040506070809}, + {0x0B0C0D0E0F101112, 0x030405060708090A}, + {0x0C0D0E0F10111213, 0x0405060708090A0B}, + {0x0D0E0F1011121314, 0x05060708090A0B0C}, + {0x0E0F101112131415, 0x060708090A0B0C0D}, + {0x0F10111213141516, 0x0708090A0B0C0D0E}, + {0x1011121314151617, 0x08090A0B0C0D0E0F}, + {0x1112131415161718, 0x090A0B0C0D0E0F10}, + {0x1213141516171819, 0x0A0B0C0D0E0F1011}, + {0x131415161718191A, 0x0B0C0D0E0F101112}, + {0x1415161718191A1B, 0x0C0D0E0F10111213}, + {0x15161718191A1B1C, 0x0D0E0F1011121314}, + {0x161718191A1B1C1D, 0x0E0F101112131415}, + {0x1718191A1B1C1D1E, 0x0F10111213141516}, + }; + auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + auto lvsl_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsl_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); + lvsl_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsl_values_v16i8_ptr, index_i64); + auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsl_values_v16i8_ptr, 16); + SetVr(vd, val_v16i8); +} + +void Compiler::LVEBX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto val_i8 = ReadMemory(addr_i64, 8); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); + auto vd_v16i8 = GetVrAsIntVec(vd, 8); + vd_v16i8 = m_ir_builder->CreateInsertElement(vd_v16i8, val_i8, index_i64); + SetVr(vd, vd_v16i8); +} + +void Compiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNeg(ra_i64); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); + auto diff_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, diff_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFCO"); + } +} + +void Compiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, rb_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + } +} + +void Compiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128)); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128)); + auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); + prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); + auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MULHWU(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateZExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + prod_i64 = m_ir_builder->CreateLShr(prod_i64, 32); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MFOCRF(u32 a, u32 rd, u32 crm) { + auto cr_i32 = GetCr(); + auto cr_i64 = m_ir_builder->CreateZExt(cr_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, cr_i64); +} + +void Compiler::LWARX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); auto val_i32_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt32Ty()); val_i32_ptr->setAlignment(4); @@ -2477,269 +2477,269 @@ void Compiler::LWARX(u32 rd, u32 ra, u32 rb) { val_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), val_i32); auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); SetGpr(rd, val_i64); -} - -void Compiler::LDX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); -} - -void Compiler::LWZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateShl(rs_i64, rb_i64); - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false)); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateShl(rs_i128, rb_i128); - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::AND(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { - Value * ra_i64; - Value * rb_i64; - if (l == 0) { - ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); - rb_i64 = m_ir_builder->CreateZExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); - } else { - ra_i64 = GetGpr(ra); - rb_i64 = GetGpr(rb); - } - - SetCrFieldUnsignedCmp(crfd, ra_i64, rb_i64); -} - -void Compiler::LVSR(u32 vd, u32 ra, u32 rb) { - static const u128 s_lvsr_values[] = { - {0x18191A1B1C1D1E1F, 0x1011121314151617}, - {0x1718191A1B1C1D1E, 0x0F10111213141516}, - {0x161718191A1B1C1D, 0x0E0F101112131415}, - {0x15161718191A1B1C, 0x0D0E0F1011121314}, - {0x1415161718191A1B, 0x0C0D0E0F10111213}, - {0x131415161718191A, 0x0B0C0D0E0F101112}, - {0x1213141516171819, 0x0A0B0C0D0E0F1011}, - {0x1112131415161718, 0x090A0B0C0D0E0F10}, - {0x1011121314151617, 0x08090A0B0C0D0E0F}, - {0x0F10111213141516, 0x0708090A0B0C0D0E}, - {0x0E0F101112131415, 0x060708090A0B0C0D}, - {0x0D0E0F1011121314, 0x05060708090A0B0C}, - {0x0C0D0E0F10111213, 0x0405060708090A0B}, - {0x0B0C0D0E0F101112, 0x030405060708090A}, - {0x0A0B0C0D0E0F1011, 0x0203040506070809}, - {0x090A0B0C0D0E0F10, 0x0102030405060708}, - }; - - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - auto lvsr_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsr_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); - lvsr_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsr_values_v16i8_ptr, index_i64); - auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsr_values_v16i8_ptr, 16); - SetVr(vd, val_v16i8); -} - -void Compiler::LVEHX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); - auto val_i16 = ReadMemory(addr_i64, 16, 2); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 1); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); - auto vd_v8i16 = GetVrAsIntVec(vd, 16); - vd_v8i16 = m_ir_builder->CreateInsertElement(vd_v8i16, val_i16, index_i64); - SetVr(vd, vd_v8i16); -} - -void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto diff_i64 = m_ir_builder->CreateSub(rb_i64, ra_i64); - SetGpr(rd, diff_i64); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFO"); - } -} - -void Compiler::LDUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::DCBST(u32 ra, u32 rb) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { - auto rs_i64 = GetGpr(rs); - auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false)); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - rb_i64 = m_ir_builder->CreateNot(rb_i64); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::TD(u32 to, u32 ra, u32 rb) { - CompilationError("TD"); -} - -void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); - auto val_i32 = ReadMemory(addr_i64, 32, 4); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 2); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); - auto vd_v4i32 = GetVrAsIntVec(vd, 32); - vd_v4i32 = m_ir_builder->CreateInsertElement(vd_v4i32, val_i32, index_i64); - SetVr(vd, vd_v4i32); -} - -void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128)); - auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128)); - auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); - prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); - auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MULHW(u32 rd, u32 ra, u32 rb, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - prod_i64 = m_ir_builder->CreateAShr(prod_i64, 32); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LDARX(u32 rd, u32 ra, u32 rb) { +} + +void Compiler::LDX(u32 rd, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); +} + +void Compiler::LWZX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateShl(rs_i64, rb_i64); + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CNTLZW(u32 ra, u32 rs, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt32Ty()), rs_i32, m_ir_builder->getInt1(false)); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateShl(rs_i128, rb_i128); + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::AND(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) { + Value * ra_i64; + Value * rb_i64; + if (l == 0) { + ra_i64 = m_ir_builder->CreateZExt(GetGpr(ra, 32), m_ir_builder->getInt64Ty()); + rb_i64 = m_ir_builder->CreateZExt(GetGpr(rb, 32), m_ir_builder->getInt64Ty()); + } else { + ra_i64 = GetGpr(ra); + rb_i64 = GetGpr(rb); + } + + SetCrFieldUnsignedCmp(crfd, ra_i64, rb_i64); +} + +void Compiler::LVSR(u32 vd, u32 ra, u32 rb) { + static const u128 s_lvsr_values[] = { + {0x18191A1B1C1D1E1F, 0x1011121314151617}, + {0x1718191A1B1C1D1E, 0x0F10111213141516}, + {0x161718191A1B1C1D, 0x0E0F101112131415}, + {0x15161718191A1B1C, 0x0D0E0F1011121314}, + {0x1415161718191A1B, 0x0C0D0E0F10111213}, + {0x131415161718191A, 0x0B0C0D0E0F101112}, + {0x1213141516171819, 0x0A0B0C0D0E0F1011}, + {0x1112131415161718, 0x090A0B0C0D0E0F10}, + {0x1011121314151617, 0x08090A0B0C0D0E0F}, + {0x0F10111213141516, 0x0708090A0B0C0D0E}, + {0x0E0F101112131415, 0x060708090A0B0C0D}, + {0x0D0E0F1011121314, 0x05060708090A0B0C}, + {0x0C0D0E0F10111213, 0x0405060708090A0B}, + {0x0B0C0D0E0F101112, 0x030405060708090A}, + {0x0A0B0C0D0E0F1011, 0x0203040506070809}, + {0x090A0B0C0D0E0F10, 0x0102030405060708}, + }; + + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + auto lvsr_values_v16i8_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsr_values), VectorType::get(m_ir_builder->getInt8Ty(), 16)->getPointerTo()); + lvsr_values_v16i8_ptr = m_ir_builder->CreateGEP(lvsr_values_v16i8_ptr, index_i64); + auto val_v16i8 = m_ir_builder->CreateAlignedLoad(lvsr_values_v16i8_ptr, 16); + SetVr(vd, val_v16i8); +} + +void Compiler::LVEHX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); + auto val_i16 = ReadMemory(addr_i64, 16, 2); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 1); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); + auto vd_v8i16 = GetVrAsIntVec(vd, 16); + vd_v8i16 = m_ir_builder->CreateInsertElement(vd_v8i16, val_i16, index_i64); + SetVr(vd, vd_v8i16); +} + +void Compiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto diff_i64 = m_ir_builder->CreateSub(rb_i64, ra_i64); + SetGpr(rd, diff_i64); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFO"); + } +} + +void Compiler::LDUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::DCBST(u32 ra, u32 rb) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LWZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::CNTLZD(u32 ra, u32 rs, bool rc) { + auto rs_i64 = GetGpr(rs); + auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, m_ir_builder->getInt64Ty()), rs_i64, m_ir_builder->getInt1(false)); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + rb_i64 = m_ir_builder->CreateNot(rb_i64); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::TD(u32 to, u32 ra, u32 rb) { + CompilationError("TD"); +} + +void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); + auto val_i32 = ReadMemory(addr_i64, 32, 4); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 2); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); + auto vd_v4i32 = GetVrAsIntVec(vd, 32); + vd_v4i32 = m_ir_builder->CreateInsertElement(vd_v4i32, val_i32, index_i64); + SetVr(vd, vd_v4i32); +} + +void Compiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128)); + auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128)); + auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128); + prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64); + auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty()); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MULHW(u32 rd, u32 ra, u32 rb, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + prod_i64 = m_ir_builder->CreateAShr(prod_i64, 32); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LDARX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); auto val_i64_ptr = m_ir_builder->CreateAlloca(m_ir_builder->getInt64Ty()); val_i64_ptr->setAlignment(8); @@ -2747,175 +2747,175 @@ void Compiler::LDARX(u32 rd, u32 ra, u32 rb) { auto val_i64 = (Value *)m_ir_builder->CreateLoad(val_i64_ptr); val_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt64Ty()), val_i64); SetGpr(rd, val_i64); -} - -void Compiler::DCBF(u32 ra, u32 rb) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LBZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LVX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - SetVr(vd, mem_i128); -} - -void Compiler::NEG(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto diff_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(0), ra_i64); - SetGpr(rd, diff_i64); - - if (rc) { - SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("NEGO"); - } -} - -void Compiler::LBZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::NOR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateXor(res_i64, (s64)-1); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVEBX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); - auto vs_v16i8 = GetVrAsIntVec(vs, 8); - auto val_i8 = m_ir_builder->CreateExtractElement(vs_v16i8, index_i64); - WriteMemory(addr_i64, val_i8); -} - -void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFEO"); - } -} - -void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDEO"); - } -} - -void Compiler::MTOCRF(u32 l, u32 crm, u32 rs) { - auto rs_i32 = GetGpr(rs, 32); - auto cr_i32 = GetCr(); - u32 mask = 0; - - for (u32 i = 0; i < 8; i++) { - if (crm & (1 << i)) { - mask |= 0xF << ((7 - i) * 4); - if (l) { - break; - } - } - } - - cr_i32 = m_ir_builder->CreateAnd(cr_i32, ~mask); - rs_i32 = m_ir_builder->CreateAnd(rs_i32, ~mask); - cr_i32 = m_ir_builder->CreateOr(cr_i32, rs_i32); - SetCr(cr_i32); -} - -void Compiler::STDX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 64)); -} - -void Compiler::STWCX_(u32 rs, u32 ra, u32 rb) { +} + +void Compiler::DCBF(u32 ra, u32 rb) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LBZX(u32 rd, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LVX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + SetVr(vd, mem_i128); +} + +void Compiler::NEG(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto diff_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(0), ra_i64); + SetGpr(rd, diff_i64); + + if (rc) { + SetCrFieldSignedCmp(0, diff_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("NEGO"); + } +} + +void Compiler::LBZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::NOR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateXor(res_i64, (s64)-1); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVEBX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64); + auto vs_v16i8 = GetVrAsIntVec(vs, 8); + auto val_i8 = m_ir_builder->CreateExtractElement(vs_v16i8, index_i64); + WriteMemory(addr_i64, val_i8); +} + +void Compiler::SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFEO"); + } +} + +void Compiler::ADDE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, rb_i64); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDEO"); + } +} + +void Compiler::MTOCRF(u32 l, u32 crm, u32 rs) { + auto rs_i32 = GetGpr(rs, 32); + auto cr_i32 = GetCr(); + u32 mask = 0; + + for (u32 i = 0; i < 8; i++) { + if (crm & (1 << i)) { + mask |= 0xF << ((7 - i) * 4); + if (l) { + break; + } + } + } + + cr_i32 = m_ir_builder->CreateAnd(cr_i32, ~mask); + rs_i32 = m_ir_builder->CreateAnd(rs_i32, ~mask); + cr_i32 = m_ir_builder->CreateOr(cr_i32, rs_i32); + SetCr(cr_i32); +} + +void Compiler::STDX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 64)); +} + +void Compiler::STWCX_(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); auto rs_i32 = GetGpr(rs, 32); rs_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt32Ty()), rs_i32); @@ -2923,118 +2923,118 @@ void Compiler::STWCX_(u32 rs, u32 ra, u32 rb) { rs_i32_ptr->setAlignment(4); m_ir_builder->CreateStore(rs_i32, rs_i32_ptr); auto success_i1 = Call("vm.reservation_update", vm::reservation_update, addr_i32, m_ir_builder->CreateBitCast(rs_i32_ptr, m_ir_builder->getInt8PtrTy()), m_ir_builder->getInt32(4)); - + auto cr_i32 = GetCr(); cr_i32 = SetBit(cr_i32, 2, success_i1); SetCr(cr_i32); -} - -void Compiler::STWX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STVEHX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 1); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); - auto vs_v8i16 = GetVrAsIntVec(vs, 16); - auto val_i16 = m_ir_builder->CreateExtractElement(vs_v8i16, index_i64); - WriteMemory(addr_i64, val_i16, 2); -} - -void Compiler::STDUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 64)); - SetGpr(ra, addr_i64); -} - -void Compiler::STWUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 32)); - SetGpr(ra, addr_i64); -} - -void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - index_i64 = m_ir_builder->CreateLShr(index_i64, 2); - index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); - auto vs_v4i32 = GetVrAsIntVec(vs, 32); - auto val_i32 = m_ir_builder->CreateExtractElement(vs_v4i32, index_i64); - WriteMemory(addr_i64, val_i32, 4); -} - -void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto ca_i64 = GetXerCa(); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, sum_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDZEO"); - } -} - -void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto ca_i64 = GetXerCa(); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFZEO"); - } -} - -void Compiler::STDCX_(u32 rs, u32 ra, u32 rb) { +} + +void Compiler::STWX(u32 rs, u32 ra, u32 rb) { auto addr_i64 = GetGpr(rb); if (ra) { auto ra_i64 = GetGpr(ra); addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); } - + + WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STVEHX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 1); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64); + auto vs_v8i16 = GetVrAsIntVec(vs, 16); + auto val_i16 = m_ir_builder->CreateExtractElement(vs_v8i16, index_i64); + WriteMemory(addr_i64, val_i16, 2); +} + +void Compiler::STDUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 64)); + SetGpr(ra, addr_i64); +} + +void Compiler::STWUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 32)); + SetGpr(ra, addr_i64); +} + +void Compiler::STVEWX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL); + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + index_i64 = m_ir_builder->CreateLShr(index_i64, 2); + index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64); + auto vs_v4i32 = GetVrAsIntVec(vs, 32); + auto val_i32 = m_ir_builder->CreateExtractElement(vs_v4i32, index_i64); + WriteMemory(addr_i64, val_i32, 4); +} + +void Compiler::ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto ca_i64 = GetXerCa(); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto sum_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, sum_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDZEO"); + } +} + +void Compiler::SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto ca_i64 = GetXerCa(); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFZEO"); + } +} + +void Compiler::STDCX_(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + auto addr_i32 = m_ir_builder->CreateTrunc(addr_i64, m_ir_builder->getInt32Ty()); auto rs_i64 = GetGpr(rs); rs_i64 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getInt64Ty()), rs_i64); @@ -3042,2996 +3042,2996 @@ void Compiler::STDCX_(u32 rs, u32 ra, u32 rb) { rs_i64_ptr->setAlignment(8); m_ir_builder->CreateStore(rs_i64, rs_i64_ptr); auto success_i1 = Call("vm.reservation_update", vm::reservation_update, addr_i32, m_ir_builder->CreateBitCast(rs_i64_ptr, m_ir_builder->getInt8PtrTy()), m_ir_builder->getInt32(8)); - + auto cr_i32 = GetCr(); cr_i32 = SetBit(cr_i32, 2, success_i1); SetCr(cr_i32); -} - -void Compiler::STBX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 8)); -} - -void Compiler::STVX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - WriteMemory(addr_i64, GetVr(vs), 16); -} - -void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - ra_i64 = m_ir_builder->CreateNot(ra_i64); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("SUBFMEO"); - } -} - -void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("MULLDO"); - } -} - -void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { - auto ca_i64 = GetXerCa(); - auto ra_i64 = GetGpr(ra); - auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); - auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); - res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); - auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); - auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); - SetGpr(rd, res_i64); - SetXerCa(carry_i1); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDMEO"); - } -} - -void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); - auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); - auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); - SetGpr(rd, prod_i64); - - if (rc) { - SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("MULLWO"); - } -} - -void Compiler::DCBTST(u32 ra, u32 rb, u32 th) { - // TODO: Implement this - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::STBUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 8)); - SetGpr(ra, addr_i64); -} - -void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, rb_i64); - SetGpr(rd, sum_i64); - - if (rc) { - SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO: Implement this - CompilationError("ADDO"); - } -} - -void Compiler::DCBT(u32 ra, u32 rb, u32 th) { - // TODO: Implement this using prefetch - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHZX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateNot(res_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) { +} + +void Compiler::STBX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 8)); +} + +void Compiler::STVX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + WriteMemory(addr_i64, GetVr(vs), 16); +} + +void Compiler::SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + ra_i64 = m_ir_builder->CreateNot(ra_i64); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("SUBFMEO"); + } +} + +void Compiler::MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("MULLDO"); + } +} + +void Compiler::ADDME(u32 rd, u32 ra, u32 oe, bool rc) { + auto ca_i64 = GetXerCa(); + auto ra_i64 = GetGpr(ra); + auto res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), ra_i64, ca_i64); + auto res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry1_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + res_s = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::uadd_with_overflow, m_ir_builder->getInt64Ty()), res_i64, m_ir_builder->getInt64((s64)-1)); + res_i64 = m_ir_builder->CreateExtractValue(res_s, {0}); + auto carry2_i1 = m_ir_builder->CreateExtractValue(res_s, {1}); + auto carry_i1 = m_ir_builder->CreateOr(carry1_i1, carry2_i1); + SetGpr(rd, res_i64); + SetXerCa(carry_i1); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDMEO"); + } +} + +void Compiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto ra_i64 = m_ir_builder->CreateSExt(ra_i32, m_ir_builder->getInt64Ty()); + auto rb_i64 = m_ir_builder->CreateSExt(rb_i32, m_ir_builder->getInt64Ty()); + auto prod_i64 = m_ir_builder->CreateMul(ra_i64, rb_i64); + SetGpr(rd, prod_i64); + + if (rc) { + SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("MULLWO"); + } +} + +void Compiler::DCBTST(u32 ra, u32 rb, u32 th) { + // TODO: Implement this + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::STBUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 8)); + SetGpr(ra, addr_i64); +} + +void Compiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto sum_i64 = m_ir_builder->CreateAdd(ra_i64, rb_i64); + SetGpr(rd, sum_i64); + + if (rc) { + SetCrFieldSignedCmp(0, sum_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO: Implement this + CompilationError("ADDO"); + } +} + +void Compiler::DCBT(u32 ra, u32 rb, u32 th) { + // TODO: Implement this using prefetch + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHZX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateNot(res_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) { CompilationError("ECIWX"); - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //auto mem_i32 = ReadMemory(addr_i64, 32); - //auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - //SetGpr(rd, mem_i64); -} - -void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::XOR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::MFSPR(u32 rd, u32 spr) { - Value * rd_i64; - auto n = (spr >> 5) | ((spr & 0x1f) << 5); - - switch (n) { - case 0x001: - rd_i64 = GetXer(); - break; - case 0x008: - rd_i64 = GetLr(); - break; - case 0x009: - rd_i64 = GetCtr(); - break; - case 0x100: - rd_i64 = GetVrsave(); - break; - case 0x10C: - rd_i64 = Call("get_time", get_time); - break; - case 0x10D: - rd_i64 = Call("get_time", get_time); - rd_i64 = m_ir_builder->CreateLShr(rd_i64, 32); - break; - default: - assert(0); - break; - } - - SetGpr(rd, rd_i64); -} - -void Compiler::LWAX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::DST(u32 ra, u32 rb, u32 strm, u32 t) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHAX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LVXL(u32 vd, u32 ra, u32 rb) { - LVX(vd, ra, rb); -} - -void Compiler::MFTB(u32 rd, u32 spr) { - auto tb_i64 = Call("get_time", get_time); - - u32 n = (spr >> 5) | ((spr & 0x1f) << 5); - if (n == 0x10D) { - tb_i64 = m_ir_builder->CreateLShr(tb_i64, 32); - } - - SetGpr(rd, tb_i64); -} - -void Compiler::LWAUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::DSTST(u32 ra, u32 rb, u32 strm, u32 t) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::LHAUX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STHX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16)); -} - -void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - rb_i64 = m_ir_builder->CreateNot(rb_i64); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) { + //auto addr_i64 = GetGpr(rb); + //if (ra) { + // auto ra_i64 = GetGpr(ra); + // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + //} + + //auto mem_i32 = ReadMemory(addr_i64, 32); + //auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + //SetGpr(rd, mem_i64); +} + +void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::XOR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateXor(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::MFSPR(u32 rd, u32 spr) { + Value * rd_i64; + auto n = (spr >> 5) | ((spr & 0x1f) << 5); + + switch (n) { + case 0x001: + rd_i64 = GetXer(); + break; + case 0x008: + rd_i64 = GetLr(); + break; + case 0x009: + rd_i64 = GetCtr(); + break; + case 0x100: + rd_i64 = GetVrsave(); + break; + case 0x10C: + rd_i64 = Call("get_time", get_time); + break; + case 0x10D: + rd_i64 = Call("get_time", get_time); + rd_i64 = m_ir_builder->CreateLShr(rd_i64, 32); + break; + default: + assert(0); + break; + } + + SetGpr(rd, rd_i64); +} + +void Compiler::LWAX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::DST(u32 ra, u32 rb, u32 strm, u32 t) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHAX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LVXL(u32 vd, u32 ra, u32 rb) { + LVX(vd, ra, rb); +} + +void Compiler::MFTB(u32 rd, u32 spr) { + auto tb_i64 = Call("get_time", get_time); + + u32 n = (spr >> 5) | ((spr & 0x1f) << 5); + if (n == 0x10D) { + tb_i64 = m_ir_builder->CreateLShr(tb_i64, 32); + } + + SetGpr(rd, tb_i64); +} + +void Compiler::LWAUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::DSTST(u32 ra, u32 rb, u32 strm, u32 t) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::LHAUX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STHX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16)); +} + +void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + rb_i64 = m_ir_builder->CreateNot(rb_i64); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) { CompilationError("ECOWX"); - //auto addr_i64 = GetGpr(rb); - //if (ra) { - // auto ra_i64 = GetGpr(ra); - // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - //} - - //WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STHUX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 16)); - SetGpr(ra, addr_i64); -} - -void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateUDiv(ra_i64, rb_i64); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVDUO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto res_i32 = m_ir_builder->CreateUDiv(ra_i32, rb_i32); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVWUO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::MTSPR(u32 spr, u32 rs) { - auto rs_i64 = GetGpr(rs); - auto n = (spr >> 5) | ((spr & 0x1f) << 5); - - switch (n) { - case 0x001: - SetXer(rs_i64); - break; - case 0x008: - SetLr(rs_i64); - break; - case 0x009: - SetCtr(rs_i64); - break; - case 0x100: - SetVrsave(rs_i64); - break; - default: - assert(0); - break; - } - -} - -void Compiler::NAND(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); - res_i64 = m_ir_builder->CreateNot(res_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVXL(u32 vs, u32 ra, u32 rb) { - STVX(vs, ra, rb); -} - -void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i64 = GetGpr(ra); - auto rb_i64 = GetGpr(rb); - auto res_i64 = m_ir_builder->CreateSDiv(ra_i64, rb_i64); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVDO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - auto ra_i32 = GetGpr(ra, 32); - auto rb_i32 = GetGpr(rb, 32); - auto res_i32 = m_ir_builder->CreateSDiv(ra_i32, rb_i32); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } - - if (oe) { - // TODO implement oe - CompilationError("DIVWO"); - } - - // TODO make sure an exception does not occur on divide by 0 and overflow -} - -void Compiler::LVLX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto eb_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); - eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); - auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - mem_i128 = m_ir_builder->CreateShl(mem_i128, eb_i128); - SetVr(vd, mem_i128); -} - -void Compiler::LDBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64, 0, false); - SetGpr(rd, mem_i64); -} - -void Compiler::LSWX(u32 rd, u32 ra, u32 rb) { - CompilationError("LSWX"); -} - -void Compiler::LWBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32, 0, false); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LFSX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); -} - -void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateLShr(rs_i64, rb_i64); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateLShr(rs_i128, rb_i128); - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, res_i64); - - if (rc) { - SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LVRX(u32 vd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto eb_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), addr_i64); - eb_i64 = m_ir_builder->CreateAnd(eb_i64, 0xF); - eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); - auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); - auto mem_i128 = ReadMemory(addr_i64, 128, 16); - mem_i128 = m_ir_builder->CreateLShr(mem_i128, eb_i128); - auto cmp_i1 = m_ir_builder->CreateICmpNE(eb_i64, m_ir_builder->getInt64(0)); - auto cmp_i128 = m_ir_builder->CreateSExt(cmp_i1, m_ir_builder->getIntNTy(128)); - mem_i128 = m_ir_builder->CreateAnd(mem_i128, cmp_i128); - SetVr(vd, mem_i128); -} - -void Compiler::LSWI(u32 rd, u32 ra, u32 nb) { - auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); - - nb = nb ? nb : 32; - for (u32 i = 0; i < nb; i += 4) { - auto val_i32 = ReadMemory(addr_i64, 32, 0, true, false); - - if (i + 4 <= nb) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } else { - u32 mask = 0xFFFFFFFF << ((4 - (nb - i)) * 8); - val_i32 = m_ir_builder->CreateAnd(val_i32, mask); - } - - auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, val_i64); - rd = (rd + 1) % 32; - } -} - -void Compiler::LFSUX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::SYNC(u32 l) { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::LFDX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); -} - -void Compiler::LFDUX(u32 frd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STVLX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - auto size_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), index_i64); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - auto vs_i128 = GetVr(vs); - vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); - auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); - vs_i128_ptr->setAlignment(16); - m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); - auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); - - Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), - addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); -} - -void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs), 0, false); -} - -void Compiler::STSWX(u32 rs, u32 ra, u32 rb) { - CompilationError("STSWX"); -} - -void Compiler::STWBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32), 0, false); -} - -void Compiler::STFSX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::STVRX(u32 vs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto size_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); - auto index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), size_i64); - addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFF0); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - auto vs_i128 = GetVr(vs); - vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); - auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); - vs_i128_ptr->setAlignment(16); - m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); - auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); - vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64); - - Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), - addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); -} - -void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::STSWI(u32 rd, u32 ra, u32 nb) { - auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); - - nb = nb ? nb : 32; - for (u32 i = 0; i < nb; i += 4) { - auto val_i32 = GetGpr(rd, 32); - - if (i + 4 <= nb) { - WriteMemory(addr_i64, val_i32, 0, true, false); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - rd = (rd + 1) % 32; - } else { - u32 n = nb - i; - if (n >= 2) { - auto val_i16 = m_ir_builder->CreateLShr(val_i32, 16); - val_i16 = m_ir_builder->CreateTrunc(val_i16, m_ir_builder->getInt16Ty()); - WriteMemory(addr_i64, val_i16); - - if (n == 3) { - auto val_i8 = m_ir_builder->CreateLShr(val_i32, 8); - val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(2)); - WriteMemory(addr_i64, val_i8); - } - } else { - auto val_i8 = m_ir_builder->CreateLShr(val_i32, 24); - val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); - WriteMemory(addr_i64, val_i8); - } - } - } -} - -void Compiler::STFDX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); -} - -void Compiler::STFDUX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LVLXL(u32 vd, u32 ra, u32 rb) { - LVLX(vd, ra, rb); -} - -void Compiler::LHBRX(u32 rd, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16, 0, false); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); - auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); - auto res_i64 = m_ir_builder->CreateAShr(rs_i64, rb_i64); - auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); - SetGpr(ra, ra_i64); - - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); - auto rb_i8 = GetGpr(rb, 8); - rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); - auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); - auto res_i128 = m_ir_builder->CreateAShr(rs_i128, rb_i128); - auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); - auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, ra_i64); - - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::LVRXL(u32 vd, u32 ra, u32 rb) { - LVRX(vd, ra, rb); -} - -void Compiler::DSS(u32 strm, u32 a) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); - rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); - auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh); - auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); - SetGpr(ra, ra_i64); - - auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { - auto rs_i64 = GetGpr(rs); - auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); - rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); - auto res_i128 = m_ir_builder->CreateAShr(rs_i128, sh); - auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); - auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); - SetGpr(ra, ra_i64); - - auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); - auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); - auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); - auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); - SetXerCa(ca_i1); - - if (rc) { - SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { - SRADI1(ra, rs, sh, rc); -} - -void Compiler::EIEIO() { - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); -} - -void Compiler::STVLXL(u32 vs, u32 ra, u32 rb) { - STVLX(vs, ra, rb); -} - -void Compiler::STHBRX(u32 rs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16), 0, false); -} - -void Compiler::EXTSH(u32 ra, u32 rs, bool rc) { - auto rs_i16 = GetGpr(rs, 16); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i16, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STVRXL(u32 vs, u32 ra, u32 rb) { - STVRX(vs, ra, rb); -} - -void Compiler::EXTSB(u32 ra, u32 rs, bool rc) { - auto rs_i8 = GetGpr(rs, 8); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i8, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::STFIWX(u32 frs, u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - auto frs_i32 = m_ir_builder->CreateTrunc(frs_i64, m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::EXTSW(u32 ra, u32 rs, bool rc) { - auto rs_i32 = GetGpr(rs, 32); - auto rs_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty()); - SetGpr(ra, rs_i64); - - if (rc) { - SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); - } -} - -void Compiler::ICBI(u32 ra, u32 rs) { - // TODO: Revisit - m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); -} - -void Compiler::DCBZ(u32 ra, u32 rb) { - auto addr_i64 = GetGpr(rb); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - addr_i64 = m_ir_builder->CreateAnd(addr_i64, ~(127ULL)); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); - auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); - - std::vector types = {(Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty()}; - m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types), - addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true)); -} - -void Compiler::LWZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LWZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LBZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LBZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i8 = ReadMemory(addr_i64, 8); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STW(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 32)); -} - -void Compiler::STWU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 32)); - SetGpr(ra, addr_i64); -} - -void Compiler::STB(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 8)); -} - -void Compiler::STBU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 8)); - SetGpr(ra, addr_i64); -} - -void Compiler::LHZ(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LHZU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LHA(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::LHAU(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i16 = ReadMemory(addr_i64, 16); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STH(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 16)); -} - -void Compiler::STHU(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 16)); - SetGpr(ra, addr_i64); -} - -void Compiler::LMW(u32 rd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); - } - - for (u32 i = rd; i < 32; i++) { - auto val_i32 = ReadMemory(addr_i64, 32); - auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); - SetGpr(i, val_i64); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } -} - -void Compiler::STMW(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); - } - - for (u32 i = rs; i < 32; i++) { - auto val_i32 = GetGpr(i, 32); - WriteMemory(addr_i64, val_i32); - addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); - } -} - -void Compiler::LFS(u32 frd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); -} - -void Compiler::LFSU(u32 frd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - auto mem_i32 = ReadMemory(addr_i64, 32); - SetFpr(frd, mem_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::LFD(u32 frd, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); -} - -void Compiler::LFDU(u32 frd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetFpr(frd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::STFS(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); -} - -void Compiler::STFSU(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); - WriteMemory(addr_i64, frs_i32); - SetGpr(ra, addr_i64); -} - -void Compiler::STFD(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); -} - -void Compiler::STFDU(u32 frs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); - WriteMemory(addr_i64, frs_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LD(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); -} - -void Compiler::LDU(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - auto mem_i64 = ReadMemory(addr_i64, 64); - SetGpr(rd, mem_i64); - SetGpr(ra, addr_i64); -} - -void Compiler::LWA(u32 rd, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - auto mem_i32 = ReadMemory(addr_i64, 32); - auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); - SetGpr(rd, mem_i64); -} - -void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FDIVS."); - } - - // TODO: Set flags -} - -void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FADDS."); - } - - // TODO: Set flags -} - -void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FSQRTS."); - } - - // TODO: Set flags -} - -void Compiler::FRES(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FRES."); - } - - // TODO: Set flags -} - -void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMULS."); - } - - // TODO: Set flags -} - -void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMADDS."); - } - - // TODO: Set flags -} - -void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FMSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FNMSUBS."); - } - - // TODO: Set flags -} - -void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); - SetFpr(frd, res_f32); - - if (rc) { - // TODO: Implement this - CompilationError("FNMADDS."); - } - - // TODO: Set flags -} - -void Compiler::STD(u32 rs, u32 ra, s32 d) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); - if (ra) { - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - } - - WriteMemory(addr_i64, GetGpr(rs, 64)); -} - -void Compiler::STDU(u32 rs, u32 ra, s32 ds) { - auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); - auto ra_i64 = GetGpr(ra); - addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); - - WriteMemory(addr_i64, GetGpr(rs, 64)); - SetGpr(ra, addr_i64); -} - -void Compiler::MTFSB1(u32 crbd, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSB1."); - } -} - -void Compiler::MCRFS(u32 crbd, u32 crbs) { - auto fpscr_i32 = GetFpscr(); - auto val_i32 = GetNibble(fpscr_i32, crbs); - SetCrField(crbd, val_i32); - - switch (crbs) { - case 0: - fpscr_i32 = ClrBit(fpscr_i32, 0); - fpscr_i32 = ClrBit(fpscr_i32, 3); - break; - case 1: - fpscr_i32 = ClrNibble(fpscr_i32, 1); - break; - case 2: - fpscr_i32 = ClrNibble(fpscr_i32, 2); - break; - case 3: - fpscr_i32 = ClrBit(fpscr_i32, 12); - break; - case 5: - fpscr_i32 = ClrBit(fpscr_i32, 21); - fpscr_i32 = ClrBit(fpscr_i32, 22); - fpscr_i32 = ClrBit(fpscr_i32, 23); - break; - default: - break; - } - - SetFpscr(fpscr_i32); -} - -void Compiler::MTFSB0(u32 crbd, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = ClrBit(fpscr_i32, crbd); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSB0."); - } -} - -void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF)); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSFI."); - } -} - -void Compiler::MFFS(u32 frd, bool rc) { - auto fpscr_i32 = GetFpscr(); - auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty()); - SetFpr(frd, fpscr_i64); - - if (rc) { - // TODO: Implement this - CompilationError("MFFS."); - } -} - -void Compiler::MTFSF(u32 flm, u32 frb, bool rc) { - u32 mask = 0; - for(u32 i = 0; i < 8; i++) { - if (flm & (1 << i)) { - mask |= 0xF << (i * 4); - } - } - - auto rb_i32 = GetFpr(frb, 32, true); - auto fpscr_i32 = GetFpscr(); - fpscr_i32 = m_ir_builder->CreateAnd(fpscr_i32, ~mask); - rb_i32 = m_ir_builder->CreateAnd(rb_i32, mask); - fpscr_i32 = m_ir_builder->CreateOr(fpscr_i32, rb_i32); - SetFpscr(fpscr_i32); - - if (rc) { - // TODO: Implement this - CompilationError("MTFSF."); - } -} - -void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); - auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); - auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); - SetCr(cr_i32); - - // TODO: Set flags / Handle NaN -} - -void Compiler::FRSP(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f32 = m_ir_builder->CreateFPTrunc(rb_f64, m_ir_builder->getFloatTy()); - auto res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy()); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FRSP."); - } - - // TODO: Revisit this - // TODO: Set flags -} - -void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); - auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIW."); - } - - // TODO: Set flags / Implement rounding modes -} - -void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); - auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); - auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIWZ."); - } - - // TODO: Set flags -} - -void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FDIV."); - } - - // TODO: Set flags -} - -void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSUB."); - } - - // TODO: Set flags -} - -void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FADD."); - } - - // TODO: Set flags -} - -void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSQRT."); - } - - // TODO: Set flags -} - -void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto cmp_i1 = m_ir_builder->CreateFCmpOGE(ra_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0.0)); - auto res_f64 = m_ir_builder->CreateSelect(cmp_i1, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FSEL."); - } - - // TODO: Set flags -} - -void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMUL."); - } - - // TODO: Set flags -} - -void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); - res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), res_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FRSQRTE."); - } -} - -void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMSUB."); - } - - // TODO: Set flags -} - -void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FMADD."); - } - - // TODO: Set flags -} - -void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rc_f64 = m_ir_builder->CreateFNeg(rc_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNMSUB."); - } - - // TODO: Set flags -} - -void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto rc_f64 = GetFpr(frc); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - rc_f64 = m_ir_builder->CreateFNeg(rc_f64); - auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNMADD."); - } - - // TODO: Set flags -} - -void Compiler::FCMPO(u32 crfd, u32 fra, u32 frb) { - auto ra_f64 = GetFpr(fra); - auto rb_f64 = GetFpr(frb); - auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); - auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); - auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); - SetCr(cr_i32); - - // TODO: Set flags / Handle NaN -} - -void Compiler::FNEG(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - rb_f64 = m_ir_builder->CreateFNeg(rb_f64); - SetFpr(frd, rb_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNEG."); - } - - // TODO: Set flags -} - -void Compiler::FMR(u32 frd, u32 frb, bool rc) { - SetFpr(frd, GetFpr(frb)); - - if (rc) { - // TODO: Implement this - CompilationError("FMR."); - } - - // TODO: Set flags -} - -void Compiler::FNABS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); - res_f64 = m_ir_builder->CreateFNeg(res_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FNABS."); - } - - // TODO: Set flags -} - -void Compiler::FABS(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FABS."); - } - - // TODO: Set flags -} - -void Compiler::FCTID(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); - auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTID."); - } - - // TODO: Set flags / Implement rounding modes -} - -void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { - auto rb_f64 = GetFpr(frb); - auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); - auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); - auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); - res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); - res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); - SetFpr(frd, res_i64); - - if (rc) { - // TODO: Implement this - CompilationError("FCTIDZ."); - } - - // TODO: Set flags -} - -void Compiler::FCFID(u32 frd, u32 frb, bool rc) { - auto rb_i64 = GetFpr(frb, 64, true); - auto res_f64 = m_ir_builder->CreateSIToFP(rb_i64, m_ir_builder->getDoubleTy()); - SetFpr(frd, res_f64); - - if (rc) { - // TODO: Implement this - CompilationError("FCFID."); - } - - // TODO: Set flags -} - -void Compiler::UNK(const u32 code, const u32 opcode, const u32 gcode) { - CompilationError(fmt::Format("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode)); -} - -std::string Compiler::GetBasicBlockNameFromAddress(u32 address, const std::string & suffix) const { - std::string name; - - if (address == 0) { - name = "entry"; - } else if (address == 0xFFFFFFFF) { - name = "default_exit"; - } else { - name = fmt::Format("instr_0x%08X", address); - } - - if (suffix != "") { - name += "_" + suffix; - } - - return name; -} - -u32 Compiler::GetAddressFromBasicBlockName(const std::string & name) const { - if (name.compare(0, 6, "instr_") == 0) { - return strtoul(name.c_str() + 6, nullptr, 0); - } else if (name == GetBasicBlockNameFromAddress(0)) { - return 0; - } else if (name == GetBasicBlockNameFromAddress(0xFFFFFFFF)) { - return 0xFFFFFFFF; - } - - return 0; -} - -BasicBlock * Compiler::GetBasicBlockFromAddress(u32 address, const std::string & suffix, bool create_if_not_exist) { - auto block_name = GetBasicBlockNameFromAddress(address, suffix); - BasicBlock * block = nullptr; - BasicBlock * next_block = nullptr; - for (auto i = m_state.function->begin(); i != m_state.function->end(); i++) { - if (i->getName() == block_name) { - block = &(*i); - break; - } - -#ifdef _DEBUG - auto block_address = GetAddressFromBasicBlockName(i->getName()); - if (block_address > address) { - next_block = &(*i); - break; - } -#endif - } - - if (!block && create_if_not_exist) { - block = BasicBlock::Create(m_ir_builder->getContext(), block_name, m_state.function, next_block); - } - - return block; -} - -Value * Compiler::GetBit(Value * val, u32 n) { - Value * bit; - -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - if (val->getType()->isIntegerTy(32)) { - bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31- n))); - } else if (val->getType()->isIntegerTy(64)) { - bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n))); - } else { -#endif - if (val->getType()->getIntegerBitWidth() != (n + 1)) { - bit = m_ir_builder->CreateLShr(val, val->getType()->getIntegerBitWidth() - n - 1); - } - - bit = m_ir_builder->CreateAnd(bit, 1); -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - } -#endif - - return bit; -} - -Value * Compiler::ClrBit(Value * val, u32 n) { - return m_ir_builder->CreateAnd(val, ~((u64)1 << (val->getType()->getIntegerBitWidth() - n - 1))); -} - -Value * Compiler::SetBit(Value * val, u32 n, Value * bit, bool doClear) { - if (doClear) { - val = ClrBit(val, n); - } - - if (bit->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { - bit = m_ir_builder->CreateZExt(bit, val->getType()); - } else if (bit->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { - bit = m_ir_builder->CreateTrunc(bit, val->getType()); - } - - if (val->getType()->getIntegerBitWidth() != (n + 1)) { - bit = m_ir_builder->CreateShl(bit, bit->getType()->getIntegerBitWidth() - n - 1); - } - - return m_ir_builder->CreateOr(val, bit); -} - -Value * Compiler::GetNibble(Value * val, u32 n) { - Value * nibble; - -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - if (val->getType()->isIntegerTy(32)) { - nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4))); - } else if (val->getType()->isIntegerTy(64)) { - nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4))); - } else { -#endif - if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { - val = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); - } - - nibble = m_ir_builder->CreateAnd(val, 0xF); -#ifdef PPU_LLVM_RECOMPILER_USE_BMI - } -#endif - - return nibble; -} - -Value * Compiler::ClrNibble(Value * val, u32 n) { - return m_ir_builder->CreateAnd(val, ~((u64)0xF << ((((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4))); -} - -Value * Compiler::SetNibble(Value * val, u32 n, Value * nibble, bool doClear) { - if (doClear) { - val = ClrNibble(val, n); - } - - if (nibble->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { - nibble = m_ir_builder->CreateZExt(nibble, val->getType()); - } else if (nibble->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { - nibble = m_ir_builder->CreateTrunc(nibble, val->getType()); - } - - if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { - nibble = m_ir_builder->CreateShl(nibble, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); - } - - return m_ir_builder->CreateOr(val, nibble); -} - -Value * Compiler::SetNibble(Value * val, u32 n, Value * b0, Value * b1, Value * b2, Value * b3, bool doClear) { - if (doClear) { - val = ClrNibble(val, n); - } - - if (b0) { - val = SetBit(val, n * 4, b0, false); - } - - if (b1) { - val = SetBit(val, (n * 4) + 1, b1, false); - } - - if (b2) { - val = SetBit(val, (n * 4) + 2, b2, false); - } - - if (b3) { - val = SetBit(val, (n * 4) + 3, b3, false); - } - - return val; -} - -Value * Compiler::GetPc() { - auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); - auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(pc_i32_ptr, 4); -} - -void Compiler::SetPc(Value * val_ix) { - auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); - auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_ix, m_ir_builder->getInt32Ty()); - m_ir_builder->CreateAlignedStore(val_i32, pc_i32_ptr, 4); -} - -Value * Compiler::GetGpr(u32 r, u32 num_bits) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); - auto r_ix_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getIntNTy(num_bits)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(r_ix_ptr, 8); -} - -void Compiler::SetGpr(u32 r, Value * val_x64) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); - auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - m_ir_builder->CreateAlignedStore(val_i64, r_i64_ptr, 8); -} - -Value * Compiler::GetCr() { - auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); - auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(cr_i32_ptr, 4); -} - -Value * Compiler::GetCrField(u32 n) { - return GetNibble(GetCr(), n); -} - -void Compiler::SetCr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); - auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, cr_i32_ptr, 4); -} - -void Compiler::SetCrField(u32 n, Value * field) { - SetCr(SetNibble(GetCr(), n, field)); -} - -void Compiler::SetCrField(u32 n, Value * b0, Value * b1, Value * b2, Value * b3) { - SetCr(SetNibble(GetCr(), n, b0, b1, b2, b3)); -} - -void Compiler::SetCrFieldSignedCmp(u32 n, Value * a, Value * b) { - auto lt_i1 = m_ir_builder->CreateICmpSLT(a, b); - auto gt_i1 = m_ir_builder->CreateICmpSGT(a, b); - auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); - SetCr(cr_i32); -} - -void Compiler::SetCrFieldUnsignedCmp(u32 n, Value * a, Value * b) { - auto lt_i1 = m_ir_builder->CreateICmpULT(a, b); - auto gt_i1 = m_ir_builder->CreateICmpUGT(a, b); - auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); - SetCr(cr_i32); -} - -void Compiler::SetCr6AfterVectorCompare(u32 vr) { - auto vr_v16i8 = GetVrAsIntVec(vr, 8); - auto vr_mask_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmovmskb_128), vr_v16i8); - auto cmp0_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0)); - auto cmp1_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0xFFFF)); - auto cr_i32 = GetCr(); - cr_i32 = SetNibble(cr_i32, 6, cmp1_i1, nullptr, cmp0_i1, nullptr); - SetCr(cr_i32); -} - -Value * Compiler::GetLr() { - auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); - auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(lr_i64_ptr, 8); -} - -void Compiler::SetLr(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); - auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, lr_i64_ptr, 8); -} - -Value * Compiler::GetCtr() { - auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); - auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(ctr_i64_ptr, 8); -} - -void Compiler::SetCtr(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); - auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, ctr_i64_ptr, 8); -} - -Value * Compiler::GetXer() { - auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); - auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(xer_i64_ptr, 8); -} - -Value * Compiler::GetXerCa() { - return GetBit(GetXer(), 34); -} - -Value * Compiler::GetXerSo() { - return GetBit(GetXer(), 32); -} - -void Compiler::SetXer(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); - auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, xer_i64_ptr, 8); -} - -void Compiler::SetXerCa(Value * ca) { - auto xer_i64 = GetXer(); - xer_i64 = SetBit(xer_i64, 34, ca); - SetXer(xer_i64); -} - -void Compiler::SetXerSo(Value * so) { - auto xer_i64 = GetXer(); - xer_i64 = SetBit(xer_i64, 32, so); - SetXer(xer_i64); -} - -Value * Compiler::GetVrsave() { - auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); - auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4); - return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty()); -} - -void Compiler::SetVrsave(Value * val_x64) { - auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty()); - auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); - auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8); -} - -Value * Compiler::GetFpscr() { - auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); - auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4); -} - -void Compiler::SetFpscr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); - auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4); -} - -Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); - if (!as_int) { - auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); - auto r_f64 = m_ir_builder->CreateAlignedLoad(r_f64_ptr, 8); - if (bits == 32) { - return m_ir_builder->CreateFPTrunc(r_f64, m_ir_builder->getFloatTy()); - } else { - return r_f64; - } - } else { - auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - auto r_i64 = m_ir_builder->CreateAlignedLoad(r_i64_ptr, 8); - if (bits == 32) { - return m_ir_builder->CreateTrunc(r_i64, m_ir_builder->getInt32Ty()); - } else { - return r_i64; - } - } -} - -void Compiler::SetFpr(u32 r, Value * val) { - auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); - auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); - - Value* val_f64; - if (val->getType()->isDoubleTy() || val->getType()->isIntegerTy(64)) { - val_f64 = m_ir_builder->CreateBitCast(val, m_ir_builder->getDoubleTy()); - } else if (val->getType()->isFloatTy() || val->getType()->isIntegerTy(32)) { - auto val_f32 = m_ir_builder->CreateBitCast(val, m_ir_builder->getFloatTy()); - val_f64 = m_ir_builder->CreateFPExt(val_f32, m_ir_builder->getDoubleTy()); - } else { - assert(0); - } - - m_ir_builder->CreateAlignedStore(val_f64, r_f64_ptr, 8); -} - -Value * Compiler::GetVscr() { - auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); - auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vscr_i32_ptr, 4); -} - -void Compiler::SetVscr(Value * val_x32) { - auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); - auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); - auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i32, vscr_i32_ptr, 4); -} - -Value * Compiler::GetVr(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_i128_ptr, 16); -} - -Value * Compiler::GetVrAsIntVec(u32 vr, u32 vec_elt_num_bits) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_vec_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getIntNTy(vec_elt_num_bits), 128 / vec_elt_num_bits)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_vec_ptr, 16); -} - -Value * Compiler::GetVrAsFloatVec(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_v4f32_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getFloatTy(), 4)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_v4f32_ptr, 16); -} - -Value * Compiler::GetVrAsDoubleVec(u32 vr) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto vr_v2f64_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getDoubleTy(), 2)->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(vr_v2f64_ptr, 16); -} - -void Compiler::SetVr(u32 vr, Value * val_x128) { - auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); - auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); - auto val_i128 = m_ir_builder->CreateBitCast(val_x128, m_ir_builder->getIntNTy(128)); - m_ir_builder->CreateAlignedStore(val_i128, vr_i128_ptr, 16); -} - -Value * Compiler::CheckBranchCondition(u32 bo, u32 bi) { - bool bo0 = bo & 0x10 ? true : false; - bool bo1 = bo & 0x08 ? true : false; - bool bo2 = bo & 0x04 ? true : false; - bool bo3 = bo & 0x02 ? true : false; - - auto ctr_i64 = GetCtr(); - if (!bo2) { - ctr_i64 = m_ir_builder->CreateSub(ctr_i64, m_ir_builder->getInt64(1)); - SetCtr(ctr_i64); - } - - Value * ctr_ok_i1 = nullptr; - if (!bo2) { - // TODO: Check if we should compare all bits or just the lower 32 bits. This depends on MSR[SF]. Not sure what it is for PS3. - ctr_ok_i1 = m_ir_builder->CreateICmpNE(ctr_i64, m_ir_builder->getInt64(0)); - if (bo3) { - ctr_ok_i1 = m_ir_builder->CreateXor(ctr_ok_i1, m_ir_builder->getInt1(bo3)); - } - } - - Value * cond_ok_i1 = nullptr; - if (!bo0) { - auto cr_bi_i32 = GetBit(GetCr(), bi); - cond_ok_i1 = m_ir_builder->CreateTrunc(cr_bi_i32, m_ir_builder->getInt1Ty()); - if (!bo1) { - cond_ok_i1 = m_ir_builder->CreateXor(cond_ok_i1, m_ir_builder->getInt1(!bo1)); - } - } - - Value * cmp_i1 = nullptr; - if (ctr_ok_i1 && cond_ok_i1) { - cmp_i1 = m_ir_builder->CreateAnd(ctr_ok_i1, cond_ok_i1); - } else if (ctr_ok_i1) { - cmp_i1 = ctr_ok_i1; - } else if (cond_ok_i1) { - cmp_i1 = cond_ok_i1; - } - - return cmp_i1; -} - -void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool lk, bool target_is_lr) { - if (lk) { - SetLr(m_ir_builder->getInt64(m_state.current_instruction_address + 4)); - } - - auto current_block = m_ir_builder->GetInsertBlock(); - - BasicBlock * target_block = nullptr; - if (dyn_cast(target_i32)) { - // Target address is an immediate value. - u32 target_address = (u32)(dyn_cast(target_i32)->getLimitedValue()); - if (lk) { - // Function call - if (cmp_i1) { // There is no need to create a new block for an unconditional jump - target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); - m_ir_builder->SetInsertPoint(target_block); - } - - SetPc(target_i32); - IndirectCall(target_address, m_ir_builder->getInt64(0), true); - m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); - } else { - // Local branch - target_block = GetBasicBlockFromAddress(target_address); - } - } else { - // Target address is in a register - if (cmp_i1) { // There is no need to create a new block for an unconditional jump - target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); - m_ir_builder->SetInsertPoint(target_block); - } - - SetPc(target_i32); - if (target_is_lr && !lk) { - // Return from this function - m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); - } else if (lk) { - auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); - auto unknown_function_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "unknown_function"); - - auto switch_instr = m_ir_builder->CreateSwitch(target_i32, unknown_function_block); - m_ir_builder->SetInsertPoint(unknown_function_block); - m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); - m_ir_builder->CreateBr(next_block); - - auto call_i = m_state.cfg->calls.find(m_state.current_instruction_address); - if (call_i != m_state.cfg->calls.end()) { - for (auto function_i = call_i->second.begin(); function_i != call_i->second.end(); function_i++) { - auto block = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("0x%08X", *function_i)); - m_ir_builder->SetInsertPoint(block); - IndirectCall(*function_i, m_ir_builder->getInt64(0), true); - m_ir_builder->CreateBr(next_block); - switch_instr->addCase(m_ir_builder->getInt32(*function_i), block); - } - } - } else { - auto switch_instr = m_ir_builder->CreateSwitch(target_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); - auto branch_i = m_state.cfg->branches.find(m_state.current_instruction_address); - if (branch_i != m_state.cfg->branches.end()) { - for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { - switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); - } - } - } - } - - if (cmp_i1) { - // Conditional branch - auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); - m_ir_builder->SetInsertPoint(current_block); - m_ir_builder->CreateCondBr(cmp_i1, target_block, next_block); - } else { - // Unconditional branch - if (target_block) { - m_ir_builder->SetInsertPoint(current_block); - m_ir_builder->CreateBr(target_block); - } - } - - m_state.hit_branch_instruction = true; -} - -Value * Compiler::ReadMemory(Value * addr_i64, u32 bits, u32 alignment, bool bswap, bool could_be_mmio) { + //auto addr_i64 = GetGpr(rb); + //if (ra) { + // auto ra_i64 = GetGpr(ra); + // addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + //} + + //WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STHUX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 16)); + SetGpr(ra, addr_i64); +} + +void Compiler::OR(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateOr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::DIVDU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateUDiv(ra_i64, rb_i64); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVDUO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::DIVWU(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto res_i32 = m_ir_builder->CreateUDiv(ra_i32, rb_i32); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVWUO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::MTSPR(u32 spr, u32 rs) { + auto rs_i64 = GetGpr(rs); + auto n = (spr >> 5) | ((spr & 0x1f) << 5); + + switch (n) { + case 0x001: + SetXer(rs_i64); + break; + case 0x008: + SetLr(rs_i64); + break; + case 0x009: + SetCtr(rs_i64); + break; + case 0x100: + SetVrsave(rs_i64); + break; + default: + assert(0); + break; + } + +} + +void Compiler::NAND(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateAnd(rs_i64, rb_i64); + res_i64 = m_ir_builder->CreateNot(res_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVXL(u32 vs, u32 ra, u32 rb) { + STVX(vs, ra, rb); +} + +void Compiler::DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i64 = GetGpr(ra); + auto rb_i64 = GetGpr(rb); + auto res_i64 = m_ir_builder->CreateSDiv(ra_i64, rb_i64); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVDO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { + auto ra_i32 = GetGpr(ra, 32); + auto rb_i32 = GetGpr(rb, 32); + auto res_i32 = m_ir_builder->CreateSDiv(ra_i32, rb_i32); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } + + if (oe) { + // TODO implement oe + CompilationError("DIVWO"); + } + + // TODO make sure an exception does not occur on divide by 0 and overflow +} + +void Compiler::LVLX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto eb_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF); + eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); + auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + mem_i128 = m_ir_builder->CreateShl(mem_i128, eb_i128); + SetVr(vd, mem_i128); +} + +void Compiler::LDBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64, 0, false); + SetGpr(rd, mem_i64); +} + +void Compiler::LSWX(u32 rd, u32 ra, u32 rb) { + CompilationError("LSWX"); +} + +void Compiler::LWBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32, 0, false); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LFSX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); +} + +void Compiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateLShr(rs_i64, rb_i64); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateLShr(rs_i128, rb_i128); + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, res_i64); + + if (rc) { + SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LVRX(u32 vd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto eb_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), addr_i64); + eb_i64 = m_ir_builder->CreateAnd(eb_i64, 0xF); + eb_i64 = m_ir_builder->CreateShl(eb_i64, 3); + auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128)); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL); + auto mem_i128 = ReadMemory(addr_i64, 128, 16); + mem_i128 = m_ir_builder->CreateLShr(mem_i128, eb_i128); + auto cmp_i1 = m_ir_builder->CreateICmpNE(eb_i64, m_ir_builder->getInt64(0)); + auto cmp_i128 = m_ir_builder->CreateSExt(cmp_i1, m_ir_builder->getIntNTy(128)); + mem_i128 = m_ir_builder->CreateAnd(mem_i128, cmp_i128); + SetVr(vd, mem_i128); +} + +void Compiler::LSWI(u32 rd, u32 ra, u32 nb) { + auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); + + nb = nb ? nb : 32; + for (u32 i = 0; i < nb; i += 4) { + auto val_i32 = ReadMemory(addr_i64, 32, 0, true, false); + + if (i + 4 <= nb) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } else { + u32 mask = 0xFFFFFFFF << ((4 - (nb - i)) * 8); + val_i32 = m_ir_builder->CreateAnd(val_i32, mask); + } + + auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, val_i64); + rd = (rd + 1) % 32; + } +} + +void Compiler::LFSUX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::SYNC(u32 l) { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::LFDX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); +} + +void Compiler::LFDUX(u32 frd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STVLX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + auto size_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), index_i64); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + auto vs_i128 = GetVr(vs); + vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); + auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); + vs_i128_ptr->setAlignment(16); + m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); + auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); + + Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), + addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); +} + +void Compiler::STDBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs), 0, false); +} + +void Compiler::STSWX(u32 rs, u32 ra, u32 rb) { + CompilationError("STSWX"); +} + +void Compiler::STWBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 32), 0, false); +} + +void Compiler::STFSX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::STVRX(u32 vs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto size_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf); + auto index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(16), size_i64); + addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFF0); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + auto vs_i128 = GetVr(vs); + vs_i128 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, vs_i128->getType()), vs_i128); + auto vs_i128_ptr = m_ir_builder->CreateAlloca(vs_i128->getType()); + vs_i128_ptr->setAlignment(16); + m_ir_builder->CreateAlignedStore(vs_i128, vs_i128_ptr, 16); + auto vs_i8_ptr = m_ir_builder->CreateBitCast(vs_i128_ptr, m_ir_builder->getInt8PtrTy()); + vs_i8_ptr = m_ir_builder->CreateGEP(vs_i8_ptr, index_i64); + + Type * types[3] = { m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt8PtrTy(), m_ir_builder->getInt64Ty() }; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memcpy, types), + addr_i8_ptr, vs_i8_ptr, size_i64, m_ir_builder->getInt32(1), m_ir_builder->getInt1(false)); +} + +void Compiler::STFSUX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::STSWI(u32 rd, u32 ra, u32 nb) { + auto addr_i64 = ra ? GetGpr(ra) : m_ir_builder->getInt64(0); + + nb = nb ? nb : 32; + for (u32 i = 0; i < nb; i += 4) { + auto val_i32 = GetGpr(rd, 32); + + if (i + 4 <= nb) { + WriteMemory(addr_i64, val_i32, 0, true, false); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + rd = (rd + 1) % 32; + } else { + u32 n = nb - i; + if (n >= 2) { + auto val_i16 = m_ir_builder->CreateLShr(val_i32, 16); + val_i16 = m_ir_builder->CreateTrunc(val_i16, m_ir_builder->getInt16Ty()); + WriteMemory(addr_i64, val_i16); + + if (n == 3) { + auto val_i8 = m_ir_builder->CreateLShr(val_i32, 8); + val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(2)); + WriteMemory(addr_i64, val_i8); + } + } else { + auto val_i8 = m_ir_builder->CreateLShr(val_i32, 24); + val_i8 = m_ir_builder->CreateTrunc(val_i8, m_ir_builder->getInt8Ty()); + WriteMemory(addr_i64, val_i8); + } + } + } +} + +void Compiler::STFDX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); +} + +void Compiler::STFDUX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LVLXL(u32 vd, u32 ra, u32 rb) { + LVLX(vd, ra, rb); +} + +void Compiler::LHBRX(u32 rd, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16, 0, false); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F); + auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty()); + auto res_i64 = m_ir_builder->CreateAShr(rs_i64, rb_i64); + auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); + SetGpr(ra, ra_i64); + + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); + auto rb_i8 = GetGpr(rb, 8); + rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F); + auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128)); + auto res_i128 = m_ir_builder->CreateAShr(rs_i128, rb_i128); + auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); + auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, ra_i64); + + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::LVRXL(u32 vd, u32 ra, u32 rb) { + LVRX(vd, ra, rb); +} + +void Compiler::DSS(u32 strm, u32 a) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty()); + rs_i64 = m_ir_builder->CreateShl(rs_i64, 32); + auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh); + auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32); + SetGpr(ra, ra_i64); + + auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) { + auto rs_i64 = GetGpr(rs); + auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128)); + rs_i128 = m_ir_builder->CreateShl(rs_i128, 64); + auto res_i128 = m_ir_builder->CreateAShr(rs_i128, sh); + auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64); + auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty()); + SetGpr(ra, ra_i64); + + auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty()); + auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0)); + auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0)); + auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1); + SetXerCa(ca_i1); + + if (rc) { + SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) { + SRADI1(ra, rs, sh, rc); +} + +void Compiler::EIEIO() { + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence)); +} + +void Compiler::STVLXL(u32 vs, u32 ra, u32 rb) { + STVLX(vs, ra, rb); +} + +void Compiler::STHBRX(u32 rs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16), 0, false); +} + +void Compiler::EXTSH(u32 ra, u32 rs, bool rc) { + auto rs_i16 = GetGpr(rs, 16); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i16, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STVRXL(u32 vs, u32 ra, u32 rb) { + STVRX(vs, ra, rb); +} + +void Compiler::EXTSB(u32 ra, u32 rs, bool rc) { + auto rs_i8 = GetGpr(rs, 8); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i8, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::STFIWX(u32 frs, u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + auto frs_i32 = m_ir_builder->CreateTrunc(frs_i64, m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::EXTSW(u32 ra, u32 rs, bool rc) { + auto rs_i32 = GetGpr(rs, 32); + auto rs_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty()); + SetGpr(ra, rs_i64); + + if (rc) { + SetCrFieldSignedCmp(0, rs_i64, m_ir_builder->getInt64(0)); + } +} + +void Compiler::ICBI(u32 ra, u32 rs) { + // TODO: Revisit + m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::donothing)); +} + +void Compiler::DCBZ(u32 ra, u32 rb) { + auto addr_i64 = GetGpr(rb); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + addr_i64 = m_ir_builder->CreateAnd(addr_i64, ~(127ULL)); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + std::vector types = {(Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty()}; + m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types), + addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true)); +} + +void Compiler::LWZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LWZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LBZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LBZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i8 = ReadMemory(addr_i64, 8); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i8, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STW(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 32)); +} + +void Compiler::STWU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 32)); + SetGpr(ra, addr_i64); +} + +void Compiler::STB(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 8)); +} + +void Compiler::STBU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 8)); + SetGpr(ra, addr_i64); +} + +void Compiler::LHZ(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LHZU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateZExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LHA(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::LHAU(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i16 = ReadMemory(addr_i64, 16); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i16, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STH(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 16)); +} + +void Compiler::STHU(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 16)); + SetGpr(ra, addr_i64); +} + +void Compiler::LMW(u32 rd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); + } + + for (u32 i = rd; i < 32; i++) { + auto val_i32 = ReadMemory(addr_i64, 32); + auto val_i64 = m_ir_builder->CreateZExt(val_i32, m_ir_builder->getInt64Ty()); + SetGpr(i, val_i64); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } +} + +void Compiler::STMW(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + addr_i64 = m_ir_builder->CreateAdd(addr_i64, GetGpr(ra)); + } + + for (u32 i = rs; i < 32; i++) { + auto val_i32 = GetGpr(i, 32); + WriteMemory(addr_i64, val_i32); + addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64(4)); + } +} + +void Compiler::LFS(u32 frd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); +} + +void Compiler::LFSU(u32 frd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + auto mem_i32 = ReadMemory(addr_i64, 32); + SetFpr(frd, mem_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::LFD(u32 frd, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); +} + +void Compiler::LFDU(u32 frd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetFpr(frd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::STFS(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); +} + +void Compiler::STFSU(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i32 = m_ir_builder->CreateBitCast(GetFpr(frs, 32), m_ir_builder->getInt32Ty()); + WriteMemory(addr_i64, frs_i32); + SetGpr(ra, addr_i64); +} + +void Compiler::STFD(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); +} + +void Compiler::STFDU(u32 frs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto frs_i64 = m_ir_builder->CreateBitCast(GetFpr(frs), m_ir_builder->getInt64Ty()); + WriteMemory(addr_i64, frs_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LD(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); +} + +void Compiler::LDU(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + auto mem_i64 = ReadMemory(addr_i64, 64); + SetGpr(rd, mem_i64); + SetGpr(ra, addr_i64); +} + +void Compiler::LWA(u32 rd, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + auto mem_i32 = ReadMemory(addr_i64, 32); + auto mem_i64 = m_ir_builder->CreateSExt(mem_i32, m_ir_builder->getInt64Ty()); + SetGpr(rd, mem_i64); +} + +void Compiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FDIVS."); + } + + // TODO: Set flags +} + +void Compiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FADDS."); + } + + // TODO: Set flags +} + +void Compiler::FSQRTS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FSQRTS."); + } + + // TODO: Set flags +} + +void Compiler::FRES(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FRES."); + } + + // TODO: Set flags +} + +void Compiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMULS."); + } + + // TODO: Set flags +} + +void Compiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMADDS."); + } + + // TODO: Set flags +} + +void Compiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FMSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FNMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FNMSUBS."); + } + + // TODO: Set flags +} + +void Compiler::FNMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy()); + SetFpr(frd, res_f32); + + if (rc) { + // TODO: Implement this + CompilationError("FNMADDS."); + } + + // TODO: Set flags +} + +void Compiler::STD(u32 rs, u32 ra, s32 d) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)d); + if (ra) { + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + } + + WriteMemory(addr_i64, GetGpr(rs, 64)); +} + +void Compiler::STDU(u32 rs, u32 ra, s32 ds) { + auto addr_i64 = (Value *)m_ir_builder->getInt64((s64)ds); + auto ra_i64 = GetGpr(ra); + addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64); + + WriteMemory(addr_i64, GetGpr(rs, 64)); + SetGpr(ra, addr_i64); +} + +void Compiler::MTFSB1(u32 crbd, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSB1."); + } +} + +void Compiler::MCRFS(u32 crbd, u32 crbs) { + auto fpscr_i32 = GetFpscr(); + auto val_i32 = GetNibble(fpscr_i32, crbs); + SetCrField(crbd, val_i32); + + switch (crbs) { + case 0: + fpscr_i32 = ClrBit(fpscr_i32, 0); + fpscr_i32 = ClrBit(fpscr_i32, 3); + break; + case 1: + fpscr_i32 = ClrNibble(fpscr_i32, 1); + break; + case 2: + fpscr_i32 = ClrNibble(fpscr_i32, 2); + break; + case 3: + fpscr_i32 = ClrBit(fpscr_i32, 12); + break; + case 5: + fpscr_i32 = ClrBit(fpscr_i32, 21); + fpscr_i32 = ClrBit(fpscr_i32, 22); + fpscr_i32 = ClrBit(fpscr_i32, 23); + break; + default: + break; + } + + SetFpscr(fpscr_i32); +} + +void Compiler::MTFSB0(u32 crbd, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = ClrBit(fpscr_i32, crbd); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSB0."); + } +} + +void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) { + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF)); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSFI."); + } +} + +void Compiler::MFFS(u32 frd, bool rc) { + auto fpscr_i32 = GetFpscr(); + auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty()); + SetFpr(frd, fpscr_i64); + + if (rc) { + // TODO: Implement this + CompilationError("MFFS."); + } +} + +void Compiler::MTFSF(u32 flm, u32 frb, bool rc) { + u32 mask = 0; + for(u32 i = 0; i < 8; i++) { + if (flm & (1 << i)) { + mask |= 0xF << (i * 4); + } + } + + auto rb_i32 = GetFpr(frb, 32, true); + auto fpscr_i32 = GetFpscr(); + fpscr_i32 = m_ir_builder->CreateAnd(fpscr_i32, ~mask); + rb_i32 = m_ir_builder->CreateAnd(rb_i32, mask); + fpscr_i32 = m_ir_builder->CreateOr(fpscr_i32, rb_i32); + SetFpscr(fpscr_i32); + + if (rc) { + // TODO: Implement this + CompilationError("MTFSF."); + } +} + +void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); + auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); + auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); + SetCr(cr_i32); + + // TODO: Set flags / Handle NaN +} + +void Compiler::FRSP(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f32 = m_ir_builder->CreateFPTrunc(rb_f64, m_ir_builder->getFloatTy()); + auto res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy()); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FRSP."); + } + + // TODO: Revisit this + // TODO: Set flags +} + +void Compiler::FCTIW(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); + auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIW."); + } + + // TODO: Set flags / Implement rounding modes +} + +void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0)); + auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty()); + auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIWZ."); + } + + // TODO: Set flags +} + +void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FDIV."); + } + + // TODO: Set flags +} + +void Compiler::FSUB(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSUB."); + } + + // TODO: Set flags +} + +void Compiler::FADD(u32 frd, u32 fra, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FADD."); + } + + // TODO: Set flags +} + +void Compiler::FSQRT(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSQRT."); + } + + // TODO: Set flags +} + +void Compiler::FSEL(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto cmp_i1 = m_ir_builder->CreateFCmpOGE(ra_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0.0)); + auto res_f64 = m_ir_builder->CreateSelect(cmp_i1, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FSEL."); + } + + // TODO: Set flags +} + +void Compiler::FMUL(u32 frd, u32 fra, u32 frc, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMUL."); + } + + // TODO: Set flags +} + +void Compiler::FRSQRTE(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::sqrt, m_ir_builder->getDoubleTy()), rb_f64); + res_f64 = m_ir_builder->CreateFDiv(ConstantFP::get(m_ir_builder->getDoubleTy(), 1.0), res_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FRSQRTE."); + } +} + +void Compiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMSUB."); + } + + // TODO: Set flags +} + +void Compiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FMADD."); + } + + // TODO: Set flags +} + +void Compiler::FNMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rc_f64 = m_ir_builder->CreateFNeg(rc_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNMSUB."); + } + + // TODO: Set flags +} + +void Compiler::FNMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto rc_f64 = GetFpr(frc); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + rc_f64 = m_ir_builder->CreateFNeg(rc_f64); + auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fmuladd, m_ir_builder->getDoubleTy()), ra_f64, rc_f64, rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNMADD."); + } + + // TODO: Set flags +} + +void Compiler::FCMPO(u32 crfd, u32 fra, u32 frb) { + auto ra_f64 = GetFpr(fra); + auto rb_f64 = GetFpr(frb); + auto lt_i1 = m_ir_builder->CreateFCmpOLT(ra_f64, rb_f64); + auto gt_i1 = m_ir_builder->CreateFCmpOGT(ra_f64, rb_f64); + auto eq_i1 = m_ir_builder->CreateFCmpOEQ(ra_f64, rb_f64); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, crfd, lt_i1, gt_i1, eq_i1, m_ir_builder->getInt1(false)); + SetCr(cr_i32); + + // TODO: Set flags / Handle NaN +} + +void Compiler::FNEG(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + rb_f64 = m_ir_builder->CreateFNeg(rb_f64); + SetFpr(frd, rb_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNEG."); + } + + // TODO: Set flags +} + +void Compiler::FMR(u32 frd, u32 frb, bool rc) { + SetFpr(frd, GetFpr(frb)); + + if (rc) { + // TODO: Implement this + CompilationError("FMR."); + } + + // TODO: Set flags +} + +void Compiler::FNABS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); + res_f64 = m_ir_builder->CreateFNeg(res_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FNABS."); + } + + // TODO: Set flags +} + +void Compiler::FABS(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto res_f64 = (Value *)m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::fabs, m_ir_builder->getDoubleTy()), rb_f64); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FABS."); + } + + // TODO: Set flags +} + +void Compiler::FCTID(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); + auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTID."); + } + + // TODO: Set flags / Implement rounding modes +} + +void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) { + auto rb_f64 = GetFpr(frb); + auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0)); + auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0)); + auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty()); + res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64); + res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64); + SetFpr(frd, res_i64); + + if (rc) { + // TODO: Implement this + CompilationError("FCTIDZ."); + } + + // TODO: Set flags +} + +void Compiler::FCFID(u32 frd, u32 frb, bool rc) { + auto rb_i64 = GetFpr(frb, 64, true); + auto res_f64 = m_ir_builder->CreateSIToFP(rb_i64, m_ir_builder->getDoubleTy()); + SetFpr(frd, res_f64); + + if (rc) { + // TODO: Implement this + CompilationError("FCFID."); + } + + // TODO: Set flags +} + +void Compiler::UNK(const u32 code, const u32 opcode, const u32 gcode) { + CompilationError(fmt::Format("Unknown/Illegal opcode! (0x%08x : 0x%x : 0x%x)", code, opcode, gcode)); +} + +std::string Compiler::GetBasicBlockNameFromAddress(u32 address, const std::string & suffix) const { + std::string name; + + if (address == 0) { + name = "entry"; + } else if (address == 0xFFFFFFFF) { + name = "default_exit"; + } else { + name = fmt::Format("instr_0x%08X", address); + } + + if (suffix != "") { + name += "_" + suffix; + } + + return name; +} + +u32 Compiler::GetAddressFromBasicBlockName(const std::string & name) const { + if (name.compare(0, 6, "instr_") == 0) { + return strtoul(name.c_str() + 6, nullptr, 0); + } else if (name == GetBasicBlockNameFromAddress(0)) { + return 0; + } else if (name == GetBasicBlockNameFromAddress(0xFFFFFFFF)) { + return 0xFFFFFFFF; + } + + return 0; +} + +BasicBlock * Compiler::GetBasicBlockFromAddress(u32 address, const std::string & suffix, bool create_if_not_exist) { + auto block_name = GetBasicBlockNameFromAddress(address, suffix); + BasicBlock * block = nullptr; + BasicBlock * next_block = nullptr; + for (auto i = m_state.function->begin(); i != m_state.function->end(); i++) { + if (i->getName() == block_name) { + block = &(*i); + break; + } + +#ifdef _DEBUG + auto block_address = GetAddressFromBasicBlockName(i->getName()); + if (block_address > address) { + next_block = &(*i); + break; + } +#endif + } + + if (!block && create_if_not_exist) { + block = BasicBlock::Create(m_ir_builder->getContext(), block_name, m_state.function, next_block); + } + + return block; +} + +Value * Compiler::GetBit(Value * val, u32 n) { + Value * bit; + +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + if (val->getType()->isIntegerTy(32)) { + bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32(1 << (31- n))); + } else if (val->getType()->isIntegerTy(64)) { + bit = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)1 << (63 - n))); + } else { +#endif + if (val->getType()->getIntegerBitWidth() != (n + 1)) { + bit = m_ir_builder->CreateLShr(val, val->getType()->getIntegerBitWidth() - n - 1); + } + + bit = m_ir_builder->CreateAnd(bit, 1); +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + } +#endif + + return bit; +} + +Value * Compiler::ClrBit(Value * val, u32 n) { + return m_ir_builder->CreateAnd(val, ~((u64)1 << (val->getType()->getIntegerBitWidth() - n - 1))); +} + +Value * Compiler::SetBit(Value * val, u32 n, Value * bit, bool doClear) { + if (doClear) { + val = ClrBit(val, n); + } + + if (bit->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { + bit = m_ir_builder->CreateZExt(bit, val->getType()); + } else if (bit->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { + bit = m_ir_builder->CreateTrunc(bit, val->getType()); + } + + if (val->getType()->getIntegerBitWidth() != (n + 1)) { + bit = m_ir_builder->CreateShl(bit, bit->getType()->getIntegerBitWidth() - n - 1); + } + + return m_ir_builder->CreateOr(val, bit); +} + +Value * Compiler::GetNibble(Value * val, u32 n) { + Value * nibble; + +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + if (val->getType()->isIntegerTy(32)) { + nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_32), val, m_ir_builder->getInt32((u64)0xF << ((7 - n) * 4))); + } else if (val->getType()->isIntegerTy(64)) { + nibble = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::x86_bmi_pext_64), val, m_ir_builder->getInt64((u64)0xF << ((15 - n) * 4))); + } else { +#endif + if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { + val = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); + } + + nibble = m_ir_builder->CreateAnd(val, 0xF); +#ifdef PPU_LLVM_RECOMPILER_USE_BMI + } +#endif + + return nibble; +} + +Value * Compiler::ClrNibble(Value * val, u32 n) { + return m_ir_builder->CreateAnd(val, ~((u64)0xF << ((((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4))); +} + +Value * Compiler::SetNibble(Value * val, u32 n, Value * nibble, bool doClear) { + if (doClear) { + val = ClrNibble(val, n); + } + + if (nibble->getType()->getIntegerBitWidth() < val->getType()->getIntegerBitWidth()) { + nibble = m_ir_builder->CreateZExt(nibble, val->getType()); + } else if (nibble->getType()->getIntegerBitWidth() > val->getType()->getIntegerBitWidth()) { + nibble = m_ir_builder->CreateTrunc(nibble, val->getType()); + } + + if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) { + nibble = m_ir_builder->CreateShl(nibble, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4); + } + + return m_ir_builder->CreateOr(val, nibble); +} + +Value * Compiler::SetNibble(Value * val, u32 n, Value * b0, Value * b1, Value * b2, Value * b3, bool doClear) { + if (doClear) { + val = ClrNibble(val, n); + } + + if (b0) { + val = SetBit(val, n * 4, b0, false); + } + + if (b1) { + val = SetBit(val, (n * 4) + 1, b1, false); + } + + if (b2) { + val = SetBit(val, (n * 4) + 2, b2, false); + } + + if (b3) { + val = SetBit(val, (n * 4) + 3, b3, false); + } + + return val; +} + +Value * Compiler::GetPc() { + auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); + auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(pc_i32_ptr, 4); +} + +void Compiler::SetPc(Value * val_ix) { + auto pc_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, PC)); + auto pc_i32_ptr = m_ir_builder->CreateBitCast(pc_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_ix, m_ir_builder->getInt32Ty()); + m_ir_builder->CreateAlignedStore(val_i32, pc_i32_ptr, 4); +} + +Value * Compiler::GetGpr(u32 r, u32 num_bits) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); + auto r_ix_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getIntNTy(num_bits)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(r_ix_ptr, 8); +} + +void Compiler::SetGpr(u32 r, Value * val_x64) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, GPR[r])); + auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + m_ir_builder->CreateAlignedStore(val_i64, r_i64_ptr, 8); +} + +Value * Compiler::GetCr() { + auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); + auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(cr_i32_ptr, 4); +} + +Value * Compiler::GetCrField(u32 n) { + return GetNibble(GetCr(), n); +} + +void Compiler::SetCr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto cr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CR)); + auto cr_i32_ptr = m_ir_builder->CreateBitCast(cr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, cr_i32_ptr, 4); +} + +void Compiler::SetCrField(u32 n, Value * field) { + SetCr(SetNibble(GetCr(), n, field)); +} + +void Compiler::SetCrField(u32 n, Value * b0, Value * b1, Value * b2, Value * b3) { + SetCr(SetNibble(GetCr(), n, b0, b1, b2, b3)); +} + +void Compiler::SetCrFieldSignedCmp(u32 n, Value * a, Value * b) { + auto lt_i1 = m_ir_builder->CreateICmpSLT(a, b); + auto gt_i1 = m_ir_builder->CreateICmpSGT(a, b); + auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); + SetCr(cr_i32); +} + +void Compiler::SetCrFieldUnsignedCmp(u32 n, Value * a, Value * b) { + auto lt_i1 = m_ir_builder->CreateICmpULT(a, b); + auto gt_i1 = m_ir_builder->CreateICmpUGT(a, b); + auto eq_i1 = m_ir_builder->CreateICmpEQ(a, b); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, n, lt_i1, gt_i1, eq_i1, GetXerSo()); + SetCr(cr_i32); +} + +void Compiler::SetCr6AfterVectorCompare(u32 vr) { + auto vr_v16i8 = GetVrAsIntVec(vr, 8); + auto vr_mask_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_pmovmskb_128), vr_v16i8); + auto cmp0_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0)); + auto cmp1_i1 = m_ir_builder->CreateICmpEQ(vr_mask_i32, m_ir_builder->getInt32(0xFFFF)); + auto cr_i32 = GetCr(); + cr_i32 = SetNibble(cr_i32, 6, cmp1_i1, nullptr, cmp0_i1, nullptr); + SetCr(cr_i32); +} + +Value * Compiler::GetLr() { + auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); + auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(lr_i64_ptr, 8); +} + +void Compiler::SetLr(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto lr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, LR)); + auto lr_i64_ptr = m_ir_builder->CreateBitCast(lr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, lr_i64_ptr, 8); +} + +Value * Compiler::GetCtr() { + auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); + auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(ctr_i64_ptr, 8); +} + +void Compiler::SetCtr(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto ctr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, CTR)); + auto ctr_i64_ptr = m_ir_builder->CreateBitCast(ctr_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, ctr_i64_ptr, 8); +} + +Value * Compiler::GetXer() { + auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); + auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(xer_i64_ptr, 8); +} + +Value * Compiler::GetXerCa() { + return GetBit(GetXer(), 34); +} + +Value * Compiler::GetXerSo() { + return GetBit(GetXer(), 32); +} + +void Compiler::SetXer(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto xer_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, XER)); + auto xer_i64_ptr = m_ir_builder->CreateBitCast(xer_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i64, xer_i64_ptr, 8); +} + +void Compiler::SetXerCa(Value * ca) { + auto xer_i64 = GetXer(); + xer_i64 = SetBit(xer_i64, 34, ca); + SetXer(xer_i64); +} + +void Compiler::SetXerSo(Value * so) { + auto xer_i64 = GetXer(); + xer_i64 = SetBit(xer_i64, 32, so); + SetXer(xer_i64); +} + +Value * Compiler::GetVrsave() { + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4); + return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty()); +} + +void Compiler::SetVrsave(Value * val_x64) { + auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); + auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty()); + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8); +} + +Value * Compiler::GetFpscr() { + auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); + auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4); +} + +void Compiler::SetFpscr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR)); + auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4); +} + +Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); + if (!as_int) { + auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); + auto r_f64 = m_ir_builder->CreateAlignedLoad(r_f64_ptr, 8); + if (bits == 32) { + return m_ir_builder->CreateFPTrunc(r_f64, m_ir_builder->getFloatTy()); + } else { + return r_f64; + } + } else { + auto r_i64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); + auto r_i64 = m_ir_builder->CreateAlignedLoad(r_i64_ptr, 8); + if (bits == 32) { + return m_ir_builder->CreateTrunc(r_i64, m_ir_builder->getInt32Ty()); + } else { + return r_i64; + } + } +} + +void Compiler::SetFpr(u32 r, Value * val) { + auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r])); + auto r_f64_ptr = m_ir_builder->CreateBitCast(r_i8_ptr, m_ir_builder->getDoubleTy()->getPointerTo()); + + Value* val_f64; + if (val->getType()->isDoubleTy() || val->getType()->isIntegerTy(64)) { + val_f64 = m_ir_builder->CreateBitCast(val, m_ir_builder->getDoubleTy()); + } else if (val->getType()->isFloatTy() || val->getType()->isIntegerTy(32)) { + auto val_f32 = m_ir_builder->CreateBitCast(val, m_ir_builder->getFloatTy()); + val_f64 = m_ir_builder->CreateFPExt(val_f32, m_ir_builder->getDoubleTy()); + } else { + assert(0); + } + + m_ir_builder->CreateAlignedStore(val_f64, r_f64_ptr, 8); +} + +Value * Compiler::GetVscr() { + auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); + auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vscr_i32_ptr, 4); +} + +void Compiler::SetVscr(Value * val_x32) { + auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty()); + auto vscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VSCR)); + auto vscr_i32_ptr = m_ir_builder->CreateBitCast(vscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, vscr_i32_ptr, 4); +} + +Value * Compiler::GetVr(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_i128_ptr, 16); +} + +Value * Compiler::GetVrAsIntVec(u32 vr, u32 vec_elt_num_bits) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_vec_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getIntNTy(vec_elt_num_bits), 128 / vec_elt_num_bits)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_vec_ptr, 16); +} + +Value * Compiler::GetVrAsFloatVec(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_v4f32_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getFloatTy(), 4)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_v4f32_ptr, 16); +} + +Value * Compiler::GetVrAsDoubleVec(u32 vr) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto vr_v2f64_ptr = m_ir_builder->CreateBitCast(vr_i128_ptr, VectorType::get(m_ir_builder->getDoubleTy(), 2)->getPointerTo()); + return m_ir_builder->CreateAlignedLoad(vr_v2f64_ptr, 16); +} + +void Compiler::SetVr(u32 vr, Value * val_x128) { + auto vr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VPR[vr])); + auto vr_i128_ptr = m_ir_builder->CreateBitCast(vr_i8_ptr, m_ir_builder->getIntNTy(128)->getPointerTo()); + auto val_i128 = m_ir_builder->CreateBitCast(val_x128, m_ir_builder->getIntNTy(128)); + m_ir_builder->CreateAlignedStore(val_i128, vr_i128_ptr, 16); +} + +Value * Compiler::CheckBranchCondition(u32 bo, u32 bi) { + bool bo0 = bo & 0x10 ? true : false; + bool bo1 = bo & 0x08 ? true : false; + bool bo2 = bo & 0x04 ? true : false; + bool bo3 = bo & 0x02 ? true : false; + + auto ctr_i64 = GetCtr(); + if (!bo2) { + ctr_i64 = m_ir_builder->CreateSub(ctr_i64, m_ir_builder->getInt64(1)); + SetCtr(ctr_i64); + } + + Value * ctr_ok_i1 = nullptr; + if (!bo2) { + // TODO: Check if we should compare all bits or just the lower 32 bits. This depends on MSR[SF]. Not sure what it is for PS3. + ctr_ok_i1 = m_ir_builder->CreateICmpNE(ctr_i64, m_ir_builder->getInt64(0)); + if (bo3) { + ctr_ok_i1 = m_ir_builder->CreateXor(ctr_ok_i1, m_ir_builder->getInt1(bo3)); + } + } + + Value * cond_ok_i1 = nullptr; + if (!bo0) { + auto cr_bi_i32 = GetBit(GetCr(), bi); + cond_ok_i1 = m_ir_builder->CreateTrunc(cr_bi_i32, m_ir_builder->getInt1Ty()); + if (!bo1) { + cond_ok_i1 = m_ir_builder->CreateXor(cond_ok_i1, m_ir_builder->getInt1(!bo1)); + } + } + + Value * cmp_i1 = nullptr; + if (ctr_ok_i1 && cond_ok_i1) { + cmp_i1 = m_ir_builder->CreateAnd(ctr_ok_i1, cond_ok_i1); + } else if (ctr_ok_i1) { + cmp_i1 = ctr_ok_i1; + } else if (cond_ok_i1) { + cmp_i1 = cond_ok_i1; + } + + return cmp_i1; +} + +void Compiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_i32, bool lk, bool target_is_lr) { + if (lk) { + SetLr(m_ir_builder->getInt64(m_state.current_instruction_address + 4)); + } + + auto current_block = m_ir_builder->GetInsertBlock(); + + BasicBlock * target_block = nullptr; + if (dyn_cast(target_i32)) { + // Target address is an immediate value. + u32 target_address = (u32)(dyn_cast(target_i32)->getLimitedValue()); + if (lk) { + // Function call + if (cmp_i1) { // There is no need to create a new block for an unconditional jump + target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); + m_ir_builder->SetInsertPoint(target_block); + } + + SetPc(target_i32); + IndirectCall(target_address, m_ir_builder->getInt64(0), true); + m_ir_builder->CreateBr(GetBasicBlockFromAddress(m_state.current_instruction_address + 4)); + } else { + // Local branch + target_block = GetBasicBlockFromAddress(target_address); + } + } else { + // Target address is in a register + if (cmp_i1) { // There is no need to create a new block for an unconditional jump + target_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "target"); + m_ir_builder->SetInsertPoint(target_block); + } + + SetPc(target_i32); + if (target_is_lr && !lk) { + // Return from this function + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + } else if (lk) { + auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); + auto unknown_function_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "unknown_function"); + + auto switch_instr = m_ir_builder->CreateSwitch(target_i32, unknown_function_block); + m_ir_builder->SetInsertPoint(unknown_function_block); + m_ir_builder->CreateCall2(m_execute_unknown_function, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt64(0)); + m_ir_builder->CreateBr(next_block); + + auto call_i = m_state.cfg->calls.find(m_state.current_instruction_address); + if (call_i != m_state.cfg->calls.end()) { + for (auto function_i = call_i->second.begin(); function_i != call_i->second.end(); function_i++) { + auto block = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("0x%08X", *function_i)); + m_ir_builder->SetInsertPoint(block); + IndirectCall(*function_i, m_ir_builder->getInt64(0), true); + m_ir_builder->CreateBr(next_block); + switch_instr->addCase(m_ir_builder->getInt32(*function_i), block); + } + } + } else { + auto switch_instr = m_ir_builder->CreateSwitch(target_i32, GetBasicBlockFromAddress(0xFFFFFFFF)); + auto branch_i = m_state.cfg->branches.find(m_state.current_instruction_address); + if (branch_i != m_state.cfg->branches.end()) { + for (auto next_instr_i = branch_i->second.begin(); next_instr_i != branch_i->second.end(); next_instr_i++) { + switch_instr->addCase(m_ir_builder->getInt32(*next_instr_i), GetBasicBlockFromAddress(*next_instr_i)); + } + } + } + } + + if (cmp_i1) { + // Conditional branch + auto next_block = GetBasicBlockFromAddress(m_state.current_instruction_address + 4); + m_ir_builder->SetInsertPoint(current_block); + m_ir_builder->CreateCondBr(cmp_i1, target_block, next_block); + } else { + // Unconditional branch + if (target_block) { + m_ir_builder->SetInsertPoint(current_block); + m_ir_builder->CreateBr(target_block); + } + } + + m_state.hit_branch_instruction = true; +} + +Value * Compiler::ReadMemory(Value * addr_i64, u32 bits, u32 alignment, bool bswap, bool could_be_mmio) { addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getIntNTy(bits)->getPointerTo()); auto val_ix = (Value *)m_ir_builder->CreateLoad(eaddr_ix_ptr, alignment); if (bits > 8 && bswap) { val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, m_ir_builder->getIntNTy(bits)), val_ix); - } + } return val_ix; -} - -void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool bswap, bool could_be_mmio) { +} + +void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool bswap, bool could_be_mmio) { if (val_ix->getType()->getIntegerBitWidth() > 8 && bswap) { val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, val_ix->getType()), val_ix); - } + } addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFF); auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr(0))); auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, val_ix->getType()->getPointerTo()); m_ir_builder->CreateAlignedStore(val_ix, eaddr_ix_ptr, alignment); -} - -template -Type * Compiler::CppToLlvmType() { - if (std::is_void::value) { - return m_ir_builder->getVoidTy(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt64Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt32Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt16Ty(); - } else if (std::is_same::value || std::is_same::value) { - return m_ir_builder->getInt8Ty(); - } else if (std::is_same::value) { - return m_ir_builder->getFloatTy(); - } else if (std::is_same::value) { - return m_ir_builder->getDoubleTy(); +} + +template +Type * Compiler::CppToLlvmType() { + if (std::is_void::value) { + return m_ir_builder->getVoidTy(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt64Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt32Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt16Ty(); + } else if (std::is_same::value || std::is_same::value) { + return m_ir_builder->getInt8Ty(); + } else if (std::is_same::value) { + return m_ir_builder->getFloatTy(); + } else if (std::is_same::value) { + return m_ir_builder->getDoubleTy(); } else if (std::is_same::value) { return m_ir_builder->getInt1Ty(); - } else if (std::is_pointer::value) { - return m_ir_builder->getInt8PtrTy(); - } else { - assert(0); - } - - return nullptr; -} - -template -Value * Compiler::Call(const char * name, Func function, Args... args) { - auto fn = m_module->getFunction(name); - if (!fn) { - std::vector fn_args_type = {args->getType()...}; - auto fn_type = FunctionType::get(CppToLlvmType(), fn_args_type, false); - fn = cast(m_module->getOrInsertFunction(name, fn_type)); - fn->setCallingConv(CallingConv::X86_64_Win64); - m_execution_engine->addGlobalMapping(fn, (void *&)function); - } - - std::vector fn_args = {args...}; - return m_ir_builder->CreateCall(fn, fn_args); -} - -llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_function) { - auto ordinal = m_recompilation_engine.AllocateOrdinal(address, is_function); - auto location_i64 = m_ir_builder->getInt64(m_recompilation_engine.GetAddressOfExecutableLookup() + (ordinal * sizeof(u64))); - auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); - auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); - auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); - return m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); -} - -void Compiler::CompilationError(const std::string & error) { - LOG_ERROR(PPU, "[0x%08X] %s", m_state.current_instruction_address, error.c_str()); - Emu.Pause(); -} - -void Compiler::InitRotateMask() { - for (u32 mb = 0; mb < 64; mb++) { - for (u32 me = 0; me < 64; me++) { - u64 mask = ((u64)-1 >> mb) ^ ((me >= 63) ? 0 : (u64)-1 >> (me + 1)); - s_rotate_mask[mb][me] = mb > me ? ~mask : mask; - } - } -} - -std::mutex RecompilationEngine::s_mutex; -std::shared_ptr RecompilationEngine::s_the_instance = nullptr; - -RecompilationEngine::RecompilationEngine() - : ThreadBase("PPU Recompilation Engine") - , m_log(nullptr) - , m_next_ordinal(0) - , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn) { - m_compiler.RunAllTests(); -} - -RecompilationEngine::~RecompilationEngine() { - Stop(); -} - -u32 RecompilationEngine::AllocateOrdinal(u32 address, bool is_function) { - std::lock_guard lock(m_address_to_ordinal_lock); - - auto i = m_address_to_ordinal.find(address); - if (i == m_address_to_ordinal.end()) { - assert(m_next_ordinal < (sizeof(m_executable_lookup) / sizeof(m_executable_lookup[0]))); - - m_executable_lookup[m_next_ordinal] = is_function ? ExecutionEngine::ExecuteFunction : ExecutionEngine::ExecuteTillReturn; - std::atomic_thread_fence(std::memory_order_release); - i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, m_next_ordinal++)); - } - - return i->second; -} - -u32 RecompilationEngine::GetOrdinal(u32 address) const { - std::lock_guard lock(m_address_to_ordinal_lock); - - auto i = m_address_to_ordinal.find(address); - if (i != m_address_to_ordinal.end()) { - return i->second; - } else { - return 0xFFFFFFFF; - } -} - -const Executable RecompilationEngine::GetExecutable(u32 ordinal) const { - std::atomic_thread_fence(std::memory_order_acquire); - return m_executable_lookup[ordinal]; -} - -u64 RecompilationEngine::GetAddressOfExecutableLookup() const { - return (u64)m_executable_lookup; -} - -void RecompilationEngine::NotifyTrace(ExecutionTrace * execution_trace) { - { - std::lock_guard lock(m_pending_execution_traces_lock); - m_pending_execution_traces.push_back(execution_trace); - } - - if (!IsAlive()) { - Start(); - } - - Notify(); - // TODO: Increase the priority of the recompilation engine thread -} - -raw_fd_ostream & RecompilationEngine::Log() { - if (!m_log) { - std::string error; - m_log = new raw_fd_ostream("PPULLVMRecompiler.log", error, sys::fs::F_Text); - m_log->SetUnbuffered(); - } - - return *m_log; -} - -void RecompilationEngine::Task() { - bool is_idling = false; - std::chrono::nanoseconds idling_time(0); - std::chrono::nanoseconds recompiling_time(0); - - auto start = std::chrono::high_resolution_clock::now(); - while (!TestDestroy() && !Emu.IsStopped()) { - bool work_done_this_iteration = false; - ExecutionTrace * execution_trace = nullptr; - - { - std::lock_guard lock(m_pending_execution_traces_lock); - - auto i = m_pending_execution_traces.begin(); - if (i != m_pending_execution_traces.end()) { - execution_trace = *i; - m_pending_execution_traces.erase(i); - } - } - - if (execution_trace) { - ProcessExecutionTrace(*execution_trace); - delete execution_trace; - work_done_this_iteration = true; - } - - if (!work_done_this_iteration) { - // TODO: Reduce the priority of the recompilation engine thread if its set to high priority - } else { - is_idling = false; - } - - if (is_idling) { - auto recompiling_start = std::chrono::high_resolution_clock::now(); - - // Recompile the function whose CFG has changed the most since the last time it was compiled - auto candidate = (BlockEntry *)nullptr; - size_t max_diff = 0; - for (auto block : m_block_table) { - if (block->IsFunction() && block->is_compiled) { - auto diff = block->cfg.GetSize() - block->last_compiled_cfg_size; - if (diff > max_diff) { - candidate = block; - max_diff = diff; - } - } - } - - if (candidate != nullptr) { - Log() << "Recompiling: " << candidate->ToString() << "\n"; - CompileBlock(*candidate); - work_done_this_iteration = true; - } - - auto recompiling_end = std::chrono::high_resolution_clock::now(); - recompiling_time += std::chrono::duration_cast(recompiling_end - recompiling_start); - } - - if (!work_done_this_iteration) { - is_idling = true; - - // Wait a few ms for something to happen - auto idling_start = std::chrono::high_resolution_clock::now(); - WaitForAnySignal(250); - auto idling_end = std::chrono::high_resolution_clock::now(); - idling_time += std::chrono::duration_cast(idling_end - idling_start); - } - } - - std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); - auto total_time = std::chrono::duration_cast(end - start); - auto compiler_stats = m_compiler.GetStats(); - - Log() << "Total time = " << total_time.count() / 1000000 << "ms\n"; - Log() << " Time spent compiling = " << compiler_stats.total_time.count() / 1000000 << "ms\n"; - Log() << " Time spent building IR = " << compiler_stats.ir_build_time.count() / 1000000 << "ms\n"; - Log() << " Time spent optimizing = " << compiler_stats.optimization_time.count() / 1000000 << "ms\n"; - Log() << " Time spent translating = " << compiler_stats.translation_time.count() / 1000000 << "ms\n"; - Log() << " Time spent recompiling = " << recompiling_time.count() / 1000000 << "ms\n"; - Log() << " Time spent idling = " << idling_time.count() / 1000000 << "ms\n"; - Log() << " Time spent doing misc tasks = " << (total_time.count() - idling_time.count() - compiler_stats.total_time.count()) / 1000000 << "ms\n"; - Log() << "Ordinals allocated = " << m_next_ordinal << "\n"; - - LOG_NOTICE(PPU, "PPU LLVM Recompilation thread exiting."); - s_the_instance = nullptr; // Can cause deadlock if this is the last instance. Need to fix this. -} - -void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution_trace) { - auto execution_trace_id = execution_trace.GetId(); - auto processed_execution_trace_i = m_processed_execution_traces.find(execution_trace_id); - if (processed_execution_trace_i == m_processed_execution_traces.end()) { -#ifdef _DEBUG - Log() << "Trace: " << execution_trace.ToString() << "\n"; -#endif - // Find the function block - BlockEntry key(execution_trace.function_address, execution_trace.function_address); - auto block_i = m_block_table.find(&key); - if (block_i == m_block_table.end()) { - block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); - } - - auto function_block = *block_i; - block_i = m_block_table.end(); - auto split_trace = false; - std::vector tmp_block_list; - for (auto trace_i = execution_trace.entries.begin(); trace_i != execution_trace.entries.end(); trace_i++) { - if (trace_i->type == ExecutionTraceEntry::Type::CompiledBlock) { - block_i = m_block_table.end(); - split_trace = true; - } - - if (block_i == m_block_table.end()) { - BlockEntry key(trace_i->GetPrimaryAddress(), execution_trace.function_address); - block_i = m_block_table.find(&key); - if (block_i == m_block_table.end()) { - block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); - } - - tmp_block_list.push_back(*block_i); - } - - const ExecutionTraceEntry * next_trace = nullptr; - if (trace_i + 1 != execution_trace.entries.end()) { - next_trace = &(*(trace_i + 1)); - } else if (!split_trace && execution_trace.type == ExecutionTrace::Type::Loop) { - next_trace = &(*(execution_trace.entries.begin())); - } - - UpdateControlFlowGraph((*block_i)->cfg, *trace_i, next_trace); - if (*block_i != function_block) { - UpdateControlFlowGraph(function_block->cfg, *trace_i, next_trace); - } - } - - processed_execution_trace_i = m_processed_execution_traces.insert(m_processed_execution_traces.end(), std::make_pair(execution_trace_id, std::move(tmp_block_list))); - } - - for (auto i = processed_execution_trace_i->second.begin(); i != processed_execution_trace_i->second.end(); i++) { - if (!(*i)->is_compiled) { - (*i)->num_hits++; - if ((*i)->num_hits >= 1000) { // TODO: Make this configurable - CompileBlock(*(*i)); - } - } - } - - std::remove_if(processed_execution_trace_i->second.begin(), processed_execution_trace_i->second.end(), [](const BlockEntry * b)->bool { return b->is_compiled; }); -} - -void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry) { - if (this_entry.type == ExecutionTraceEntry::Type::Instruction) { - cfg.instruction_addresses.insert(this_entry.GetPrimaryAddress()); - - if (next_entry) { - if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { - if (next_entry->GetPrimaryAddress() != (this_entry.GetPrimaryAddress() + 4)) { - cfg.branches[this_entry.GetPrimaryAddress()].insert(next_entry->GetPrimaryAddress()); - } - } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { - cfg.calls[this_entry.data.instruction.address].insert(next_entry->GetPrimaryAddress()); - } - } - } else if (this_entry.type == ExecutionTraceEntry::Type::CompiledBlock) { - if (next_entry) { - if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { - cfg.branches[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); - } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { - cfg.calls[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); - } - } - } -} - -void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { -#ifdef _DEBUG - Log() << "Compile: " << block_entry.ToString() << "\n"; - Log() << "CFG: " << block_entry.cfg.ToString() << "\n"; -#endif - - auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction()); - auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), block_entry.cfg, true, - block_entry.IsFunction() ? true : false /*generate_linkable_exits*/); - m_executable_lookup[ordinal] = executable; - block_entry.last_compiled_cfg_size = block_entry.cfg.GetSize(); - block_entry.is_compiled = true; -} - -std::shared_ptr RecompilationEngine::GetInstance() { - std::lock_guard lock(s_mutex); - - if (s_the_instance == nullptr) { - s_the_instance = std::shared_ptr(new RecompilationEngine()); - } - - return s_the_instance; -} - -Tracer::Tracer() - : m_recompilation_engine(RecompilationEngine::GetInstance()) { - m_stack.reserve(100); -} - -Tracer::~Tracer() { - Terminate(); -} - -void Tracer::Trace(TraceType trace_type, u32 arg1, u32 arg2) { - ExecutionTrace * execution_trace = nullptr; - - switch (trace_type) { - case TraceType::CallFunction: - // arg1 is address of the function - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::FunctionCall, arg1)); - break; - case TraceType::EnterFunction: - // arg1 is address of the function - m_stack.push_back(new ExecutionTrace(arg1)); - break; - case TraceType::ExitFromCompiledFunction: - // arg1 is address of function. - // arg2 is the address of the exit instruction. - if (arg2) { - m_stack.push_back(new ExecutionTrace(arg1)); - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); - } - break; - case TraceType::Return: - // No args used - execution_trace = m_stack.back(); - execution_trace->type = ExecutionTrace::Type::Linear; - m_stack.pop_back(); - break; - case TraceType::Instruction: - // arg1 is the address of the instruction - for (int i = (int)m_stack.back()->entries.size() - 1; i >= 0; i--) { - if ((m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::Instruction && m_stack.back()->entries[i].data.instruction.address == arg1) || - (m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::CompiledBlock && m_stack.back()->entries[i].data.compiled_block.entry_address == arg1)) { - // Found a loop - execution_trace = new ExecutionTrace(m_stack.back()->function_address); - execution_trace->type = ExecutionTrace::Type::Loop; - std::copy(m_stack.back()->entries.begin() + i, m_stack.back()->entries.end(), std::back_inserter(execution_trace->entries)); - m_stack.back()->entries.erase(m_stack.back()->entries.begin() + i + 1, m_stack.back()->entries.end()); - break; - } - } - - if (!execution_trace) { - // A loop was not found - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::Instruction, arg1)); - } - break; - case TraceType::ExitFromCompiledBlock: - // arg1 is address of the compiled block. - // arg2 is the address of the exit instruction. - m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); - - if (arg2 == 0) { - // Return from function - execution_trace = m_stack.back(); - execution_trace->type = ExecutionTrace::Type::Linear; - m_stack.pop_back(); - } - break; - default: - assert(0); - break; - } - - if (execution_trace) { - m_recompilation_engine->NotifyTrace(execution_trace); - } -} - -void Tracer::Terminate() { - // TODO: Notify recompilation engine -} - -ppu_recompiler_llvm::ExecutionEngine::ExecutionEngine(PPUThread & ppu) - : m_ppu(ppu) - , m_interpreter(new PPUInterpreter(ppu)) - , m_decoder(m_interpreter) - , m_last_cache_clear_time(std::chrono::high_resolution_clock::now()) - , m_recompilation_engine(RecompilationEngine::GetInstance()) { -} - -ppu_recompiler_llvm::ExecutionEngine::~ExecutionEngine() { + } else if (std::is_pointer::value) { + return m_ir_builder->getInt8PtrTy(); + } else { + assert(0); + } -} - -u32 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) { - ExecuteFunction(&m_ppu, 0); - return 0; -} - -void ppu_recompiler_llvm::ExecutionEngine::RemoveUnusedEntriesFromCache() const { - auto now = std::chrono::high_resolution_clock::now(); - if (std::chrono::duration_cast(now - m_last_cache_clear_time).count() > 10000) { - for (auto i = m_address_to_ordinal.begin(); i != m_address_to_ordinal.end();) { - auto tmp = i; - i++; - if (tmp->second.second == 0) { - m_address_to_ordinal.erase(tmp); - } else { - tmp->second.second = 0; - } - } - - m_last_cache_clear_time = now; - } -} - -Executable ppu_recompiler_llvm::ExecutionEngine::GetExecutable(u32 address, Executable default_executable) const { - // Find the ordinal for the specified address and insert it to the cache - auto i = m_address_to_ordinal.find(address); - if (i == m_address_to_ordinal.end()) { - auto ordinal = m_recompilation_engine->GetOrdinal(address); - if (ordinal != 0xFFFFFFFF) { - i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, std::make_pair(ordinal, 0))); - } - } - - Executable executable = default_executable; - if (i != m_address_to_ordinal.end()) { - i->second.second++; - executable = m_recompilation_engine->GetExecutable(i->second.first); - } - - RemoveUnusedEntriesFromCache(); - return executable; -} - -u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteFunction(PPUThread * ppu_state, u64 context) { - auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); - execution_engine->m_tracer.Trace(Tracer::TraceType::EnterFunction, ppu_state->PC, 0); - return ExecuteTillReturn(ppu_state, 0); -} - -u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_state, u64 context) { - auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); - auto terminate = false; - auto branch_type = BranchType::NonBranch; - - if (context) { - execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledFunction, context >> 32, context & 0xFFFFFFFF); - } - - while (!terminate && !Emu.IsStopped()) { - if (Emu.IsPaused()) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - continue; - } - - auto executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteTillReturn); - if (executable != ExecuteTillReturn && executable != ExecuteFunction) { - auto entry = ppu_state->PC; - auto exit = (u32)executable(ppu_state, 0); - execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledBlock, entry, exit); - if (exit == 0) { - terminate = true; - } - } else { - execution_engine->m_tracer.Trace(Tracer::TraceType::Instruction, ppu_state->PC, 0); - auto instruction = re32(vm::get_ref(ppu_state->PC)); - execution_engine->m_decoder.Decode(instruction); - branch_type = ppu_state->m_is_branch ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; - ppu_state->NextPc(4); - - switch (branch_type) { - case BranchType::Return: - execution_engine->m_tracer.Trace(Tracer::TraceType::Return, 0, 0); - terminate = true; - break; - case BranchType::FunctionCall: - execution_engine->m_tracer.Trace(Tracer::TraceType::CallFunction, ppu_state->PC, 0); - executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteFunction); - executable(ppu_state, 0); - break; - case BranchType::LocalBranch: - break; - case BranchType::NonBranch: - break; - default: - assert(0); - break; - } - } - } - - return 0; -} - -BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { - auto type = BranchType::NonBranch; - auto field1 = instruction >> 26; - auto lk = instruction & 1; - - if (field1 == 16 || field1 == 18) { - type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; - } else if (field1 == 19) { - u32 field2 = (instruction >> 1) & 0x3FF; - if (field2 == 16) { - type = lk ? BranchType::FunctionCall : BranchType::Return; - } else if (field2 == 528) { - type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; - } - } - - return type; -} + return nullptr; +} + +template +Value * Compiler::Call(const char * name, Func function, Args... args) { + auto fn = m_module->getFunction(name); + if (!fn) { + std::vector fn_args_type = {args->getType()...}; + auto fn_type = FunctionType::get(CppToLlvmType(), fn_args_type, false); + fn = cast(m_module->getOrInsertFunction(name, fn_type)); + fn->setCallingConv(CallingConv::X86_64_Win64); + m_execution_engine->addGlobalMapping(fn, (void *&)function); + } + + std::vector fn_args = {args...}; + return m_ir_builder->CreateCall(fn, fn_args); +} + +llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_function) { + auto ordinal = m_recompilation_engine.AllocateOrdinal(address, is_function); + auto location_i64 = m_ir_builder->getInt64(m_recompilation_engine.GetAddressOfExecutableLookup() + (ordinal * sizeof(u64))); + auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); + auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); + auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); + return m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); +} + +void Compiler::CompilationError(const std::string & error) { + LOG_ERROR(PPU, "[0x%08X] %s", m_state.current_instruction_address, error.c_str()); + Emu.Pause(); +} + +void Compiler::InitRotateMask() { + for (u32 mb = 0; mb < 64; mb++) { + for (u32 me = 0; me < 64; me++) { + u64 mask = ((u64)-1 >> mb) ^ ((me >= 63) ? 0 : (u64)-1 >> (me + 1)); + s_rotate_mask[mb][me] = mb > me ? ~mask : mask; + } + } +} + +std::mutex RecompilationEngine::s_mutex; +std::shared_ptr RecompilationEngine::s_the_instance = nullptr; + +RecompilationEngine::RecompilationEngine() + : ThreadBase("PPU Recompilation Engine") + , m_log(nullptr) + , m_next_ordinal(0) + , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn) { + m_compiler.RunAllTests(); +} + +RecompilationEngine::~RecompilationEngine() { + Stop(); +} + +u32 RecompilationEngine::AllocateOrdinal(u32 address, bool is_function) { + std::lock_guard lock(m_address_to_ordinal_lock); + + auto i = m_address_to_ordinal.find(address); + if (i == m_address_to_ordinal.end()) { + assert(m_next_ordinal < (sizeof(m_executable_lookup) / sizeof(m_executable_lookup[0]))); + + m_executable_lookup[m_next_ordinal] = is_function ? ExecutionEngine::ExecuteFunction : ExecutionEngine::ExecuteTillReturn; + std::atomic_thread_fence(std::memory_order_release); + i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, m_next_ordinal++)); + } + + return i->second; +} + +u32 RecompilationEngine::GetOrdinal(u32 address) const { + std::lock_guard lock(m_address_to_ordinal_lock); + + auto i = m_address_to_ordinal.find(address); + if (i != m_address_to_ordinal.end()) { + return i->second; + } else { + return 0xFFFFFFFF; + } +} + +const Executable RecompilationEngine::GetExecutable(u32 ordinal) const { + std::atomic_thread_fence(std::memory_order_acquire); + return m_executable_lookup[ordinal]; +} + +u64 RecompilationEngine::GetAddressOfExecutableLookup() const { + return (u64)m_executable_lookup; +} + +void RecompilationEngine::NotifyTrace(ExecutionTrace * execution_trace) { + { + std::lock_guard lock(m_pending_execution_traces_lock); + m_pending_execution_traces.push_back(execution_trace); + } + + if (!IsAlive()) { + Start(); + } + + Notify(); + // TODO: Increase the priority of the recompilation engine thread +} + +raw_fd_ostream & RecompilationEngine::Log() { + if (!m_log) { + std::string error; + m_log = new raw_fd_ostream("PPULLVMRecompiler.log", error, sys::fs::F_Text); + m_log->SetUnbuffered(); + } + + return *m_log; +} + +void RecompilationEngine::Task() { + bool is_idling = false; + std::chrono::nanoseconds idling_time(0); + std::chrono::nanoseconds recompiling_time(0); + + auto start = std::chrono::high_resolution_clock::now(); + while (!TestDestroy() && !Emu.IsStopped()) { + bool work_done_this_iteration = false; + ExecutionTrace * execution_trace = nullptr; + + { + std::lock_guard lock(m_pending_execution_traces_lock); + + auto i = m_pending_execution_traces.begin(); + if (i != m_pending_execution_traces.end()) { + execution_trace = *i; + m_pending_execution_traces.erase(i); + } + } + + if (execution_trace) { + ProcessExecutionTrace(*execution_trace); + delete execution_trace; + work_done_this_iteration = true; + } + + if (!work_done_this_iteration) { + // TODO: Reduce the priority of the recompilation engine thread if its set to high priority + } else { + is_idling = false; + } + + if (is_idling) { + auto recompiling_start = std::chrono::high_resolution_clock::now(); + + // Recompile the function whose CFG has changed the most since the last time it was compiled + auto candidate = (BlockEntry *)nullptr; + size_t max_diff = 0; + for (auto block : m_block_table) { + if (block->IsFunction() && block->is_compiled) { + auto diff = block->cfg.GetSize() - block->last_compiled_cfg_size; + if (diff > max_diff) { + candidate = block; + max_diff = diff; + } + } + } + + if (candidate != nullptr) { + Log() << "Recompiling: " << candidate->ToString() << "\n"; + CompileBlock(*candidate); + work_done_this_iteration = true; + } + + auto recompiling_end = std::chrono::high_resolution_clock::now(); + recompiling_time += std::chrono::duration_cast(recompiling_end - recompiling_start); + } + + if (!work_done_this_iteration) { + is_idling = true; + + // Wait a few ms for something to happen + auto idling_start = std::chrono::high_resolution_clock::now(); + WaitForAnySignal(250); + auto idling_end = std::chrono::high_resolution_clock::now(); + idling_time += std::chrono::duration_cast(idling_end - idling_start); + } + } + + std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); + auto total_time = std::chrono::duration_cast(end - start); + auto compiler_stats = m_compiler.GetStats(); + + Log() << "Total time = " << total_time.count() / 1000000 << "ms\n"; + Log() << " Time spent compiling = " << compiler_stats.total_time.count() / 1000000 << "ms\n"; + Log() << " Time spent building IR = " << compiler_stats.ir_build_time.count() / 1000000 << "ms\n"; + Log() << " Time spent optimizing = " << compiler_stats.optimization_time.count() / 1000000 << "ms\n"; + Log() << " Time spent translating = " << compiler_stats.translation_time.count() / 1000000 << "ms\n"; + Log() << " Time spent recompiling = " << recompiling_time.count() / 1000000 << "ms\n"; + Log() << " Time spent idling = " << idling_time.count() / 1000000 << "ms\n"; + Log() << " Time spent doing misc tasks = " << (total_time.count() - idling_time.count() - compiler_stats.total_time.count()) / 1000000 << "ms\n"; + Log() << "Ordinals allocated = " << m_next_ordinal << "\n"; + + LOG_NOTICE(PPU, "PPU LLVM Recompilation thread exiting."); + s_the_instance = nullptr; // Can cause deadlock if this is the last instance. Need to fix this. +} + +void RecompilationEngine::ProcessExecutionTrace(const ExecutionTrace & execution_trace) { + auto execution_trace_id = execution_trace.GetId(); + auto processed_execution_trace_i = m_processed_execution_traces.find(execution_trace_id); + if (processed_execution_trace_i == m_processed_execution_traces.end()) { +#ifdef _DEBUG + Log() << "Trace: " << execution_trace.ToString() << "\n"; +#endif + // Find the function block + BlockEntry key(execution_trace.function_address, execution_trace.function_address); + auto block_i = m_block_table.find(&key); + if (block_i == m_block_table.end()) { + block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); + } + + auto function_block = *block_i; + block_i = m_block_table.end(); + auto split_trace = false; + std::vector tmp_block_list; + for (auto trace_i = execution_trace.entries.begin(); trace_i != execution_trace.entries.end(); trace_i++) { + if (trace_i->type == ExecutionTraceEntry::Type::CompiledBlock) { + block_i = m_block_table.end(); + split_trace = true; + } + + if (block_i == m_block_table.end()) { + BlockEntry key(trace_i->GetPrimaryAddress(), execution_trace.function_address); + block_i = m_block_table.find(&key); + if (block_i == m_block_table.end()) { + block_i = m_block_table.insert(m_block_table.end(), new BlockEntry(key.cfg.start_address, key.cfg.function_address)); + } + + tmp_block_list.push_back(*block_i); + } + + const ExecutionTraceEntry * next_trace = nullptr; + if (trace_i + 1 != execution_trace.entries.end()) { + next_trace = &(*(trace_i + 1)); + } else if (!split_trace && execution_trace.type == ExecutionTrace::Type::Loop) { + next_trace = &(*(execution_trace.entries.begin())); + } + + UpdateControlFlowGraph((*block_i)->cfg, *trace_i, next_trace); + if (*block_i != function_block) { + UpdateControlFlowGraph(function_block->cfg, *trace_i, next_trace); + } + } + + processed_execution_trace_i = m_processed_execution_traces.insert(m_processed_execution_traces.end(), std::make_pair(execution_trace_id, std::move(tmp_block_list))); + } + + for (auto i = processed_execution_trace_i->second.begin(); i != processed_execution_trace_i->second.end(); i++) { + if (!(*i)->is_compiled) { + (*i)->num_hits++; + if ((*i)->num_hits >= 1000) { // TODO: Make this configurable + CompileBlock(*(*i)); + } + } + } + + std::remove_if(processed_execution_trace_i->second.begin(), processed_execution_trace_i->second.end(), [](const BlockEntry * b)->bool { return b->is_compiled; }); +} + +void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const ExecutionTraceEntry & this_entry, const ExecutionTraceEntry * next_entry) { + if (this_entry.type == ExecutionTraceEntry::Type::Instruction) { + cfg.instruction_addresses.insert(this_entry.GetPrimaryAddress()); + + if (next_entry) { + if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { + if (next_entry->GetPrimaryAddress() != (this_entry.GetPrimaryAddress() + 4)) { + cfg.branches[this_entry.GetPrimaryAddress()].insert(next_entry->GetPrimaryAddress()); + } + } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { + cfg.calls[this_entry.data.instruction.address].insert(next_entry->GetPrimaryAddress()); + } + } + } else if (this_entry.type == ExecutionTraceEntry::Type::CompiledBlock) { + if (next_entry) { + if (next_entry->type == ExecutionTraceEntry::Type::Instruction || next_entry->type == ExecutionTraceEntry::Type::CompiledBlock) { + cfg.branches[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); + } else if (next_entry->type == ExecutionTraceEntry::Type::FunctionCall) { + cfg.calls[this_entry.data.compiled_block.exit_address].insert(next_entry->GetPrimaryAddress()); + } + } + } +} + +void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { +#ifdef _DEBUG + Log() << "Compile: " << block_entry.ToString() << "\n"; + Log() << "CFG: " << block_entry.cfg.ToString() << "\n"; +#endif + + auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction()); + auto executable = m_compiler.Compile(fmt::Format("fn_0x%08X_%u", block_entry.cfg.start_address, block_entry.revision++), block_entry.cfg, true, + block_entry.IsFunction() ? true : false /*generate_linkable_exits*/); + m_executable_lookup[ordinal] = executable; + block_entry.last_compiled_cfg_size = block_entry.cfg.GetSize(); + block_entry.is_compiled = true; +} + +std::shared_ptr RecompilationEngine::GetInstance() { + std::lock_guard lock(s_mutex); + + if (s_the_instance == nullptr) { + s_the_instance = std::shared_ptr(new RecompilationEngine()); + } + + return s_the_instance; +} + +Tracer::Tracer() + : m_recompilation_engine(RecompilationEngine::GetInstance()) { + m_stack.reserve(100); +} + +Tracer::~Tracer() { + Terminate(); +} + +void Tracer::Trace(TraceType trace_type, u32 arg1, u32 arg2) { + ExecutionTrace * execution_trace = nullptr; + + switch (trace_type) { + case TraceType::CallFunction: + // arg1 is address of the function + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::FunctionCall, arg1)); + break; + case TraceType::EnterFunction: + // arg1 is address of the function + m_stack.push_back(new ExecutionTrace(arg1)); + break; + case TraceType::ExitFromCompiledFunction: + // arg1 is address of function. + // arg2 is the address of the exit instruction. + if (arg2) { + m_stack.push_back(new ExecutionTrace(arg1)); + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); + } + break; + case TraceType::Return: + // No args used + execution_trace = m_stack.back(); + execution_trace->type = ExecutionTrace::Type::Linear; + m_stack.pop_back(); + break; + case TraceType::Instruction: + // arg1 is the address of the instruction + for (int i = (int)m_stack.back()->entries.size() - 1; i >= 0; i--) { + if ((m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::Instruction && m_stack.back()->entries[i].data.instruction.address == arg1) || + (m_stack.back()->entries[i].type == ExecutionTraceEntry::Type::CompiledBlock && m_stack.back()->entries[i].data.compiled_block.entry_address == arg1)) { + // Found a loop + execution_trace = new ExecutionTrace(m_stack.back()->function_address); + execution_trace->type = ExecutionTrace::Type::Loop; + std::copy(m_stack.back()->entries.begin() + i, m_stack.back()->entries.end(), std::back_inserter(execution_trace->entries)); + m_stack.back()->entries.erase(m_stack.back()->entries.begin() + i + 1, m_stack.back()->entries.end()); + break; + } + } + + if (!execution_trace) { + // A loop was not found + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::Instruction, arg1)); + } + break; + case TraceType::ExitFromCompiledBlock: + // arg1 is address of the compiled block. + // arg2 is the address of the exit instruction. + m_stack.back()->entries.push_back(ExecutionTraceEntry(ExecutionTraceEntry::Type::CompiledBlock, arg1, arg2)); + + if (arg2 == 0) { + // Return from function + execution_trace = m_stack.back(); + execution_trace->type = ExecutionTrace::Type::Linear; + m_stack.pop_back(); + } + break; + default: + assert(0); + break; + } + + if (execution_trace) { + m_recompilation_engine->NotifyTrace(execution_trace); + } +} + +void Tracer::Terminate() { + // TODO: Notify recompilation engine +} + +ppu_recompiler_llvm::ExecutionEngine::ExecutionEngine(PPUThread & ppu) + : m_ppu(ppu) + , m_interpreter(new PPUInterpreter(ppu)) + , m_decoder(m_interpreter) + , m_last_cache_clear_time(std::chrono::high_resolution_clock::now()) + , m_recompilation_engine(RecompilationEngine::GetInstance()) { +} + +ppu_recompiler_llvm::ExecutionEngine::~ExecutionEngine() { + +} + +u32 ppu_recompiler_llvm::ExecutionEngine::DecodeMemory(const u32 address) { + ExecuteFunction(&m_ppu, 0); + return 0; +} + +void ppu_recompiler_llvm::ExecutionEngine::RemoveUnusedEntriesFromCache() const { + auto now = std::chrono::high_resolution_clock::now(); + if (std::chrono::duration_cast(now - m_last_cache_clear_time).count() > 10000) { + for (auto i = m_address_to_ordinal.begin(); i != m_address_to_ordinal.end();) { + auto tmp = i; + i++; + if (tmp->second.second == 0) { + m_address_to_ordinal.erase(tmp); + } else { + tmp->second.second = 0; + } + } + + m_last_cache_clear_time = now; + } +} + +Executable ppu_recompiler_llvm::ExecutionEngine::GetExecutable(u32 address, Executable default_executable) const { + // Find the ordinal for the specified address and insert it to the cache + auto i = m_address_to_ordinal.find(address); + if (i == m_address_to_ordinal.end()) { + auto ordinal = m_recompilation_engine->GetOrdinal(address); + if (ordinal != 0xFFFFFFFF) { + i = m_address_to_ordinal.insert(m_address_to_ordinal.end(), std::make_pair(address, std::make_pair(ordinal, 0))); + } + } + + Executable executable = default_executable; + if (i != m_address_to_ordinal.end()) { + i->second.second++; + executable = m_recompilation_engine->GetExecutable(i->second.first); + } + + RemoveUnusedEntriesFromCache(); + return executable; +} + +u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteFunction(PPUThread * ppu_state, u64 context) { + auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); + execution_engine->m_tracer.Trace(Tracer::TraceType::EnterFunction, ppu_state->PC, 0); + return ExecuteTillReturn(ppu_state, 0); +} + +u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_state, u64 context) { + auto execution_engine = (ExecutionEngine *)ppu_state->GetDecoder(); + auto terminate = false; + auto branch_type = BranchType::NonBranch; + + if (context) { + execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledFunction, context >> 32, context & 0xFFFFFFFF); + } + + while (!terminate && !Emu.IsStopped()) { + if (Emu.IsPaused()) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + continue; + } + + auto executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteTillReturn); + if (executable != ExecuteTillReturn && executable != ExecuteFunction) { + auto entry = ppu_state->PC; + auto exit = (u32)executable(ppu_state, 0); + execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledBlock, entry, exit); + if (exit == 0) { + terminate = true; + } + } else { + execution_engine->m_tracer.Trace(Tracer::TraceType::Instruction, ppu_state->PC, 0); + auto instruction = re32(vm::get_ref(ppu_state->PC)); + execution_engine->m_decoder.Decode(instruction); + branch_type = ppu_state->m_is_branch ? GetBranchTypeFromInstruction(instruction) : BranchType::NonBranch; + ppu_state->NextPc(4); + + switch (branch_type) { + case BranchType::Return: + execution_engine->m_tracer.Trace(Tracer::TraceType::Return, 0, 0); + terminate = true; + break; + case BranchType::FunctionCall: + execution_engine->m_tracer.Trace(Tracer::TraceType::CallFunction, ppu_state->PC, 0); + executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteFunction); + executable(ppu_state, 0); + break; + case BranchType::LocalBranch: + break; + case BranchType::NonBranch: + break; + default: + assert(0); + break; + } + } + } + + return 0; +} + +BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { + auto type = BranchType::NonBranch; + auto field1 = instruction >> 26; + auto lk = instruction & 1; + + if (field1 == 16 || field1 == 18) { + type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; + } else if (field1 == 19) { + u32 field2 = (instruction >> 1) & 0x3FF; + if (field2 == 16) { + type = lk ? BranchType::FunctionCall : BranchType::Return; + } else if (field2 == 528) { + type = lk ? BranchType::FunctionCall : BranchType::LocalBranch; + } + } + + return type; +} From 20dce26b1d91352b2154fadd1917179604b0a1c8 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 17 Feb 2015 03:08:23 +0300 Subject: [PATCH 13/25] Reservations improved --- Utilities/Thread.cpp | 351 ++++++++++++++++++++++++++++----- rpcs3/Emu/Memory/atomic_type.h | 6 + rpcs3/Emu/Memory/vm.cpp | 26 +-- rpcs3/Emu/Memory/vm.h | 2 +- 4 files changed, 313 insertions(+), 72 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index f90accc485..c5e8f28da1 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -51,7 +51,7 @@ void SetCurrentThreadDebugName(const char* threadName) enum x64_reg_t : u32 { - X64R_RAX, + X64R_RAX = 0, X64R_RCX, X64R_RDX, X64R_RBX, @@ -68,7 +68,7 @@ enum x64_reg_t : u32 X64R_R14, X64R_R15, - X64R_XMM0, + X64R_XMM0 = 0, X64R_XMM1, X64R_XMM2, X64R_XMM3, @@ -140,7 +140,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (lock) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): LOCK prefix found twice", (size_t)code - out_length); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): LOCK prefix found twice", (size_t)code - out_length); } lock = true; @@ -150,7 +150,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (repne) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", (size_t)code - out_length); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REPNE/REPNZ prefix found twice", (size_t)code - out_length); } repne = true; @@ -160,7 +160,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (repe) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", (size_t)code - out_length); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): REP/REPE/REPZ prefix found twice", (size_t)code - out_length); } repe = true; @@ -176,7 +176,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (pg2) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", (size_t)code - out_length, prefix, pg2); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): 0x%02x (group 2 prefix) found after 0x%02x", (size_t)code - out_length, prefix, pg2); } else { @@ -189,7 +189,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (oso) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): operand-size override prefix found twice", (size_t)code - out_length); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): operand-size override prefix found twice", (size_t)code - out_length); } oso = true; @@ -198,7 +198,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz case 0x67: // group 4 { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): address-size override prefix found", (size_t)code - out_length, prefix); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): address-size override prefix found", (size_t)code - out_length, prefix); out_op = X64OP_NONE; out_reg = X64_NOT_SET; out_size = 0; @@ -212,7 +212,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { if (rex) { - LOG_ERROR(GENERAL, "decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", (size_t)code - out_length, prefix, rex); + LOG_ERROR(MEMORY, "decode_x64_reg_op(%016llxh): 0x%02x (REX prefix) found after 0x%02x", (size_t)code - out_length, prefix, rex); } else { @@ -423,7 +423,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz } } - LOG_WARNING(GENERAL, "decode_x64_reg_op(%016llxh): unsupported opcode found (%016llX%016llX)", (size_t)code - out_length, *(be_t*)(code - out_length), *(be_t*)(code - out_length + 8)); + LOG_WARNING(MEMORY, "decode_x64_reg_op(%016llxh): unsupported opcode found (%016llX%016llX)", (size_t)code - out_length, *(be_t*)(code - out_length), *(be_t*)(code - out_length + 8)); out_op = X64OP_NONE; out_reg = X64_NOT_SET; out_size = 0; @@ -434,7 +434,9 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz typedef CONTEXT x64_context; -#define X64REG(context, reg) (&(&context->Rax)[reg]) +#define X64REG(context, reg) (&(&(context)->Rax)[reg]) +#define XMMREG(context, reg) (reinterpret_cast(&(&(context)->Xmm0)[reg])) +#define EFLAGS(context) ((context)->EFlags) #else @@ -443,6 +445,8 @@ typedef ucontext_t x64_context; #ifdef __APPLE__ #define X64REG(context, reg) (darwin_x64reg(context, reg)) +#define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext->__fs.__fpu_xmm0[reg])) +#define EFLAGS(context) ((context)->uc_mcontext->__ss.__eflags) uint64_t* darwin_x64reg(x64_context *context, int reg) { @@ -498,7 +502,9 @@ static const reg_table_t reg_table[17] = REG_R8, REG_R9, REG_R10, REG_R11, REG_R12, REG_R13, REG_R14, REG_R15, REG_RIP }; -#define X64REG(context, reg) (&context->uc_mcontext.gregs[reg_table[reg]]) +#define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) +#define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext.fpregs->_xmm[reg])) +#define EFLAGS(context) ((context)->uc_mcontext.eflags) #endif // __APPLE__ @@ -554,7 +560,7 @@ bool get_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, size_ return true; } - LOG_ERROR(GENERAL, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size); + LOG_ERROR(MEMORY, "get_x64_reg_value(): invalid arguments (reg=%d, d_size=%lld, i_size=%lld)", reg, d_size, i_size); return false; } @@ -563,36 +569,113 @@ bool put_x64_reg_value(x64_context* context, x64_reg_t reg, size_t d_size, u64 v // save x64 reg value (for load operations) if (reg - X64R_RAX < 16) { - // store the value into x64 register - *X64REG(context, reg - X64R_RAX) = (u32)value; - return true; + // save the value into x64 register + switch (d_size) + { + case 1: *X64REG(context, reg - X64R_RAX) = value & 0xff | *X64REG(context, reg - X64R_RAX) & 0xffffff00; return true; + case 2: *X64REG(context, reg - X64R_RAX) = value & 0xffff | *X64REG(context, reg - X64R_RAX) & 0xffff0000; return true; + case 4: *X64REG(context, reg - X64R_RAX) = value & 0xffffffff; return true; + case 8: *X64REG(context, reg - X64R_RAX) = value; return true; + } } - LOG_ERROR(GENERAL, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", reg, d_size, value); + LOG_ERROR(MEMORY, "put_x64_reg_value(): invalid destination (reg=%d, d_size=%lld, value=0x%llx)", reg, d_size, value); return false; } -void fix_x64_reg_op(x64_context* context, x64_op_t& op, x64_reg_t& reg, size_t& d_size, size_t& i_size) +bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y) +{ + switch (d_size) + { + case 1: break; + case 2: break; + case 4: break; + case 8: break; + default: LOG_ERROR(MEMORY, "set_x64_cmp_flags(): invalid d_size (%lld)", d_size); return false; + } + + const u64 sign = 1ull << (d_size * 8 - 1); // sign mask + const u64 diff = x - y; + const u64 summ = x + y; + + if (((x & y) | ((x ^ y) & ~summ)) & sign) + { + EFLAGS(context) |= 0x1; // set CF + } + else + { + EFLAGS(context) &= ~0x1; // clear CF + } + + if (x == y) + { + EFLAGS(context) |= 0x40; // set ZF + } + else + { + EFLAGS(context) &= ~0x40; // clear ZF + } + + if (diff & sign) + { + EFLAGS(context) |= 0x80; // set SF + } + else + { + EFLAGS(context) &= ~0x80; // clear SF + } + + if ((x ^ summ) & (y ^ summ) & sign) + { + EFLAGS(context) |= 0x800; // set OF + } + else + { + EFLAGS(context) &= ~0x800; // clear OF + } + + const u8 p1 = (u8)diff ^ ((u8)diff >> 4); + const u8 p2 = p1 ^ (p1 >> 2); + const u8 p3 = p2 ^ (p2 >> 1); + + if ((p3 & 1) == 0) + { + EFLAGS(context) |= 0x4; // set PF + } + else + { + EFLAGS(context) &= ~0x4; // clear PF + } + + if (((x & y) | ((x ^ y) & ~summ)) & 0x8) + { + EFLAGS(context) |= 0x10; // set AF + } + else + { + EFLAGS(context) &= ~0x10; // clear AF + } + + return true; +} + +size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, size_t d_size, size_t i_size) { if (op == X64OP_MOVS && reg != X64_NOT_SET) // get "full" access size from RCX register { u64 counter; if (!get_x64_reg_value(context, reg, 8, i_size, counter)) { - op = X64OP_NONE; - reg = X64_NOT_SET; - d_size = 0; - i_size = 0; - return; + return ~0ull; } - d_size *= counter; - reg = X64_NOT_SET; - return; + return d_size * counter; } + + return d_size; } -bool handle_access_violation(const u32 addr, bool is_writing, x64_context* context) +bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) { auto code = (const u8*)RIP(context); @@ -603,37 +686,28 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte // decode single x64 instruction that causes memory access decode_x64_reg_op(code, op, reg, d_size, i_size); - fix_x64_reg_op(context, op, reg, d_size, i_size); - if (d_size + addr >= 0x100000000ull) + if ((d_size | d_size + addr) >= 0x100000000ull) { - LOG_ERROR(GENERAL, "Invalid d_size (0x%llx)", d_size); + LOG_ERROR(MEMORY, "Invalid d_size (0x%llx)", d_size); return false; } - if (op == X64OP_CMPXCHG) - { - // detect whether this instruction can't actually modify memory to avoid breaking reservation; - // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction - u64 cmp, exch; - if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) - { - return false; - } + // get length of data being accessed + size_t a_size = get_x64_access_size(context, op, reg, d_size, i_size); - if (cmp == exch) - { - // could also be emulated without attempt to write memory - is_writing = false; - } + if ((a_size | a_size + addr) >= 0x100000000ull) + { + LOG_ERROR(MEMORY, "Invalid a_size (0x%llx)", a_size); + return false; } // check if address is RawSPU MMIO register if (addr - RAW_SPU_BASE_ADDR < (6 * RAW_SPU_OFFSET) && (addr % RAW_SPU_OFFSET) >= RAW_SPU_PROB_OFFSET) { - if (d_size != 4 || !i_size) + if (a_size != 4 || !d_size || !i_size) { - LOG_ERROR(GENERAL, "Invalid instruction (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size); + LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); return false; } @@ -662,7 +736,7 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte case X64OP_MOVS: // TODO default: { - LOG_ERROR(GENERAL, "Invalid operation (op=%d)", op); + LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size); return false; } } @@ -672,14 +746,189 @@ bool handle_access_violation(const u32 addr, bool is_writing, x64_context* conte return true; } - // check if fault is caused by reservation - if (vm::reservation_query(addr, (u32)d_size, is_writing)) + if (op == X64OP_CMPXCHG) { - return true; + // detect whether this instruction can't actually modify memory to avoid breaking reservation; + // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction + u64 cmp, exch; + if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) + { + return false; + } + + if (cmp == exch) + { + // this will skip reservation bound check + a_size = 0; + } } + // check if fault is caused by the reservation + return vm::reservation_query(addr, (u32)a_size, is_writing, [&]() -> bool + { + // write memory using "privileged" access to avoid breaking reservation + if (!d_size || !i_size) + { + LOG_ERROR(MEMORY, "Invalid or unsupported instruction (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); + return false; + } + + switch (op) + { + case X64OP_STORE: + { + if (d_size == 16) + { + if (reg - X64R_XMM0 >= 16) + { + LOG_ERROR(MEMORY, "X64OP_STORE: d_size=16, reg=%d", reg); + return false; + } + + memcpy(vm::get_priv_ptr(addr), XMMREG(context, reg - X64R_XMM0), 16); + break; + } + + if (d_size > 8) + { + LOG_ERROR(MEMORY, "X64OP_STORE: d_size=%lld", d_size); + return false; + } + + u64 reg_value; + if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value)) + { + return false; + } + + memcpy(vm::get_priv_ptr(addr), ®_value, d_size); + break; + } + case X64OP_MOVS: + { + if (d_size > 8) + { + LOG_ERROR(MEMORY, "X64OP_MOVS: d_size=%lld", d_size); + return false; + } + + if (vm::get_ptr(addr) != (void*)RDI(context)) + { + LOG_ERROR(MEMORY, "X64OP_MOVS error: rdi=0x%llx, addr=0x%x", RDI(context), addr); + return false; + } + + u32 a_addr = addr; + + while (a_addr >> 12 == addr >> 12) + { + u64 value; + + // copy data + memcpy(&value, (void*)RSI(context), d_size); + memcpy(vm::get_priv_ptr(a_addr), &value, d_size); + + // shift pointers + if (EFLAGS(context) & 0x400 /* direction flag */) + { + // for reversed direction, addr argument should be calculated in different way + LOG_ERROR(MEMORY, "X64OP_MOVS TODO: reversed direction"); + return false; + //RSI(context) -= d_size; + //RDI(context) -= d_size; + //a_addr -= (u32)d_size; + } + else + { + RSI(context) += d_size; + RDI(context) += d_size; + a_addr += (u32)d_size; + } + + // decrement counter + if (reg == X64_NOT_SET || !--RCX(context)) + { + break; + } + } + + if (reg == X64_NOT_SET || !RCX(context)) + { + break; + } + + // don't skip partially processed instruction + return true; + } + case X64OP_XCHG: + { + if (d_size != 1 && d_size != 2 && d_size != 4 && d_size != 8) + { + LOG_ERROR(MEMORY, "X64OP_XCHG: d_size=%lld", d_size); + return false; + } + + u64 reg_value; + if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value)) + { + return false; + } + + switch (d_size) + { + case 1: reg_value = vm::get_priv_ref>(addr).exchange((u8)reg_value); break; + case 2: reg_value = vm::get_priv_ref>(addr).exchange((u16)reg_value); break; + case 4: reg_value = vm::get_priv_ref>(addr).exchange((u32)reg_value); break; + case 8: reg_value = vm::get_priv_ref>(addr).exchange((u64)reg_value); break; + } + + if (!put_x64_reg_value(context, reg, d_size, reg_value)) + { + return false; + } + break; + } + case X64OP_CMPXCHG: + { + if (d_size != 1 && d_size != 2 && d_size != 4 && d_size != 8) + { + LOG_ERROR(MEMORY, "X64OP_CMPXCHG: d_size=%lld", d_size); + return false; + } + + u64 reg_value, old_value, cmp_value; + if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, cmp_value)) + { + return false; + } + + switch (d_size) + { + case 1: old_value = vm::get_priv_ref>(addr).compare_and_swap((u8)cmp_value, (u8)reg_value); break; + case 2: old_value = vm::get_priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; + case 4: old_value = vm::get_priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; + case 8: old_value = vm::get_priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; + } + + if (!put_x64_reg_value(context, X64R_RAX, d_size, old_value) || !set_x64_cmp_flags(context, d_size, cmp_value, old_value)) + { + return false; + } + break; + } + default: + { + LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, a_size=0x%llx, i_size=%lld)", op, reg, d_size, a_size, i_size); + return false; + } + } + + // skip processed instruction + RIP(context) += i_size; + return true; + }); + // TODO: allow recovering from a page fault as a feature of PS3 virtual memory - return false; } #ifdef _WIN32 diff --git a/rpcs3/Emu/Memory/atomic_type.h b/rpcs3/Emu/Memory/atomic_type.h index 7309f9cd2b..24ad05a7f7 100644 --- a/rpcs3/Emu/Memory/atomic_type.h +++ b/rpcs3/Emu/Memory/atomic_type.h @@ -1,5 +1,11 @@ #pragma once +#undef InterlockedExchange +#undef InterlockedCompareExchange +#undef InterlockedOr +#undef InterlockedAnd +#undef InterlockedXor + template struct _to_atomic { diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 8f50f1169a..a69272b117 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -271,7 +271,7 @@ namespace vm return true; } - bool reservation_query(u32 addr, u32 size, bool is_writing) + bool reservation_query(u32 addr, u32 size, bool is_writing, std::function callback) { std::lock_guard lock(g_reservation_mutex); @@ -280,31 +280,17 @@ namespace vm return false; } - if (is_writing) + // check if current reservation and address may overlap + if (g_reservation_addr >> 12 == addr >> 12 && is_writing) { - assert(size); - - if (addr + size - 1 >= g_reservation_addr && g_reservation_addr + g_reservation_size - 1 >= addr) + if (size && addr + size - 1 >= g_reservation_addr && g_reservation_addr + g_reservation_size - 1 >= addr) { - // break the reservation if writing access and reservation overlap + // break the reservation if overlap _reservation_break(addr); } else { - // full-size check (isn't accurate enough) - if (!check_addr(addr, size)) - { - return false; - } - - // assume that the same memory page is accessed (isn't accurate enough) - if (g_reservation_addr >> 12 != addr >> 12) - { - return false; - } - - // write memory using "privileged" access to avoid breaking reservation - return false; + return callback(); //? true : _reservation_break(addr), true; } } diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index e21d484be4..035aa2ff50 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -39,7 +39,7 @@ namespace vm // attempt to atomically update reserved memory bool reservation_update(u32 addr, const void* data, u32 size); // for internal use - bool reservation_query(u32 addr, u32 size, bool is_writing); + bool reservation_query(u32 addr, u32 size, bool is_writing, std::function callback); // for internal use void reservation_free(); // perform complete operation From bddad4d76683270fde88e5f189776caef33f9ebc Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 17 Feb 2015 03:40:10 +0300 Subject: [PATCH 14/25] Compilation fix --- Utilities/Thread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index c5e8f28da1..e3faa972c5 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -504,7 +504,7 @@ static const reg_table_t reg_table[17] = #define X64REG(context, reg) (&(context)->uc_mcontext.gregs[reg_table[reg]]) #define XMMREG(context, reg) (reinterpret_cast(&(context)->uc_mcontext.fpregs->_xmm[reg])) -#define EFLAGS(context) ((context)->uc_mcontext.eflags) +#define EFLAGS(context) ((context)->uc_mcontext.gregs[REG_EFL]) #endif // __APPLE__ @@ -814,7 +814,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) if (vm::get_ptr(addr) != (void*)RDI(context)) { - LOG_ERROR(MEMORY, "X64OP_MOVS error: rdi=0x%llx, addr=0x%x", RDI(context), addr); + LOG_ERROR(MEMORY, "X64OP_MOVS error: rdi=0x%llx, addr=0x%x", (u64)RDI(context), addr); return false; } From 3f3873ceb5bd7ab3e1af0d53b12b3398d5577173 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 17 Feb 2015 05:01:47 +0300 Subject: [PATCH 15/25] STOS support (for memset) --- Utilities/Thread.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index e3faa972c5..d9639ee00f 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -111,6 +111,7 @@ enum x64_op_t : u32 // example: add [rax],eax -> X64OP_LOAD_ADD_STORE (this will probably never happen for MMIO registers) X64OP_MOVS, + X64OP_STOS, X64OP_XCHG, X64OP_CMPXCHG, }; @@ -397,6 +398,24 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz } break; } + case 0xaa: + { + if (!oso && !lock && !repe && !rex) // STOS + { + out_op = X64OP_STOS; + out_reg = X64_NOT_SET; + out_size = 1; + return; + } + if (!oso && !lock && repe) // REP STOS + { + out_op = X64OP_STOS; + out_reg = rex & 8 ? X64R_RCX : X64R_ECX; + out_size = 1; + return; + } + break; + } case 0xc6: { if (!lock && !oso && get_modRM_reg(code, 0) == X64R_RAX) // MOV r8/m8, imm8 @@ -661,7 +680,7 @@ bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y) size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, size_t d_size, size_t i_size) { - if (op == X64OP_MOVS && reg != X64_NOT_SET) // get "full" access size from RCX register + if ((op == X64OP_MOVS || op == X64OP_STOS) && reg != X64_NOT_SET) // get "full" access size from RCX register { u64 counter; if (!get_x64_reg_value(context, reg, 8, i_size, counter)) @@ -733,7 +752,8 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) break; } - case X64OP_MOVS: // TODO + case X64OP_MOVS: // possibly, TODO + case X64OP_STOS: default: { LOG_ERROR(MEMORY, "Invalid or unsupported operation (op=%d, reg=%d, d_size=%lld, i_size=%lld)", op, reg, d_size, i_size); @@ -860,6 +880,63 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) // don't skip partially processed instruction return true; } + case X64OP_STOS: + { + if (d_size > 8) + { + LOG_ERROR(MEMORY, "X64OP_STOS: d_size=%lld", d_size); + return false; + } + + if (vm::get_ptr(addr) != (void*)RDI(context)) + { + LOG_ERROR(MEMORY, "X64OP_STOS error: rdi=0x%llx, addr=0x%x", (u64)RDI(context), addr); + return false; + } + + u64 value; + if (!get_x64_reg_value(context, X64R_RAX, d_size, i_size, value)) + { + return false; + } + + u32 a_addr = addr; + + while (a_addr >> 12 == addr >> 12) + { + // fill data with value + memcpy(vm::get_priv_ptr(a_addr), &value, d_size); + + // shift pointers + if (EFLAGS(context) & 0x400 /* direction flag */) + { + // for reversed direction, addr argument should be calculated in different way + LOG_ERROR(MEMORY, "X64OP_STOS TODO: reversed direction"); + return false; + //RDI(context) -= d_size; + //a_addr -= (u32)d_size; + } + else + { + RDI(context) += d_size; + a_addr += (u32)d_size; + } + + // decrement counter + if (reg == X64_NOT_SET || !--RCX(context)) + { + break; + } + } + + if (reg == X64_NOT_SET || !RCX(context)) + { + break; + } + + // don't skip partially processed instruction + return true; + } case X64OP_XCHG: { if (d_size != 1 && d_size != 2 && d_size != 4 && d_size != 8) From 1f2eafc4f255c3adb656f9e0dc7c4218e205c449 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 17 Feb 2015 18:27:15 +0300 Subject: [PATCH 16/25] Loader fixed --- Utilities/Thread.cpp | 79 ++++++++++++++------------------ rpcs3/Emu/Cell/PPUThread.cpp | 2 +- rpcs3/Emu/System.h | 7 --- rpcs3/Loader/ELF32.cpp | 12 +++-- rpcs3/Loader/ELF64.cpp | 89 ++++++++++++++++++++++++------------ rpcs3/Loader/ELF64.h | 1 + rpcs3/Loader/Loader.cpp | 4 +- 7 files changed, 107 insertions(+), 87 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index d9639ee00f..f78fc150a7 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -680,15 +680,41 @@ bool set_x64_cmp_flags(x64_context* context, size_t d_size, u64 x, u64 y) size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, size_t d_size, size_t i_size) { - if ((op == X64OP_MOVS || op == X64OP_STOS) && reg != X64_NOT_SET) // get "full" access size from RCX register + if (op == X64OP_MOVS || op == X64OP_STOS) { - u64 counter; - if (!get_x64_reg_value(context, reg, 8, i_size, counter)) + if (EFLAGS(context) & 0x400 /* direction flag */) { - return ~0ull; + // skip reservation bound check (TODO) + return 0; } - return d_size * counter; + if (reg != X64_NOT_SET) // get "full" access size from RCX register + { + u64 counter; + if (!get_x64_reg_value(context, reg, 8, i_size, counter)) + { + return -1; + } + + return d_size * counter; + } + } + + if (op == X64OP_CMPXCHG) + { + // detect whether this instruction can't actually modify memory to avoid breaking reservation; + // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction + u64 cmp, exch; + if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) + { + return -1; + } + + if (cmp == exch) + { + // skip reservation bound check + return 0; + } } return d_size; @@ -766,23 +792,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) return true; } - if (op == X64OP_CMPXCHG) - { - // detect whether this instruction can't actually modify memory to avoid breaking reservation; - // this may theoretically cause endless loop, but it shouldn't be a problem if only read_sync() generates such instruction - u64 cmp, exch; - if (!get_x64_reg_value(context, reg, d_size, i_size, cmp) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, exch)) - { - return false; - } - - if (cmp == exch) - { - // this will skip reservation bound check - a_size = 0; - } - } - // check if fault is caused by the reservation return vm::reservation_query(addr, (u32)a_size, is_writing, [&]() -> bool { @@ -809,12 +818,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) break; } - if (d_size > 8) - { - LOG_ERROR(MEMORY, "X64OP_STORE: d_size=%lld", d_size); - return false; - } - u64 reg_value; if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value)) { @@ -834,7 +837,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) if (vm::get_ptr(addr) != (void*)RDI(context)) { - LOG_ERROR(MEMORY, "X64OP_MOVS error: rdi=0x%llx, addr=0x%x", (u64)RDI(context), addr); + LOG_ERROR(MEMORY, "X64OP_MOVS: rdi=0x%llx, rsi=0x%llx, addr=0x%x", (u64)RDI(context), (u64)RSI(context), addr); return false; } @@ -851,7 +854,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) // shift pointers if (EFLAGS(context) & 0x400 /* direction flag */) { - // for reversed direction, addr argument should be calculated in different way LOG_ERROR(MEMORY, "X64OP_MOVS TODO: reversed direction"); return false; //RSI(context) -= d_size; @@ -890,7 +892,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) if (vm::get_ptr(addr) != (void*)RDI(context)) { - LOG_ERROR(MEMORY, "X64OP_STOS error: rdi=0x%llx, addr=0x%x", (u64)RDI(context), addr); + LOG_ERROR(MEMORY, "X64OP_STOS: rdi=0x%llx, addr=0x%x", (u64)RDI(context), addr); return false; } @@ -910,7 +912,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) // shift pointers if (EFLAGS(context) & 0x400 /* direction flag */) { - // for reversed direction, addr argument should be calculated in different way LOG_ERROR(MEMORY, "X64OP_STOS TODO: reversed direction"); return false; //RDI(context) -= d_size; @@ -939,12 +940,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) } case X64OP_XCHG: { - if (d_size != 1 && d_size != 2 && d_size != 4 && d_size != 8) - { - LOG_ERROR(MEMORY, "X64OP_XCHG: d_size=%lld", d_size); - return false; - } - u64 reg_value; if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value)) { @@ -957,6 +952,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) case 2: reg_value = vm::get_priv_ref>(addr).exchange((u16)reg_value); break; case 4: reg_value = vm::get_priv_ref>(addr).exchange((u32)reg_value); break; case 8: reg_value = vm::get_priv_ref>(addr).exchange((u64)reg_value); break; + default: return false; } if (!put_x64_reg_value(context, reg, d_size, reg_value)) @@ -967,12 +963,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) } case X64OP_CMPXCHG: { - if (d_size != 1 && d_size != 2 && d_size != 4 && d_size != 8) - { - LOG_ERROR(MEMORY, "X64OP_CMPXCHG: d_size=%lld", d_size); - return false; - } - u64 reg_value, old_value, cmp_value; if (!get_x64_reg_value(context, reg, d_size, i_size, reg_value) || !get_x64_reg_value(context, X64R_RAX, d_size, i_size, cmp_value)) { @@ -985,6 +975,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) case 2: old_value = vm::get_priv_ref>(addr).compare_and_swap((u16)cmp_value, (u16)reg_value); break; case 4: old_value = vm::get_priv_ref>(addr).compare_and_swap((u32)cmp_value, (u32)reg_value); break; case 8: old_value = vm::get_priv_ref>(addr).compare_and_swap((u64)cmp_value, (u64)reg_value); break; + default: return false; } if (!put_x64_reg_value(context, X64R_RAX, d_size, old_value) || !set_x64_cmp_flags(context, d_size, cmp_value, old_value)) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 63ccda64d6..08d0f15815 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -73,7 +73,7 @@ void PPUThread::InitRegs() //GPR[12] = Emu.GetMallocPageSize(); GPR[13] = ppu_get_tls(GetId()) + 0x7000; // 0x7000 is usually subtracted from r13 to access first TLS element (details are not clear) - LR = Emu.GetCPUThreadExit(); + LR = 0; CTR = PC; CR.CR = 0x22000082; VSCR.NJ = 1; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index d9615e2613..a5a94f0ea9 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -83,7 +83,6 @@ class Emulator uint m_mode; u32 m_rsx_callback; - u32 m_cpu_thr_exit; u32 m_cpu_thr_stop; std::vector> m_modules_init; @@ -183,11 +182,6 @@ public: m_rsx_callback = addr; } - void SetCPUThreadExit(u32 addr) - { - m_cpu_thr_exit = addr; - } - void SetCPUThreadStop(u32 addr) { m_cpu_thr_stop = addr; @@ -202,7 +196,6 @@ public: u32 GetMallocPageSize() { return m_info.GetProcParam().malloc_pagesize; } u32 GetRSXCallback() const { return m_rsx_callback; } - u32 GetCPUThreadExit() const { return m_cpu_thr_exit; } u32 GetCPUThreadStop() const { return m_cpu_thr_stop; } void CheckStatus(); diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 4eef027421..a118451126 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -19,10 +19,16 @@ namespace loader { handler::error_code elf32::init(vfsStream& stream) { + m_ehdr = {}; + m_phdrs.clear(); + m_shdrs.clear(); + error_code res = handler::init(stream); if (res != ok) + { return res; + } m_stream->Read(&m_ehdr, sizeof(ehdr)); @@ -52,8 +58,6 @@ namespace loader if (m_stream->Read(m_phdrs.data(), size) != size) return broken_file; } - else - m_phdrs.clear(); if (m_ehdr.data_le.e_shnum) { @@ -64,8 +68,6 @@ namespace loader if (m_stream->Read(m_shdrs.data(), size) != size) return broken_file; } - else - m_shdrs.clear(); return ok; } @@ -133,7 +135,7 @@ namespace loader auto armv7_thr_stop_data = vm::psv::ptr::make(Memory.PSV.RAM.AllocAlign(3 * 4)); armv7_thr_stop_data[0] = 0xf870; // HACK instruction (Thumb) armv7_thr_stop_data[1] = 0x0001; // index 1 - Emu.SetCPUThreadExit(armv7_thr_stop_data.addr()); + Emu.SetCPUThreadStop(armv7_thr_stop_data.addr()); u32 entry = 0; // actual entry point (ELFs entry point is ignored) u32 fnid_addr = 0; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index a83883484c..c4076fca07 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -23,10 +23,23 @@ namespace loader { handler::error_code elf64::init(vfsStream& stream) { + m_ehdr = {}; + m_sprx_module_info = {}; + m_sprx_function_info = {}; + + m_phdrs.clear(); + m_shdrs.clear(); + + m_sprx_segments_info.clear(); + m_sprx_import_info.clear(); + m_sprx_export_info.clear(); + error_code res = handler::init(stream); if (res != ok) + { return res; + } m_stream->Read(&m_ehdr, sizeof(ehdr)); @@ -58,8 +71,6 @@ namespace loader if (m_stream->Read(m_phdrs.data(), m_ehdr.e_phnum * sizeof(phdr)) != m_ehdr.e_phnum * sizeof(phdr)) return broken_file; } - else - m_phdrs.clear(); if (m_ehdr.e_shnum) { @@ -68,8 +79,6 @@ namespace loader if (m_stream->Read(m_shdrs.data(), m_ehdr.e_shnum * sizeof(shdr)) != m_ehdr.e_shnum * sizeof(shdr)) return broken_file; } - else - m_shdrs.clear(); if (is_sprx()) { @@ -79,11 +88,6 @@ namespace loader //m_stream->Seek(handler::get_stream_offset() + m_phdrs[1].p_vaddr.addr()); //m_stream->Read(&m_sprx_function_info, sizeof(sprx_function_info)); } - else - { - m_sprx_import_info.clear(); - m_sprx_export_info.clear(); - } return ok; } @@ -95,6 +99,7 @@ namespace loader switch ((u32)phdr.p_type) { case 0x1: //load + { if (phdr.p_memsz) { sprx_segment_info segment; @@ -186,8 +191,10 @@ namespace loader } break; + } case 0x700000a4: //relocation + { m_stream->Seek(handler::get_stream_offset() + phdr.p_offset); for (uint i = 0; i < phdr.p_filesz; i += sizeof(sys_prx_relocation_info_t)) @@ -227,6 +234,7 @@ namespace loader break; } + } } for (auto &m : info.modules) @@ -264,6 +272,12 @@ namespace loader //store elf to memory vm::ps3::init(); + error_code res = alloc_memory(0); + if (res != ok) + { + return res; + } + std::vector start_funcs; std::vector stop_funcs; @@ -273,6 +287,7 @@ namespace loader for (const auto module : lle_dir) { elf64 sprx_handler; + vfsFile fsprx(lle_dir.GetPath() + "/" + module->name); if (fsprx.IsOpened()) @@ -286,12 +301,12 @@ namespace loader if (!load_lib.LoadValue(false)) { - LOG_ERROR(LOADER, "skipped lle library '%s'", sprx_handler.sprx_get_module_name().c_str()); + LOG_WARNING(LOADER, "Skipped LLE library '%s'", sprx_handler.sprx_get_module_name().c_str()); continue; } else { - LOG_WARNING(LOADER, "loading lle library '%s'", sprx_handler.sprx_get_module_name().c_str()); + LOG_WARNING(LOADER, "Loading LLE library '%s'", sprx_handler.sprx_get_module_name().c_str()); } sprx_info info; @@ -332,7 +347,7 @@ namespace loader } } - error_code res = load_data(0); + res = load_data(0); if (res != ok) return res; @@ -345,18 +360,11 @@ namespace loader rsx_callback_data[1] = SC(0); rsx_callback_data[2] = BLR(); - auto ppu_thr_exit_data = vm::ptr::make(Memory.MainMem.AllocAlign(3 * 4)); - ppu_thr_exit_data[0] = ADDI(r11, 0, 41); - ppu_thr_exit_data[1] = SC(0); - ppu_thr_exit_data[2] = BLR(); - Emu.SetCPUThreadExit(ppu_thr_exit_data.addr()); - auto ppu_thr_stop_data = vm::ptr::make(Memory.MainMem.AllocAlign(2 * 4)); ppu_thr_stop_data[0] = SC(3); ppu_thr_stop_data[1] = BLR(); Emu.SetCPUThreadStop(ppu_thr_stop_data.addr()); - //vm::write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE); /* //TODO static const int branch_size = 6 * 4; @@ -395,6 +403,31 @@ namespace loader return ok; } + handler::error_code elf64::alloc_memory(u64 offset) + { + for (auto &phdr : m_phdrs) + { + switch (phdr.p_type.value()) + { + case 0x00000001: //LOAD + { + if (phdr.p_memsz) + { + if (!vm::alloc(vm::cast(phdr.p_vaddr.addr()), vm::cast(phdr.p_memsz, "phdr.p_memsz"), vm::main)) + { + LOG_ERROR(LOADER, "%s(): AllocFixed(0x%llx, 0x%llx) failed", __FUNCTION__, phdr.p_vaddr.addr(), phdr.p_memsz); + + return loading_error; + } + } + break; + } + } + } + + return ok; + } + handler::error_code elf64::load_data(u64 offset) { for (auto &phdr : m_phdrs) @@ -402,16 +435,9 @@ namespace loader switch (phdr.p_type.value()) { case 0x00000001: //LOAD + { if (phdr.p_memsz) { - if (!vm::alloc(phdr.p_vaddr.addr(), (u32)phdr.p_memsz, vm::main)) - { - // addr() has be_t<> type (test) - LOG_ERROR(LOADER, "%s(): AllocFixed(0x%llx, 0x%x) failed", __FUNCTION__, phdr.p_vaddr.addr(), (u32)phdr.p_memsz); - - return loading_error; - } - if (phdr.p_filesz) { m_stream->Seek(handler::get_stream_offset() + phdr.p_offset); @@ -420,15 +446,19 @@ namespace loader } } break; + } case 0x00000007: //TLS + { Emu.SetTLSData( vm::cast(phdr.p_vaddr.addr(), "TLS: phdr.p_vaddr"), vm::cast(phdr.p_filesz.value(), "TLS: phdr.p_filesz"), vm::cast(phdr.p_memsz.value(), "TLS: phdr.p_memsz")); break; + } case 0x60000001: //LOOS+1 + { if (phdr.p_filesz) { const sys_process_param& proc_param = *(sys_process_param*)phdr.p_vaddr.get_ptr(); @@ -458,8 +488,10 @@ namespace loader } } break; + } case 0x60000002: //LOOS+2 + { if (phdr.p_filesz) { const sys_proc_prx_param& proc_prx_param = *(sys_proc_prx_param*)phdr.p_vaddr.get_ptr(); @@ -492,7 +524,7 @@ namespace loader struct stub_data_t { be_t data[3]; - } + } static const stub_data = { be_t::make(MR(11, 2)), @@ -537,6 +569,7 @@ namespace loader } break; } + } } return ok; diff --git a/rpcs3/Loader/ELF64.h b/rpcs3/Loader/ELF64.h index a3acc0475e..74d8bdfb02 100644 --- a/rpcs3/Loader/ELF64.h +++ b/rpcs3/Loader/ELF64.h @@ -156,6 +156,7 @@ namespace loader error_code init(vfsStream& stream) override; error_code load() override; + error_code alloc_memory(u64 offset); error_code load_data(u64 offset); error_code load_sprx(sprx_info& info); bool is_sprx() const { return m_ehdr.e_type == 0xffa4; } diff --git a/rpcs3/Loader/Loader.cpp b/rpcs3/Loader/Loader.cpp index 47ef19c595..c34e9112bc 100644 --- a/rpcs3/Loader/Loader.cpp +++ b/rpcs3/Loader/Loader.cpp @@ -19,11 +19,11 @@ namespace loader return true; } - LOG_ERROR(LOADER, "loader::load() failed: %s", i->get_error_code().c_str()); + LOG_NOTICE(LOADER, "loader::load() failed: %s", i->get_error_code().c_str()); } else { - LOG_ERROR(LOADER, "loader::init() failed: %s", i->get_error_code().c_str()); + LOG_NOTICE(LOADER, "loader::init() failed: %s", i->get_error_code().c_str()); stream.Seek(i->get_stream_offset()); } } From af986d8f4cd14c903bc7c677c7083d27d274f520 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 18 Feb 2015 19:22:06 +0300 Subject: [PATCH 17/25] Loader improved, ModuleManager refactored --- Utilities/Thread.cpp | 14 +- Utilities/Thread.h | 3 +- rpcs3/Emu/ARMv7/PSVFuncList.cpp | 47 +- rpcs3/Emu/ARMv7/PSVFuncList.h | 2 +- rpcs3/Emu/CPU/CPUThread.cpp | 205 +++---- rpcs3/Emu/CPU/CPUThread.h | 2 + rpcs3/Emu/Cell/PPCDecoder.h | 2 +- rpcs3/Emu/Cell/PPCInstrTable.h | 1 - rpcs3/Emu/Cell/PPUDisAsm.h | 4 + rpcs3/Emu/Cell/PPUInstrTable.h | 3 + rpcs3/Emu/Cell/PPUInterpreter.h | 4 + rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 4 + rpcs3/Emu/Cell/PPULLVMRecompiler.h | 1 + rpcs3/Emu/Cell/PPUOpcodes.h | 2 + rpcs3/Emu/SysCalls/ModuleManager.cpp | 523 ++++++---------- rpcs3/Emu/SysCalls/ModuleManager.h | 21 +- rpcs3/Emu/SysCalls/Modules.cpp | 230 +++++--- rpcs3/Emu/SysCalls/Modules.h | 78 +-- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 70 ++- rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp | 100 ++-- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 95 ++- rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp | 10 +- rpcs3/Emu/SysCalls/Modules/cellCamera.cpp | 84 ++- rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 128 ++-- rpcs3/Emu/SysCalls/Modules/cellFiber.cpp | 104 ++-- rpcs3/Emu/SysCalls/Modules/cellFont.cpp | 183 +++--- rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp | 29 +- rpcs3/Emu/SysCalls/Modules/cellGame.cpp | 102 ++-- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 434 +++++++------- rpcs3/Emu/SysCalls/Modules/cellGem.cpp | 99 ++-- rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp | 54 +- rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp | 56 +- rpcs3/Emu/SysCalls/Modules/cellKb.cpp | 40 +- rpcs3/Emu/SysCalls/Modules/cellL10n.cpp | 346 ++++++----- rpcs3/Emu/SysCalls/Modules/cellMic.cpp | 96 ++- rpcs3/Emu/SysCalls/Modules/cellMouse.cpp | 36 +- rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp | 18 +- rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp | 55 +- rpcs3/Emu/SysCalls/Modules/cellOvis.cpp | 18 +- rpcs3/Emu/SysCalls/Modules/cellPad.cpp | 62 +- rpcs3/Emu/SysCalls/Modules/cellPamf.cpp | 135 +++-- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 100 ++-- rpcs3/Emu/SysCalls/Modules/cellResc.cpp | 169 +++--- rpcs3/Emu/SysCalls/Modules/cellRtc.cpp | 140 +++-- rpcs3/Emu/SysCalls/Modules/cellSail.cpp | 301 +++++----- rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp | 88 +-- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 278 +++++---- rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp | 132 ++--- rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp | 30 +- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 186 +++--- rpcs3/Emu/SysCalls/Modules/cellSync2.cpp | 152 +++-- rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp | 107 ++-- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 231 ++++---- rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp | 16 +- rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp | 22 +- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 96 ++- rpcs3/Emu/SysCalls/Modules/cellVpost.cpp | 48 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 92 ++- rpcs3/Emu/SysCalls/Modules/sceNp.cpp | 556 +++++++++--------- rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp | 92 ++- rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp | 106 ++-- rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp | 8 +- rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp | 72 ++- rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp | 120 ++-- rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp | 203 ++++--- rpcs3/Emu/SysCalls/Modules/sys_io.cpp | 8 +- rpcs3/Emu/SysCalls/Modules/sys_net.cpp | 160 +++-- rpcs3/Emu/SysCalls/SysCalls.cpp | 9 +- rpcs3/Emu/SysCalls/lv2/cellFs.cpp | 303 +++++----- rpcs3/Emu/System.cpp | 6 +- rpcs3/Loader/ELF64.cpp | 190 ++++-- 72 files changed, 3684 insertions(+), 3839 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index f78fc150a7..a47f656695 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1182,11 +1182,15 @@ void ThreadBase::Start() } catch (const char* e) { - LOG_ERROR(GENERAL, "%s: %s", GetThreadName().c_str(), e); + LOG_ERROR(GENERAL, "Exception: %s", e); + DumpInformation(); + Emu.Pause(); } catch (const std::string& e) { - LOG_ERROR(GENERAL, "%s: %s", GetThreadName().c_str(), e.c_str()); + LOG_ERROR(GENERAL, "Exception: %s", e); + DumpInformation(); + Emu.Pause(); } m_alive = false; @@ -1325,11 +1329,13 @@ void thread_t::start(std::function func) } catch (const char* e) { - LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e); + LOG_ERROR(GENERAL, "Exception: %s", e); + Emu.Pause(); } catch (const std::string& e) { - LOG_ERROR(GENERAL, "%s: %s", name.c_str(), e.c_str()); + LOG_ERROR(GENERAL, "Exception: %s", e.c_str()); + Emu.Pause(); } if (Emu.IsStopped()) diff --git a/Utilities/Thread.h b/Utilities/Thread.h index 4e51438636..aaad35bca3 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -24,8 +24,9 @@ public: virtual void SetThreadName(const std::string& name); void WaitForAnySignal(u64 time = 1); - void Notify(); + + virtual void DumpInformation() {} }; NamedThreadBase* GetCurrentNamedThread(); diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index 21d9c6488e..763b36d4af 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -7,6 +7,19 @@ std::vector g_psv_modules; void add_psv_func(psv_func& data) { + for (auto& f : g_psv_func_list) + { + if (f.nid == data.nid && &f - g_psv_func_list.data() >= 2 /* special functions count */) + { + if (data.func) + { + f.func = data.func; + } + + return; + } + } + g_psv_func_list.push_back(data); } @@ -27,28 +40,46 @@ u32 get_psv_func_index(const psv_func* func) { auto res = func - g_psv_func_list.data(); - assert((size_t)res < g_psv_func_list.size()); + if ((size_t)res >= g_psv_func_list.size()) + { + throw __FUNCTION__; + } return (u32)res; } const psv_func* get_psv_func_by_index(u32 index) { - assert(index < g_psv_func_list.size()); + if (index >= g_psv_func_list.size()) + { + return nullptr; + } return &g_psv_func_list[index]; } void execute_psv_func_by_index(ARMv7Context& context, u32 index) { - auto func = get_psv_func_by_index(index); - - auto old_last_syscall = context.thread.m_last_syscall; - context.thread.m_last_syscall = func->nid; + if (auto func = get_psv_func_by_index(index)) + { + auto old_last_syscall = context.thread.m_last_syscall; + context.thread.m_last_syscall = func->nid; - (*func->func)(context); + if (func->func) + { + (*func->func)(context); + } + else + { + throw "Unimplemented function"; + } - context.thread.m_last_syscall = old_last_syscall; + context.thread.m_last_syscall = old_last_syscall; + } + else + { + throw "Invalid function index"; + } } extern psv_log_base sceAppMgr; diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 8ddb45ab75..34cd990c93 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -472,7 +472,7 @@ namespace psv_func_detail // Basic information about the HLE function struct psv_func { - u32 nid; // Unique function ID only for old PSV executables (should be generated individually for each elf loaded) + u32 nid; // Unique function ID (should be generated individually for each elf loaded) const char* name; // Function name for information std::shared_ptr func; // Function caller instance psv_log_base* module; // Module for information diff --git a/rpcs3/Emu/CPU/CPUThread.cpp b/rpcs3/Emu/CPU/CPUThread.cpp index b2224af9c0..ba398cad80 100644 --- a/rpcs3/Emu/CPU/CPUThread.cpp +++ b/rpcs3/Emu/CPU/CPUThread.cpp @@ -37,6 +37,76 @@ CPUThread::~CPUThread() safe_delete(m_dec); } +void CPUThread::DumpInformation() +{ + auto get_syscall_name = [this](u64 syscall) -> std::string + { + switch (GetType()) + { + case CPU_THREAD_ARMv7: + { + if ((u32)syscall == syscall) + { + if (syscall) + { + if (auto func = get_psv_func_by_nid((u32)syscall)) + { + return func->name; + } + } + else + { + return{}; + } + } + + return "unknown function"; + } + + case CPU_THREAD_PPU: + { + if ((u32)syscall == syscall) + { + if (syscall) + { + if (syscall < 1024) + { + // TODO: + //return SysCalls::GetSyscallName((u32)syscall); + return "unknown syscall"; + } + else + { + return SysCalls::GetHLEFuncName((u32)syscall); + } + } + else + { + return{}; + } + } + + return "unknown function"; + } + + case CPU_THREAD_SPU: + case CPU_THREAD_RAW_SPU: + default: + { + if (!syscall) + { + return{}; + } + + return "unknown function"; + } + } + }; + + LOG_ERROR(GENERAL, "Information: is_alive=%d, m_last_syscall=0x%llx (%s)", IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); + LOG_WARNING(GENERAL, RegsToString()); +} + bool CPUThread::IsRunning() const { return m_status == Running; } bool CPUThread::IsPaused() const { return m_status == Paused; } bool CPUThread::IsStopped() const { return m_status == Stopped; } @@ -246,70 +316,6 @@ void CPUThread::ExecOnce() void CPUThread::Task() { - auto get_syscall_name = [this](u64 syscall) -> std::string - { - switch (GetType()) - { - case CPU_THREAD_ARMv7: - { - if ((u32)syscall == syscall) - { - if (syscall) - { - if (auto func = get_psv_func_by_nid((u32)syscall)) - { - return func->name; - } - } - else - { - return{}; - } - } - - return "unknown function"; - } - - case CPU_THREAD_PPU: - { - if ((u32)syscall == syscall) - { - if (syscall) - { - if (syscall < 1024) - { - // TODO: - //return SysCalls::GetSyscallName((u32)syscall); - return "unknown syscall"; - } - else - { - return SysCalls::GetHLEFuncName((u32)syscall); - } - } - else - { - return{}; - } - } - - return "unknown function"; - } - - case CPU_THREAD_SPU: - case CPU_THREAD_RAW_SPU: - default: - { - if (!syscall) - { - return{}; - } - - return "unknown function"; - } - } - }; - if (Ini.HLELogging.GetValue()) LOG_NOTICE(GENERAL, "%s enter", CPUThread::GetFName().c_str()); const std::vector& bp = Emu.GetBreakPoints(); @@ -325,55 +331,41 @@ void CPUThread::Task() std::vector trace; - try + while (true) { - while (true) + int status = ThreadStatus(); + + if (status == CPUThread_Stopped || status == CPUThread_Break) { - int status = ThreadStatus(); + break; + } - if (status == CPUThread_Stopped || status == CPUThread_Break) + if (status == CPUThread_Sleeping) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + continue; + } + + Step(); + //if (m_trace_enabled) + //trace.push_back(PC); + NextPc(m_dec->DecodeMemory(PC + m_offset)); + + if (status == CPUThread_Step) + { + m_is_step = false; + break; + } + + for (uint i = 0; i < bp.size(); ++i) + { + if (bp[i] == PC) { + Emu.Pause(); break; } - - if (status == CPUThread_Sleeping) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - continue; - } - - Step(); - //if (m_trace_enabled) trace.push_back(PC); - NextPc(m_dec->DecodeMemory(PC + m_offset)); - - if (status == CPUThread_Step) - { - m_is_step = false; - break; - } - - for (uint i = 0; i < bp.size(); ++i) - { - if (bp[i] == PC) - { - Emu.Pause(); - break; - } - } } } - catch (const std::string& e) - { - LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); - LOG_NOTICE(GENERAL, RegsToString()); - Emu.Pause(); - } - catch (const char* e) - { - LOG_ERROR(GENERAL, "Exception: %s (is_alive=%d, m_last_syscall=0x%llx (%s))", e, IsAlive(), m_last_syscall, get_syscall_name(m_last_syscall)); - LOG_NOTICE(GENERAL, RegsToString()); - Emu.Pause(); - } if (trace.size()) { @@ -383,7 +375,7 @@ void CPUThread::Task() for (auto& v : trace) //LOG_NOTICE(GENERAL, "PC = 0x%x", v); { - if (v - prev != 4) + if (v - prev != 4 && v - prev != 2) { LOG_NOTICE(GENERAL, "Trace: 0x%08x .. 0x%08x", start, prev); start = v; @@ -394,6 +386,5 @@ void CPUThread::Task() LOG_NOTICE(GENERAL, "Trace end: 0x%08x .. 0x%08x", start, prev); } - if (Ini.HLELogging.GetValue()) LOG_NOTICE(GENERAL, "%s leave", CPUThread::GetFName().c_str()); } diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 35010483cc..8731894a25 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -44,6 +44,8 @@ protected: bool m_trace_call_stack; + virtual void DumpInformation() override; + public: virtual void InitRegs() = 0; diff --git a/rpcs3/Emu/Cell/PPCDecoder.h b/rpcs3/Emu/Cell/PPCDecoder.h index a653f06e81..0a602f562a 100644 --- a/rpcs3/Emu/Cell/PPCDecoder.h +++ b/rpcs3/Emu/Cell/PPCDecoder.h @@ -29,4 +29,4 @@ template static InstrList<(1 << (CodeField::size)), TO>* new_list(InstrList* parent, const CodeField& func, InstrCaller* error_func = nullptr) { return connect_list(parent, new InstrList<(1 << (CodeField::size)), TO>(func, error_func)); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/Cell/PPCInstrTable.h b/rpcs3/Emu/Cell/PPCInstrTable.h index b0f23521ba..fead638bdb 100644 --- a/rpcs3/Emu/Cell/PPCInstrTable.h +++ b/rpcs3/Emu/Cell/PPCInstrTable.h @@ -170,4 +170,3 @@ public: return encode(data, value); } }; - diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 228c9edd4e..86d988ee67 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1030,6 +1030,10 @@ private: Write(fmt::Format("bc [%x:%x:%x:%x:%x], cr%d[%x], 0x%x, %d, %d", bo0, bo1, bo2, bo3, bo4, bi/4, bi%4, bd, aa, lk)); } + void HACK(u32 index) + { + Write(fmt::Format("hack %d", index)); + } void SC(u32 lev) { switch (lev) diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index a22627f2ae..62e19e0138 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -177,6 +177,8 @@ namespace PPU_instr //This immediate field is used to specify a 16-bit unsigned integer static CodeField<16, 31> uimm16; + static CodeField<6, 31> uimm26; + /* Record bit. 0 Does not update the condition register (CR). @@ -241,6 +243,7 @@ namespace PPU_instr bind_instr(main_list, ADDI, RD, RA, simm16); bind_instr(main_list, ADDIS, RD, RA, simm16); bind_instr(main_list, BC, BO, BI, BD, AA, LK); + bind_instr(main_list, HACK, uimm26); bind_instr(main_list, SC, LEV); bind_instr(main_list, B, LI, AA, LK); bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index fdb7cc5250..d4bdbc4a8b 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2253,6 +2253,10 @@ private: if(lk) CPU.LR = nextLR; } } + void HACK(u32 index) + { + execute_ps3_func_by_index(CPU, index); + } void SC(u32 lev) { switch (lev) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index dedaf358bf..41a2c554be 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1995,6 +1995,10 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); } +void Compiler::HACK(u32 index) { + Call("execute_ps3_func_by_index", &execute_ps3_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index)); +} + void Compiler::SC(u32 lev) { switch (lev) { case 0: diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 40a9472e1e..f0a5a1d23a 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -469,6 +469,7 @@ namespace ppu_recompiler_llvm { void ADDI(u32 rd, u32 ra, s32 simm16) override; void ADDIS(u32 rd, u32 ra, s32 simm16) override; void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) override; + void HACK(u32 id) override; void SC(u32 sc_code) override; void B(s32 ll, u32 aa, u32 lk) override; void MCRF(u32 crfd, u32 crfs) override; diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index aee76ba295..c23669d3bf 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -4,6 +4,7 @@ namespace PPU_opcodes { enum PPU_MainOpcodes { + HACK = 0x01, //HLE Call TDI = 0x02, //Trap Doubleword Immediate TWI = 0x03, //Trap Word Immediate G_04 = 0x04, @@ -648,6 +649,7 @@ public: virtual void ADDI(u32 rd, u32 ra, s32 simm16) = 0; virtual void ADDIS(u32 rd, u32 ra, s32 simm16) = 0; virtual void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) = 0; + virtual void HACK(u32 index) = 0; virtual void SC(u32 lev) = 0; virtual void B(s32 ll, u32 aa, u32 lk) = 0; virtual void MCRF(u32 crfd, u32 crfs) = 0; diff --git a/rpcs3/Emu/SysCalls/ModuleManager.cpp b/rpcs3/Emu/SysCalls/ModuleManager.cpp index 17cdd88a60..72be0defa3 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.cpp +++ b/rpcs3/Emu/SysCalls/ModuleManager.cpp @@ -1,328 +1,217 @@ #include "stdafx.h" #include "ModuleManager.h" -extern void cellAdec_init(Module* pxThis); -extern void cellAtrac_init(Module* pxThis); -extern void cellAudio_init(Module* pxThis); -extern void cellAvconfExt_init(Module* pxThis); -extern void cellCamera_init(Module* pxThis); -extern void cellCamera_unload(); -extern void cellDmux_init(Module *pxThis); -extern void cellFiber_init(Module *pxThis); -extern void cellFont_init(Module *pxThis); -extern void cellFont_load(); -extern void cellFont_unload(); -extern void cellFontFT_init(Module *pxThis); -extern void cellFontFT_load(); -extern void cellFontFT_unload(); -extern void cellGame_init(Module *pxThis); -extern void cellGcmSys_init(Module *pxThis); -extern void cellGcmSys_load(); -extern void cellGcmSys_unload(); -extern void cellGem_init(Module *pxThis); -extern void cellGem_unload(); -extern void cellJpgDec_init(Module *pxThis); -extern void cellGifDec_init(Module *pxThis); -extern void cellL10n_init(Module *pxThis); -extern void cellMic_init(Module *pxThis); -extern void cellMic_unload(); -extern void cellNetCtl_init(Module *pxThis); -extern void cellNetCtl_unload(); -extern void cellOvis_init(Module *pxThis); -extern void cellPamf_init(Module *pxThis); -extern void cellPngDec_init(Module *pxThis); -extern void cellResc_init(Module *pxThis); -extern void cellResc_load(); -extern void cellResc_unload(); -extern void cellRtc_init(Module *pxThis); -extern void cellSail_init(Module *pxThis); -extern void cellSpurs_init(Module *pxThis); -extern void cellSpursJq_init(Module *pxThis); -extern void cellSubdisplay_init(Module *pxThis); -extern void cellSync_init(Module *pxThis); -extern void cellSync2_init(Module *pxThis); -extern void cellSysutil_init(Module *pxThis); -extern void cellSysutil_load(); -extern void cellSysutilAp_init(Module *pxThis); -extern void cellSysmodule_init(Module *pxThis); -extern void cellUserInfo_init(Module *pxThis); -extern void cellVdec_init(Module *pxThis); -extern void cellVpost_init(Module *pxThis); -extern void libmixer_init(Module *pxThis); -extern void sceNp_init(Module *pxThis); -extern void sceNp_unload(); -extern void sceNpClans_init(Module *pxThis); -extern void sceNpClans_unload(); -extern void sceNpCommerce2_init(Module *pxThis); -extern void sceNpCommerce2_unload(); -extern void sceNpSns_init(Module *pxThis); -extern void sceNpSns_unload(); -extern void sceNpTrophy_init(Module *pxThis); -extern void sceNpTrophy_unload(); -extern void sceNpTus_init(Module *pxThis); -extern void sceNpTus_unload(); -extern void sysPrxForUser_init(Module *pxThis); -extern void sysPrxForUser_load(); -extern void sys_fs_init(Module *pxThis); -extern void sys_fs_load(); -extern void sys_io_init(Module *pxThis); -extern void sys_net_init(Module *pxThis); +extern Module sys_fs; +extern Module cellAdec; +extern Module cellAtrac; +extern Module cellAudio; +extern Module cellAvconfExt; +extern Module cellCamera; +extern Module cellDmux; +extern Module cellFiber; +extern Module cellFont; +extern Module cellFontFT; +extern Module cellGame; +extern Module cellGcmSys; +extern Module cellGem; +extern Module cellGifDec; +extern Module cellJpgDec; +extern Module sys_io; +extern Module cellL10n; +extern Module cellMic; +extern Module sys_io; +extern Module cellSysutil; +extern Module cellNetCtl; +extern Module cellOvis; +extern Module sys_io; +extern Module cellPamf; +extern Module cellPngDec; +extern Module cellResc; +extern Module cellRtc; +extern Module cellSail; +extern Module cellSysutil; +extern Module cellSpurs; +extern Module cellSpursJq; +extern Module cellSubdisplay; +extern Module cellSync; +extern Module cellSync2; +extern Module cellSysmodule; +extern Module cellSysutil; +extern Module cellSysutilAp; +extern Module cellUserInfo; +extern Module cellVdec; +extern Module cellVpost; +extern Module libmixer; +extern Module sceNp; +extern Module sceNpClans; +extern Module sceNpCommerce2; +extern Module sceNpSns; +extern Module sceNpTrophy; +extern Module sceNpTus; +extern Module sys_io; +extern Module sys_net; +extern Module sysPrxForUser; struct ModuleInfo { - u16 id; //0xffff is used by module with only name + s32 id; //-1 is used by module with only name const char* name; - void(*init)(Module *pxThis); - void(*load)(); - void(*unload)(); + Module* module; } -static const g_modules_list[] = +static const g_module_list[] = { - { 0x0000, "sys_net", sys_net_init, nullptr, nullptr }, - { 0x0001, "sys_http", nullptr, nullptr, nullptr }, - { 0x0002, "cellHttpUtil", nullptr, nullptr, nullptr }, - { 0x0003, "cellSsl", nullptr, nullptr, nullptr }, - { 0x0004, "cellHttps", nullptr, nullptr, nullptr }, - { 0x0005, "libvdec", cellVdec_init, nullptr, nullptr }, - { 0x0006, "cellAdec", cellAdec_init, nullptr, nullptr }, - { 0x0007, "cellDmux", cellDmux_init, nullptr, nullptr }, - { 0x0008, "cellVpost", cellVpost_init, nullptr, nullptr }, - { 0x0009, "cellRtc", cellRtc_init, nullptr, nullptr }, - { 0x000a, "cellSpurs", cellSpurs_init, nullptr, nullptr }, - { 0x000b, "cellOvis", cellOvis_init, nullptr, nullptr }, - { 0x000c, "cellSheap", nullptr, nullptr, nullptr }, - { 0x000d, "sys_sync", nullptr, nullptr, nullptr }, - { 0x000e, "sys_fs", sys_fs_init, sys_fs_load, nullptr }, - { 0x000f, "cellJpgDec", cellJpgDec_init, nullptr, nullptr }, - { 0x0010, "cellGcmSys", cellGcmSys_init, cellGcmSys_load, cellGcmSys_unload }, - { 0x0011, "cellAudio", cellAudio_init, nullptr, nullptr }, - { 0x0012, "cellPamf", cellPamf_init, nullptr, nullptr }, - { 0x0013, "cellAtrac", cellAtrac_init, nullptr, nullptr }, - { 0x0014, "cellNetCtl", cellNetCtl_init, nullptr, cellNetCtl_unload }, - { 0x0015, "cellSysutil", cellSysutil_init, cellSysutil_load, nullptr }, - { 0x0016, "sceNp", sceNp_init, nullptr, sceNp_unload }, - { 0x0017, "sys_io", sys_io_init, nullptr, nullptr }, - { 0x0018, "cellPngDec", cellPngDec_init, nullptr, nullptr }, - { 0x0019, "cellFont", cellFont_init, cellFont_load, cellFont_unload }, - { 0x001a, "cellFontFT", cellFontFT_init, cellFontFT_load, cellFontFT_unload }, - { 0x001b, "cellFreetype", nullptr, nullptr, nullptr }, - { 0x001c, "cellUsbd", nullptr, nullptr, nullptr }, - { 0x001d, "cellSail", cellSail_init, nullptr, nullptr }, - { 0x001e, "cellL10n", cellL10n_init, nullptr, nullptr }, - { 0x001f, "cellResc", cellResc_init, cellResc_load, cellResc_unload }, - { 0x0020, "cellDaisy", nullptr, nullptr, nullptr }, - { 0x0021, "cellKey2char", nullptr, nullptr, nullptr }, - { 0x0022, "cellMic", cellMic_init, nullptr, cellMic_unload }, - { 0x0023, "cellCamera", cellCamera_init, nullptr, cellCamera_unload }, - { 0x0024, "cellVdecMpeg2", nullptr, nullptr, nullptr }, - { 0x0025, "cellVdecAvc", nullptr, nullptr, nullptr }, - { 0x0026, "cellAdecLpcm", nullptr, nullptr, nullptr }, - { 0x0027, "cellAdecAc3", nullptr, nullptr, nullptr }, - { 0x0028, "cellAdecAtx", nullptr, nullptr, nullptr }, - { 0x0029, "cellAdecAt3", nullptr, nullptr, nullptr }, - { 0x002a, "cellDmuxPamf", nullptr, nullptr, nullptr }, - { 0x002e, "cellLv2dbg", nullptr, nullptr, nullptr }, - { 0x0030, "cellUsbpspcm", nullptr, nullptr, nullptr }, - { 0x0031, "cellAvconfExt", cellAvconfExt_init, nullptr, nullptr }, - { 0x0032, "cellUserInfo", cellUserInfo_init, nullptr, nullptr }, - { 0x0033, "cellSysutilSavedata", nullptr, nullptr, nullptr }, - { 0x0034, "cellSubdisplay", cellSubdisplay_init, nullptr, nullptr }, - { 0x0035, "cellSysutilRec", nullptr, nullptr, nullptr }, - { 0x0036, "cellVideoExport", nullptr, nullptr, nullptr }, - { 0x0037, "cellGameExec", nullptr, nullptr, nullptr }, - { 0x0038, "sceNp2", nullptr, nullptr, nullptr }, - { 0x0039, "cellSysutilAp", cellSysutilAp_init, nullptr, nullptr }, - { 0x003a, "cellSysutilNpClans", sceNpClans_init, nullptr, sceNpClans_unload }, - { 0x003b, "cellSysutilOskExt", nullptr, nullptr, nullptr }, - { 0x003c, "cellVdecDivx", nullptr, nullptr, nullptr }, - { 0x003d, "cellJpgEnc", nullptr, nullptr, nullptr }, - { 0x003e, "cellGame", cellGame_init, nullptr, nullptr }, - { 0x003f, "cellBgdl", nullptr, nullptr, nullptr }, - { 0x0040, "cellFreetypeTT", nullptr, nullptr, nullptr }, - { 0x0041, "cellSysutilVideoUpload", nullptr, nullptr, nullptr }, - { 0x0042, "cellSysutilSysconfExt", nullptr, nullptr, nullptr }, - { 0x0043, "cellFiber", cellFiber_init, nullptr, nullptr }, - { 0x0044, "cellNpCommerce2", sceNpCommerce2_init, nullptr, sceNpCommerce2_unload }, - { 0x0045, "cellNpTus", sceNpTus_init, nullptr, sceNpTus_unload }, - { 0x0046, "cellVoice", nullptr, nullptr, nullptr }, - { 0x0047, "cellAdecCelp8", nullptr, nullptr, nullptr }, - { 0x0048, "cellCelp8Enc", nullptr, nullptr, nullptr }, - { 0x0049, "cellLicenseArea", nullptr, nullptr, nullptr }, - { 0x004a, "cellMusic2", nullptr, nullptr, nullptr }, - { 0x004e, "cellScreenshot", nullptr, nullptr, nullptr }, - { 0x004f, "cellMusicDecode", nullptr, nullptr, nullptr }, - { 0x0050, "cellSpursJq", cellSpursJq_init, nullptr, nullptr }, - { 0x0052, "cellPngEnc", nullptr, nullptr, nullptr }, - { 0x0053, "cellMusicDecode2", nullptr, nullptr, nullptr }, - { 0x0055, "cellSync2", cellSync2_init, nullptr, nullptr }, - { 0x0056, "cellNpUtil", nullptr, nullptr, nullptr }, - { 0x0057, "cellRudp", nullptr, nullptr, nullptr }, - { 0x0059, "cellNpSns", sceNpSns_init, nullptr, sceNpSns_unload }, - { 0x005a, "cellGem", cellGem_init, nullptr, cellGem_unload }, - { 0xf00a, "cellCelpEnc", nullptr, nullptr, nullptr }, - { 0xf010, "cellGifDec", cellGifDec_init, nullptr, nullptr }, - { 0xf019, "cellAdecCelp", nullptr, nullptr, nullptr }, - { 0xf01b, "cellAdecM2bc", nullptr, nullptr, nullptr }, - { 0xf01d, "cellAdecM4aac", nullptr, nullptr, nullptr }, - { 0xf01e, "cellAdecMp3", nullptr, nullptr, nullptr }, - { 0xf023, "cellImejp", nullptr, nullptr, nullptr }, - { 0xf028, "cellMusic", nullptr, nullptr, nullptr }, - { 0xf029, "cellPhotoExport", nullptr, nullptr, nullptr }, - { 0xf02a, "cellPrint", nullptr, nullptr, nullptr }, - { 0xf02b, "cellPhotoImport", nullptr, nullptr, nullptr }, - { 0xf02c, "cellMusicExport", nullptr, nullptr, nullptr }, - { 0xf02e, "cellPhotoDecode", nullptr, nullptr, nullptr }, - { 0xf02f, "cellSearch", nullptr, nullptr, nullptr }, - { 0xf030, "cellAvchat2", nullptr, nullptr, nullptr }, - { 0xf034, "cellSailRec", nullptr, nullptr, nullptr }, - { 0xf035, "sceNpTrophy", sceNpTrophy_init, nullptr, sceNpTrophy_unload }, - { 0xf053, "cellAdecAt3multi", nullptr, nullptr, nullptr }, - { 0xf054, "cellLibatrac3multi", nullptr, nullptr, nullptr }, - { 0xffff, "cellSync", cellSync_init, nullptr, nullptr }, - { 0xffff, "cellSysmodule", cellSysmodule_init, nullptr, nullptr }, - { 0xffff, "libmixer", libmixer_init, nullptr, nullptr }, - { 0xffff, "sysPrxForUser", sysPrxForUser_init, sysPrxForUser_load, nullptr } + { 0x0000, "sys_net", &sys_net }, + { 0x0001, "sys_http", nullptr }, + { 0x0002, "cellHttpUtil", nullptr }, + { 0x0003, "cellSsl", nullptr }, + { 0x0004, "cellHttps", nullptr }, + { 0x0005, "libvdec", &cellVdec }, + { 0x0006, "cellAdec", &cellAdec }, + { 0x0007, "cellDmux", &cellDmux }, + { 0x0008, "cellVpost", &cellVpost }, + { 0x0009, "cellRtc", &cellRtc }, + { 0x000a, "cellSpurs", &cellSpurs }, + { 0x000b, "cellOvis", &cellOvis }, + { 0x000c, "cellSheap", nullptr }, + { 0x000d, "sys_sync", &cellSync }, + { 0x000e, "sys_fs", &sys_fs }, + { 0x000f, "cellJpgDec", &cellJpgDec }, + { 0x0010, "cellGcmSys", &cellGcmSys }, + { 0x0011, "cellAudio", &cellAudio }, + { 0x0012, "cellPamf", &cellPamf }, + { 0x0013, "cellAtrac", &cellAtrac }, + { 0x0014, "cellNetCtl", &cellNetCtl }, + { 0x0015, "cellSysutil", &cellSysutil }, + { 0x0016, "sceNp", &sceNp }, + { 0x0017, "sys_io", &sys_io }, + { 0x0018, "cellPngDec", &cellPngDec }, + { 0x0019, "cellFont", &cellFont }, + { 0x001a, "cellFontFT", &cellFontFT }, + { 0x001b, "cellFreetype", nullptr }, + { 0x001c, "cellUsbd", nullptr }, + { 0x001d, "cellSail", &cellSail }, + { 0x001e, "cellL10n", &cellL10n }, + { 0x001f, "cellResc", &cellResc }, + { 0x0020, "cellDaisy", nullptr }, + { 0x0021, "cellKey2char", nullptr }, + { 0x0022, "cellMic", &cellMic }, + { 0x0023, "cellCamera", &cellCamera }, + { 0x0024, "cellVdecMpeg2", nullptr }, + { 0x0025, "cellVdecAvc", nullptr }, + { 0x0026, "cellAdecLpcm", nullptr }, + { 0x0027, "cellAdecAc3", nullptr }, + { 0x0028, "cellAdecAtx", nullptr }, + { 0x0029, "cellAdecAt3", nullptr }, + { 0x002a, "cellDmuxPamf", nullptr }, + { 0x002e, "cellLv2dbg", nullptr }, + { 0x0030, "cellUsbpspcm", nullptr }, + { 0x0031, "cellAvconfExt", &cellAvconfExt }, + { 0x0032, "cellUserInfo", &cellUserInfo }, + { 0x0033, "cellSysutilSavedata", nullptr }, + { 0x0034, "cellSubdisplay", &cellSubdisplay }, + { 0x0035, "cellSysutilRec", nullptr }, + { 0x0036, "cellVideoExport", nullptr }, + { 0x0037, "cellGameExec", nullptr }, + { 0x0038, "sceNp2", nullptr }, + { 0x0039, "cellSysutilAp", &cellSysutilAp }, + { 0x003a, "cellSysutilNpClans", nullptr }, + { 0x003b, "cellSysutilOskExt", nullptr }, + { 0x003c, "cellVdecDivx", nullptr }, + { 0x003d, "cellJpgEnc", nullptr }, + { 0x003e, "cellGame", &cellGame }, + { 0x003f, "cellBgdl", nullptr }, + { 0x0040, "cellFreetypeTT", nullptr }, + { 0x0041, "cellSysutilVideoUpload", nullptr }, + { 0x0042, "cellSysutilSysconfExt", nullptr }, + { 0x0043, "cellFiber", &cellFiber }, + { 0x0044, "sceNpCommerce2", &sceNpCommerce2 }, + { 0x0045, "sceNpTus", &sceNpTus }, + { 0x0046, "cellVoice", nullptr }, + { 0x0047, "cellAdecCelp8", nullptr }, + { 0x0048, "cellCelp8Enc", nullptr }, + { 0x0049, "cellLicenseArea", nullptr }, + { 0x004a, "cellMusic2", nullptr }, + { 0x004e, "cellScreenshot", nullptr }, + { 0x004f, "cellMusicDecode", nullptr }, + { 0x0050, "cellSpursJq", &cellSpursJq }, + { 0x0052, "cellPngEnc", nullptr }, + { 0x0053, "cellMusicDecode2", nullptr }, + { 0x0055, "cellSync2", &cellSync2 }, + { 0x0056, "sceNpUtil", nullptr }, + { 0x0057, "cellRudp", nullptr }, + { 0x0059, "sceNpSns", &sceNpSns }, + { 0x005a, "cellGem", &cellGem }, + { 0xf00a, "cellCelpEnc", nullptr }, + { 0xf010, "cellGifDec", &cellGifDec }, + { 0xf019, "cellAdecCelp", nullptr }, + { 0xf01b, "cellAdecM2bc", nullptr }, + { 0xf01d, "cellAdecM4aac", nullptr }, + { 0xf01e, "cellAdecMp3", nullptr }, + { 0xf023, "cellImejp", nullptr }, + { 0xf028, "cellMusic", nullptr }, + { 0xf029, "cellPhotoExport", nullptr }, + { 0xf02a, "cellPrint", nullptr }, + { 0xf02b, "cellPhotoImport", nullptr }, + { 0xf02c, "cellMusicExport", nullptr }, + { 0xf02e, "cellPhotoDecode", nullptr }, + { 0xf02f, "cellSearch", nullptr }, + { 0xf030, "cellAvchat2", nullptr }, + { 0xf034, "cellSailRec", nullptr }, + { 0xf035, "sceNpTrophy", &sceNpTrophy }, + { 0xf053, "cellAdecAt3multi", nullptr }, + { 0xf054, "cellLibatrac3multi", nullptr }, + + { -1, "cellSync", &cellSync }, + { -1, "cellSysmodule", &cellSysmodule }, + { -1, "libmixer", &libmixer }, + { -1, "sysPrxForUser", &sysPrxForUser }, }; -void ModuleManager::init() +void ModuleManager::Init() { - //TODO Refactor every Module part to remove the global pointer defined in each module's file - //and the need to call init functions after its constructor - - //To define a new module, add it in g_modules_list - //m.init the function which defines module's own functions and assignes module's pointer to its global pointer if (!initialized) { - u32 global_module_nb = sizeof(g_modules_list) / sizeof(g_modules_list[0]); - m_mod_init.reserve(global_module_nb); - for (auto& m : g_modules_list) + for (auto& m : g_module_list) { - m_mod_init.emplace_back(m.id, m.name, m.load, m.unload); - if (m.init) - m.init(&m_mod_init.back()); + if (m.module) + { + m.module->Init(); + } } initialized = true; } } -ModuleManager::ModuleManager() : -m_max_module_id(0), -m_module_2_count(0), -initialized(false) +ModuleManager::ModuleManager() + : initialized(false) { - memset(m_modules, 0, 3 * 0xFF * sizeof(Module*)); } ModuleManager::~ModuleManager() { - UnloadModules(); } -bool ModuleManager::IsLoadedFunc(u32 id) const +void ModuleManager::Close() { - for (u32 i = 0; iid == id) + if (m.module && m.module->on_stop) { - return true; + m.module->on_stop(); } } - return false; -} - -bool ModuleManager::CallFunc(PPUThread& CPU, u32 num) -{ - func_caller* func = nullptr; - { - std::lock_guard lock(m_funcs_lock); - - for (u32 i = 0; iid == num) - { - func = m_modules_funcs_list[i]->func; - break; - } - } - } - - if (func) - { - (*func)(CPU); - return true; - } - return false; -} - -bool ModuleManager::UnloadFunc(u32 id) -{ - std::lock_guard lock(m_funcs_lock); - - for (u32 i = 0; iid == id) - { - m_modules_funcs_list.erase(m_modules_funcs_list.begin() + i); - - return true; - } - } - - return false; -} - -u32 ModuleManager::GetFuncNumById(u32 id) -{ - return id; -} - -//to load the default modules after calling this call Init() again -void ModuleManager::UnloadModules() -{ - for (u32 i = 0; i<3; ++i) - { - for (u32 j = 0; jUnLoad(); - } - } - } - - //reset state of the module manager - //this could be done by calling the destructor and then a placement-new - //to avoid repeating the initial values here but the defaults aren't - //complicated enough to complicate this by using the placement-new - m_mod_init.clear(); //destroy Module(s), their respective global pointer become invalid - m_max_module_id = 0; - m_module_2_count = 0; initialized = false; - memset(m_modules, 0, 3 * 0xFF * sizeof(Module*)); - - std::lock_guard lock(m_funcs_lock); - m_modules_funcs_list.clear(); } -Module* ModuleManager::GetModuleByName(const std::string& name) +Module* ModuleManager::GetModuleByName(const char* name) { - for (u32 i = 0; iGetName() == name) + if (!strcmp(name, m.name)) { - return m_modules[0][i]; - } - - if (m_modules[1][i] && m_modules[1][i]->GetName() == name) - { - return m_modules[1][i]; - } - - if (m_modules[2][i] && m_modules[2][i]->GetName() == name) - { - return m_modules[2][i]; + return m.module; } } @@ -331,72 +220,26 @@ Module* ModuleManager::GetModuleByName(const std::string& name) Module* ModuleManager::GetModuleById(u16 id) { - for (u32 i = 0; iGetID() == id) + if (m.id == id) { - return m_modules[0][i]; - } - - if (m_modules[1][i] && m_modules[1][i]->GetID() == id) - { - return m_modules[1][i]; + return m.module; } } return nullptr; } -void ModuleManager::SetModule(u16 id, Module* module) +bool ModuleManager::CheckModuleId(u16 id) { - if (id != 0xffff) //id != -1 + for (auto& m : g_module_list) { - u8 index2 = (u8)id; - if (u16(index2 + 1) > m_max_module_id) + if (m.id == id) { - m_max_module_id = u16(index2 + 1); - } - - u8 index; - switch (id >> 8) - { - case 0x00: index = 0; break;//id = 0x0000 to 0x00fe go to m_modules[0] - case 0xf0: index = 1; break;//id = 0xf000 to 0xf0fe go to m_modules[1] - default: assert(0); return; - } - - //fill m_modules[index] by truncating id to 8 bits - if (m_modules[index][index2]) //if module id collision - { - //Not sure if this is a good idea to hide collision - module->SetName(m_modules[index][index2]->GetName()); - m_modules[index][index2] = module; - //don't need to delete since m_mod_init has the ownership - } - else - { - m_modules[index][index2] = module; - } - } - else //id = 0xffff go to m_modules[2] - { - //fill m_modules[2] from 0 to 0xff - m_modules[2][m_module_2_count] = module; - ++m_module_2_count; - if (m_module_2_count > m_max_module_id) - { - m_max_module_id = m_module_2_count; + return true; } } + + return false; } - - -void ModuleManager::AddFunc(ModuleFunc *func) -{ - std::lock_guard guard(m_funcs_lock); - - if (!IsLoadedFunc(func->id)) - { - m_modules_funcs_list.push_back(func); - } -} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/ModuleManager.h b/rpcs3/Emu/SysCalls/ModuleManager.h index 524887112d..4da02e2539 100644 --- a/rpcs3/Emu/SysCalls/ModuleManager.h +++ b/rpcs3/Emu/SysCalls/ModuleManager.h @@ -3,26 +3,15 @@ class ModuleManager { - Module* m_modules[3][0xff];//keep pointer to modules split in 3 categories according to their id - uint m_max_module_id; //max index in m_modules[2][], m_modules[1][] and m_modules[0][] - uint m_module_2_count; //max index in m_modules[2][] - std::mutex m_funcs_lock; - std::vector m_modules_funcs_list; - std::vector m_mod_init; //owner of Module bool initialized; public: ModuleManager(); ~ModuleManager(); - void init(); - void AddFunc(ModuleFunc *func); - void SetModule(u16 id, Module* module);//insert into m_modules - bool IsLoadedFunc(u32 id) const; - bool CallFunc(PPUThread& CPU, u32 num); - bool UnloadFunc(u32 id); - void UnloadModules(); - u32 GetFuncNumById(u32 id); - Module* GetModuleByName(const std::string& name); + void Init(); + void Close(); + Module* GetModuleByName(const char* name); Module* GetModuleById(u16 id); -}; \ No newline at end of file + bool CheckModuleId(u16 id); +}; diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 3de1be5414..9e10944726 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -7,7 +7,99 @@ #include "ModuleManager.h" #include "Emu/Cell/PPUInstrTable.h" -u32 getFunctionId(const char* name) +std::vector g_ps3_func_list; + +u32 add_ps3_func(ModuleFunc& func) +{ + for (auto& f : g_ps3_func_list) + { + if (f.id == func.id) + { + // partial update + + if (func.func) + { + f.func = func.func; + } + + if (func.lle_func) + { + f.lle_func = func.lle_func; + } + + return (u32)(&f - g_ps3_func_list.data()); + } + } + + g_ps3_func_list.push_back(func); + return (u32)g_ps3_func_list.size() - 1; +} + +ModuleFunc* get_ps3_func_by_nid(u32 nid, u32* out_index) +{ + for (auto& f : g_ps3_func_list) + { + if (f.id == nid) + { + if (out_index) + { + *out_index = (u32)(&f - g_ps3_func_list.data()); + } + + return &f; + } + } + + return nullptr; +} + +ModuleFunc* get_ps3_func_by_index(u32 index) +{ + if (index >= g_ps3_func_list.size()) + { + return nullptr; + } + + return &g_ps3_func_list[index]; +} + +void execute_ps3_func_by_index(PPUThread& CPU, u32 index) +{ + if (auto func = get_ps3_func_by_index(index)) + { + // save RTOC + vm::write64(vm::cast(CPU.GPR[1] + 0x28), CPU.GPR[2]); + + auto old_last_syscall = CPU.m_last_syscall; + CPU.m_last_syscall = func->id; + + if (func->lle_func) + { + func->lle_func(CPU); + } + else if (func->func) + { + (*func->func)(CPU); + } + else + { + throw "Unimplemented function"; + } + + CPU.m_last_syscall = old_last_syscall; + } + else + { + throw "Invalid function index"; + } +} + +void clear_ps3_functions() +{ + g_ps3_func_list.clear(); +} + +u32 get_function_id(const char* name) { const char* suffix = "\x67\x59\x65\x99\x04\x25\x04\x90\x56\x64\x27\x49\x94\x89\x74\x1A"; // Symbol name suffix u8 output[20]; @@ -23,111 +115,52 @@ u32 getFunctionId(const char* name) return (u32&)output[0]; } -Module::Module(u16 id, const char* name, void(*load)(), void(*unload)()) +Module::Module(const char* name, void(*init)()) : m_is_loaded(false) , m_name(name) - , m_id(id) - , m_load_func(load) - , m_unload_func(unload) + , m_init(init) { - Emu.GetModuleManager().SetModule(m_id, this); -} - -Module::Module(Module &&other) - : m_is_loaded(false) - , m_id(0) - , m_load_func(nullptr) - , m_unload_func(nullptr) -{ - std::swap(this->m_name,other.m_name); - std::swap(this->m_id, other.m_id); - std::swap(this->m_is_loaded, other.m_is_loaded); - std::swap(this->m_load_func, other.m_load_func); - std::swap(this->m_unload_func, other.m_unload_func); - std::swap(this->m_funcs_list, other.m_funcs_list); -} - -Module &Module::operator =(Module &&other) -{ - std::swap(this->m_name, other.m_name); - std::swap(this->m_id, other.m_id); - std::swap(this->m_is_loaded, other.m_is_loaded); - std::swap(this->m_load_func, other.m_load_func); - std::swap(this->m_unload_func, other.m_unload_func); - std::swap(this->m_funcs_list, other.m_funcs_list); - return *this; } Module::~Module() { - UnLoad(); +} - for (auto &i : m_funcs_list) - { - delete i.second; - } - - m_funcs_list.clear(); +void Module::Init() +{ + m_init(); } void Module::Load() { - if(IsLoaded()) - return; - - if(m_load_func) m_load_func(); - - for (auto &i : m_funcs_list) + if (IsLoaded()) { - Emu.GetModuleManager().AddFunc(i.second); + return; + } + + if (on_load) + { + on_load(); } SetLoaded(true); } -void Module::UnLoad() +void Module::Unload() { - if(!IsLoaded()) - return; - - if(m_unload_func) m_unload_func(); - - for (auto &i : m_funcs_list) + if (!IsLoaded()) { - i.second->lle_func.set(0); + return; } - // TODO: Re-enable this when needed - // This was disabled because some functions would get unloaded and - // some games tried to use them, thus only printing a TODO message - //for(u32 i=0; iid); - //} + if (on_unload) + { + on_unload(); + } SetLoaded(false); } -bool Module::Load(u32 id) -{ - if(Emu.GetModuleManager().IsLoadedFunc(id)) - return false; - - auto res = m_funcs_list.find(id); - - if (res == m_funcs_list.end()) - return false; - - Emu.GetModuleManager().AddFunc(res->second); - - return true; -} - -bool Module::UnLoad(u32 id) -{ - return Emu.GetModuleManager().UnloadFunc(id); -} - void Module::SetLoaded(bool loaded) { m_is_loaded = loaded; @@ -138,11 +171,6 @@ bool Module::IsLoaded() const return m_is_loaded; } -u16 Module::GetID() const -{ - return m_id; -} - const std::string& Module::GetName() const { return m_name; @@ -178,22 +206,32 @@ void Module::PushNewFuncSub(SFunc* func) Emu.GetSFuncManager().push_back(func); } -void fix_import(Module* module, u32 func, u32 addr) +void fix_import(Module* module, u32 nid, u32 addr) { using namespace PPU_instr; vm::ptr ptr = vm::ptr::make(addr); - *ptr++ = ADDIS(11, 0, func >> 16); - *ptr++ = ORI(11, 11, func & 0xffff); - *ptr++ = NOP(); - ++ptr; - *ptr++ = SC(0); - *ptr++ = BLR(); - *ptr++ = NOP(); - *ptr++ = NOP(); + u32 index; - module->Load(func); + if (auto func = get_ps3_func_by_nid(nid, &index)) + { + *ptr++ = HACK(index); + *ptr++ = BLR(); + } + else + { + module->Error("Unimplemented function 0x%x (0x%x)", nid, addr); + } + + //*ptr++ = ADDIS(11, 0, func >> 16); + //*ptr++ = ORI(11, 11, func & 0xffff); + //*ptr++ = NOP(); + //++ptr; + //*ptr++ = SC(0); + //*ptr++ = BLR(); + //*ptr++ = NOP(); + //*ptr++ = NOP(); } void fix_relocs(Module* module, u32 lib, u32 start, u32 end, u32 seg2) @@ -248,4 +286,4 @@ void fix_relocs(Module* module, u32 lib, u32 start, u32 end, u32 seg2) module->Notice("fix_relocs(): 0x%x : 0x%llx", i - lib, flag); } } -} \ No newline at end of file +} diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 6172e623fc..f52049a426 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -4,24 +4,22 @@ #include "ErrorCodes.h" #include "LogBase.h" -//TODO +class Module; + struct ModuleFunc { u32 id; - func_caller* func; + Module* module; + std::shared_ptr func; vm::ptr lle_func; - ModuleFunc(u32 id, func_caller* func, vm::ptr lle_func = vm::ptr::make(0)) + ModuleFunc(u32 id, Module* module, func_caller* func, vm::ptr lle_func = vm::ptr::make(0)) : id(id) + , module(module) , func(func) , lle_func(lle_func) { } - - ~ModuleFunc() - { - delete func; - } }; struct SFuncOp @@ -50,46 +48,36 @@ class StaticFuncManager; class Module : public LogBase { std::string m_name; - u16 m_id; bool m_is_loaded; - void (*m_load_func)(); - void (*m_unload_func)(); + void(*m_init)(); IdManager& GetIdManager() const; void PushNewFuncSub(SFunc* func); -public: - std::unordered_map m_funcs_list; + Module() = delete; - Module(u16 id, const char* name, void(*load)() = nullptr, void(*unload)() = nullptr); +public: + Module(const char* name, void(*init)()); Module(Module &other) = delete; - Module(Module &&other); + Module(Module &&other) = delete; Module &operator =(Module &other) = delete; - Module &operator =(Module &&other); - - ModuleFunc* GetFunc(u32 id) - { - auto res = m_funcs_list.find(id); - - if (res == m_funcs_list.end()) - return nullptr; - - return res->second; - } + Module &operator =(Module &&other) = delete; ~Module(); + std::function on_load; + std::function on_unload; + std::function on_stop; + + void Init(); void Load(); - void UnLoad(); - bool Load(u32 id); - bool UnLoad(u32 id); + void Unload(); void SetLoaded(bool loaded = true); bool IsLoaded() const; - u16 GetID() const; virtual const std::string& GetName() const override; void SetName(const std::string& name); @@ -128,29 +116,23 @@ public: } bool RemoveId(u32 id); - - void RegisterLLEFunc(u32 id, vm::ptr func) - { - if (auto f = GetFunc(id)) - { - f->lle_func = func; - return; - } - - m_funcs_list[id] = new ModuleFunc(id, nullptr, func); - } template __forceinline void AddFunc(u32 id, T func); - template __forceinline void AddFunc(const char* name, T func); + template __forceinline void AddFunc(const char* name, T func); template __forceinline void AddFuncSub(const char group[8], const u64 ops[], const char* name, T func); }; -u32 getFunctionId(const char* name); +u32 add_ps3_func(ModuleFunc& func); +ModuleFunc* get_ps3_func_by_nid(u32 nid, u32* out_index = nullptr); +ModuleFunc* get_ps3_func_by_index(u32 index); +void execute_ps3_func_by_index(PPUThread& CPU, u32 id); +void clear_ps3_functions(); +u32 get_function_id(const char* name); template __forceinline void Module::AddFunc(u32 id, T func) { - m_funcs_list[id] = new ModuleFunc(id, bind_func(func)); + add_ps3_func(ModuleFunc(id, this, bind_func(func))); } template @@ -185,7 +167,7 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], cons PushNewFuncSub(sf); } -void fix_import(Module* module, u32 func, u32 addr); +void fix_import(Module* module, u32 nid, u32 addr); #define FIX_IMPORT(module, func, addr) fix_import(module, getFunctionId(#func), addr) @@ -193,8 +175,8 @@ void fix_relocs(Module* module, u32 lib, u32 start, u32 end, u32 seg2); #define REG_SUB(module, group, name, ...) \ static const u64 name ## _table[] = {__VA_ARGS__ , 0}; \ - module->AddFuncSub(group, name ## _table, #name, name) + module.AddFuncSub(group, name ## _table, #name, name) -#define REG_FUNC(module, name) module->AddFunc(getFunctionId(#name), name) +#define REG_FUNC(module, name) module.AddFunc(get_function_id(#name), name) -#define UNIMPLEMENTED_FUNC(module) module->Todo("%s", __FUNCTION__) \ No newline at end of file +#define UNIMPLEMENTED_FUNC(module) module.Fatal("%s", __FUNCTION__) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 08cdef858c..34f646f7d9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -17,9 +17,9 @@ extern "C" #include "cellPamf.h" #include "cellAdec.h" -Module *cellAdec = nullptr; +extern Module cellAdec; -#define ADEC_ERROR(...) { cellAdec->Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread +#define ADEC_ERROR(...) { cellAdec.Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread AudioDecoder::AudioDecoder(AudioCodecType type, u32 addr, u32 size, vm::ptr func, u32 arg) : type(type) @@ -135,7 +135,7 @@ next: OMAHeader oma(1 /* atrac3p id */, adec.sample_rate, adec.ch_cfg, adec.frame_size); if (buf_size < sizeof(oma)) { - cellAdec->Error("adecRead(): OMAHeader writing failed"); + cellAdec.Error("adecRead(): OMAHeader writing failed"); Emu.Pause(); return 0; } @@ -153,7 +153,7 @@ next: AdecTask task; if (!adec.job.peek(task, 0, &adec.is_closed)) { - if (Emu.IsStopped()) cellAdec->Warning("adecRawRead() aborted"); + if (Emu.IsStopped()) cellAdec.Warning("adecRawRead() aborted"); return 0; } @@ -187,7 +187,7 @@ next: default: { - cellAdec->Error("adecRawRead(): unknown task (%d)", task.type); + cellAdec.Error("adecRawRead(): unknown task (%d)", task.type); Emu.Pause(); return -1; } @@ -219,7 +219,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) std::shared_ptr sptr(adec_ptr); AudioDecoder& adec = *adec_ptr; - u32 adec_id = cellAdec->GetNewId(sptr); + u32 adec_id = cellAdec.GetNewId(sptr); adec.id = adec_id; @@ -254,7 +254,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) case adecStartSeq: { // TODO: reset data - cellAdec->Warning("adecStartSeq:"); + cellAdec.Warning("adecStartSeq:"); adec.reader.addr = 0; adec.reader.size = 0; @@ -276,7 +276,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) case adecEndSeq: { // TODO: finalize - cellAdec->Warning("adecEndSeq:"); + cellAdec.Warning("adecEndSeq:"); adec.cbFunc(*adec.adecCb, adec.id, CELL_ADEC_MSG_TYPE_SEQDONE, CELL_OK, adec.cbArg); adec.just_finished = true; @@ -372,7 +372,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) { if (Emu.IsStopped() || adec.is_closed) { - if (Emu.IsStopped()) cellAdec->Warning("adecDecodeAu: aborted"); + if (Emu.IsStopped()) cellAdec.Warning("adecDecodeAu: aborted"); break; } @@ -416,7 +416,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) { if (decode < 0) { - cellAdec->Error("adecDecodeAu: AU decoding error(0x%x)", decode); + cellAdec.Error("adecDecodeAu: AU decoding error(0x%x)", decode); } if (!got_frame && adec.reader.size == 0) break; } @@ -484,11 +484,11 @@ bool adecCheckType(AudioCodecType type) { switch (type) { - case CELL_ADEC_TYPE_ATRACX: cellAdec->Notice("adecCheckType(): ATRAC3plus"); break; - case CELL_ADEC_TYPE_ATRACX_2CH: cellAdec->Notice("adecCheckType(): ATRAC3plus 2ch"); break; - case CELL_ADEC_TYPE_ATRACX_6CH: cellAdec->Notice("adecCheckType(): ATRAC3plus 6ch"); break; - case CELL_ADEC_TYPE_ATRACX_8CH: cellAdec->Notice("adecCheckType(): ATRAC3plus 8ch"); break; - case CELL_ADEC_TYPE_MP3: cellAdec->Notice("adecCheckType(): MP3"); break; + case CELL_ADEC_TYPE_ATRACX: cellAdec.Notice("adecCheckType(): ATRAC3plus"); break; + case CELL_ADEC_TYPE_ATRACX_2CH: cellAdec.Notice("adecCheckType(): ATRAC3plus 2ch"); break; + case CELL_ADEC_TYPE_ATRACX_6CH: cellAdec.Notice("adecCheckType(): ATRAC3plus 6ch"); break; + case CELL_ADEC_TYPE_ATRACX_8CH: cellAdec.Notice("adecCheckType(): ATRAC3plus 8ch"); break; + case CELL_ADEC_TYPE_MP3: cellAdec.Notice("adecCheckType(): MP3"); break; case CELL_ADEC_TYPE_LPCM_PAMF: case CELL_ADEC_TYPE_AC3: @@ -498,7 +498,7 @@ bool adecCheckType(AudioCodecType type) case CELL_ADEC_TYPE_M4AAC: case CELL_ADEC_TYPE_CELP8: { - cellAdec->Todo("Unimplemented audio codec type (%d)", type); + cellAdec.Todo("Unimplemented audio codec type (%d)", type); Emu.Pause(); break; } @@ -510,7 +510,7 @@ bool adecCheckType(AudioCodecType type) int cellAdecQueryAttr(vm::ptr type, vm::ptr attr) { - cellAdec->Warning("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellAdec.Warning("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; @@ -524,7 +524,7 @@ int cellAdecQueryAttr(vm::ptr type, vm::ptr attr) int cellAdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellAdec->Warning("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellAdec.Warning("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.addr(), res.addr(), cb.addr(), handle.addr()); if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; @@ -536,7 +536,7 @@ int cellAdecOpen(vm::ptr type, vm::ptr res, vm:: int cellAdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellAdec->Warning("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellAdec.Warning("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.addr(), res.addr(), cb.addr(), handle.addr()); if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; @@ -548,7 +548,7 @@ int cellAdecOpenEx(vm::ptr type, vm::ptr res, int cellAdecClose(u32 handle) { - cellAdec->Warning("cellAdecClose(handle=%d)", handle); + cellAdec.Warning("cellAdecClose(handle=%d)", handle); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -563,7 +563,7 @@ int cellAdecClose(u32 handle) { if (Emu.IsStopped()) { - cellAdec->Warning("cellAdecClose(%d) aborted", handle); + cellAdec.Warning("cellAdecClose(%d) aborted", handle); break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack @@ -576,7 +576,7 @@ int cellAdecClose(u32 handle) int cellAdecStartSeq(u32 handle, u32 param_addr) { - cellAdec->Warning("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr); + cellAdec.Warning("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -603,7 +603,7 @@ int cellAdecStartSeq(u32 handle, u32 param_addr) task.at3p.output = param->bw_pcm; task.at3p.downmix = param->downmix_flag; task.at3p.ats_header = param->au_includes_ats_hdr_flg; - cellAdec->Todo("*** CellAdecParamAtracX: sr=%d, ch_cfg=%d(%d), frame_size=0x%x, extra=0x%x, output=%d, downmix=%d, ats_header=%d", + cellAdec.Todo("*** CellAdecParamAtracX: sr=%d, ch_cfg=%d(%d), frame_size=0x%x, extra=0x%x, output=%d, downmix=%d, ats_header=%d", task.at3p.sample_rate, task.at3p.channel_config, task.at3p.channels, task.at3p.frame_size, (u32&)task.at3p.extra_config, task.at3p.output, task.at3p.downmix, task.at3p.ats_header); break; } @@ -611,12 +611,12 @@ int cellAdecStartSeq(u32 handle, u32 param_addr) { auto param = vm::ptr::make(param_addr); - cellAdec->Todo("*** CellAdecParamMP3: bw_pcm=%d", param->bw_pcm); + cellAdec.Todo("*** CellAdecParamMP3: bw_pcm=%d", param->bw_pcm); break; } default: { - cellAdec->Todo("cellAdecStartSeq(): Unimplemented audio codec type(%d)", adec->type); + cellAdec.Todo("cellAdecStartSeq(): Unimplemented audio codec type(%d)", adec->type); Emu.Pause(); return CELL_OK; } @@ -628,7 +628,7 @@ int cellAdecStartSeq(u32 handle, u32 param_addr) int cellAdecEndSeq(u32 handle) { - cellAdec->Warning("cellAdecEndSeq(handle=%d)", handle); + cellAdec.Warning("cellAdecEndSeq(handle=%d)", handle); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -642,7 +642,7 @@ int cellAdecEndSeq(u32 handle) int cellAdecDecodeAu(u32 handle, vm::ptr auInfo) { - cellAdec->Log("cellAdecDecodeAu(handle=%d, auInfo_addr=0x%x)", handle, auInfo.addr()); + cellAdec.Log("cellAdecDecodeAu(handle=%d, auInfo_addr=0x%x)", handle, auInfo.addr()); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -657,14 +657,14 @@ int cellAdecDecodeAu(u32 handle, vm::ptr auInfo) task.au.pts = ((u64)auInfo->pts.upper << 32) | (u64)auInfo->pts.lower; task.au.userdata = auInfo->userData; - //cellAdec->Notice("cellAdecDecodeAu(): addr=0x%x, size=0x%x, pts=0x%llx", task.au.addr, task.au.size, task.au.pts); + //cellAdec.Notice("cellAdecDecodeAu(): addr=0x%x, size=0x%x, pts=0x%llx", task.au.addr, task.au.size, task.au.pts); adec->job.push(task, &adec->is_closed); return CELL_OK; } int cellAdecGetPcm(u32 handle, vm::ptr outBuffer) { - cellAdec->Log("cellAdecGetPcm(handle=%d, outBuffer_addr=0x%x)", handle, outBuffer.addr()); + cellAdec.Log("cellAdecGetPcm(handle=%d, outBuffer_addr=0x%x)", handle, outBuffer.addr()); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -770,7 +770,7 @@ int cellAdecGetPcm(u32 handle, vm::ptr outBuffer) } else { - cellAdec->Fatal("cellAdecGetPcm(): unsupported frame format (channels=%d, format=%d)", frame->channels, frame->format); + cellAdec.Fatal("cellAdecGetPcm(): unsupported frame format (channels=%d, format=%d)", frame->channels, frame->format); } } @@ -779,7 +779,7 @@ int cellAdecGetPcm(u32 handle, vm::ptr outBuffer) int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) { - cellAdec->Log("cellAdecGetPcmItem(handle=%d, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr.addr()); + cellAdec.Log("cellAdecGetPcmItem(handle=%d, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr.addr()); std::shared_ptr adec; if (!Emu.GetIdManager().GetIDData(handle, adec)) @@ -839,7 +839,7 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) } else { - cellAdec->Error("cellAdecGetPcmItem(): unsupported channel count (%d)", frame->channels); + cellAdec.Error("cellAdecGetPcmItem(): unsupported channel count (%d)", frame->channels); Emu.Pause(); } } @@ -855,10 +855,8 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) return CELL_OK; } -void cellAdec_init(Module * pxThis) +Module cellAdec("cellAdec", []() { - cellAdec = pxThis; - REG_FUNC(cellAdec, cellAdecQueryAttr); REG_FUNC(cellAdec, cellAdecOpen); REG_FUNC(cellAdec, cellAdecOpenEx); @@ -868,4 +866,4 @@ void cellAdec_init(Module * pxThis) REG_FUNC(cellAdec, cellAdecDecodeAu); REG_FUNC(cellAdec, cellAdecGetPcm); REG_FUNC(cellAdec, cellAdecGetPcmItem); -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp index 5ee26e36d0..ed3c645231 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp @@ -3,7 +3,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" -Module *cellAtrac = nullptr; +extern Module cellAtrac; #include "cellAtrac.h" @@ -15,7 +15,7 @@ u32 libatrac3plus_rtoc; s64 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) { - cellAtrac->Warning("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)", + cellAtrac.Warning("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)", pHandle.addr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x11F4, libatrac3plus_rtoc); @@ -27,7 +27,7 @@ s64 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, u32 pucBuffe s64 cellAtracCreateDecoder(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) { - cellAtrac->Warning("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", + cellAtrac.Warning("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0FF0, libatrac3plus_rtoc); @@ -39,7 +39,7 @@ s64 cellAtracCreateDecoder(vm::ptr pHandle, u32 pucWorkMem_addr s64 cellAtracCreateDecoderExt(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr pExtRes) { - cellAtrac->Warning("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)", + cellAtrac.Warning("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)", pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0DB0, libatrac3plus_rtoc); @@ -51,7 +51,7 @@ s64 cellAtracCreateDecoderExt(vm::ptr pHandle, u32 pucWorkMem_a s64 cellAtracDeleteDecoder(vm::ptr pHandle) { - cellAtrac->Warning("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr()); + cellAtrac.Warning("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0D08, libatrac3plus_rtoc); #endif @@ -61,7 +61,7 @@ s64 cellAtracDeleteDecoder(vm::ptr pHandle) s64 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr puiSamples, vm::ptr puiFinishflag, vm::ptr piRemainFrame) { - cellAtrac->Warning("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)", + cellAtrac.Warning("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), pfOutAddr, puiSamples.addr(), puiFinishflag.addr(), piRemainFrame.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x09A8, libatrac3plus_rtoc); @@ -75,7 +75,7 @@ s64 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr pHandle, vm::ptr ppucWritePointer, vm::ptr puiWritableByte, vm::ptr puiReadPosition) { - cellAtrac->Warning("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)", + cellAtrac.Warning("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)", pHandle.addr(), ppucWritePointer.addr(), puiWritableByte.addr(), puiReadPosition.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0BE8, libatrac3plus_rtoc); @@ -89,7 +89,7 @@ s64 cellAtracGetStreamDataInfo(vm::ptr pHandle, vm::ptr pp s64 cellAtracAddStreamData(vm::ptr pHandle, u32 uiAddByte) { - cellAtrac->Warning("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.addr(), uiAddByte); + cellAtrac.Warning("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.addr(), uiAddByte); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0AFC, libatrac3plus_rtoc); #endif @@ -99,7 +99,7 @@ s64 cellAtracAddStreamData(vm::ptr pHandle, u32 uiAddByte) s64 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRemainFrame) { - cellAtrac->Warning("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), piRemainFrame.addr()); + cellAtrac.Warning("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), piRemainFrame.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x092C, libatrac3plus_rtoc); #endif @@ -110,7 +110,7 @@ s64 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRem s64 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVacantSize) { - cellAtrac->Warning("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.addr(), puiVacantSize.addr()); + cellAtrac.Warning("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.addr(), puiVacantSize.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x08B0, libatrac3plus_rtoc); #endif @@ -121,7 +121,7 @@ s64 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVac s64 cellAtracIsSecondBufferNeeded(vm::ptr pHandle) { - cellAtrac->Warning("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr()); + cellAtrac.Warning("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0010, libatrac3plus_rtoc); #endif @@ -131,7 +131,7 @@ s64 cellAtracIsSecondBufferNeeded(vm::ptr pHandle) s64 cellAtracGetSecondBufferInfo(vm::ptr pHandle, vm::ptr puiReadPosition, vm::ptr puiDataByte) { - cellAtrac->Warning("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)", + cellAtrac.Warning("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)", pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x07E8, libatrac3plus_rtoc); @@ -144,7 +144,7 @@ s64 cellAtracGetSecondBufferInfo(vm::ptr pHandle, vm::ptr s64 cellAtracSetSecondBuffer(vm::ptr pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte) { - cellAtrac->Warning("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)", + cellAtrac.Warning("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)", pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0704, libatrac3plus_rtoc); @@ -155,7 +155,7 @@ s64 cellAtracSetSecondBuffer(vm::ptr pHandle, u32 pucSecondBuff s64 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChannel) { - cellAtrac->Warning("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.addr(), puiChannel.addr()); + cellAtrac.Warning("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.addr(), puiChannel.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0060, libatrac3plus_rtoc); #endif @@ -166,7 +166,7 @@ s64 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChanne s64 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxSample) { - cellAtrac->Warning("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.addr(), puiMaxSample.addr()); + cellAtrac.Warning("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.addr(), puiMaxSample.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x00AC, libatrac3plus_rtoc); #endif @@ -177,7 +177,7 @@ s64 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxS s64 cellAtracGetNextSample(vm::ptr pHandle, vm::ptr puiNextSample) { - cellAtrac->Warning("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.addr(), puiNextSample.addr()); + cellAtrac.Warning("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.addr(), puiNextSample.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0688, libatrac3plus_rtoc); #endif @@ -188,7 +188,7 @@ s64 cellAtracGetNextSample(vm::ptr pHandle, vm::ptr puiNex s64 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSample, vm::ptr piLoopStartSample, vm::ptr piLoopEndSample) { - cellAtrac->Warning("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)", + cellAtrac.Warning("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)", pHandle.addr(), piEndSample.addr(), piLoopStartSample.addr(), piLoopEndSample.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0104, libatrac3plus_rtoc); @@ -202,7 +202,7 @@ s64 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSa s64 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr puiSamplePosition) { - cellAtrac->Warning("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)", + cellAtrac.Warning("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)", pHandle.addr(), puiSamplePosition.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0190, libatrac3plus_rtoc); @@ -214,7 +214,7 @@ s64 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr pHandle, vm::ptr puiBitrate) { - cellAtrac->Warning("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)", + cellAtrac.Warning("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)", pHandle.addr(), puiBitrate.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0374, libatrac3plus_rtoc); @@ -226,7 +226,7 @@ s64 cellAtracGetBitrate(vm::ptr pHandle, vm::ptr puiBitrat s64 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNum, vm::ptr puiLoopStatus) { - cellAtrac->Warning("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)", + cellAtrac.Warning("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)", pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x025C, libatrac3plus_rtoc); @@ -239,7 +239,7 @@ s64 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNu s64 cellAtracSetLoopNum(vm::ptr pHandle, int iLoopNum) { - cellAtrac->Warning("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.addr(), iLoopNum); + cellAtrac.Warning("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.addr(), iLoopNum); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x1538, libatrac3plus_rtoc); #endif @@ -249,7 +249,7 @@ s64 cellAtracSetLoopNum(vm::ptr pHandle, int iLoopNum) s64 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiSample, vm::ptr pBufferInfo) { - cellAtrac->Warning("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)", + cellAtrac.Warning("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)", pHandle.addr(), uiSample, pBufferInfo.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x05BC, libatrac3plus_rtoc); @@ -264,7 +264,7 @@ s64 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiS s64 cellAtracResetPlayPosition(vm::ptr pHandle, u32 uiSample, u32 uiWriteByte) { - cellAtrac->Warning("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)", + cellAtrac.Warning("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)", pHandle.addr(), uiSample, uiWriteByte); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x04E4, libatrac3plus_rtoc); @@ -275,7 +275,7 @@ s64 cellAtracResetPlayPosition(vm::ptr pHandle, u32 uiSample, u s64 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr piResult) { - cellAtrac->Warning("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)", + cellAtrac.Warning("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)", pHandle.addr(), piResult.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x02E4, libatrac3plus_rtoc); @@ -285,40 +285,38 @@ s64 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr return CELL_OK; } -void cellAtrac_init(Module *pxThis) +Module cellAtrac("cellAtrac", []() { - cellAtrac = pxThis; + cellAtrac.AddFunc(0x66afc68e, cellAtracSetDataAndGetMemSize); - cellAtrac->AddFunc(0x66afc68e, cellAtracSetDataAndGetMemSize); + cellAtrac.AddFunc(0xfa293e88, cellAtracCreateDecoder); + cellAtrac.AddFunc(0x2642d4cc, cellAtracCreateDecoderExt); + cellAtrac.AddFunc(0x761cb9be, cellAtracDeleteDecoder); - cellAtrac->AddFunc(0xfa293e88, cellAtracCreateDecoder); - cellAtrac->AddFunc(0x2642d4cc, cellAtracCreateDecoderExt); - cellAtrac->AddFunc(0x761cb9be, cellAtracDeleteDecoder); + cellAtrac.AddFunc(0x8eb0e65f, cellAtracDecode); - cellAtrac->AddFunc(0x8eb0e65f, cellAtracDecode); + cellAtrac.AddFunc(0x2bfff084, cellAtracGetStreamDataInfo); + cellAtrac.AddFunc(0x46cfc013, cellAtracAddStreamData); + cellAtrac.AddFunc(0xdfab73aa, cellAtracGetRemainFrame); + cellAtrac.AddFunc(0xc9a95fcb, cellAtracGetVacantSize); + cellAtrac.AddFunc(0x99efe171, cellAtracIsSecondBufferNeeded); + cellAtrac.AddFunc(0xbe07f05e, cellAtracGetSecondBufferInfo); + cellAtrac.AddFunc(0x06ddb53e, cellAtracSetSecondBuffer); - cellAtrac->AddFunc(0x2bfff084, cellAtracGetStreamDataInfo); - cellAtrac->AddFunc(0x46cfc013, cellAtracAddStreamData); - cellAtrac->AddFunc(0xdfab73aa, cellAtracGetRemainFrame); - cellAtrac->AddFunc(0xc9a95fcb, cellAtracGetVacantSize); - cellAtrac->AddFunc(0x99efe171, cellAtracIsSecondBufferNeeded); - cellAtrac->AddFunc(0xbe07f05e, cellAtracGetSecondBufferInfo); - cellAtrac->AddFunc(0x06ddb53e, cellAtracSetSecondBuffer); + cellAtrac.AddFunc(0x0f9667b6, cellAtracGetChannel); + cellAtrac.AddFunc(0x5f62d546, cellAtracGetMaxSample); + cellAtrac.AddFunc(0x4797d1ff, cellAtracGetNextSample); + cellAtrac.AddFunc(0xcf01d5d4, cellAtracGetSoundInfo); + cellAtrac.AddFunc(0x7b22e672, cellAtracGetNextDecodePosition); + cellAtrac.AddFunc(0x006016da, cellAtracGetBitrate); - cellAtrac->AddFunc(0x0f9667b6, cellAtracGetChannel); - cellAtrac->AddFunc(0x5f62d546, cellAtracGetMaxSample); - cellAtrac->AddFunc(0x4797d1ff, cellAtracGetNextSample); - cellAtrac->AddFunc(0xcf01d5d4, cellAtracGetSoundInfo); - cellAtrac->AddFunc(0x7b22e672, cellAtracGetNextDecodePosition); - cellAtrac->AddFunc(0x006016da, cellAtracGetBitrate); + cellAtrac.AddFunc(0xab6b6dbf, cellAtracGetLoopInfo); + cellAtrac.AddFunc(0x78ba5c41, cellAtracSetLoopNum); - cellAtrac->AddFunc(0xab6b6dbf, cellAtracGetLoopInfo); - cellAtrac->AddFunc(0x78ba5c41, cellAtracSetLoopNum); + cellAtrac.AddFunc(0x99fb73d1, cellAtracGetBufferInfoForResetting); + cellAtrac.AddFunc(0x7772eb2b, cellAtracResetPlayPosition); - cellAtrac->AddFunc(0x99fb73d1, cellAtracGetBufferInfoForResetting); - cellAtrac->AddFunc(0x7772eb2b, cellAtracResetPlayPosition); - - cellAtrac->AddFunc(0xb5c11938, cellAtracGetInternalErrorInfo); + cellAtrac.AddFunc(0xb5c11938, cellAtracGetInternalErrorInfo); #ifdef PRX_DEBUG CallAfter([]() @@ -342,4 +340,4 @@ void cellAtrac_init(Module *pxThis) fix_relocs(cellAtrac, libatrac3plus, 0x3EF0, 0x5048, 0x3CE0); }); #endif -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 11e7b78220..ede262b6e7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -15,13 +15,13 @@ #include "cellAudio.h" -Module *cellAudio = nullptr; +extern Module cellAudio; AudioConfig g_audio; s32 cellAudioInit() { - cellAudio->Warning("cellAudioInit()"); + cellAudio.Warning("cellAudioInit()"); if (!g_audio.state.compare_and_swap_test(AUDIO_STATE_NOT_INITIALIZED, AUDIO_STATE_INITIALIZED)) { @@ -177,7 +177,7 @@ s32 cellAudioInit() const u64 missed_time = stamp0 - g_audio.start_time - expected_time; if (missed_time > AUDIO_SAMPLES * MHZ / 48000) { - cellAudio->Notice("%f ms adjusted", (float)missed_time / 1000); + cellAudio.Notice("%f ms adjusted", (float)missed_time / 1000); g_audio.start_time += missed_time; } @@ -434,7 +434,7 @@ s32 cellAudioInit() s32 cellAudioQuit() { - cellAudio->Warning("cellAudioQuit()"); + cellAudio.Warning("cellAudioQuit()"); if (!g_audio.state.compare_and_swap_test(AUDIO_STATE_INITIALIZED, AUDIO_STATE_FINALIZED)) { @@ -448,7 +448,7 @@ s32 cellAudioQuit() s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portNum) { - cellAudio->Warning("cellAudioPortOpen(audioParam=0x%x, portNum=0x%x)", audioParam, portNum); + cellAudio.Warning("cellAudioPortOpen(audioParam=0x%x, portNum=0x%x)", audioParam, portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -484,35 +484,35 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN // list unsupported flags if (attr & CELL_AUDIO_PORTATTR_BGM) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_BGM"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_BGM"); } if (attr & CELL_AUDIO_PORTATTR_OUT_SECONDARY) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_SECONDARY"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_SECONDARY"); } if (attr & CELL_AUDIO_PORTATTR_OUT_PERSONAL_0) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_0"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_0"); } if (attr & CELL_AUDIO_PORTATTR_OUT_PERSONAL_1) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_1"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_1"); } if (attr & CELL_AUDIO_PORTATTR_OUT_PERSONAL_2) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_2"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_2"); } if (attr & CELL_AUDIO_PORTATTR_OUT_PERSONAL_3) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_3"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_PERSONAL_3"); } if (attr & CELL_AUDIO_PORTATTR_OUT_NO_ROUTE) { - cellAudio->Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_NO_ROUTE"); + cellAudio.Todo("cellAudioPortOpen(): CELL_AUDIO_PORTATTR_OUT_NO_ROUTE"); } if (attr & 0xFFFFFFFFF0EFEFEEULL) { - cellAudio->Todo("cellAudioPortOpen(): unknown attributes set (0x%llx)", attr); + cellAudio.Todo("cellAudioPortOpen(): unknown attributes set (0x%llx)", attr); } // open audio port @@ -546,14 +546,14 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN port.level_inc = 0.0f; *portNum = port_index; - cellAudio->Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", channel, block, attr, port.level, port_index); + cellAudio.Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", channel, block, attr, port.level, port_index); return CELL_OK; } s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) { - cellAudio->Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig=0x%x)", portNum, portConfig); + cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig=0x%x)", portNum, portConfig); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -586,7 +586,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) s32 cellAudioPortStart(u32 portNum) { - cellAudio->Warning("cellAudioPortStart(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -609,7 +609,7 @@ s32 cellAudioPortStart(u32 portNum) s32 cellAudioPortClose(u32 portNum) { - cellAudio->Warning("cellAudioPortClose(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -632,7 +632,7 @@ s32 cellAudioPortClose(u32 portNum) s32 cellAudioPortStop(u32 portNum) { - cellAudio->Warning("cellAudioPortStop(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStop(portNum=0x%x)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -655,7 +655,7 @@ s32 cellAudioPortStop(u32 portNum) s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) { - cellAudio->Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp=0x%x)", portNum, tag, stamp); + cellAudio.Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp=0x%x)", portNum, tag, stamp); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -685,7 +685,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) { - cellAudio->Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag=0x%x)", portNum, blockNo, tag); + cellAudio.Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag=0x%x)", portNum, blockNo, tag); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -728,7 +728,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) s32 cellAudioSetPortLevel(u32 portNum, float level) { - cellAudio->Log("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level); + cellAudio.Log("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -756,7 +756,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) } else { - cellAudio->Todo("cellAudioSetPortLevel(portNum=0x%x): negative level value (%f)", portNum, level); + cellAudio.Todo("cellAudioSetPortLevel(portNum=0x%x): negative level value (%f)", portNum, level); } return CELL_OK; @@ -765,7 +765,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) // Utility Functions int cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) { - cellAudio->Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.addr(), key.addr()); + cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.addr(), key.addr()); std::lock_guard lock(g_audio.mutex); @@ -784,7 +784,7 @@ int cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) return CELL_AUDIO_ERROR_EVENT_QUEUE; } - *id = cellAudio->GetNewId(eq); + *id = cellAudio.GetNewId(eq); *key = event_key; return CELL_OK; @@ -792,13 +792,13 @@ int cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) int cellAudioCreateNotifyEventQueueEx(vm::ptr id, vm::ptr key, u32 iFlags) { - cellAudio->Todo("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.addr(), key.addr(), iFlags); + cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.addr(), key.addr(), iFlags); return CELL_OK; } int cellAudioSetNotifyEventQueue(u64 key) { - cellAudio->Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); + cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); std::lock_guard lock(g_audio.mutex); @@ -824,13 +824,13 @@ int cellAudioSetNotifyEventQueue(u64 key) int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags) { - cellAudio->Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); return CELL_OK; } int cellAudioRemoveNotifyEventQueue(u64 key) { - cellAudio->Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); + cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); std::lock_guard lock(g_audio.mutex); @@ -864,13 +864,13 @@ int cellAudioRemoveNotifyEventQueue(u64 key) int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags) { - cellAudio->Todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + cellAudio.Todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); return CELL_OK; } s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio->Log("cellAudioAddData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAddData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -885,7 +885,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio->Error("cellAudioAddData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAddData(): invalid samples value (0x%x)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -903,7 +903,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio->Log("cellAudioAdd2chData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -918,7 +918,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio->Error("cellAudioAdd2chData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAdd2chData(): invalid samples value (0x%x)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -928,7 +928,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu if (port.channel == 2) { - cellAudio->Error("cellAudioAdd2chData(portNum=%d): port.channel = 2", portNum); + cellAudio.Error("cellAudioAdd2chData(portNum=%d): port.channel = 2", portNum); } else if (port.channel == 6) { @@ -958,7 +958,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu } else { - cellAudio->Error("cellAudioAdd2chData(portNum=%d): invalid port.channel value (%d)", portNum, port.channel); + cellAudio.Error("cellAudioAdd2chData(portNum=%d): invalid port.channel value (%d)", portNum, port.channel); } return CELL_OK; @@ -966,7 +966,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) { - cellAudio->Log("cellAudioAdd6chData(portNum=%d, src=0x%x, volume=%f)", portNum, src, volume); + cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=0x%x, volume=%f)", portNum, src, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -984,7 +984,7 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) if (port.channel == 2 || port.channel == 6) { - cellAudio->Error("cellAudioAdd2chData(portNum=%d): port.channel = %d", portNum, port.channel); + cellAudio.Error("cellAudioAdd2chData(portNum=%d): port.channel = %d", portNum, port.channel); } else if (port.channel == 8) { @@ -1002,7 +1002,7 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) } else { - cellAudio->Error("cellAudioAdd6chData(portNum=%d): invalid port.channel value (%d)", portNum, port.channel); + cellAudio.Error("cellAudioAdd6chData(portNum=%d): invalid port.channel value (%d)", portNum, port.channel); } return CELL_OK; @@ -1010,32 +1010,30 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume) { - cellAudio->Todo("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume); + cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume); return CELL_OK; } int cellAudioSendAck(u64 data3) { - cellAudio->Todo("cellAudioSendAck(data3=0x%llx)", data3); + cellAudio.Todo("cellAudioSendAck(data3=0x%llx)", data3); return CELL_OK; } int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice) { - cellAudio->Todo("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice); + cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice); return CELL_OK; } int cellAudioUnsetPersonalDevice(int iPersonalStream) { - cellAudio->Todo("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream); + cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream); return CELL_OK; } -void cellAudio_init(Module *pxThis) +Module cellAudio("cellAudio", []() { - cellAudio = pxThis; - g_audio.state.write_relaxed(AUDIO_STATE_NOT_INITIALIZED); g_audio.buffer = 0; g_audio.indexes = 0; @@ -1063,9 +1061,4 @@ void cellAudio_init(Module *pxThis) REG_FUNC(cellAudio, cellAudioSendAck); REG_FUNC(cellAudio, cellAudioSetPersonalDevice); REG_FUNC(cellAudio, cellAudioUnsetPersonalDevice); -} - -void cellAudio_load() -{ - // CELL_SYSMODULE AUDIO module is rarely loaded manually, so cellAudio_load() won't be called in every case -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp index 9014f472f0..3cf9114e6a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp @@ -4,7 +4,7 @@ #include "Emu/SysCalls/Modules.h" #include "Emu/RSX/sysutil_video.h" -Module *cellAvconfExt = nullptr; +extern Module cellAvconfExt; int cellVideoOutConvertCursorColor() { @@ -14,7 +14,7 @@ int cellVideoOutConvertCursorColor() int cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) { - cellAvconfExt->Warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize_addr=0x%x)", videoOut, screenSize.addr()); + cellAvconfExt.Warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize_addr=0x%x)", videoOut, screenSize.addr()); if (videoOut != CELL_VIDEO_OUT_PRIMARY) { @@ -53,12 +53,10 @@ int cellVideoOutSetGamma() return CELL_OK; } -void cellAvconfExt_init(Module *pxThis) +Module cellAvconfExt("cellAvconfExt", []() { - cellAvconfExt = pxThis; - REG_FUNC(cellAvconfExt, cellVideoOutConvertCursorColor); REG_FUNC(cellAvconfExt, cellVideoOutGetScreenSize); REG_FUNC(cellAvconfExt, cellVideoOutGetGamma); REG_FUNC(cellAvconfExt, cellVideoOutSetGamma); -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp index d363ca072e..ab8f5d4526 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellCamera.cpp @@ -5,7 +5,7 @@ #include "cellCamera.h" -Module *cellCamera = nullptr; +extern Module cellCamera; const char* attributes[] = {"GAIN", "REDBLUEGAIN", "SATURATION", "EXPOSURE", "BRIGHTNESS", "AEC", "AGC", "AWB", "ABC", "LED", "AUDIOGAIN", "QS", "NONZEROCOEFFS", "YUVFLAG", "JPEGFLAG", "BACKLIGHTCOMP", "MIRRORFLAG", "MEASUREDQS", "422FLAG", "USBLOAD", "GAMMA", "GREENGAIN", "AGCLIMIT", "DENOISE", "FRAMERATEADJUST", "PIXELOUTLIERFILTER", "AGCLOW", "AGCHIGH", "DEVICELOCATION", "FORMATCAP", "FORMATINDEX", "NUMFRAME", "FRAMEINDEX", "FRAMESIZE", "INTERVALTYPE", @@ -27,7 +27,7 @@ cellCameraInternal cellCameraInstance; int cellCameraInit() { - cellCamera->Warning("cellCameraInit()"); + cellCamera.Warning("cellCameraInit()"); if (cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_ALREADY_INIT; @@ -84,7 +84,7 @@ int cellCameraInit() int cellCameraEnd() { - cellCamera->Warning("cellCameraEnd()"); + cellCamera.Warning("cellCameraEnd()"); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; @@ -132,7 +132,7 @@ int cellCameraGetDeviceGUID() int cellCameraGetType(s32 dev_num, vm::ptr type) { - cellCamera->Warning("cellCameraGetType(dev_num=%d, type_addr=0x%x)", dev_num, type.addr()); + cellCamera.Warning("cellCameraGetType(dev_num=%d, type_addr=0x%x)", dev_num, type.addr()); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; @@ -174,7 +174,7 @@ int cellCameraIsStarted() int cellCameraGetAttribute(s32 dev_num, CellCameraAttribute attrib, vm::ptr arg1, vm::ptr arg2) { - cellCamera->Warning("cellCameraGetAttribute(dev_num=%d, attrib=%s(%d), arg1=0x%x, arg2=0x%x)", dev_num, attributes[attrib], arg1.addr(), arg2.addr()); + cellCamera.Warning("cellCameraGetAttribute(dev_num=%d, attrib=%s(%d), arg1=0x%x, arg2=0x%x)", dev_num, attributes[attrib], arg1.addr(), arg2.addr()); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; @@ -288,7 +288,7 @@ int cellCameraGetAttribute(s32 dev_num, CellCameraAttribute attrib, vm::ptr int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u32 arg2) { - cellCamera->Warning("cellCameraSetAttribute(dev_num=%d, attrib=%s(%d), arg1=%d, arg2=%d)", dev_num, attributes[attrib], attrib, arg1, arg2); + cellCamera.Warning("cellCameraSetAttribute(dev_num=%d, attrib=%s(%d), arg1=%d, arg2=%d)", dev_num, attributes[attrib], attrib, arg1, arg2); if (!cellCameraInstance.m_bInitialized) return CELL_CAMERA_ERROR_NOT_INIT; @@ -355,7 +355,7 @@ int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u3 else if (attrib == 28) cellCameraInstance.m_camera.attributes.DEVICELOCATION = arg1; else if (attrib == 29) - cellCamera->Error("Tried to write to read-only (?) value: FORMATCAP"); + cellCamera.Error("Tried to write to read-only (?) value: FORMATCAP"); else if (attrib == 30) cellCameraInstance.m_camera.attributes.FORMATINDEX = arg1; else if (attrib == 31) @@ -387,7 +387,7 @@ int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u3 else if (attrib == 44) return CELL_CAMERA_ERROR_PARAM; else if (attrib == 45) - cellCamera->Error("Tried to write to read-only (?) value: READMODE"); + cellCamera.Error("Tried to write to read-only (?) value: READMODE"); else if (attrib == 46) cellCameraInstance.m_camera.attributes.GAMEPID = arg1; else if (attrib == 47) @@ -395,7 +395,7 @@ int cellCameraSetAttribute(s32 dev_num, CellCameraAttribute attrib, u32 arg1, u3 else if (attrib == 48) cellCameraInstance.m_camera.attributes.READFINISH = arg1; else if (attrib == 49) - cellCamera->Error("Tried to write to read-only (?) value: ATTRIBUTE_UNKNOWN"); + cellCamera.Error("Tried to write to read-only (?) value: ATTRIBUTE_UNKNOWN"); return CELL_OK; } @@ -555,42 +555,40 @@ void cellCamera_unload() cellCameraInstance.m_bInitialized = false; } -void cellCamera_init(Module* pxThis) +Module cellCamera("cellCamera", []() { - cellCamera = pxThis; + cellCamera.AddFunc(0xbf47c5dd, cellCameraInit); + cellCamera.AddFunc(0x5ad46570, cellCameraEnd); + cellCamera.AddFunc(0x85e1b8da, cellCameraOpen); + cellCamera.AddFunc(0x5d25f866, cellCameraOpenEx); + cellCamera.AddFunc(0x379c5dd6, cellCameraClose); - cellCamera->AddFunc(0xbf47c5dd, cellCameraInit); - cellCamera->AddFunc(0x5ad46570, cellCameraEnd); - cellCamera->AddFunc(0x85e1b8da, cellCameraOpen); - cellCamera->AddFunc(0x5d25f866, cellCameraOpenEx); - cellCamera->AddFunc(0x379c5dd6, cellCameraClose); + cellCamera.AddFunc(0x602e2052, cellCameraGetDeviceGUID); + cellCamera.AddFunc(0x58bc5870, cellCameraGetType); + cellCamera.AddFunc(0x8ca53dde, cellCameraIsAvailable); + cellCamera.AddFunc(0x7e063bbc, cellCameraIsAttached); + cellCamera.AddFunc(0xfa160f24, cellCameraIsOpen); + cellCamera.AddFunc(0x5eebf24e, cellCameraIsStarted); + cellCamera.AddFunc(0x532b8aaa, cellCameraGetAttribute); + cellCamera.AddFunc(0x8cd56eee, cellCameraSetAttribute); + cellCamera.AddFunc(0x7dac520c, cellCameraGetBufferSize); + cellCamera.AddFunc(0x10697d7f, cellCameraGetBufferInfo); + cellCamera.AddFunc(0x0e63c444, cellCameraGetBufferInfoEx); - cellCamera->AddFunc(0x602e2052, cellCameraGetDeviceGUID); - cellCamera->AddFunc(0x58bc5870, cellCameraGetType); - cellCamera->AddFunc(0x8ca53dde, cellCameraIsAvailable); - cellCamera->AddFunc(0x7e063bbc, cellCameraIsAttached); - cellCamera->AddFunc(0xfa160f24, cellCameraIsOpen); - cellCamera->AddFunc(0x5eebf24e, cellCameraIsStarted); - cellCamera->AddFunc(0x532b8aaa, cellCameraGetAttribute); - cellCamera->AddFunc(0x8cd56eee, cellCameraSetAttribute); - cellCamera->AddFunc(0x7dac520c, cellCameraGetBufferSize); - cellCamera->AddFunc(0x10697d7f, cellCameraGetBufferInfo); - cellCamera->AddFunc(0x0e63c444, cellCameraGetBufferInfoEx); + cellCamera.AddFunc(0x61dfbe83, cellCameraPrepExtensionUnit); + cellCamera.AddFunc(0xeb6f95fb, cellCameraCtrlExtensionUnit); + cellCamera.AddFunc(0xb602e328, cellCameraGetExtensionUnit); + cellCamera.AddFunc(0x2dea3e9b, cellCameraSetExtensionUnit); - cellCamera->AddFunc(0x61dfbe83, cellCameraPrepExtensionUnit); - cellCamera->AddFunc(0xeb6f95fb, cellCameraCtrlExtensionUnit); - cellCamera->AddFunc(0xb602e328, cellCameraGetExtensionUnit); - cellCamera->AddFunc(0x2dea3e9b, cellCameraSetExtensionUnit); + cellCamera.AddFunc(0x81f83db9, cellCameraReset); + cellCamera.AddFunc(0x456dc4aa, cellCameraStart); + cellCamera.AddFunc(0x3845d39b, cellCameraRead); + cellCamera.AddFunc(0x21fc151f, cellCameraReadEx); + cellCamera.AddFunc(0xe28b206b, cellCameraReadComplete); + cellCamera.AddFunc(0x02f5ced0, cellCameraStop); - cellCamera->AddFunc(0x81f83db9, cellCameraReset); - cellCamera->AddFunc(0x456dc4aa, cellCameraStart); - cellCamera->AddFunc(0x3845d39b, cellCameraRead); - cellCamera->AddFunc(0x21fc151f, cellCameraReadEx); - cellCamera->AddFunc(0xe28b206b, cellCameraReadComplete); - cellCamera->AddFunc(0x02f5ced0, cellCameraStop); - - cellCamera->AddFunc(0xb0647e5a, cellCameraSetNotifyEventQueue); - cellCamera->AddFunc(0x9b98d258, cellCameraRemoveNotifyEventQueue); - cellCamera->AddFunc(0xa7fd2f5b, cellCameraSetNotifyEventQueue2); - cellCamera->AddFunc(0x44673f07, cellCameraRemoveNotifyEventQueue2); -} + cellCamera.AddFunc(0xb0647e5a, cellCameraSetNotifyEventQueue); + cellCamera.AddFunc(0x9b98d258, cellCameraRemoveNotifyEventQueue); + cellCamera.AddFunc(0xa7fd2f5b, cellCameraSetNotifyEventQueue2); + cellCamera.AddFunc(0x44673f07, cellCameraRemoveNotifyEventQueue2); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 9bf3c1ff03..4e3e7e610a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -8,9 +8,9 @@ #include "cellPamf.h" #include "cellDmux.h" -Module *cellDmux = nullptr; +extern Module cellDmux; -#define DMUX_ERROR(...) { cellDmux->Error(__VA_ARGS__); Emu.Pause(); return; } // only for demuxer thread +#define DMUX_ERROR(...) { cellDmux.Error(__VA_ARGS__); Emu.Pause(); return; } // only for demuxer thread PesHeader::PesHeader(DemuxerStream& stream) : pts(CODEC_TS_INVALID) @@ -62,7 +62,7 @@ PesHeader::PesHeader(DemuxerStream& stream) if ((v & 0xf0) != 0x10) { - cellDmux->Error("PesHeader(): dts not found (v=0x%x, size=%d, pos=%d)", v, size, pos - 1); + cellDmux.Error("PesHeader(): dts not found (v=0x%x, size=%d, pos=%d)", v, size, pos - 1); stream.skip(size - pos); return; } @@ -71,7 +71,7 @@ PesHeader::PesHeader(DemuxerStream& stream) } else { - cellDmux->Warning("PesHeader(): unknown code (v=0x%x, size=%d, pos=%d)", v, size, pos - 1); + cellDmux.Warning("PesHeader(): unknown code (v=0x%x, size=%d, pos=%d)", v, size, pos - 1); stream.skip(size - pos); pos = size; break; @@ -210,13 +210,13 @@ bool ElementaryStream::release() std::lock_guard lock(m_mutex); if (released >= put_count) { - cellDmux->Error("es::release() error: buffer is empty"); + cellDmux.Error("es::release() error: buffer is empty"); Emu.Pause(); return false; } if (released >= got_count) { - cellDmux->Error("es::release() error: buffer has not been seen yet"); + cellDmux.Error("es::release() error: buffer has not been seen yet"); Emu.Pause(); return false; } @@ -224,7 +224,7 @@ bool ElementaryStream::release() u32 addr = 0; if (!entries.pop(addr, &dmux->is_closed) || !addr) { - cellDmux->Error("es::release() error: entries.Pop() failed"); + cellDmux.Error("es::release() error: entries.Pop() failed"); Emu.Pause(); return false; } @@ -238,7 +238,7 @@ bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool updat std::lock_guard lock(m_mutex); if (got_count < released) { - cellDmux->Error("es::peek() error: got_count(%d) < released(%d) (put_count=%d)", got_count, released, put_count); + cellDmux.Error("es::peek() error: got_count(%d) < released(%d) (put_count=%d)", got_count, released, put_count); Emu.Pause(); return false; } @@ -250,7 +250,7 @@ bool ElementaryStream::peek(u32& out_data, bool no_ex, u32& out_spec, bool updat u32 addr = 0; if (!entries.peek(addr, got_count - released, &dmux->is_closed) || !addr) { - cellDmux->Error("es::peek() error: entries.Peek() failed"); + cellDmux.Error("es::peek() error: entries.Peek() failed"); Emu.Pause(); return false; } @@ -292,7 +292,7 @@ void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, vm::ptrmemSize = 0x7000; // 0x73d9 from ps3 - cellDmux->Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor, + cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor, (u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2); } @@ -301,7 +301,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) std::shared_ptr sptr(dmux_ptr); Demuxer& dmux = *dmux_ptr; - u32 dmux_id = cellDmux->GetNewId(sptr); + u32 dmux_id = cellDmux.GetNewId(sptr); dmux.id = dmux_id; @@ -403,7 +403,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) stream.skip(4); stream.get(len); - cellDmux->Notice("PRIVATE_STREAM_2 (%d)", len); + cellDmux.Notice("PRIVATE_STREAM_2 (%d)", len); if (!stream.check(len)) { @@ -494,7 +494,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) es.push_au(frame_size + 8, es.last_dts, es.last_pts, stream.userdata, false /* TODO: set correct value */, 0); - //cellDmux->Notice("ATX AU pushed (ats=0x%llx, frame_size=%d)", *(be_t*)data, frame_size); + //cellDmux.Notice("ATX AU pushed (ats=0x%llx, frame_size=%d)", *(be_t*)data, frame_size); auto esMsg = vm::ptr::make(dmux.memAddr + (cb_add ^= 16)); esMsg->msgType = CELL_DMUX_ES_MSG_TYPE_AU_FOUND; @@ -504,7 +504,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) } else { - cellDmux->Notice("PRIVATE_STREAM_1 (len=%d, fid_minor=0x%x)", len, fid_minor); + cellDmux.Notice("PRIVATE_STREAM_1 (len=%d, fid_minor=0x%x)", len, fid_minor); stream.skip(len); } break; @@ -581,7 +581,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) } else { - cellDmux->Notice("Video stream (code=0x%x, len=%d)", code, len); + cellDmux.Notice("Video stream (code=0x%x, len=%d)", code, len); stream.skip(len); } break; @@ -614,7 +614,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) { if (task.stream.discontinuity) { - cellDmux->Warning("dmuxSetStream (beginning)"); + cellDmux.Warning("dmuxSetStream (beginning)"); for (u32 i = 0; i < sizeof(esALL) / sizeof(esALL[0]); i++) { if (esALL[i]) @@ -729,7 +729,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) if (es.raw_data.size()) { - cellDmux->Error("dmuxFlushEs: 0x%x bytes lost (es_id=%d)", (u32)es.raw_data.size(), es.id); + cellDmux.Error("dmuxFlushEs: 0x%x bytes lost (es_id=%d)", (u32)es.raw_data.size(), es.id); } // callback @@ -766,7 +766,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) int cellDmuxQueryAttr(vm::ptr demuxerType, vm::ptr demuxerAttr) { - cellDmux->Warning("cellDmuxQueryAttr(demuxerType_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType.addr(), demuxerAttr.addr()); + cellDmux.Warning("cellDmuxQueryAttr(demuxerType_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType.addr(), demuxerAttr.addr()); if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { @@ -779,7 +779,7 @@ int cellDmuxQueryAttr(vm::ptr demuxerType, vm::ptr demuxerType2, vm::ptr demuxerAttr) { - cellDmux->Warning("cellDmuxQueryAttr2(demuxerType2_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType2.addr(), demuxerAttr.addr()); + cellDmux.Warning("cellDmuxQueryAttr2(demuxerType2_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType2.addr(), demuxerAttr.addr()); if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { @@ -793,7 +793,7 @@ int cellDmuxQueryAttr2(vm::ptr demuxerType2, vm::ptr demuxerType, vm::ptr demuxerResource, vm::ptr demuxerCb, vm::ptr demuxerHandle) { - cellDmux->Warning("cellDmuxOpen(demuxerType_addr=0x%x, demuxerResource_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpen(demuxerType_addr=0x%x, demuxerResource_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType.addr(), demuxerResource.addr(), demuxerCb.addr(), demuxerHandle.addr()); if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) @@ -811,7 +811,7 @@ int cellDmuxOpen(vm::ptr demuxerType, vm::ptr demuxerType, vm::ptr demuxerResourceEx, vm::ptr demuxerCb, vm::ptr demuxerHandle) { - cellDmux->Warning("cellDmuxOpenEx(demuxerType_addr=0x%x, demuxerResourceEx_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpenEx(demuxerType_addr=0x%x, demuxerResourceEx_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType.addr(), demuxerResourceEx.addr(), demuxerCb.addr(), demuxerHandle.addr()); if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) @@ -829,7 +829,7 @@ int cellDmuxOpenEx(vm::ptr demuxerType, vm::ptr demuxerType2, vm::ptr demuxerResource2, vm::ptr demuxerCb, vm::ptr demuxerHandle) { - cellDmux->Warning("cellDmuxOpen2(demuxerType2_addr=0x%x, demuxerResource2_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", + cellDmux.Warning("cellDmuxOpen2(demuxerType2_addr=0x%x, demuxerResource2_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", demuxerType2.addr(), demuxerResource2.addr(), demuxerCb.addr(), demuxerHandle.addr()); if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) @@ -846,7 +846,7 @@ int cellDmuxOpen2(vm::ptr demuxerType2, vm::ptrWarning("cellDmuxClose(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxClose(demuxerHandle=%d)", demuxerHandle); std::shared_ptr dmux; if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) @@ -861,7 +861,7 @@ int cellDmuxClose(u32 demuxerHandle) { if (Emu.IsStopped()) { - cellDmux->Warning("cellDmuxClose(%d) aborted", demuxerHandle); + cellDmux.Warning("cellDmuxClose(%d) aborted", demuxerHandle); return CELL_OK; } @@ -875,7 +875,7 @@ int cellDmuxClose(u32 demuxerHandle) int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize, bool discontinuity, u64 userData) { - cellDmux->Log("cellDmuxSetStream(demuxerHandle=%d, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx", + cellDmux.Log("cellDmuxSetStream(demuxerHandle=%d, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx", demuxerHandle, streamAddress, streamSize, discontinuity, userData); std::shared_ptr dmux; @@ -903,7 +903,7 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize int cellDmuxResetStream(u32 demuxerHandle) { - cellDmux->Warning("cellDmuxResetStream(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxResetStream(demuxerHandle=%d)", demuxerHandle); std::shared_ptr dmux; if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) @@ -917,7 +917,7 @@ int cellDmuxResetStream(u32 demuxerHandle) int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) { - cellDmux->Warning("cellDmuxResetStreamAndWaitDone(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxResetStreamAndWaitDone(demuxerHandle=%d)", demuxerHandle); std::shared_ptr dmux; if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) @@ -930,7 +930,7 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) { if (Emu.IsStopped()) { - cellDmux->Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); + cellDmux.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack @@ -941,7 +941,7 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) int cellDmuxQueryEsAttr(vm::ptr demuxerType, vm::ptr esFilterId, const u32 esSpecificInfo_addr, vm::ptr esAttr) { - cellDmux->Warning("cellDmuxQueryEsAttr(demuxerType_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", + cellDmux.Warning("cellDmuxQueryEsAttr(demuxerType_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", demuxerType.addr(), esFilterId.addr(), esSpecificInfo_addr, esAttr.addr()); if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) @@ -957,7 +957,7 @@ int cellDmuxQueryEsAttr(vm::ptr demuxerType, vm::ptr demuxerType2, vm::ptr esFilterId, const u32 esSpecificInfo_addr, vm::ptr esAttr) { - cellDmux->Warning("cellDmuxQueryEsAttr2(demuxerType2_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", + cellDmux.Warning("cellDmuxQueryEsAttr2(demuxerType2_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", demuxerType2.addr(), esFilterId.addr(), esSpecificInfo_addr, esAttr.addr()); if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) @@ -974,7 +974,7 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFil vm::ptr esResourceInfo, vm::ptr esCb, const u32 esSpecificInfo_addr, vm::ptr esHandle) { - cellDmux->Warning("cellDmuxEnableEs(demuxerHandle=%d, esFilterId_addr=0x%x, esResourceInfo_addr=0x%x, esCb_addr=0x%x, " + cellDmux.Warning("cellDmuxEnableEs(demuxerHandle=%d, esFilterId_addr=0x%x, esResourceInfo_addr=0x%x, esCb_addr=0x%x, " "esSpecificInfo_addr=0x%x, esHandle_addr=0x%x)", demuxerHandle, esFilterId.addr(), esResourceInfo.addr(), esCb.addr(), esSpecificInfo_addr, esHandle.addr()); @@ -990,11 +990,11 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFil esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2, esCb->cbEsMsgFunc.to_le(), esCb->cbArg, esSpecificInfo_addr)); - u32 id = cellDmux->GetNewId(es); + u32 id = cellDmux.GetNewId(es); es->id = id; *esHandle = id; - cellDmux->Warning("*** New ES(dmux=%d, addr=0x%x, size=0x%x, filter(0x%x, 0x%x, 0x%x, 0x%x), cb=0x%x(arg=0x%x), spec=0x%x): id = %d", + cellDmux.Warning("*** New ES(dmux=%d, addr=0x%x, size=0x%x, filter(0x%x, 0x%x, 0x%x, 0x%x), cb=0x%x(arg=0x%x), spec=0x%x): id = %d", demuxerHandle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, id); DemuxerTask task(dmuxEnableEs); @@ -1007,7 +1007,7 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFil int cellDmuxDisableEs(u32 esHandle) { - cellDmux->Warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle); std::shared_ptr es; if (!Emu.GetIdManager().GetIDData(esHandle, es)) @@ -1025,7 +1025,7 @@ int cellDmuxDisableEs(u32 esHandle) int cellDmuxResetEs(u32 esHandle) { - cellDmux->Log("cellDmuxResetEs(esHandle=0x%x)", esHandle); + cellDmux.Log("cellDmuxResetEs(esHandle=0x%x)", esHandle); std::shared_ptr es; if (!Emu.GetIdManager().GetIDData(esHandle, es)) @@ -1043,7 +1043,7 @@ int cellDmuxResetEs(u32 esHandle) int cellDmuxGetAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecificInfo_ptr) { - cellDmux->Log("cellDmuxGetAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", + cellDmux.Log("cellDmuxGetAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", esHandle, auInfo_ptr.addr(), auSpecificInfo_ptr.addr()); std::shared_ptr es; @@ -1066,7 +1066,7 @@ int cellDmuxGetAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecific int cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecificInfo_ptr) { - cellDmux->Log("cellDmuxPeekAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", + cellDmux.Log("cellDmuxPeekAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", esHandle, auInfo_ptr.addr(), auSpecificInfo_ptr.addr()); std::shared_ptr es; @@ -1089,7 +1089,7 @@ int cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecifi int cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpecificInfo_ptr) { - cellDmux->Log("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", + cellDmux.Log("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", esHandle, auInfoEx_ptr.addr(), auSpecificInfo_ptr.addr()); std::shared_ptr es; @@ -1112,7 +1112,7 @@ int cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpec int cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpecificInfo_ptr) { - cellDmux->Log("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", + cellDmux.Log("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", esHandle, auInfoEx_ptr.addr(), auSpecificInfo_ptr.addr()); std::shared_ptr es; @@ -1135,7 +1135,7 @@ int cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpe int cellDmuxReleaseAu(u32 esHandle) { - cellDmux->Log("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); + cellDmux.Log("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); std::shared_ptr es; if (!Emu.GetIdManager().GetIDData(esHandle, es)) @@ -1152,7 +1152,7 @@ int cellDmuxReleaseAu(u32 esHandle) int cellDmuxFlushEs(u32 esHandle) { - cellDmux->Warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle); + cellDmux.Warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle); std::shared_ptr es; if (!Emu.GetIdManager().GetIDData(esHandle, es)) @@ -1168,28 +1168,26 @@ int cellDmuxFlushEs(u32 esHandle) return CELL_OK; } -void cellDmux_init(Module *pxThis) +Module cellDmux("cellDmux", []() { - cellDmux = pxThis; - - cellDmux->AddFunc(0xa2d4189b, cellDmuxQueryAttr); - cellDmux->AddFunc(0x3f76e3cd, cellDmuxQueryAttr2); - cellDmux->AddFunc(0x68492de9, cellDmuxOpen); - cellDmux->AddFunc(0xf6c23560, cellDmuxOpenEx); - cellDmux->AddFunc(0x11bc3a6c, cellDmuxOpen2); - cellDmux->AddFunc(0x8c692521, cellDmuxClose); - cellDmux->AddFunc(0x04e7499f, cellDmuxSetStream); - cellDmux->AddFunc(0x5d345de9, cellDmuxResetStream); - cellDmux->AddFunc(0xccff1284, cellDmuxResetStreamAndWaitDone); - cellDmux->AddFunc(0x02170d1a, cellDmuxQueryEsAttr); - cellDmux->AddFunc(0x52911bcf, cellDmuxQueryEsAttr2); - cellDmux->AddFunc(0x7b56dc3f, cellDmuxEnableEs); - cellDmux->AddFunc(0x05371c8d, cellDmuxDisableEs); - cellDmux->AddFunc(0x21d424f0, cellDmuxResetEs); - cellDmux->AddFunc(0x42c716b5, cellDmuxGetAu); - cellDmux->AddFunc(0x2750c5e0, cellDmuxPeekAu); - cellDmux->AddFunc(0x2c9a5857, cellDmuxGetAuEx); - cellDmux->AddFunc(0x002e8da2, cellDmuxPeekAuEx); - cellDmux->AddFunc(0x24ea6474, cellDmuxReleaseAu); - cellDmux->AddFunc(0xebb3b2bd, cellDmuxFlushEs); -} + cellDmux.AddFunc(0xa2d4189b, cellDmuxQueryAttr); + cellDmux.AddFunc(0x3f76e3cd, cellDmuxQueryAttr2); + cellDmux.AddFunc(0x68492de9, cellDmuxOpen); + cellDmux.AddFunc(0xf6c23560, cellDmuxOpenEx); + cellDmux.AddFunc(0x11bc3a6c, cellDmuxOpen2); + cellDmux.AddFunc(0x8c692521, cellDmuxClose); + cellDmux.AddFunc(0x04e7499f, cellDmuxSetStream); + cellDmux.AddFunc(0x5d345de9, cellDmuxResetStream); + cellDmux.AddFunc(0xccff1284, cellDmuxResetStreamAndWaitDone); + cellDmux.AddFunc(0x02170d1a, cellDmuxQueryEsAttr); + cellDmux.AddFunc(0x52911bcf, cellDmuxQueryEsAttr2); + cellDmux.AddFunc(0x7b56dc3f, cellDmuxEnableEs); + cellDmux.AddFunc(0x05371c8d, cellDmuxDisableEs); + cellDmux.AddFunc(0x21d424f0, cellDmuxResetEs); + cellDmux.AddFunc(0x42c716b5, cellDmuxGetAu); + cellDmux.AddFunc(0x2750c5e0, cellDmuxPeekAu); + cellDmux.AddFunc(0x2c9a5857, cellDmuxGetAuEx); + cellDmux.AddFunc(0x002e8da2, cellDmuxPeekAuEx); + cellDmux.AddFunc(0x24ea6474, cellDmuxReleaseAu); + cellDmux.AddFunc(0xebb3b2bd, cellDmuxFlushEs); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp index 6f0394f352..e2d6f2d0b2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp @@ -5,7 +5,7 @@ #include "cellFiber.h" -Module* cellFiber = nullptr; +extern Module cellFiber; int _cellFiberPpuInitialize() { @@ -81,7 +81,7 @@ int cellFiberPpuJoinFiber() vm::ptr cellFiberPpuSelf() { - cellFiber->Log("cellFiberPpuSelf() -> nullptr"); // TODO + cellFiber.Log("cellFiberPpuSelf() -> nullptr"); // TODO // returns fiber structure (zero for simple PPU thread) return vm::ptr::make(0); @@ -291,61 +291,59 @@ int cellFiberPpuUtilWorkerControlInitializeWithAttribute() return CELL_OK; } -void cellFiber_init(Module *pxThis) +Module cellFiber("cellFiber", []() { - cellFiber = pxThis; + cellFiber.AddFunc(0x55870804, _cellFiberPpuInitialize); - cellFiber->AddFunc(0x55870804, _cellFiberPpuInitialize); + cellFiber.AddFunc(0x9e25c72d, _cellFiberPpuSchedulerAttributeInitialize); + cellFiber.AddFunc(0xee3b604d, cellFiberPpuInitializeScheduler); + cellFiber.AddFunc(0x8b6baa01, cellFiberPpuFinalizeScheduler); + cellFiber.AddFunc(0x12b1acf0, cellFiberPpuRunFibers); + cellFiber.AddFunc(0xf6c6900c, cellFiberPpuCheckFlags); + cellFiber.AddFunc(0xe492a675, cellFiberPpuHasRunnableFiber); - cellFiber->AddFunc(0x9e25c72d, _cellFiberPpuSchedulerAttributeInitialize); - cellFiber->AddFunc(0xee3b604d, cellFiberPpuInitializeScheduler); - cellFiber->AddFunc(0x8b6baa01, cellFiberPpuFinalizeScheduler); - cellFiber->AddFunc(0x12b1acf0, cellFiberPpuRunFibers); - cellFiber->AddFunc(0xf6c6900c, cellFiberPpuCheckFlags); - cellFiber->AddFunc(0xe492a675, cellFiberPpuHasRunnableFiber); + cellFiber.AddFunc(0xc11f8056, _cellFiberPpuAttributeInitialize); + cellFiber.AddFunc(0x7c2f4034, cellFiberPpuCreateFiber); + cellFiber.AddFunc(0xfa8d5f95, cellFiberPpuExit); + cellFiber.AddFunc(0x0c44f441, cellFiberPpuYield); + cellFiber.AddFunc(0xa6004249, cellFiberPpuJoinFiber); + cellFiber.AddFunc(0x5d9a7034, cellFiberPpuSelf); + cellFiber.AddFunc(0x8afb8356, cellFiberPpuSendSignal); + cellFiber.AddFunc(0x6c164b3b, cellFiberPpuWaitSignal); + cellFiber.AddFunc(0xa4599cf3, cellFiberPpuWaitFlag); + cellFiber.AddFunc(0xb0594b2d, cellFiberPpuGetScheduler); + cellFiber.AddFunc(0xfbf5fe40, cellFiberPpuSetPriority); + cellFiber.AddFunc(0xf3e81219, cellFiberPpuCheckStackLimit); - cellFiber->AddFunc(0xc11f8056, _cellFiberPpuAttributeInitialize); - cellFiber->AddFunc(0x7c2f4034, cellFiberPpuCreateFiber); - cellFiber->AddFunc(0xfa8d5f95, cellFiberPpuExit); - cellFiber->AddFunc(0x0c44f441, cellFiberPpuYield); - cellFiber->AddFunc(0xa6004249, cellFiberPpuJoinFiber); - cellFiber->AddFunc(0x5d9a7034, cellFiberPpuSelf); - cellFiber->AddFunc(0x8afb8356, cellFiberPpuSendSignal); - cellFiber->AddFunc(0x6c164b3b, cellFiberPpuWaitSignal); - cellFiber->AddFunc(0xa4599cf3, cellFiberPpuWaitFlag); - cellFiber->AddFunc(0xb0594b2d, cellFiberPpuGetScheduler); - cellFiber->AddFunc(0xfbf5fe40, cellFiberPpuSetPriority); - cellFiber->AddFunc(0xf3e81219, cellFiberPpuCheckStackLimit); + cellFiber.AddFunc(0x31252ec3, _cellFiberPpuContextAttributeInitialize); + cellFiber.AddFunc(0x72086315, cellFiberPpuContextInitialize); + cellFiber.AddFunc(0xb3a48079, cellFiberPpuContextFinalize); + cellFiber.AddFunc(0xaba1c563, cellFiberPpuContextRun); + cellFiber.AddFunc(0xd0066b17, cellFiberPpuContextSwitch); + cellFiber.AddFunc(0x34a81091, cellFiberPpuContextSelf); + cellFiber.AddFunc(0x01036193, cellFiberPpuContextReturnToThread); + cellFiber.AddFunc(0xb90c871b, cellFiberPpuContextCheckStackLimit); - cellFiber->AddFunc(0x31252ec3, _cellFiberPpuContextAttributeInitialize); - cellFiber->AddFunc(0x72086315, cellFiberPpuContextInitialize); - cellFiber->AddFunc(0xb3a48079, cellFiberPpuContextFinalize); - cellFiber->AddFunc(0xaba1c563, cellFiberPpuContextRun); - cellFiber->AddFunc(0xd0066b17, cellFiberPpuContextSwitch); - cellFiber->AddFunc(0x34a81091, cellFiberPpuContextSelf); - cellFiber->AddFunc(0x01036193, cellFiberPpuContextReturnToThread); - cellFiber->AddFunc(0xb90c871b, cellFiberPpuContextCheckStackLimit); + cellFiber.AddFunc(0x081c98be, cellFiberPpuContextRunScheduler); + cellFiber.AddFunc(0x0a25b6c8, cellFiberPpuContextEnterScheduler); - cellFiber->AddFunc(0x081c98be, cellFiberPpuContextRunScheduler); - cellFiber->AddFunc(0x0a25b6c8, cellFiberPpuContextEnterScheduler); + cellFiber.AddFunc(0xbf9cd933, cellFiberPpuSchedulerTraceInitialize); + cellFiber.AddFunc(0x3860a12a, cellFiberPpuSchedulerTraceFinalize); + cellFiber.AddFunc(0xadedbebf, cellFiberPpuSchedulerTraceStart); + cellFiber.AddFunc(0xe665f9a9, cellFiberPpuSchedulerTraceStop); - cellFiber->AddFunc(0xbf9cd933, cellFiberPpuSchedulerTraceInitialize); - cellFiber->AddFunc(0x3860a12a, cellFiberPpuSchedulerTraceFinalize); - cellFiber->AddFunc(0xadedbebf, cellFiberPpuSchedulerTraceStart); - cellFiber->AddFunc(0xe665f9a9, cellFiberPpuSchedulerTraceStop); - - cellFiber->AddFunc(0x68ba4568, _cellFiberPpuUtilWorkerControlAttributeInitialize); - cellFiber->AddFunc(0x1e7a247a, cellFiberPpuUtilWorkerControlRunFibers); - cellFiber->AddFunc(0x3204b146, cellFiberPpuUtilWorkerControlInitialize); - cellFiber->AddFunc(0x392c5aa5, cellFiberPpuUtilWorkerControlSetPollingMode); - cellFiber->AddFunc(0x3b417f82, cellFiberPpuUtilWorkerControlJoinFiber); - cellFiber->AddFunc(0x4fc86b2c, cellFiberPpuUtilWorkerControlDisconnectEventQueue); - cellFiber->AddFunc(0x5d3992dd, cellFiberPpuUtilWorkerControlSendSignal); - cellFiber->AddFunc(0x62a20f0d, cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs); - cellFiber->AddFunc(0xa27c95ca, cellFiberPpuUtilWorkerControlFinalize); - cellFiber->AddFunc(0xbabf714b, cellFiberPpuUtilWorkerControlWakeup); - cellFiber->AddFunc(0xbfca88d3, cellFiberPpuUtilWorkerControlCreateFiber); - cellFiber->AddFunc(0xc04e2438, cellFiberPpuUtilWorkerControlShutdown); - cellFiber->AddFunc(0xea6dc1ad, cellFiberPpuUtilWorkerControlCheckFlags); - cellFiber->AddFunc(0xf2ccad4f, cellFiberPpuUtilWorkerControlInitializeWithAttribute); -} + cellFiber.AddFunc(0x68ba4568, _cellFiberPpuUtilWorkerControlAttributeInitialize); + cellFiber.AddFunc(0x1e7a247a, cellFiberPpuUtilWorkerControlRunFibers); + cellFiber.AddFunc(0x3204b146, cellFiberPpuUtilWorkerControlInitialize); + cellFiber.AddFunc(0x392c5aa5, cellFiberPpuUtilWorkerControlSetPollingMode); + cellFiber.AddFunc(0x3b417f82, cellFiberPpuUtilWorkerControlJoinFiber); + cellFiber.AddFunc(0x4fc86b2c, cellFiberPpuUtilWorkerControlDisconnectEventQueue); + cellFiber.AddFunc(0x5d3992dd, cellFiberPpuUtilWorkerControlSendSignal); + cellFiber.AddFunc(0x62a20f0d, cellFiberPpuUtilWorkerControlConnectEventQueueToSpurs); + cellFiber.AddFunc(0xa27c95ca, cellFiberPpuUtilWorkerControlFinalize); + cellFiber.AddFunc(0xbabf714b, cellFiberPpuUtilWorkerControlWakeup); + cellFiber.AddFunc(0xbfca88d3, cellFiberPpuUtilWorkerControlCreateFiber); + cellFiber.AddFunc(0xc04e2438, cellFiberPpuUtilWorkerControlShutdown); + cellFiber.AddFunc(0xea6dc1ad, cellFiberPpuUtilWorkerControlCheckFlags); + cellFiber.AddFunc(0xf2ccad4f, cellFiberPpuUtilWorkerControlInitializeWithAttribute); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp index 69199e2f2c..7831a68fed 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFont.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFont.cpp @@ -6,21 +6,21 @@ #include "Emu/FS/vfsFile.h" #include "cellFont.h" -Module *cellFont = nullptr; +extern Module cellFont; CCellFontInternal* s_fontInternalInstance = nullptr; // Functions int cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr config) { - cellFont->Warning("cellFontInitializeWithRevision(revisionFlags=0x%llx, config=0x%x)", revisionFlags, config.addr()); + cellFont.Warning("cellFontInitializeWithRevision(revisionFlags=0x%llx, config=0x%x)", revisionFlags, config.addr()); if (s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_ALREADY_INITIALIZED; if (config->FileCache.size < 24) return CELL_FONT_ERROR_INVALID_PARAMETER; if (config->flags != 0) - cellFont->Warning("cellFontInitializeWithRevision: Unknown flags (0x%x)", config->flags); + cellFont.Warning("cellFontInitializeWithRevision: Unknown flags (0x%x)", config->flags); s_fontInternalInstance->m_buffer_addr = config->FileCache.buffer_addr; s_fontInternalInstance->m_buffer_size = config->FileCache.size; @@ -38,7 +38,7 @@ int cellFontGetRevisionFlags(vm::ptr> revisionFlags) int cellFontInit(PPUThread& CPU, vm::ptr config) { - cellFont->Log("cellFontInit(config=0x%x)", config.addr()); + cellFont.Log("cellFontInit(config=0x%x)", config.addr()); vm::stackvar> revisionFlags(CPU); revisionFlags.value() = 0; @@ -48,7 +48,7 @@ int cellFontInit(PPUThread& CPU, vm::ptr config) int cellFontEnd() { - cellFont->Log("cellFontEnd()"); + cellFont.Log("cellFontEnd()"); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; @@ -59,14 +59,14 @@ int cellFontEnd() s32 cellFontSetFontsetOpenMode(u32 openMode) { - cellFont->Log("cellFontSetFontsetOpenMode(openMode=0x%x)", openMode); + cellFont.Log("cellFontSetFontsetOpenMode(openMode=0x%x)", openMode); UNIMPLEMENTED_FUNC(cellFont); return CELL_FONT_OK; } int cellFontOpenFontMemory(vm::ptr library, u32 fontAddr, u32 fontSize, u32 subNum, u32 uniqueId, vm::ptr font) { - cellFont->Warning("cellFontOpenFontMemory(library_addr=0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font_addr=0x%x)", + cellFont.Warning("cellFontOpenFontMemory(library_addr=0x%x, fontAddr=0x%x, fontSize=%d, subNum=%d, uniqueId=%d, font_addr=0x%x)", library.addr(), fontAddr, fontSize, subNum, uniqueId, font.addr()); if (!s_fontInternalInstance->m_bInitialized) @@ -86,7 +86,7 @@ int cellFontOpenFontMemory(vm::ptr library, u32 fontAddr, u32 f int cellFontOpenFontFile(vm::ptr library, vm::ptr fontPath, u32 subNum, s32 uniqueId, vm::ptr font) { std::string fp(fontPath.get_ptr()); - cellFont->Warning("cellFontOpenFontFile(library_addr=0x%x, fontPath=\"%s\", subNum=%d, uniqueId=%d, font_addr=0x%x)", + cellFont.Warning("cellFontOpenFontFile(library_addr=0x%x, fontPath=\"%s\", subNum=%d, uniqueId=%d, font_addr=0x%x)", library.addr(), fp.c_str(), subNum, uniqueId, font.addr()); vfsFile f(fp); @@ -103,13 +103,13 @@ int cellFontOpenFontFile(vm::ptr library, vm::ptr f int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::ptr fontType, vm::ptr font) { - cellFont->Log("cellFontOpenFontset(library_addr=0x%x, fontType_addr=0x%x, font_addr=0x%x)", + cellFont.Log("cellFontOpenFontset(library_addr=0x%x, fontType_addr=0x%x, font_addr=0x%x)", library.addr(), fontType.addr(), font.addr()); if (!s_fontInternalInstance->m_bInitialized) return CELL_FONT_ERROR_UNINITIALIZED; if (fontType->map != CELL_FONT_MAP_UNICODE) - cellFont->Warning("cellFontOpenFontset: Only Unicode is supported"); + cellFont.Warning("cellFontOpenFontset: Only Unicode is supported"); std::string file; switch((u32)fontType->type) @@ -168,12 +168,12 @@ int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::pt case CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_RSANS2_SET: case CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_YG_DFHEI5_VAGR2_SET: case CELL_FONT_TYPE_SEURAT_CAPIE_MARU_GOTHIC_VAGR2_SET: - cellFont->Warning("cellFontOpenFontset: fontType->type = %d not supported yet. RD-R-LATIN.TTF will be used instead.", fontType->type); + cellFont.Warning("cellFontOpenFontset: fontType->type = %d not supported yet. RD-R-LATIN.TTF will be used instead.", fontType->type); file = "/dev_flash/data/font/SCE-PS3-RD-R-LATIN.TTF"; break; default: - cellFont->Warning("cellFontOpenFontset: fontType->type = %d not supported.", fontType->type); + cellFont.Warning("cellFontOpenFontset: fontType->type = %d not supported.", fontType->type); return CELL_FONT_ERROR_NO_SUPPORT_FONTSET; } @@ -186,7 +186,7 @@ int cellFontOpenFontset(PPUThread& CPU, vm::ptr library, vm::pt int cellFontOpenFontInstance(vm::ptr openedFont, vm::ptr font) { - cellFont->Warning("cellFontOpenFontInstance(openedFont=0x%x, font=0x%x)", openedFont.addr(), font.addr()); + cellFont.Warning("cellFontOpenFontInstance(openedFont=0x%x, font=0x%x)", openedFont.addr(), font.addr()); font->renderer_addr = openedFont->renderer_addr; font->scale_x = openedFont->scale_x; @@ -200,14 +200,14 @@ int cellFontOpenFontInstance(vm::ptr openedFont, vm::ptr fon s32 cellFontSetFontOpenMode(u32 openMode) { - cellFont->Log("cellFontSetFontOpenMode(openMode=0x%x)", openMode); + cellFont.Log("cellFontSetFontOpenMode(openMode=0x%x)", openMode); UNIMPLEMENTED_FUNC(cellFont); return CELL_FONT_OK; } int cellFontCreateRenderer(vm::ptr library, vm::ptr config, vm::ptr Renderer) { - cellFont->Warning("cellFontCreateRenderer(library_addr=0x%x, config_addr=0x%x, Renderer_addr=0x%x)", + cellFont.Warning("cellFontCreateRenderer(library_addr=0x%x, config_addr=0x%x, Renderer_addr=0x%x)", library.addr(), config.addr(), Renderer.addr()); if (!s_fontInternalInstance->m_bInitialized) @@ -220,7 +220,7 @@ int cellFontCreateRenderer(vm::ptr library, vm::ptr surface, u32 buffer_addr, s32 bufferWidthByte, s32 pixelSizeByte, s32 w, s32 h) { - cellFont->Warning("cellFontRenderSurfaceInit(surface_addr=0x%x, buffer_addr=0x%x, bufferWidthByte=%d, pixelSizeByte=%d, w=%d, h=%d)", + cellFont.Warning("cellFontRenderSurfaceInit(surface_addr=0x%x, buffer_addr=0x%x, bufferWidthByte=%d, pixelSizeByte=%d, w=%d, h=%d)", surface.addr(), buffer_addr, bufferWidthByte, pixelSizeByte, w, h); surface->buffer_addr = buffer_addr; @@ -235,7 +235,7 @@ void cellFontRenderSurfaceInit(vm::ptr surface, u32 buffe void cellFontRenderSurfaceSetScissor(vm::ptr surface, s32 x0, s32 y0, s32 w, s32 h) { - cellFont->Warning("cellFontRenderSurfaceSetScissor(surface_addr=0x%x, x0=%d, y0=%d, w=%d, h=%d)", + cellFont.Warning("cellFontRenderSurfaceSetScissor(surface_addr=0x%x, x0=%d, y0=%d, w=%d, h=%d)", surface.addr(), x0, y0, w, h); surface->Scissor.x0 = x0; @@ -246,7 +246,7 @@ void cellFontRenderSurfaceSetScissor(vm::ptr surface, s32 int cellFontSetScalePixel(vm::ptr font, float w, float h) { - cellFont->Log("cellFontSetScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); + cellFont.Log("cellFontSetScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); font->scale_x = w; font->scale_y = h; @@ -255,7 +255,7 @@ int cellFontSetScalePixel(vm::ptr font, float w, float h) int cellFontGetHorizontalLayout(vm::ptr font, vm::ptr layout) { - cellFont->Log("cellFontGetHorizontalLayout(font_addr=0x%x, layout_addr=0x%x)", + cellFont.Log("cellFontGetHorizontalLayout(font_addr=0x%x, layout_addr=0x%x)", font.addr(), layout.addr()); int ascent, descent, lineGap; @@ -270,7 +270,7 @@ int cellFontGetHorizontalLayout(vm::ptr font, vm::ptr font, vm::ptr renderer) { - cellFont->Warning("cellFontBindRenderer(font_addr=0x%x, renderer_addr=0x%x)", + cellFont.Warning("cellFontBindRenderer(font_addr=0x%x, renderer_addr=0x%x)", font.addr(), renderer.addr()); if (font->renderer_addr) @@ -282,7 +282,7 @@ int cellFontBindRenderer(vm::ptr font, vm::ptr rende int cellFontUnbindRenderer(vm::ptr font) { - cellFont->Warning("cellFontBindRenderer(font_addr=0x%x)", font.addr()); + cellFont.Warning("cellFontBindRenderer(font_addr=0x%x)", font.addr()); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; @@ -299,7 +299,7 @@ int cellFontDestroyRenderer() int cellFontSetupRenderScalePixel(vm::ptr font, float w, float h) { - cellFont->Log("cellFontSetupRenderScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); + cellFont.Log("cellFontSetupRenderScalePixel(font_addr=0x%x, w=%f, h=%f)", font.addr(), w, h); if (!font->renderer_addr) return CELL_FONT_ERROR_RENDERER_UNBIND; @@ -310,7 +310,7 @@ int cellFontSetupRenderScalePixel(vm::ptr font, float w, float h) int cellFontGetRenderCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) { - cellFont->Log("cellFontGetRenderCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", + cellFont.Log("cellFontGetRenderCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", font.addr(), code, metrics.addr()); if (!font->renderer_addr) @@ -322,7 +322,7 @@ int cellFontGetRenderCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr< int cellFontRenderCharGlyphImage(vm::ptr font, u32 code, vm::ptr surface, float x, float y, vm::ptr metrics, vm::ptr transInfo) { - cellFont->Log("cellFontRenderCharGlyphImage(font_addr=0x%x, code=0x%x, surface_addr=0x%x, x=%f, y=%f, metrics_addr=0x%x, trans_addr=0x%x)", + cellFont.Log("cellFontRenderCharGlyphImage(font_addr=0x%x, code=0x%x, surface_addr=0x%x, x=%f, y=%f, metrics_addr=0x%x, trans_addr=0x%x)", font.addr(), code, surface.addr(), x, y, metrics.addr(), transInfo.addr()); if (!font->renderer_addr) @@ -366,7 +366,7 @@ int cellFontEndLibrary() int cellFontSetEffectSlant(vm::ptr font, float slantParam) { - cellFont->Log("cellFontSetEffectSlant(font_addr=0x%x, slantParam=%f)", font.addr(), slantParam); + cellFont.Log("cellFontSetEffectSlant(font_addr=0x%x, slantParam=%f)", font.addr(), slantParam); if (slantParam < -1.0 || slantParam > 1.0) return CELL_FONT_ERROR_INVALID_PARAMETER; @@ -377,7 +377,7 @@ int cellFontSetEffectSlant(vm::ptr font, float slantParam) int cellFontGetEffectSlant(vm::ptr font, vm::ptr> slantParam) { - cellFont->Warning("cellFontSetEffectSlant(font_addr=0x%x, slantParam_addr=0x%x)", font.addr(), slantParam.addr()); + cellFont.Warning("cellFontSetEffectSlant(font_addr=0x%x, slantParam_addr=0x%x)", font.addr(), slantParam.addr()); *slantParam = font->slant; return CELL_FONT_OK; @@ -385,7 +385,7 @@ int cellFontGetEffectSlant(vm::ptr font, vm::ptr> slantPar int cellFontGetFontIdCode(vm::ptr font, u32 code, vm::ptr fontId, vm::ptr fontCode) { - cellFont->Todo("cellFontGetFontIdCode(font_addr=0x%x, code=0x%x, fontId_addr=0x%x, fontCode_addr=0x%x)", font.addr(), code, fontId.addr(), fontCode.addr()); + cellFont.Todo("cellFontGetFontIdCode(font_addr=0x%x, code=0x%x, fontId_addr=0x%x, fontCode_addr=0x%x)", font.addr(), code, fontId.addr(), fontCode.addr()); // TODO: ? return CELL_FONT_OK; @@ -393,7 +393,7 @@ int cellFontGetFontIdCode(vm::ptr font, u32 code, vm::ptr fontId, int cellFontCloseFont(vm::ptr font) { - cellFont->Warning("cellFontCloseFont(font_addr=0x%x)", font.addr()); + cellFont.Warning("cellFontCloseFont(font_addr=0x%x)", font.addr()); if (font->origin == CELL_FONT_OPEN_FONTSET || font->origin == CELL_FONT_OPEN_FONT_FILE || @@ -405,7 +405,7 @@ int cellFontCloseFont(vm::ptr font) int cellFontGetCharGlyphMetrics(vm::ptr font, u32 code, vm::ptr metrics) { - cellFont->Log("cellFontGetCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", font.addr(), code, metrics.addr()); + cellFont.Log("cellFontGetCharGlyphMetrics(font_addr=0x%x, code=0x%x, metrics_addr=0x%x)", font.addr(), code, metrics.addr()); int x0, y0, x1, y1; int advanceWidth, leftSideBearing; @@ -541,7 +541,7 @@ int cellFontDeleteGlyph() int cellFontExtend(u32 a1, u32 a2, u32 a3) { - cellFont->Warning("cellFontExtend(a1=0x%x, a2=0x%x, a3=0x%x)", a1, a2, a3); + cellFont.Warning("cellFontExtend(a1=0x%x, a2=0x%x, a3=0x%x)", a1, a2, a3); //In a test I did: a1=0xcfe00000, a2=0x0, a3=(pointer to something) if (a1 == 0xcfe00000) { @@ -577,70 +577,65 @@ int cellFontGetCharGlyphMetricsVertical() return CELL_FONT_OK; } -void cellFont_init(Module *pxThis) -{ - cellFont = pxThis; - - cellFont->AddFunc(0x25c107e6, cellFontInit); - cellFont->AddFunc(0x6bf6f832, cellFontSetFontsetOpenMode); - cellFont->AddFunc(0x6cfada83, cellFontSetFontOpenMode); - cellFont->AddFunc(0x042e74e3, cellFontCreateRenderer); - cellFont->AddFunc(0x1387c45c, cellFontGetHorizontalLayout); - cellFont->AddFunc(0x21ebb248, cellFontDestroyRenderer); - cellFont->AddFunc(0x227e1e3c, cellFontSetupRenderScalePixel); - cellFont->AddFunc(0x29329541, cellFontOpenFontInstance); - cellFont->AddFunc(0x297f0e93, cellFontSetScalePixel); - cellFont->AddFunc(0x2da9fd9d, cellFontGetRenderCharGlyphMetrics); - cellFont->AddFunc(0x40d40544, cellFontEndLibrary); - cellFont->AddFunc(0x66a23100, cellFontBindRenderer); - cellFont->AddFunc(0x7ab47f7e, cellFontEnd); - cellFont->AddFunc(0x8657c8f5, cellFontSetEffectSlant); - cellFont->AddFunc(0xe16e679a, cellFontGetEffectSlant); - cellFont->AddFunc(0x88be4799, cellFontRenderCharGlyphImage); - cellFont->AddFunc(0x90b9465e, cellFontRenderSurfaceInit); - cellFont->AddFunc(0x98ac5524, cellFontGetFontIdCode); - cellFont->AddFunc(0xa885cc9b, cellFontOpenFontset); - cellFont->AddFunc(0xb276f1f6, cellFontCloseFont); - cellFont->AddFunc(0xb422b005, cellFontRenderSurfaceSetScissor); - cellFont->AddFunc(0xd8eaee9f, cellFontGetCharGlyphMetrics); - cellFont->AddFunc(0xf03dcc29, cellFontInitializeWithRevision); - cellFont->AddFunc(0x061049ad, cellFontGraphicsSetFontRGBA); - cellFont->AddFunc(0x073fa321, cellFontOpenFontsetOnMemory); - cellFont->AddFunc(0x0a7306a4, cellFontOpenFontFile); - cellFont->AddFunc(0x16322df1, cellFontGraphicsSetScalePixel); - cellFont->AddFunc(0x2388186c, cellFontGraphicsGetScalePixel); - cellFont->AddFunc(0x25253fe4, cellFontSetEffectWeight); - cellFont->AddFunc(0x53f529fe, cellFontGlyphSetupVertexesGlyph); - cellFont->AddFunc(0x698897f8, cellFontGetVerticalLayout); - cellFont->AddFunc(0x700e6223, cellFontGetRenderCharGlyphMetricsVertical); - cellFont->AddFunc(0x70f3e728, cellFontSetScalePoint); - cellFont->AddFunc(0x78d05e08, cellFontSetupRenderEffectSlant); - cellFont->AddFunc(0x7c83bc15, cellFontGraphicsSetLineRGBA); - cellFont->AddFunc(0x87bd650f, cellFontGraphicsSetDrawType); - cellFont->AddFunc(0x8a35c887, cellFontEndGraphics); - cellFont->AddFunc(0x970d4c22, cellFontGraphicsSetupDrawContext); - cellFont->AddFunc(0x9e19072b, cellFontOpenFontMemory); - cellFont->AddFunc(0xa6dc25d1, cellFontSetupRenderEffectWeight); - cellFont->AddFunc(0xa8fae920, cellFontGlyphGetOutlineControlDistance); - cellFont->AddFunc(0xb4d112af, cellFontGlyphGetVertexesGlyphSize); - cellFont->AddFunc(0xc17259de, cellFontGenerateCharGlyph); - cellFont->AddFunc(0xd62f5d76, cellFontDeleteGlyph); - cellFont->AddFunc(0xdee0836c, cellFontExtend); - cellFont->AddFunc(0xe857a0ca, cellFontRenderCharGlyphImageVertical); - cellFont->AddFunc(0xfb3341ba, cellFontSetResolutionDpi); - cellFont->AddFunc(0xfe9a6dd7, cellFontGetCharGlyphMetricsVertical); - cellFont->AddFunc(0xf16379fa, cellFontUnbindRenderer); - cellFont->AddFunc(0xb015a84e, cellFontGetRevisionFlags); -} - -void cellFont_load() +Module cellFont("cellFont", []() { s_fontInternalInstance = new CCellFontInternal(); -} -void cellFont_unload() -{ - // s_fontInternalInstance->m_bInitialized = false; - // s_fontInternalInstance->m_bFontGcmInitialized = false; - delete s_fontInternalInstance; -} + cellFont.on_stop = []() + { + // s_fontInternalInstance->m_bInitialized = false; + // s_fontInternalInstance->m_bFontGcmInitialized = false; + delete s_fontInternalInstance; + }; + + cellFont.AddFunc(0x25c107e6, cellFontInit); + cellFont.AddFunc(0x6bf6f832, cellFontSetFontsetOpenMode); + cellFont.AddFunc(0x6cfada83, cellFontSetFontOpenMode); + cellFont.AddFunc(0x042e74e3, cellFontCreateRenderer); + cellFont.AddFunc(0x1387c45c, cellFontGetHorizontalLayout); + cellFont.AddFunc(0x21ebb248, cellFontDestroyRenderer); + cellFont.AddFunc(0x227e1e3c, cellFontSetupRenderScalePixel); + cellFont.AddFunc(0x29329541, cellFontOpenFontInstance); + cellFont.AddFunc(0x297f0e93, cellFontSetScalePixel); + cellFont.AddFunc(0x2da9fd9d, cellFontGetRenderCharGlyphMetrics); + cellFont.AddFunc(0x40d40544, cellFontEndLibrary); + cellFont.AddFunc(0x66a23100, cellFontBindRenderer); + cellFont.AddFunc(0x7ab47f7e, cellFontEnd); + cellFont.AddFunc(0x8657c8f5, cellFontSetEffectSlant); + cellFont.AddFunc(0xe16e679a, cellFontGetEffectSlant); + cellFont.AddFunc(0x88be4799, cellFontRenderCharGlyphImage); + cellFont.AddFunc(0x90b9465e, cellFontRenderSurfaceInit); + cellFont.AddFunc(0x98ac5524, cellFontGetFontIdCode); + cellFont.AddFunc(0xa885cc9b, cellFontOpenFontset); + cellFont.AddFunc(0xb276f1f6, cellFontCloseFont); + cellFont.AddFunc(0xb422b005, cellFontRenderSurfaceSetScissor); + cellFont.AddFunc(0xd8eaee9f, cellFontGetCharGlyphMetrics); + cellFont.AddFunc(0xf03dcc29, cellFontInitializeWithRevision); + cellFont.AddFunc(0x061049ad, cellFontGraphicsSetFontRGBA); + cellFont.AddFunc(0x073fa321, cellFontOpenFontsetOnMemory); + cellFont.AddFunc(0x0a7306a4, cellFontOpenFontFile); + cellFont.AddFunc(0x16322df1, cellFontGraphicsSetScalePixel); + cellFont.AddFunc(0x2388186c, cellFontGraphicsGetScalePixel); + cellFont.AddFunc(0x25253fe4, cellFontSetEffectWeight); + cellFont.AddFunc(0x53f529fe, cellFontGlyphSetupVertexesGlyph); + cellFont.AddFunc(0x698897f8, cellFontGetVerticalLayout); + cellFont.AddFunc(0x700e6223, cellFontGetRenderCharGlyphMetricsVertical); + cellFont.AddFunc(0x70f3e728, cellFontSetScalePoint); + cellFont.AddFunc(0x78d05e08, cellFontSetupRenderEffectSlant); + cellFont.AddFunc(0x7c83bc15, cellFontGraphicsSetLineRGBA); + cellFont.AddFunc(0x87bd650f, cellFontGraphicsSetDrawType); + cellFont.AddFunc(0x8a35c887, cellFontEndGraphics); + cellFont.AddFunc(0x970d4c22, cellFontGraphicsSetupDrawContext); + cellFont.AddFunc(0x9e19072b, cellFontOpenFontMemory); + cellFont.AddFunc(0xa6dc25d1, cellFontSetupRenderEffectWeight); + cellFont.AddFunc(0xa8fae920, cellFontGlyphGetOutlineControlDistance); + cellFont.AddFunc(0xb4d112af, cellFontGlyphGetVertexesGlyphSize); + cellFont.AddFunc(0xc17259de, cellFontGenerateCharGlyph); + cellFont.AddFunc(0xd62f5d76, cellFontDeleteGlyph); + cellFont.AddFunc(0xdee0836c, cellFontExtend); + cellFont.AddFunc(0xe857a0ca, cellFontRenderCharGlyphImageVertical); + cellFont.AddFunc(0xfb3341ba, cellFontSetResolutionDpi); + cellFont.AddFunc(0xfe9a6dd7, cellFontGetCharGlyphMetricsVertical); + cellFont.AddFunc(0xf16379fa, cellFontUnbindRenderer); + cellFont.AddFunc(0xb015a84e, cellFontGetRevisionFlags); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp index f58b460f71..155b147e51 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFontFT.cpp @@ -5,13 +5,13 @@ #include "cellFont.h" #include "cellFontFT.h" -Module *cellFontFT = nullptr; +extern Module cellFontFT; CCellFontFTInternal* s_fontFtInternalInstance = nullptr; int cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, vm::ptr config, u32 lib_addr_addr) { - cellFontFT->Warning("cellFontInitLibraryFreeTypeWithRevision(revisionFlags=0x%llx, config_addr=0x%x, lib_addr_addr=0x%x", + cellFontFT.Warning("cellFontInitLibraryFreeTypeWithRevision(revisionFlags=0x%llx, config_addr=0x%x, lib_addr_addr=0x%x", revisionFlags, config.addr(), lib_addr_addr); //if (s_fontInternalInstance->m_bInitialized) @@ -34,21 +34,16 @@ int cellFontFTGetInitializedRevisionFlags() return CELL_OK; } -void cellFontFT_init(Module *pxThis) -{ - cellFontFT = pxThis; - - cellFontFT->AddFunc(0x7a0a83c4, cellFontInitLibraryFreeTypeWithRevision); - cellFontFT->AddFunc(0xec89a187, cellFontFTGetRevisionFlags); - cellFontFT->AddFunc(0xfa0c2de0, cellFontFTGetInitializedRevisionFlags); -} - -void cellFontFT_load() +Module cellFontFT("cellFontFT", []() { s_fontFtInternalInstance = new CCellFontFTInternal(); -} -void cellFontFT_unload() -{ - delete s_fontFtInternalInstance; -} + cellFontFT.on_stop = []() + { + delete s_fontFtInternalInstance; + }; + + cellFontFT.AddFunc(0x7a0a83c4, cellFontInitLibraryFreeTypeWithRevision); + cellFontFT.AddFunc(0xec89a187, cellFontFTGetRevisionFlags); + cellFontFT.AddFunc(0xfa0c2de0, cellFontFTGetInitializedRevisionFlags); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 4e45ddb87c..6edc187340 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -10,7 +10,7 @@ #include "Loader/PSF.h" #include "cellGame.h" -Module *cellGame = nullptr; +extern Module cellGame; std::string contentInfo = ""; std::string usrdir = ""; @@ -18,7 +18,7 @@ bool path_set = false; int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, vm::ptr dirName) { - cellGame->Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", + cellGame.Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", type.addr(), attributes.addr(), size.addr(), dirName.addr()); if (size) @@ -34,14 +34,14 @@ int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptrError("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); + cellGame.Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); return CELL_GAME_ERROR_ACCESS_ERROR; } PSFLoader psf(f); if (!psf.Load(false)) { - cellGame->Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); + cellGame.Error("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); return CELL_GAME_ERROR_ACCESS_ERROR; } @@ -77,7 +77,7 @@ int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptrError("cellGameBootCheck(): CELL_GAME_ERROR_FAILURE (unknown CATEGORY)"); + cellGame.Error("cellGameBootCheck(): CELL_GAME_ERROR_FAILURE (unknown CATEGORY)"); return CELL_GAME_ERROR_FAILURE; } @@ -86,11 +86,11 @@ int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, u32 reserved_addr) { - cellGame->Warning("cellGamePatchCheck(size_addr=0x%x, reserved_addr=0x%x)", size.addr(), reserved_addr); + cellGame.Warning("cellGamePatchCheck(size_addr=0x%x, reserved_addr=0x%x)", size.addr(), reserved_addr); if (reserved_addr != 0) { - cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_PARAM"); + cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; } @@ -107,21 +107,21 @@ int cellGamePatchCheck(vm::ptr size, u32 reserved_addr) vfsFile f("/app_home/../PARAM.SFO"); if (!f.IsOpened()) { - cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); + cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); return CELL_GAME_ERROR_ACCESS_ERROR; } PSFLoader psf(f); if (!psf.Load(false)) { - cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); + cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); return CELL_GAME_ERROR_ACCESS_ERROR; } std::string category = psf.GetString("CATEGORY"); if (category.substr(0, 2) != "GD") { - cellGame->Error("cellGamePatchCheck(): CELL_GAME_ERROR_NOTPATCH"); + cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_NOTPATCH"); return CELL_GAME_ERROR_NOTPATCH; } @@ -135,11 +135,11 @@ int cellGamePatchCheck(vm::ptr size, u32 reserved_addr) int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr size) { - cellGame->Warning("cellGameDataCheck(type=0x%x, dirName_addr=0x%x, size_addr=0x%x)", type, dirName.addr(), size.addr()); + cellGame.Warning("cellGameDataCheck(type=0x%x, dirName_addr=0x%x, size_addr=0x%x)", type, dirName.addr(), size.addr()); if ((type - 1) >= 3) { - cellGame->Error("cellGameDataCheck(): CELL_GAME_ERROR_PARAM"); + cellGame.Error("cellGameDataCheck(): CELL_GAME_ERROR_PARAM"); return CELL_GAME_ERROR_PARAM; } @@ -159,7 +159,7 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptrWarning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found"); + cellGame.Warning("cellGameDataCheck(): /dev_bdvd/PS3_GAME not found"); contentInfo = ""; usrdir = ""; path_set = true; @@ -176,7 +176,7 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptrWarning("cellGameDataCheck(): '%s' directory not found", dir.c_str()); + cellGame.Warning("cellGameDataCheck(): '%s' directory not found", dir.c_str()); contentInfo = ""; usrdir = ""; path_set = true; @@ -193,7 +193,7 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr contentInfoPath, vm::ptr usrdirPath) { - cellGame->Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)", + cellGame.Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)", contentInfoPath.addr(), usrdirPath.addr()); if (!contentInfoPath || !usrdirPath) @@ -219,12 +219,12 @@ int cellGameContentPermit(vm::ptr contentInfoPath, vm: int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container) { - cellGame->Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", + cellGame.Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", version, dirName.addr(), errDialog, funcStat.addr(), container); if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1) { - cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_PARAM"); + cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_PARAM"); return CELL_GAMEDATA_ERROR_PARAM; } @@ -234,7 +234,7 @@ int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di if (!Emu.GetVFS().ExistsDir(dir)) { - cellGame->Todo("cellGameDataCheckCreate(2)(): creating directory '%s'", dir.c_str()); + cellGame.Todo("cellGameDataCheckCreate(2)(): creating directory '%s'", dir.c_str()); // TODO: create data return CELL_GAMEDATA_RET_OK; } @@ -242,14 +242,14 @@ int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di vfsFile f(dir + "/PARAM.SFO"); if (!f.IsOpened()) { - cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)"); + cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)"); return CELL_GAMEDATA_ERROR_BROKEN; } PSFLoader psf(f); if (!psf.Load(false)) { - cellGame->Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); + cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); return CELL_GAMEDATA_ERROR_BROKEN; } @@ -287,36 +287,36 @@ int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di if (cbSet->setParam) { // TODO: write PARAM.SFO from cbSet - cellGame->Todo("cellGameDataCheckCreate(2)(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam); + cellGame.Todo("cellGameDataCheckCreate(2)(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam); } switch ((s32)cbResult->result) { case CELL_GAMEDATA_CBRESULT_OK_CANCEL: // TODO: do not process game data - cellGame->Warning("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); + cellGame.Warning("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); case CELL_GAMEDATA_CBRESULT_OK: return CELL_GAMEDATA_RET_OK; case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result - cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); + cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_BROKEN: - cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); + cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_NODATA: - cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); + cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_INVALID: - cellGame->Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); + cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); return CELL_GAMEDATA_ERROR_CBRESULT; default: - cellGame->Error("cellGameDataCheckCreate(2)(): callback returned unknown error (code=0x%x)"); + cellGame.Error("cellGameDataCheckCreate(2)(): callback returned unknown error (code=0x%x)"); return CELL_GAMEDATA_ERROR_CBRESULT; } } @@ -330,7 +330,7 @@ int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dir int cellGameCreateGameData(vm::ptr init, vm::ptr tmp_contentInfoPath, vm::ptr tmp_usrdirPath) { - cellGame->Todo("cellGameCreateGameData(init_addr=0x%x, tmp_contentInfoPath_addr=0x%x, tmp_usrdirPath_addr=0x%x)", + cellGame.Todo("cellGameCreateGameData(init_addr=0x%x, tmp_contentInfoPath_addr=0x%x, tmp_usrdirPath_addr=0x%x)", init.addr(), tmp_contentInfoPath.addr(), tmp_usrdirPath.addr()); // TODO: create temporary game directory, set initial PARAM.SFO parameters @@ -346,7 +346,7 @@ int cellGameDeleteGameData() int cellGameGetParamInt(u32 id, vm::ptr value) { - cellGame->Warning("cellGameGetParamInt(id=%d, value_addr=0x%x)", id, value.addr()); + cellGame.Warning("cellGameGetParamInt(id=%d, value_addr=0x%x)", id, value.addr()); // TODO: Access through cellGame***Check functions vfsFile f("/app_home/../PARAM.SFO"); @@ -369,7 +369,7 @@ int cellGameGetParamInt(u32 id, vm::ptr value) int cellGameGetParamString(u32 id, vm::ptr buf, u32 bufsize) { - cellGame->Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); + cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); // TODO: Access through cellGame***Check functions vfsFile f("/app_home/../PARAM.SFO"); @@ -441,7 +441,7 @@ int cellGameGetLocalWebContentPath() int cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr dirName) { - cellGame->Warning("cellGameContentErrorDialog(type=%d, errNeedSizeKB=%d, dirName_addr=0x%x)", type, errNeedSizeKB, dirName.addr()); + cellGame.Warning("cellGameContentErrorDialog(type=%d, errNeedSizeKB=%d, dirName_addr=0x%x)", type, errNeedSizeKB, dirName.addr()); std::string errorName; switch (type) @@ -487,35 +487,33 @@ int cellGameThemeInstallFromBuffer() return CELL_OK; } -void cellGame_init(Module *pxThis) +Module cellGame("cellGame", []() { - cellGame = pxThis; - contentInfo = ""; usrdir = ""; path_set = false; // (TODO: Disc Exchange functions missing) - cellGame->AddFunc(0xf52639ea, cellGameBootCheck); - cellGame->AddFunc(0xce4374f6, cellGamePatchCheck); - cellGame->AddFunc(0xdb9819f3, cellGameDataCheck); - cellGame->AddFunc(0x70acec67, cellGameContentPermit); + cellGame.AddFunc(0xf52639ea, cellGameBootCheck); + cellGame.AddFunc(0xce4374f6, cellGamePatchCheck); + cellGame.AddFunc(0xdb9819f3, cellGameDataCheck); + cellGame.AddFunc(0x70acec67, cellGameContentPermit); - cellGame->AddFunc(0x42a2e133, cellGameCreateGameData); - cellGame->AddFunc(0xb367c6e3, cellGameDeleteGameData); + cellGame.AddFunc(0x42a2e133, cellGameCreateGameData); + cellGame.AddFunc(0xb367c6e3, cellGameDeleteGameData); - cellGame->AddFunc(0xb7a45caf, cellGameGetParamInt); - //cellGame->AddFunc(, cellGameSetParamInt); - cellGame->AddFunc(0x3a5d726a, cellGameGetParamString); - cellGame->AddFunc(0xdaa5cd20, cellGameSetParamString); - cellGame->AddFunc(0xef9d42d5, cellGameGetSizeKB); - cellGame->AddFunc(0x2a8e6b92, cellGameGetDiscContentInfoUpdatePath); - cellGame->AddFunc(0xa80bf223, cellGameGetLocalWebContentPath); + cellGame.AddFunc(0xb7a45caf, cellGameGetParamInt); + //cellGame.AddFunc(, cellGameSetParamInt); + cellGame.AddFunc(0x3a5d726a, cellGameGetParamString); + cellGame.AddFunc(0xdaa5cd20, cellGameSetParamString); + cellGame.AddFunc(0xef9d42d5, cellGameGetSizeKB); + cellGame.AddFunc(0x2a8e6b92, cellGameGetDiscContentInfoUpdatePath); + cellGame.AddFunc(0xa80bf223, cellGameGetLocalWebContentPath); - cellGame->AddFunc(0xb0a1f8c6, cellGameContentErrorDialog); + cellGame.AddFunc(0xb0a1f8c6, cellGameContentErrorDialog); - cellGame->AddFunc(0xd24e3928, cellGameThemeInstall); - cellGame->AddFunc(0x87406734, cellGameThemeInstallFromBuffer); - //cellGame->AddFunc(, CellGameThemeInstallCallback); -} + cellGame.AddFunc(0xd24e3928, cellGameThemeInstall); + cellGame.AddFunc(0x87406734, cellGameThemeInstallFromBuffer); + //cellGame.AddFunc(, CellGameThemeInstallCallback); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index d8fc27a97d..f9f9f3624a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -10,7 +10,7 @@ //#include "Emu/SysCalls/lv2/sys_process.h" #include "cellGcmSys.h" -Module *cellGcmSys = nullptr; +extern Module cellGcmSys; const u32 tiled_pitches[] = { 0x00000000, 0x00000200, 0x00000300, 0x00000400, @@ -75,17 +75,17 @@ void InitOffsetTable() u32 cellGcmGetLabelAddress(u8 index) { - cellGcmSys->Log("cellGcmGetLabelAddress(index=%d)", index); + cellGcmSys.Log("cellGcmGetLabelAddress(index=%d)", index); return gcm_info.label_addr + 0x10 * index; } vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 location) { - cellGcmSys->Warning("cellGcmGetReportDataAddressLocation(index=%d, location=%d)", index, location); + cellGcmSys.Warning("cellGcmGetReportDataAddressLocation(index=%d, location=%d)", index, location); if (location == CELL_GCM_LOCATION_LOCAL) { if (index >= 2048) { - cellGcmSys->Error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index); + cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index); return vm::ptr::make(0); } return vm::ptr::make((u32)Memory.RSXFBMem.GetStartAddr() + index * 0x10); @@ -93,23 +93,23 @@ vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 lo if (location == CELL_GCM_LOCATION_MAIN) { if (index >= 1024 * 1024) { - cellGcmSys->Error("cellGcmGetReportDataAddressLocation: Wrong main index (%d)", index); + cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong main index (%d)", index); return vm::ptr::make(0); } // TODO: It seems m_report_main_addr is not initialized return vm::ptr::make(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10); } - cellGcmSys->Error("cellGcmGetReportDataAddressLocation: Wrong location (%d)", location); + cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong location (%d)", location); return vm::ptr::make(0); } u64 cellGcmGetTimeStamp(u32 index) { - cellGcmSys->Log("cellGcmGetTimeStamp(index=%d)", index); + cellGcmSys.Log("cellGcmGetTimeStamp(index=%d)", index); if (index >= 2048) { - cellGcmSys->Error("cellGcmGetTimeStamp: Wrong local index (%d)", index); + cellGcmSys.Error("cellGcmGetTimeStamp: Wrong local index (%d)", index); return 0; } return vm::read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10); @@ -123,7 +123,7 @@ s32 cellGcmGetCurrentField() u32 cellGcmGetNotifyDataAddress(u32 index) { - cellGcmSys->Warning("cellGcmGetNotifyDataAddress(index=%d)", index); + cellGcmSys.Warning("cellGcmGetNotifyDataAddress(index=%d)", index); // If entry not in use, return NULL u16 entry = offsetTable.eaAddress[241]; @@ -144,10 +144,10 @@ vm::ptr _cellGcmFunc12() u32 cellGcmGetReport(u32 type, u32 index) { - cellGcmSys->Warning("cellGcmGetReport(type=%d, index=%d)", type, index); + cellGcmSys.Warning("cellGcmGetReport(type=%d, index=%d)", type, index); if (index >= 2048) { - cellGcmSys->Error("cellGcmGetReport: Wrong local index (%d)", index); + cellGcmSys.Error("cellGcmGetReport: Wrong local index (%d)", index); return -1; } @@ -161,10 +161,10 @@ u32 cellGcmGetReport(u32 type, u32 index) u32 cellGcmGetReportDataAddress(u32 index) { - cellGcmSys->Warning("cellGcmGetReportDataAddress(index=%d)", index); + cellGcmSys.Warning("cellGcmGetReportDataAddress(index=%d)", index); if (index >= 2048) { - cellGcmSys->Error("cellGcmGetReportDataAddress: Wrong local index (%d)", index); + cellGcmSys.Error("cellGcmGetReportDataAddress: Wrong local index (%d)", index); return 0; } return (u32)Memory.RSXFBMem.GetStartAddr() + index * 0x10; @@ -172,7 +172,7 @@ u32 cellGcmGetReportDataAddress(u32 index) u32 cellGcmGetReportDataLocation(u32 index, u32 location) { - cellGcmSys->Warning("cellGcmGetReportDataLocation(index=%d, location=%d)", index, location); + cellGcmSys.Warning("cellGcmGetReportDataLocation(index=%d, location=%d)", index, location); vm::ptr report = cellGcmGetReportDataAddressLocation(index, location); return report->value; @@ -180,11 +180,11 @@ u32 cellGcmGetReportDataLocation(u32 index, u32 location) u64 cellGcmGetTimeStampLocation(u32 index, u32 location) { - cellGcmSys->Warning("cellGcmGetTimeStampLocation(index=%d, location=%d)", index, location); + cellGcmSys.Warning("cellGcmGetTimeStampLocation(index=%d, location=%d)", index, location); if (location == CELL_GCM_LOCATION_LOCAL) { if (index >= 2048) { - cellGcmSys->Error("cellGcmGetTimeStampLocation: Wrong local index (%d)", index); + cellGcmSys.Error("cellGcmGetTimeStampLocation: Wrong local index (%d)", index); return 0; } return vm::read64(Memory.RSXFBMem.GetStartAddr() + index * 0x10); @@ -192,14 +192,14 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location) if (location == CELL_GCM_LOCATION_MAIN) { if (index >= 1024 * 1024) { - cellGcmSys->Error("cellGcmGetTimeStampLocation: Wrong main index (%d)", index); + cellGcmSys.Error("cellGcmGetTimeStampLocation: Wrong main index (%d)", index); return 0; } // TODO: It seems m_report_main_addr is not initialized return vm::read64(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10); } - cellGcmSys->Error("cellGcmGetTimeStampLocation: Wrong location (%d)", location); + cellGcmSys.Error("cellGcmGetTimeStampLocation: Wrong location (%d)", location); return 0; } @@ -209,32 +209,32 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location) u32 cellGcmGetControlRegister() { - cellGcmSys->Log("cellGcmGetControlRegister()"); + cellGcmSys.Log("cellGcmGetControlRegister()"); return gcm_info.control_addr; } u32 cellGcmGetDefaultCommandWordSize() { - cellGcmSys->Log("cellGcmGetDefaultCommandWordSize()"); + cellGcmSys.Log("cellGcmGetDefaultCommandWordSize()"); return 0x400; } u32 cellGcmGetDefaultSegmentWordSize() { - cellGcmSys->Log("cellGcmGetDefaultSegmentWordSize()"); + cellGcmSys.Log("cellGcmGetDefaultSegmentWordSize()"); return 0x100; } s32 cellGcmInitDefaultFifoMode(s32 mode) { - cellGcmSys->Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode); + cellGcmSys.Warning("cellGcmInitDefaultFifoMode(mode=%d)", mode); return CELL_OK; } s32 cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) { - cellGcmSys->Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize); + cellGcmSys.Warning("cellGcmSetDefaultFifoSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize); return CELL_OK; } @@ -244,11 +244,11 @@ s32 cellGcmSetDefaultFifoSize(u32 bufferSize, u32 segmentSize) s32 cellGcmBindTile(u8 index) { - cellGcmSys->Warning("cellGcmBindTile(index=%d)", index); + cellGcmSys.Warning("cellGcmBindTile(index=%d)", index); if (index >= RSXThread::m_tiles_count) { - cellGcmSys->Error("cellGcmBindTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmBindTile : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -260,11 +260,11 @@ s32 cellGcmBindTile(u8 index) s32 cellGcmBindZcull(u8 index) { - cellGcmSys->Warning("cellGcmBindZcull(index=%d)", index); + cellGcmSys.Warning("cellGcmBindZcull(index=%d)", index); if (index >= RSXThread::m_zculls_count) { - cellGcmSys->Error("cellGcmBindZcull : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmBindZcull : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -276,7 +276,7 @@ s32 cellGcmBindZcull(u8 index) s32 cellGcmGetConfiguration(vm::ptr config) { - cellGcmSys->Log("cellGcmGetConfiguration(config_addr=0x%x)", config.addr()); + cellGcmSys.Log("cellGcmGetConfiguration(config_addr=0x%x)", config.addr()); *config = current_config; @@ -287,14 +287,14 @@ s32 cellGcmGetFlipStatus() { s32 status = Emu.GetGSManager().GetRender().m_flip_status; - cellGcmSys->Log("cellGcmGetFlipStatus() -> %d", status); + cellGcmSys.Log("cellGcmGetFlipStatus() -> %d", status); return status; } u32 cellGcmGetTiledPitchSize(u32 size) { - cellGcmSys->Log("cellGcmGetTiledPitchSize(size=%d)", size); + cellGcmSys.Log("cellGcmGetTiledPitchSize(size=%d)", size); for (size_t i=0; i < sizeof(tiled_pitches) / sizeof(tiled_pitches[0]) - 1; i++) { if (tiled_pitches[i] < size && size <= tiled_pitches[i+1]) { @@ -306,23 +306,20 @@ u32 cellGcmGetTiledPitchSize(u32 size) void _cellGcmFunc1() { - cellGcmSys->Todo("_cellGcmFunc1()"); + cellGcmSys.Todo("_cellGcmFunc1()"); return; } void _cellGcmFunc15(vm::ptr context) { - cellGcmSys->Todo("_cellGcmFunc15(context_addr=0x%x)", context.addr()); + cellGcmSys.Todo("_cellGcmFunc15(context_addr=0x%x)", context.addr()); return; } // Called by cellGcmInit s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSize, u32 ioAddress) { - cellGcmSys->Warning("_cellGcmInitBody(context_addr=0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context.addr(), cmdSize, ioSize, ioAddress); - - if(!cellGcmSys->IsLoaded()) - cellGcmSys->Load(); + cellGcmSys.Warning("_cellGcmInitBody(context_addr=0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context.addr(), cmdSize, ioSize, ioAddress); if(!local_size && !local_addr) { @@ -331,23 +328,23 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz Memory.RSXFBMem.AllocAlign(local_size); } - cellGcmSys->Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size); + cellGcmSys.Warning("*** local memory(addr=0x%x, size=0x%x)", local_addr, local_size); InitOffsetTable(); if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB) { - cellGcmSys->Warning("cellGcmInit(): 512MB io address space used"); + cellGcmSys.Warning("cellGcmInit(): 512MB io address space used"); Memory.RSXIOMem.SetRange(0, 0x20000000 /*512MB*/); } else { - cellGcmSys->Warning("cellGcmInit(): 256MB io address space used"); + cellGcmSys.Warning("cellGcmInit(): 256MB io address space used"); Memory.RSXIOMem.SetRange(0, 0x10000000 /*256MB*/); } if (gcmMapEaIoAddress(ioAddress, 0, ioSize, false) != CELL_OK) { - cellGcmSys->Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -396,7 +393,7 @@ s32 _cellGcmInitBody(vm::ptr context, u32 cmdSize, u32 ioSiz s32 cellGcmResetFlipStatus() { - cellGcmSys->Log("cellGcmResetFlipStatus()"); + cellGcmSys.Log("cellGcmResetFlipStatus()"); Emu.GetGSManager().GetRender().m_flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_WAITING; @@ -405,7 +402,7 @@ s32 cellGcmResetFlipStatus() s32 cellGcmSetDebugOutputLevel(s32 level) { - cellGcmSys->Warning("cellGcmSetDebugOutputLevel(level=%d)", level); + cellGcmSys.Warning("cellGcmSetDebugOutputLevel(level=%d)", level); switch (level) { @@ -423,10 +420,10 @@ s32 cellGcmSetDebugOutputLevel(s32 level) s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height) { - cellGcmSys->Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)", id, offset, width ? pitch / width : pitch, width, height); + cellGcmSys.Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)", id, offset, width ? pitch / width : pitch, width, height); if (id > 7) { - cellGcmSys->Error("cellGcmSetDisplayBuffer : CELL_EINVAL"); + cellGcmSys.Error("cellGcmSetDisplayBuffer : CELL_EINVAL"); return CELL_EINVAL; } @@ -446,14 +443,14 @@ s32 cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height void cellGcmSetFlipHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler.addr()); + cellGcmSys.Warning("cellGcmSetFlipHandler(handler_addr=%d)", handler.addr()); Emu.GetGSManager().GetRender().m_flip_handler = handler; } s32 cellGcmSetFlipMode(u32 mode) { - cellGcmSys->Warning("cellGcmSetFlipMode(mode=%d)", mode); + cellGcmSys.Warning("cellGcmSetFlipMode(mode=%d)", mode); switch (mode) { @@ -472,18 +469,18 @@ s32 cellGcmSetFlipMode(u32 mode) void cellGcmSetFlipStatus() { - cellGcmSys->Warning("cellGcmSetFlipStatus()"); + cellGcmSys.Warning("cellGcmSetFlipStatus()"); Emu.GetGSManager().GetRender().m_flip_status = 0; } s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) { - cellGcmSys->Log("cellGcmSetPrepareFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); + cellGcmSys.Log("cellGcmSetPrepareFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); if(id > 7) { - cellGcmSys->Error("cellGcmSetPrepareFlip : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmSetPrepareFlip : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -493,16 +490,16 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) if (current + 8 == ctxt->begin) { - cellGcmSys->Error("cellGcmSetPrepareFlip : queue is full"); + cellGcmSys.Error("cellGcmSetPrepareFlip : queue is full"); return CELL_GCM_ERROR_FAILURE; } if (current + 8 >= ctxt->end) { - cellGcmSys->Error("Bad flip!"); + cellGcmSys.Error("Bad flip!"); if (s32 res = ctxt->callback(ctxt, 8 /* ??? */)) { - cellGcmSys->Error("cellGcmSetPrepareFlip : callback failed (0x%08x)", res); + cellGcmSys.Error("cellGcmSetPrepareFlip : callback failed (0x%08x)", res); return res; } } @@ -526,7 +523,7 @@ s32 cellGcmSetPrepareFlip(vm::ptr ctxt, u32 id) s32 cellGcmSetFlip(vm::ptr ctxt, u32 id) { - cellGcmSys->Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); + cellGcmSys.Log("cellGcmSetFlip(ctx=0x%x, id=0x%x)", ctxt.addr(), id); s32 res = cellGcmSetPrepareFlip(ctxt, id); return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK; @@ -534,17 +531,17 @@ s32 cellGcmSetFlip(vm::ptr ctxt, u32 id) s32 cellGcmSetSecondVFrequency(u32 freq) { - cellGcmSys->Warning("cellGcmSetSecondVFrequency(level=%d)", freq); + cellGcmSys.Warning("cellGcmSetSecondVFrequency(level=%d)", freq); switch (freq) { case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ: Emu.GetGSManager().GetRender().m_frequency_mode = freq; Emu.GetGSManager().GetRender().m_fps_limit = 59.94; break; case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys->Todo("Unimplemented display frequency: Scanout"); break; + Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Scanout"); break; case CELL_GCM_DISPLAY_FREQUENCY_DISABLE: - Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys->Todo("Unimplemented display frequency: Disabled"); break; - default: cellGcmSys->Error("Improper display frequency specified!"); return CELL_OK; + Emu.GetGSManager().GetRender().m_frequency_mode = freq; cellGcmSys.Todo("Unimplemented display frequency: Disabled"); break; + default: cellGcmSys.Error("Improper display frequency specified!"); return CELL_OK; } return CELL_OK; @@ -552,30 +549,30 @@ s32 cellGcmSetSecondVFrequency(u32 freq) s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) { - cellGcmSys->Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", + cellGcmSys.Warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); if (index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) { - cellGcmSys->Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } if (offset & 0xffff || size & 0xffff || pitch & 0xf) { - cellGcmSys->Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) { - cellGcmSys->Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTileInfo : CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ENUM; } if (comp) { - cellGcmSys->Error("cellGcmSetTileInfo: bad compression mode! (%d)", comp); + cellGcmSys.Error("cellGcmSetTileInfo: bad compression mode! (%d)", comp); } auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; @@ -593,21 +590,21 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u void cellGcmSetUserHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler.addr()); + cellGcmSys.Warning("cellGcmSetUserHandler(handler_addr=0x%x)", handler.addr()); Emu.GetGSManager().GetRender().m_user_handler = handler; } void cellGcmSetVBlankHandler(vm::ptr handler) { - cellGcmSys->Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler.addr()); + cellGcmSys.Warning("cellGcmSetVBlankHandler(handler_addr=0x%x)", handler.addr()); Emu.GetGSManager().GetRender().m_vblank_handler = handler; } s32 cellGcmSetWaitFlip(vm::ptr ctxt) { - cellGcmSys->Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.addr()); + cellGcmSys.Log("cellGcmSetWaitFlip(ctx=0x%x)", ctxt.addr()); GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; @@ -615,12 +612,12 @@ s32 cellGcmSetWaitFlip(vm::ptr ctxt) s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, u32 zFormat, u32 aaFormat, u32 zCullDir, u32 zCullFormat, u32 sFunc, u32 sRef, u32 sMask) { - cellGcmSys->Todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", + cellGcmSys.Todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)", index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask); if (index >= RSXThread::m_zculls_count) { - cellGcmSys->Error("cellGcmSetZcull : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetZcull : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -643,11 +640,11 @@ s32 cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart, s32 cellGcmUnbindTile(u8 index) { - cellGcmSys->Warning("cellGcmUnbindTile(index=%d)", index); + cellGcmSys.Warning("cellGcmUnbindTile(index=%d)", index); if (index >= RSXThread::m_tiles_count) { - cellGcmSys->Error("cellGcmUnbindTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmUnbindTile : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -659,11 +656,11 @@ s32 cellGcmUnbindTile(u8 index) s32 cellGcmUnbindZcull(u8 index) { - cellGcmSys->Warning("cellGcmUnbindZcull(index=%d)", index); + cellGcmSys.Warning("cellGcmUnbindZcull(index=%d)", index); if (index >= 8) { - cellGcmSys->Error("cellGcmUnbindZcull : CELL_EINVAL"); + cellGcmSys.Error("cellGcmUnbindZcull : CELL_EINVAL"); return CELL_EINVAL; } @@ -675,25 +672,25 @@ s32 cellGcmUnbindZcull(u8 index) u32 cellGcmGetTileInfo() { - cellGcmSys->Warning("cellGcmGetTileInfo()"); + cellGcmSys.Warning("cellGcmGetTileInfo()"); return Emu.GetGSManager().GetRender().m_tiles_addr; } u32 cellGcmGetZcullInfo() { - cellGcmSys->Warning("cellGcmGetZcullInfo()"); + cellGcmSys.Warning("cellGcmGetZcullInfo()"); return Emu.GetGSManager().GetRender().m_zculls_addr; } u32 cellGcmGetDisplayInfo() { - cellGcmSys->Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); + cellGcmSys.Warning("cellGcmGetDisplayInfo() = 0x%x", Emu.GetGSManager().GetRender().m_gcm_buffers_addr); return Emu.GetGSManager().GetRender().m_gcm_buffers_addr; } s32 cellGcmGetCurrentDisplayBufferId(u32 id_addr) { - cellGcmSys->Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); + cellGcmSys.Warning("cellGcmGetCurrentDisplayBufferId(id_addr=0x%x)", id_addr); vm::write32(id_addr, Emu.GetGSManager().GetRender().m_gcm_current_buffer); @@ -720,7 +717,7 @@ s32 cellGcmGetDisplayBufferByFlipIndex() u64 cellGcmGetLastFlipTime() { - cellGcmSys->Log("cellGcmGetLastFlipTime()"); + cellGcmSys.Log("cellGcmGetLastFlipTime()"); return Emu.GetGSManager().GetRender().m_last_flip_time; } @@ -733,14 +730,14 @@ s32 cellGcmGetLastSecondVTime() u64 cellGcmGetVBlankCount() { - cellGcmSys->Log("cellGcmGetVBlankCount()"); + cellGcmSys.Log("cellGcmGetVBlankCount()"); return Emu.GetGSManager().GetRender().m_vblank_count; } s32 cellGcmInitSystemMode(u64 mode) { - cellGcmSys->Log("cellGcmInitSystemMode(mode=0x%x)", mode); + cellGcmSys.Log("cellGcmInitSystemMode(mode=0x%x)", mode); system_mode = mode; @@ -749,11 +746,11 @@ s32 cellGcmInitSystemMode(u64 mode) s32 cellGcmSetFlipImmediate(u8 id) { - cellGcmSys->Todo("cellGcmSetFlipImmediate(fid=0x%x)", id); + cellGcmSys.Todo("cellGcmSetFlipImmediate(fid=0x%x)", id); if (id > 7) { - cellGcmSys->Error("cellGcmSetFlipImmediate : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmSetFlipImmediate : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -797,7 +794,7 @@ s32 cellGcmSortRemapEaIoAddress() //---------------------------------------------------------------------------- s32 cellGcmAddressToOffset(u32 address, vm::ptr> offset) { - cellGcmSys->Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr()); + cellGcmSys.Log("cellGcmAddressToOffset(address=0x%x,offset_addr=0x%x)", address, offset.addr()); // Address not on main memory or local memory if (address >= 0xD0000000) @@ -834,14 +831,14 @@ s32 cellGcmAddressToOffset(u32 address, vm::ptr> offset) u32 cellGcmGetMaxIoMapSize() { - cellGcmSys->Log("cellGcmGetMaxIoMapSize()"); + cellGcmSys.Log("cellGcmGetMaxIoMapSize()"); return (u32)(Memory.RSXIOMem.GetEndAddr() - Memory.RSXIOMem.GetReservedAmount()); } void cellGcmGetOffsetTable(vm::ptr table) { - cellGcmSys->Log("cellGcmGetOffsetTable(table_addr=0x%x)", table.addr()); + cellGcmSys.Log("cellGcmGetOffsetTable(table_addr=0x%x)", table.addr()); table->ioAddress = offsetTable.ioAddress; table->eaAddress = offsetTable.eaAddress; @@ -849,7 +846,7 @@ void cellGcmGetOffsetTable(vm::ptr table) s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr address) { - cellGcmSys->Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%x)", ioOffset, address); + cellGcmSys.Log("cellGcmIoOffsetToAddress(ioOffset=0x%x, address=0x%x)", ioOffset, address); u32 realAddr; @@ -878,7 +875,7 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) } else { - cellGcmSys->Error("cellGcmMapEaIoAddress : CELL_GCM_ERROR_FAILURE"); + cellGcmSys.Error("cellGcmMapEaIoAddress : CELL_GCM_ERROR_FAILURE"); return CELL_GCM_ERROR_FAILURE; } @@ -887,14 +884,14 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict) s32 cellGcmMapEaIoAddress(u32 ea, u32 io, u32 size) { - cellGcmSys->Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); + cellGcmSys.Warning("cellGcmMapEaIoAddress(ea=0x%x, io=0x%x, size=0x%x)", ea, io, size); return gcmMapEaIoAddress(ea, io, size, false); } s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) { - cellGcmSys->Warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); + cellGcmSys.Warning("cellGcmMapEaIoAddressWithFlags(ea=0x%x, io=0x%x, size=0x%x, flags=0x%x)", ea, io, size, flags); assert(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/); @@ -903,7 +900,7 @@ s32 cellGcmMapEaIoAddressWithFlags(u32 ea, u32 io, u32 size, u32 flags) s32 cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) { - cellGcmSys->Warning("cellGcmMapLocalMemory(address=*0x%x, size=*0x%x)", address, size); + cellGcmSys.Warning("cellGcmMapLocalMemory(address=*0x%x, size=*0x%x)", address, size); if (!local_addr && !local_size && Memory.RSXFBMem.AllocFixed(local_addr = Memory.RSXFBMem.GetStartAddr(), local_size = 0xf900000 /* TODO */)) { @@ -912,7 +909,7 @@ s32 cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) } else { - cellGcmSys->Error("RSX local memory already mapped"); + cellGcmSys.Error("RSX local memory already mapped"); return CELL_GCM_ERROR_FAILURE; } @@ -921,7 +918,7 @@ s32 cellGcmMapLocalMemory(vm::ptr address, vm::ptr size) s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) { - cellGcmSys->Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.addr()); + cellGcmSys.Warning("cellGcmMapMainMemory(ea=0x%x,size=0x%x,offset_addr=0x%x)", ea, size, offset.addr()); if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE; @@ -942,7 +939,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) } else { - cellGcmSys->Error("cellGcmMapMainMemory : CELL_GCM_ERROR_NO_IO_PAGE_TABLE"); + cellGcmSys.Error("cellGcmMapMainMemory : CELL_GCM_ERROR_NO_IO_PAGE_TABLE"); return CELL_GCM_ERROR_NO_IO_PAGE_TABLE; } @@ -953,17 +950,17 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr offset) s32 cellGcmReserveIoMapSize(u32 size) { - cellGcmSys->Log("cellGcmReserveIoMapSize(size=0x%x)", size); + cellGcmSys.Log("cellGcmReserveIoMapSize(size=0x%x)", size); if (size & 0xFFFFF) { - cellGcmSys->Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (size > cellGcmGetMaxIoMapSize()) { - cellGcmSys->Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -973,7 +970,7 @@ s32 cellGcmReserveIoMapSize(u32 size) s32 cellGcmUnmapEaIoAddress(u32 ea) { - cellGcmSys->Log("cellGcmUnmapEaIoAddress(ea=0x%x)", ea); + cellGcmSys.Log("cellGcmUnmapEaIoAddress(ea=0x%x)", ea); u32 size; if (Memory.RSXIOMem.UnmapRealAddress(ea, size)) @@ -988,7 +985,7 @@ s32 cellGcmUnmapEaIoAddress(u32 ea) } else { - cellGcmSys->Error("cellGcmUnmapEaIoAddress(ea=0x%x): UnmapRealAddress() failed"); + cellGcmSys.Error("cellGcmUnmapEaIoAddress(ea=0x%x): UnmapRealAddress() failed"); return CELL_GCM_ERROR_FAILURE; } @@ -997,7 +994,7 @@ s32 cellGcmUnmapEaIoAddress(u32 ea) s32 cellGcmUnmapIoAddress(u32 io) { - cellGcmSys->Log("cellGcmUnmapIoAddress(io=0x%x)", io); + cellGcmSys.Log("cellGcmUnmapIoAddress(io=0x%x)", io); u32 size; if (Memory.RSXIOMem.UnmapAddress(io, size)) @@ -1012,7 +1009,7 @@ s32 cellGcmUnmapIoAddress(u32 io) } else { - cellGcmSys->Error("cellGcmUnmapIoAddress(io=0x%x): UnmapAddress() failed"); + cellGcmSys.Error("cellGcmUnmapIoAddress(io=0x%x): UnmapAddress() failed"); return CELL_GCM_ERROR_FAILURE; } @@ -1021,17 +1018,17 @@ s32 cellGcmUnmapIoAddress(u32 io) s32 cellGcmUnreserveIoMapSize(u32 size) { - cellGcmSys->Log("cellGcmUnreserveIoMapSize(size=0x%x)", size); + cellGcmSys.Log("cellGcmUnreserveIoMapSize(size=0x%x)", size); if (size & 0xFFFFF) { - cellGcmSys->Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if (size > Memory.RSXIOMem.GetReservedAmount()) { - cellGcmSys->Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmReserveIoMapSize : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } @@ -1085,7 +1082,7 @@ s32 cellGcmSetCursorImageOffset(u32 offset) void cellGcmSetDefaultCommandBuffer() { - cellGcmSys->Warning("cellGcmSetDefaultCommandBuffer()"); + cellGcmSys.Warning("cellGcmSetDefaultCommandBuffer()"); vm::write32(Emu.GetGSManager().GetRender().m_ctxt_addr, gcm_info.context_addr); } @@ -1095,14 +1092,14 @@ void cellGcmSetDefaultCommandBuffer() s32 cellGcmSetFlipCommand(vm::ptr ctx, u32 id) { - cellGcmSys->Log("cellGcmSetFlipCommand(ctx_addr=0x%x, id=0x%x)", ctx.addr(), id); + cellGcmSys.Log("cellGcmSetFlipCommand(ctx_addr=0x%x, id=0x%x)", ctx.addr(), id); return cellGcmSetPrepareFlip(ctx, id); } s32 cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, u32 label_index, u32 label_value) { - cellGcmSys->Log("cellGcmSetFlipCommandWithWaitLabel(ctx_addr=0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", + cellGcmSys.Log("cellGcmSetFlipCommandWithWaitLabel(ctx_addr=0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx.addr(), id, label_index, label_value); s32 res = cellGcmSetPrepareFlip(ctx, id); @@ -1112,31 +1109,31 @@ s32 cellGcmSetFlipCommandWithWaitLabel(vm::ptr ctx, u32 id, s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 comp, u16 base, u8 bank) { - cellGcmSys->Warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", + cellGcmSys.Warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)", index, location, offset, size, pitch, comp, base, bank); // Copied form cellGcmSetTileInfo if(index >= RSXThread::m_tiles_count || base >= 800 || bank >= 4) { - cellGcmSys->Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_VALUE"); + cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_VALUE"); return CELL_GCM_ERROR_INVALID_VALUE; } if(offset & 0xffff || size & 0xffff || pitch & 0xf) { - cellGcmSys->Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ALIGNMENT"); + cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ALIGNMENT"); return CELL_GCM_ERROR_INVALID_ALIGNMENT; } if(location >= 2 || (comp != 0 && (comp < 7 || comp > 12))) { - cellGcmSys->Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ENUM"); + cellGcmSys.Error("cellGcmSetTile : CELL_GCM_ERROR_INVALID_ENUM"); return CELL_GCM_ERROR_INVALID_ENUM; } if(comp) { - cellGcmSys->Error("cellGcmSetTile: bad compression mode! (%d)", comp); + cellGcmSys.Error("cellGcmSetTile: bad compression mode! (%d)", comp); } auto& tile = Emu.GetGSManager().GetRender().m_tiles[index]; @@ -1159,7 +1156,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co s32 cellGcmCallback(vm::ptr context, u32 count) { - cellGcmSys->Log("cellGcmCallback(context_addr=0x%x, count=0x%x)", context.addr(), count); + cellGcmSys.Log("cellGcmCallback(context_addr=0x%x, count=0x%x)", context.addr(), count); if (1) { @@ -1213,122 +1210,113 @@ s32 cellGcmCallback(vm::ptr context, u32 count) //---------------------------------------------------------------------------- -void cellGcmSys_init(Module *pxThis) -{ - cellGcmSys = pxThis; - - // Data Retrieval - cellGcmSys->AddFunc(0xc8f3bd09, cellGcmGetCurrentField); - cellGcmSys->AddFunc(0xf80196c1, cellGcmGetLabelAddress); - cellGcmSys->AddFunc(0x21cee035, cellGcmGetNotifyDataAddress); - cellGcmSys->AddFunc(0x661fe266, _cellGcmFunc12); - cellGcmSys->AddFunc(0x99d397ac, cellGcmGetReport); - cellGcmSys->AddFunc(0x9a0159af, cellGcmGetReportDataAddress); - cellGcmSys->AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); - cellGcmSys->AddFunc(0xa6b180ac, cellGcmGetReportDataLocation); - cellGcmSys->AddFunc(0x5a41c10f, cellGcmGetTimeStamp); - cellGcmSys->AddFunc(0x2ad4951b, cellGcmGetTimeStampLocation); - - // Command Buffer Control - cellGcmSys->AddFunc(0xa547adde, cellGcmGetControlRegister); - cellGcmSys->AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); - cellGcmSys->AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); - cellGcmSys->AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode); - cellGcmSys->AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize); - //cellGcmSys->AddFunc(, cellGcmReserveMethodSize); - //cellGcmSys->AddFunc(, cellGcmResetDefaultCommandBuffer); - //cellGcmSys->AddFunc(, cellGcmSetupContextData); - //cellGcmSys->AddFunc(, cellGcmCallbackForSnc); - //cellGcmSys->AddFunc(, cellGcmFinish); - //cellGcmSys->AddFunc(, cellGcmFlush); - - // Hardware Resource Management - cellGcmSys->AddFunc(0x4524cccd, cellGcmBindTile); - cellGcmSys->AddFunc(0x9dc04436, cellGcmBindZcull); - cellGcmSys->AddFunc(0x1f61b3ff, cellGcmDumpGraphicsError); - cellGcmSys->AddFunc(0xe315a0b2, cellGcmGetConfiguration); - cellGcmSys->AddFunc(0x371674cf, cellGcmGetDisplayBufferByFlipIndex); - cellGcmSys->AddFunc(0x72a577ce, cellGcmGetFlipStatus); - cellGcmSys->AddFunc(0x63387071, cellGcmGetLastFlipTime); - cellGcmSys->AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime); - cellGcmSys->AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); - cellGcmSys->AddFunc(0x723bbc7e, cellGcmGetVBlankCount); - cellGcmSys->AddFunc(0x5f909b17, _cellGcmFunc1); - cellGcmSys->AddFunc(0x3a33c1fd, _cellGcmFunc15); - cellGcmSys->AddFunc(0x15bae46b, _cellGcmInitBody); - cellGcmSys->AddFunc(0xfce9e764, cellGcmInitSystemMode); - cellGcmSys->AddFunc(0xb2e761d4, cellGcmResetFlipStatus); - cellGcmSys->AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); - cellGcmSys->AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer); - cellGcmSys->AddFunc(0xdc09357e, cellGcmSetFlip); - cellGcmSys->AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); - cellGcmSys->AddFunc(0xacee8542, cellGcmSetFlipImmediate); - cellGcmSys->AddFunc(0x4ae8d215, cellGcmSetFlipMode); - cellGcmSys->AddFunc(0xa47c09ff, cellGcmSetFlipStatus); - cellGcmSys->AddFunc(0xd01b570d, cellGcmSetGraphicsHandler); - cellGcmSys->AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip); - cellGcmSys->AddFunc(0x0a862772, cellGcmSetQueueHandler); - cellGcmSys->AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); - cellGcmSys->AddFunc(0xdc494430, cellGcmSetSecondVHandler); - cellGcmSys->AddFunc(0xbd100dbc, cellGcmSetTileInfo); - cellGcmSys->AddFunc(0x06edea9e, cellGcmSetUserHandler); - cellGcmSys->AddFunc(0xffe0160e, cellGcmSetVBlankFrequency); - cellGcmSys->AddFunc(0xa91b0402, cellGcmSetVBlankHandler); - cellGcmSys->AddFunc(0x983fb9aa, cellGcmSetWaitFlip); - cellGcmSys->AddFunc(0xd34a420d, cellGcmSetZcull); - cellGcmSys->AddFunc(0x25b40ab4, cellGcmSortRemapEaIoAddress); - cellGcmSys->AddFunc(0xd9b7653e, cellGcmUnbindTile); - cellGcmSys->AddFunc(0xa75640e8, cellGcmUnbindZcull); - cellGcmSys->AddFunc(0x657571f7, cellGcmGetTileInfo); - cellGcmSys->AddFunc(0xd9a0a879, cellGcmGetZcullInfo); - cellGcmSys->AddFunc(0x0e6b0dae, cellGcmGetDisplayInfo); - cellGcmSys->AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId); - cellGcmSys->AddFunc(0xbd6d60d9, cellGcmSetInvalidateTile); - //cellGcmSys->AddFunc(, cellGcmSetFlipWithWaitLabel); - - // Memory Mapping - cellGcmSys->AddFunc(0x21ac3697, cellGcmAddressToOffset); - cellGcmSys->AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize); - cellGcmSys->AddFunc(0x2922aed0, cellGcmGetOffsetTable); - cellGcmSys->AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress); - cellGcmSys->AddFunc(0x63441cb4, cellGcmMapEaIoAddress); - cellGcmSys->AddFunc(0x626e8518, cellGcmMapEaIoAddressWithFlags); - cellGcmSys->AddFunc(0xdb769b32, cellGcmMapLocalMemory); - cellGcmSys->AddFunc(0xa114ec67, cellGcmMapMainMemory); - cellGcmSys->AddFunc(0xa7ede268, cellGcmReserveIoMapSize); - cellGcmSys->AddFunc(0xefd00f54, cellGcmUnmapEaIoAddress); - cellGcmSys->AddFunc(0xdb23e867, cellGcmUnmapIoAddress); - cellGcmSys->AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize); - - // Cursor - cellGcmSys->AddFunc(0x107bf3a1, cellGcmInitCursor); - cellGcmSys->AddFunc(0xc47d0812, cellGcmSetCursorEnable); - cellGcmSys->AddFunc(0x69c6cc82, cellGcmSetCursorDisable); - cellGcmSys->AddFunc(0xf9bfdc72, cellGcmSetCursorImageOffset); - cellGcmSys->AddFunc(0x1a0de550, cellGcmSetCursorPosition); - cellGcmSys->AddFunc(0xbd2fa0a7, cellGcmUpdateCursor); - - // Functions for Maintaining Compatibility - cellGcmSys->AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer); - //cellGcmSys->AddFunc(, cellGcmGetCurrentBuffer); - //cellGcmSys->AddFunc(, cellGcmSetCurrentBuffer); - //cellGcmSys->AddFunc(, cellGcmSetDefaultCommandBufferAndSegmentWordSize); - //cellGcmSys->AddFunc(, cellGcmSetUserCallback); - - // Other - cellGcmSys->AddFunc(0x21397818, cellGcmSetFlipCommand); - cellGcmSys->AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); - cellGcmSys->AddFunc(0xd0b1d189, cellGcmSetTile); -} - -void cellGcmSys_load() +Module cellGcmSys("cellGcmSys", []() { current_config.ioAddress = 0; current_config.localAddress = 0; local_size = 0; local_addr = 0; -} -void cellGcmSys_unload() -{ -} + // Data Retrieval + cellGcmSys.AddFunc(0xc8f3bd09, cellGcmGetCurrentField); + cellGcmSys.AddFunc(0xf80196c1, cellGcmGetLabelAddress); + cellGcmSys.AddFunc(0x21cee035, cellGcmGetNotifyDataAddress); + cellGcmSys.AddFunc(0x661fe266, _cellGcmFunc12); + cellGcmSys.AddFunc(0x99d397ac, cellGcmGetReport); + cellGcmSys.AddFunc(0x9a0159af, cellGcmGetReportDataAddress); + cellGcmSys.AddFunc(0x8572bce2, cellGcmGetReportDataAddressLocation); + cellGcmSys.AddFunc(0xa6b180ac, cellGcmGetReportDataLocation); + cellGcmSys.AddFunc(0x5a41c10f, cellGcmGetTimeStamp); + cellGcmSys.AddFunc(0x2ad4951b, cellGcmGetTimeStampLocation); + + // Command Buffer Control + cellGcmSys.AddFunc(0xa547adde, cellGcmGetControlRegister); + cellGcmSys.AddFunc(0x5e2ee0f0, cellGcmGetDefaultCommandWordSize); + cellGcmSys.AddFunc(0x8cdf8c70, cellGcmGetDefaultSegmentWordSize); + cellGcmSys.AddFunc(0xcaabd992, cellGcmInitDefaultFifoMode); + cellGcmSys.AddFunc(0x9ba451e4, cellGcmSetDefaultFifoSize); + //cellGcmSys.AddFunc(, cellGcmReserveMethodSize); + //cellGcmSys.AddFunc(, cellGcmResetDefaultCommandBuffer); + //cellGcmSys.AddFunc(, cellGcmSetupContextData); + //cellGcmSys.AddFunc(, cellGcmCallbackForSnc); + //cellGcmSys.AddFunc(, cellGcmFinish); + //cellGcmSys.AddFunc(, cellGcmFlush); + + // Hardware Resource Management + cellGcmSys.AddFunc(0x4524cccd, cellGcmBindTile); + cellGcmSys.AddFunc(0x9dc04436, cellGcmBindZcull); + cellGcmSys.AddFunc(0x1f61b3ff, cellGcmDumpGraphicsError); + cellGcmSys.AddFunc(0xe315a0b2, cellGcmGetConfiguration); + cellGcmSys.AddFunc(0x371674cf, cellGcmGetDisplayBufferByFlipIndex); + cellGcmSys.AddFunc(0x72a577ce, cellGcmGetFlipStatus); + cellGcmSys.AddFunc(0x63387071, cellGcmGetLastFlipTime); + cellGcmSys.AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime); + cellGcmSys.AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); + cellGcmSys.AddFunc(0x723bbc7e, cellGcmGetVBlankCount); + cellGcmSys.AddFunc(0x5f909b17, _cellGcmFunc1); + cellGcmSys.AddFunc(0x3a33c1fd, _cellGcmFunc15); + cellGcmSys.AddFunc(0x15bae46b, _cellGcmInitBody); + cellGcmSys.AddFunc(0xfce9e764, cellGcmInitSystemMode); + cellGcmSys.AddFunc(0xb2e761d4, cellGcmResetFlipStatus); + cellGcmSys.AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); + cellGcmSys.AddFunc(0xa53d12ae, cellGcmSetDisplayBuffer); + cellGcmSys.AddFunc(0xdc09357e, cellGcmSetFlip); + cellGcmSys.AddFunc(0xa41ef7e8, cellGcmSetFlipHandler); + cellGcmSys.AddFunc(0xacee8542, cellGcmSetFlipImmediate); + cellGcmSys.AddFunc(0x4ae8d215, cellGcmSetFlipMode); + cellGcmSys.AddFunc(0xa47c09ff, cellGcmSetFlipStatus); + cellGcmSys.AddFunc(0xd01b570d, cellGcmSetGraphicsHandler); + cellGcmSys.AddFunc(0x0b4b62d5, cellGcmSetPrepareFlip); + cellGcmSys.AddFunc(0x0a862772, cellGcmSetQueueHandler); + cellGcmSys.AddFunc(0x4d7ce993, cellGcmSetSecondVFrequency); + cellGcmSys.AddFunc(0xdc494430, cellGcmSetSecondVHandler); + cellGcmSys.AddFunc(0xbd100dbc, cellGcmSetTileInfo); + cellGcmSys.AddFunc(0x06edea9e, cellGcmSetUserHandler); + cellGcmSys.AddFunc(0xffe0160e, cellGcmSetVBlankFrequency); + cellGcmSys.AddFunc(0xa91b0402, cellGcmSetVBlankHandler); + cellGcmSys.AddFunc(0x983fb9aa, cellGcmSetWaitFlip); + cellGcmSys.AddFunc(0xd34a420d, cellGcmSetZcull); + cellGcmSys.AddFunc(0x25b40ab4, cellGcmSortRemapEaIoAddress); + cellGcmSys.AddFunc(0xd9b7653e, cellGcmUnbindTile); + cellGcmSys.AddFunc(0xa75640e8, cellGcmUnbindZcull); + cellGcmSys.AddFunc(0x657571f7, cellGcmGetTileInfo); + cellGcmSys.AddFunc(0xd9a0a879, cellGcmGetZcullInfo); + cellGcmSys.AddFunc(0x0e6b0dae, cellGcmGetDisplayInfo); + cellGcmSys.AddFunc(0x93806525, cellGcmGetCurrentDisplayBufferId); + cellGcmSys.AddFunc(0xbd6d60d9, cellGcmSetInvalidateTile); + //cellGcmSys.AddFunc(, cellGcmSetFlipWithWaitLabel); + + // Memory Mapping + cellGcmSys.AddFunc(0x21ac3697, cellGcmAddressToOffset); + cellGcmSys.AddFunc(0xfb81c03e, cellGcmGetMaxIoMapSize); + cellGcmSys.AddFunc(0x2922aed0, cellGcmGetOffsetTable); + cellGcmSys.AddFunc(0x2a6fba9c, cellGcmIoOffsetToAddress); + cellGcmSys.AddFunc(0x63441cb4, cellGcmMapEaIoAddress); + cellGcmSys.AddFunc(0x626e8518, cellGcmMapEaIoAddressWithFlags); + cellGcmSys.AddFunc(0xdb769b32, cellGcmMapLocalMemory); + cellGcmSys.AddFunc(0xa114ec67, cellGcmMapMainMemory); + cellGcmSys.AddFunc(0xa7ede268, cellGcmReserveIoMapSize); + cellGcmSys.AddFunc(0xefd00f54, cellGcmUnmapEaIoAddress); + cellGcmSys.AddFunc(0xdb23e867, cellGcmUnmapIoAddress); + cellGcmSys.AddFunc(0x3b9bd5bd, cellGcmUnreserveIoMapSize); + + // Cursor + cellGcmSys.AddFunc(0x107bf3a1, cellGcmInitCursor); + cellGcmSys.AddFunc(0xc47d0812, cellGcmSetCursorEnable); + cellGcmSys.AddFunc(0x69c6cc82, cellGcmSetCursorDisable); + cellGcmSys.AddFunc(0xf9bfdc72, cellGcmSetCursorImageOffset); + cellGcmSys.AddFunc(0x1a0de550, cellGcmSetCursorPosition); + cellGcmSys.AddFunc(0xbd2fa0a7, cellGcmUpdateCursor); + + // Functions for Maintaining Compatibility + cellGcmSys.AddFunc(0xbc982946, cellGcmSetDefaultCommandBuffer); + //cellGcmSys.AddFunc(, cellGcmGetCurrentBuffer); + //cellGcmSys.AddFunc(, cellGcmSetCurrentBuffer); + //cellGcmSys.AddFunc(, cellGcmSetDefaultCommandBufferAndSegmentWordSize); + //cellGcmSys.AddFunc(, cellGcmSetUserCallback); + + // Other + cellGcmSys.AddFunc(0x21397818, cellGcmSetFlipCommand); + cellGcmSys.AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); + cellGcmSys.AddFunc(0xd0b1d189, cellGcmSetTile); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp index 2d629dd16d..f3245d54cf 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGem.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGem.cpp @@ -4,7 +4,7 @@ #include "cellGem.h" -Module *cellGem = nullptr; +extern Module cellGem; struct cellGemInternal { @@ -81,7 +81,7 @@ int cellGemEnableMagnetometer() int cellGemEnd() { - cellGem->Warning("cellGemEnd()"); + cellGem.Warning("cellGemEnd()"); if (!cellGemInstance.m_bInitialized) return CELL_GEM_ERROR_UNINITIALIZED; @@ -183,7 +183,7 @@ int cellGemGetInertialState() int cellGemGetInfo(vm::ptr info) { - cellGem->Warning("cellGemGetInfo(info=0x%x)", info.addr()); + cellGem.Warning("cellGemGetInfo(info=0x%x)", info.addr()); if (!cellGemInstance.m_bInitialized) return CELL_GEM_ERROR_UNINITIALIZED; @@ -199,7 +199,7 @@ int cellGemGetInfo(vm::ptr info) s32 cellGemGetMemorySize(s32 max_connect) { - cellGem->Warning("cellGemGetMemorySize(max_connect=%d)", max_connect); + cellGem.Warning("cellGemGetMemorySize(max_connect=%d)", max_connect); if (max_connect > CELL_GEM_MAX_NUM) return CELL_GEM_ERROR_INVALID_PARAMETER; @@ -265,7 +265,7 @@ int cellGemHSVtoRGB() int cellGemInit(vm::ptr attribute) { - cellGem->Warning("cellGemInit(attribute_addr=0x%x)", attribute.addr()); + cellGem.Warning("cellGemInit(attribute_addr=0x%x)", attribute.addr()); if (cellGemInstance.m_bInitialized) return CELL_GEM_ERROR_ALREADY_INITIALIZED; @@ -387,50 +387,47 @@ void cellGem_unload() cellGemInstance.m_bInitialized = false; } -void cellGem_init(Module *pxThis) +Module cellGem("cellGem", []() { - cellGem = pxThis; - - //cellGem->AddFunc(, cellGemAttributeInit); - cellGem->AddFunc(0xafa99ead, cellGemCalibrate); - cellGem->AddFunc(0x9b9714a4, cellGemClearStatusFlags); - cellGem->AddFunc(0x1a13d010, cellGemConvertVideoFinish); - cellGem->AddFunc(0x6dce048c, cellGemConvertVideoStart); - cellGem->AddFunc(0x4219de31, cellGemEnableCameraPitchAngleCorrection); - cellGem->AddFunc(0x1a2518a2, cellGemEnableMagnetometer); - cellGem->AddFunc(0xe1f85a80, cellGemEnd); - cellGem->AddFunc(0x6fc4c791, cellGemFilterState); - cellGem->AddFunc(0xce6d7791, cellGemForceRGB); - cellGem->AddFunc(0x6a5b7048, cellGemGetAccelerometerPositionInDevice); - cellGem->AddFunc(0x2d2c2764, cellGemGetAllTrackableHues); - cellGem->AddFunc(0x8befac67, cellGemGetCameraState); - cellGem->AddFunc(0x02eb41bb, cellGemGetEnvironmentLightingColor); - cellGem->AddFunc(0xb8ef56a6, cellGemGetHuePixels); - cellGem->AddFunc(0x92cc4b34, cellGemGetImageState); - cellGem->AddFunc(0xd37b127a, cellGemGetInertialState); - cellGem->AddFunc(0x9e1dff96, cellGemGetInfo); - cellGem->AddFunc(0x2e0a170d, cellGemGetMemorySize); - cellGem->AddFunc(0x1b30cc22, cellGemGetRGB); - cellGem->AddFunc(0x6db6b007, cellGemGetRumble); - cellGem->AddFunc(0x6441d38d, cellGemGetState); - cellGem->AddFunc(0xfee33481, cellGemGetStatusFlags); - cellGem->AddFunc(0x18ea899a, cellGemGetTrackerHue); - //cellGem->AddFunc(, cellGemGetVideoConvertSize); - cellGem->AddFunc(0xc7622586, cellGemHSVtoRGB); - cellGem->AddFunc(0x13ea7c64, cellGemInit); - cellGem->AddFunc(0xe3e4f0d6, cellGemInvalidateCalibration); - cellGem->AddFunc(0xfb5887f9, cellGemIsTrackableHue); - cellGem->AddFunc(0xa03ef587, cellGemPrepareCamera); - cellGem->AddFunc(0xc07896f9, cellGemPrepareVideoConvert); - //cellGem->AddFunc(, cellGemReadExternalPortDeviceInfo); - cellGem->AddFunc(0xde54e2fc, cellGemReset); - cellGem->AddFunc(0x49609306, cellGemSetRumble); - cellGem->AddFunc(0x77e08704, cellGemSetYaw); - cellGem->AddFunc(0x928ac5f8, cellGemTrackHues); - cellGem->AddFunc(0x41ae9c31, cellGemUpdateFinish); - cellGem->AddFunc(0x0ecd2261, cellGemUpdateStart); - //cellGem->AddFunc(, cellGemVideoConvertAttributeInit); - //cellGem->AddFunc(, cellGemVideoConvertAttributeInitRgba); - cellGem->AddFunc(0x1f6328d8, cellGemWriteExternalPort); - -} + //cellGem.AddFunc(, cellGemAttributeInit); + cellGem.AddFunc(0xafa99ead, cellGemCalibrate); + cellGem.AddFunc(0x9b9714a4, cellGemClearStatusFlags); + cellGem.AddFunc(0x1a13d010, cellGemConvertVideoFinish); + cellGem.AddFunc(0x6dce048c, cellGemConvertVideoStart); + cellGem.AddFunc(0x4219de31, cellGemEnableCameraPitchAngleCorrection); + cellGem.AddFunc(0x1a2518a2, cellGemEnableMagnetometer); + cellGem.AddFunc(0xe1f85a80, cellGemEnd); + cellGem.AddFunc(0x6fc4c791, cellGemFilterState); + cellGem.AddFunc(0xce6d7791, cellGemForceRGB); + cellGem.AddFunc(0x6a5b7048, cellGemGetAccelerometerPositionInDevice); + cellGem.AddFunc(0x2d2c2764, cellGemGetAllTrackableHues); + cellGem.AddFunc(0x8befac67, cellGemGetCameraState); + cellGem.AddFunc(0x02eb41bb, cellGemGetEnvironmentLightingColor); + cellGem.AddFunc(0xb8ef56a6, cellGemGetHuePixels); + cellGem.AddFunc(0x92cc4b34, cellGemGetImageState); + cellGem.AddFunc(0xd37b127a, cellGemGetInertialState); + cellGem.AddFunc(0x9e1dff96, cellGemGetInfo); + cellGem.AddFunc(0x2e0a170d, cellGemGetMemorySize); + cellGem.AddFunc(0x1b30cc22, cellGemGetRGB); + cellGem.AddFunc(0x6db6b007, cellGemGetRumble); + cellGem.AddFunc(0x6441d38d, cellGemGetState); + cellGem.AddFunc(0xfee33481, cellGemGetStatusFlags); + cellGem.AddFunc(0x18ea899a, cellGemGetTrackerHue); + //cellGem.AddFunc(, cellGemGetVideoConvertSize); + cellGem.AddFunc(0xc7622586, cellGemHSVtoRGB); + cellGem.AddFunc(0x13ea7c64, cellGemInit); + cellGem.AddFunc(0xe3e4f0d6, cellGemInvalidateCalibration); + cellGem.AddFunc(0xfb5887f9, cellGemIsTrackableHue); + cellGem.AddFunc(0xa03ef587, cellGemPrepareCamera); + cellGem.AddFunc(0xc07896f9, cellGemPrepareVideoConvert); + //cellGem.AddFunc(, cellGemReadExternalPortDeviceInfo); + cellGem.AddFunc(0xde54e2fc, cellGemReset); + cellGem.AddFunc(0x49609306, cellGemSetRumble); + cellGem.AddFunc(0x77e08704, cellGemSetYaw); + cellGem.AddFunc(0x928ac5f8, cellGemTrackHues); + cellGem.AddFunc(0x41ae9c31, cellGemUpdateFinish); + cellGem.AddFunc(0x0ecd2261, cellGemUpdateStart); + //cellGem.AddFunc(, cellGemVideoConvertAttributeInit); + //cellGem.AddFunc(, cellGemVideoConvertAttributeInitRgba); + cellGem.AddFunc(0x1f6328d8, cellGemWriteExternalPort); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index dc4a63cab1..6264c5e818 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -7,7 +7,7 @@ #include "Emu/SysCalls/lv2/cellFs.h" #include "cellGifDec.h" -Module *cellGifDec = nullptr; +extern Module cellGifDec; int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { @@ -23,7 +23,7 @@ int cellGifDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) { - cellGifDec->Warning("cellGifDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", + cellGifDec.Warning("cellGifDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", mainHandle, subHandle.addr(), src.addr(), openInfo.addr()); std::shared_ptr current_subHandle(new CellGifDecSubHandle); @@ -52,18 +52,18 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptrGetNewId(current_subHandle); + *subHandle = cellGifDec.GetNewId(current_subHandle); return CELL_OK; } int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) { - cellGifDec->Warning("cellGifDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", + cellGifDec.Warning("cellGifDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr()); std::shared_ptr subHandle_data; - if(!cellGifDec->CheckId(subHandle, subHandle_data)) + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; @@ -109,11 +109,11 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) { - cellGifDec->Warning("cellGifDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", + cellGifDec.Warning("cellGifDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", mainHandle, subHandle, inParam.addr(), outParam.addr()); std::shared_ptr subHandle_data; - if(!cellGifDec->CheckId(subHandle, subHandle_data)) + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; CellGifDecInfo& current_info = subHandle_data->info; @@ -139,13 +139,13 @@ int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { - cellGifDec->Warning("cellGifDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", + cellGifDec.Warning("cellGifDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP; std::shared_ptr subHandle_data; - if(!cellGifDec->CheckId(subHandle, subHandle_data)) + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; @@ -256,15 +256,15 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt int cellGifDecClose(u32 mainHandle, u32 subHandle) { - cellGifDec->Warning("cellGifDecClose(mainHandle=0x%x, subHandle=0x%x)", + cellGifDec.Warning("cellGifDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle, subHandle); std::shared_ptr subHandle_data; - if(!cellGifDec->CheckId(subHandle, subHandle_data)) + if(!cellGifDec.CheckId(subHandle, subHandle_data)) return CELL_GIFDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); - cellGifDec->RemoveId(subHandle); + cellGifDec.RemoveId(subHandle); return CELL_OK; } @@ -275,21 +275,19 @@ int cellGifDecDestroy(u32 mainHandle) return CELL_OK; } -void cellGifDec_init(Module *pxThis) +Module cellGifDec("cellGifDec", []() { - cellGifDec = pxThis; - - cellGifDec->AddFunc(0xb60d42a5, cellGifDecCreate); - cellGifDec->AddFunc(0x4711cb7f, cellGifDecExtCreate); - cellGifDec->AddFunc(0x75745079, cellGifDecOpen); - cellGifDec->AddFunc(0xf0da95de, cellGifDecReadHeader); - cellGifDec->AddFunc(0x41a90dc4, cellGifDecSetParameter); - cellGifDec->AddFunc(0x44b1bc61, cellGifDecDecodeData); - cellGifDec->AddFunc(0x116a7da9, cellGifDecClose); - cellGifDec->AddFunc(0xe74b2cb1, cellGifDecDestroy); + cellGifDec.AddFunc(0xb60d42a5, cellGifDecCreate); + cellGifDec.AddFunc(0x4711cb7f, cellGifDecExtCreate); + cellGifDec.AddFunc(0x75745079, cellGifDecOpen); + cellGifDec.AddFunc(0xf0da95de, cellGifDecReadHeader); + cellGifDec.AddFunc(0x41a90dc4, cellGifDecSetParameter); + cellGifDec.AddFunc(0x44b1bc61, cellGifDecDecodeData); + cellGifDec.AddFunc(0x116a7da9, cellGifDecClose); + cellGifDec.AddFunc(0xe74b2cb1, cellGifDecDestroy); - /*cellGifDec->AddFunc(0x17fb83c1, cellGifDecExtOpen); - cellGifDec->AddFunc(0xe53f91f2, cellGifDecExtReadHeader); - cellGifDec->AddFunc(0x95cae771, cellGifDecExtSetParameter); - cellGifDec->AddFunc(0x02e7e03e, cellGifDecExtDecodeData);*/ -} + /*cellGifDec.AddFunc(0x17fb83c1, cellGifDecExtOpen); + cellGifDec.AddFunc(0xe53f91f2, cellGifDecExtReadHeader); + cellGifDec.AddFunc(0x95cae771, cellGifDecExtSetParameter); + cellGifDec.AddFunc(0x02e7e03e, cellGifDecExtDecodeData);*/ +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 963ed69d80..7c2211ab50 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -6,7 +6,7 @@ #include "Emu/SysCalls/lv2/cellFs.h" #include "cellJpgDec.h" -Module *cellJpgDec = nullptr; +extern Module cellJpgDec; int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { @@ -28,7 +28,7 @@ int cellJpgDecDestroy(u32 mainHandle) int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) { - cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", + cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", mainHandle, subHandle.addr(), src.addr(), openInfo.addr()); std::shared_ptr current_subHandle(new CellJpgDecSubHandle); @@ -58,32 +58,32 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptrGetNewId(current_subHandle); + *subHandle = cellJpgDec.GetNewId(current_subHandle); return CELL_OK; } int cellJpgDecClose(u32 mainHandle, u32 subHandle) { - cellJpgDec->Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x)", + cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x)", mainHandle, subHandle); std::shared_ptr subHandle_data; - if(!cellJpgDec->CheckId(subHandle, subHandle_data)) + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; cellFsClose(subHandle_data->fd); - cellJpgDec->RemoveId(subHandle); + cellJpgDec.RemoveId(subHandle); return CELL_OK; } int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) { - cellJpgDec->Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr()); + cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr()); std::shared_ptr subHandle_data; - if(!cellJpgDec->CheckId(subHandle, subHandle_data)) + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; @@ -147,12 +147,12 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { - cellJpgDec->Log("cellJpgDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", + cellJpgDec.Log("cellJpgDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP; std::shared_ptr subHandle_data; - if(!cellJpgDec->CheckId(subHandle, subHandle_data)) + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; const u32& fd = subHandle_data->fd; @@ -261,7 +261,7 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt case CELL_JPG_UPSAMPLE_ONLY: case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA: case CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB: - cellJpgDec->Error("cellJpgDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); + cellJpgDec.Error("cellJpgDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); break; default: @@ -278,11 +278,11 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) { - cellJpgDec->Log("cellJpgDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", + cellJpgDec.Log("cellJpgDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", mainHandle, subHandle, inParam.addr(), outParam.addr()); std::shared_ptr subHandle_data; - if(!cellJpgDec->CheckId(subHandle, subHandle_data)) + if(!cellJpgDec.CheckId(subHandle, subHandle_data)) return CELL_JPGDEC_ERROR_FATAL; CellJpgDecInfo& current_info = subHandle_data->info; @@ -320,21 +320,19 @@ int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptrAddFunc(0xa7978f59, cellJpgDecCreate); - cellJpgDec->AddFunc(0x8b300f66, cellJpgDecExtCreate); - cellJpgDec->AddFunc(0x976ca5c2, cellJpgDecOpen); - cellJpgDec->AddFunc(0x6d9ebccf, cellJpgDecReadHeader); - cellJpgDec->AddFunc(0xe08f3910, cellJpgDecSetParameter); - cellJpgDec->AddFunc(0xaf8bb012, cellJpgDecDecodeData); - cellJpgDec->AddFunc(0x9338a07a, cellJpgDecClose); - cellJpgDec->AddFunc(0xd8ea91f8, cellJpgDecDestroy); - - /*cellJpgDec->AddFunc(0xa9f703e3, cellJpgDecExtOpen); - cellJpgDec->AddFunc(0xb91eb3d2, cellJpgDecExtReadHeader); - cellJpgDec->AddFunc(0x65cbbb16, cellJpgDecExtSetParameter); - cellJpgDec->AddFunc(0x716f8792, cellJpgDecExtDecodeData);*/ -} + /*cellJpgDec.AddFunc(0xa9f703e3, cellJpgDecExtOpen); + cellJpgDec.AddFunc(0xb91eb3d2, cellJpgDecExtReadHeader); + cellJpgDec.AddFunc(0x65cbbb16, cellJpgDecExtSetParameter); + cellJpgDec.AddFunc(0x716f8792, cellJpgDecExtDecodeData);*/ +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellKb.cpp b/rpcs3/Emu/SysCalls/Modules/cellKb.cpp index f580155138..930b3af20c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellKb.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellKb.cpp @@ -6,11 +6,11 @@ #include "Emu/Io/Keyboard.h" #include "cellKb.h" -extern Module *sys_io; +extern Module sys_io; int cellKbInit(u32 max_connect) { - sys_io->Warning("cellKbInit(max_connect=%d)", max_connect); + sys_io.Warning("cellKbInit(max_connect=%d)", max_connect); if (Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_ALREADY_INITIALIZED; @@ -24,7 +24,7 @@ int cellKbInit(u32 max_connect) int cellKbEnd() { - sys_io->Log("cellKbEnd()"); + sys_io.Log("cellKbEnd()"); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -35,7 +35,7 @@ int cellKbEnd() int cellKbClearBuf(u32 port_no) { - sys_io->Log("cellKbClearBuf(port_no=%d)", port_no); + sys_io.Log("cellKbClearBuf(port_no=%d)", port_no); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -50,7 +50,7 @@ int cellKbClearBuf(u32 port_no) u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode) { - sys_io->Log("cellKbCnvRawCode(arrange=%d,mkey=%d,led=%d,rawcode=%d)", arrange, mkey, led, rawcode); + sys_io.Log("cellKbCnvRawCode(arrange=%d,mkey=%d,led=%d,rawcode=%d)", arrange, mkey, led, rawcode); // CELL_KB_RAWDAT if (rawcode <= 0x03 || rawcode == 0x29 || rawcode == 0x35 || (rawcode >= 0x39 && rawcode <= 0x53) || rawcode == 0x65 || rawcode == 0x88 || rawcode == 0x8A || rawcode == 0x8B) @@ -96,7 +96,7 @@ u16 cellKbCnvRawCode(u32 arrange, u32 mkey, u32 led, u16 rawcode) int cellKbGetInfo(vm::ptr info) { - sys_io->Log("cellKbGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellKbGetInfo(info_addr=0x%x)", info.addr()); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -116,7 +116,7 @@ int cellKbGetInfo(vm::ptr info) int cellKbRead(u32 port_no, vm::ptr data) { - sys_io->Log("cellKbRead(port_no=%d,info_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellKbRead(port_no=%d,info_addr=0x%x)", port_no, data.addr()); const std::vector& keyboards = Emu.GetKeyboardManager().GetKeyboards(); if (!Emu.GetKeyboardManager().IsInited()) @@ -142,7 +142,7 @@ int cellKbRead(u32 port_no, vm::ptr data) int cellKbSetCodeType(u32 port_no, u32 type) { - sys_io->Log("cellKbSetCodeType(port_no=%d,type=%d)", port_no, type); + sys_io.Log("cellKbSetCodeType(port_no=%d,type=%d)", port_no, type); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -160,7 +160,7 @@ int cellKbSetLEDStatus(u32 port_no, u8 led) int cellKbSetReadMode(u32 port_no, u32 rmode) { - sys_io->Log("cellKbSetReadMode(port_no=%d,rmode=%d)", port_no, rmode); + sys_io.Log("cellKbSetReadMode(port_no=%d,rmode=%d)", port_no, rmode); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -173,7 +173,7 @@ int cellKbSetReadMode(u32 port_no, u32 rmode) int cellKbGetConfiguration(u32 port_no, vm::ptr config) { - sys_io->Log("cellKbGetConfiguration(port_no=%d,config_addr=0x%x)", port_no, config.addr()); + sys_io.Log("cellKbGetConfiguration(port_no=%d,config_addr=0x%x)", port_no, config.addr()); if (!Emu.GetKeyboardManager().IsInited()) return CELL_KB_ERROR_UNINITIALIZED; @@ -188,14 +188,14 @@ int cellKbGetConfiguration(u32 port_no, vm::ptr config) void cellKb_init() { - sys_io->AddFunc(0x433f6ec0, cellKbInit); - sys_io->AddFunc(0xbfce3285, cellKbEnd); - sys_io->AddFunc(0x2073b7f6, cellKbClearBuf); - sys_io->AddFunc(0x4ab1fa77, cellKbCnvRawCode); - sys_io->AddFunc(0x2f1774d5, cellKbGetInfo); - sys_io->AddFunc(0xff0a21b7, cellKbRead); - sys_io->AddFunc(0xa5f85e4d, cellKbSetCodeType); - sys_io->AddFunc(0x3f72c56e, cellKbSetLEDStatus); - sys_io->AddFunc(0xdeefdfa7, cellKbSetReadMode); - sys_io->AddFunc(0x1f71ecbe, cellKbGetConfiguration); + sys_io.AddFunc(0x433f6ec0, cellKbInit); + sys_io.AddFunc(0xbfce3285, cellKbEnd); + sys_io.AddFunc(0x2073b7f6, cellKbClearBuf); + sys_io.AddFunc(0x4ab1fa77, cellKbCnvRawCode); + sys_io.AddFunc(0x2f1774d5, cellKbGetInfo); + sys_io.AddFunc(0xff0a21b7, cellKbRead); + sys_io.AddFunc(0xa5f85e4d, cellKbSetCodeType); + sys_io.AddFunc(0x3f72c56e, cellKbSetLEDStatus); + sys_io.AddFunc(0xdeefdfa7, cellKbSetReadMode); + sys_io.AddFunc(0x1f71ecbe, cellKbGetConfiguration); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index 60bae80ecc..4fefb3b4c5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -14,11 +14,11 @@ #include #endif -Module *cellL10n = nullptr; +extern Module cellL10n; int UTF16stoUTF8s(vm::lptrl utf16, vm::ptr utf16_len, vm::ptr utf8, vm::ptr utf8_len) { - cellL10n->Warning("UTF16stoUTF8s(utf16_addr=0x%x, utf16_len_addr=0x%x, utf8_addr=0x%x, utf8_len_addr=0x%x)", + cellL10n.Warning("UTF16stoUTF8s(utf16_addr=0x%x, utf16_len_addr=0x%x, utf8_addr=0x%x, utf8_len_addr=0x%x)", utf16.addr(), utf16_len.addr(), utf8.addr(), utf8_len.addr()); std::u16string wstr = utf16.get_ptr(); // ??? @@ -41,7 +41,7 @@ int UTF16stoUTF8s(vm::lptrl utf16, vm::ptr utf16_len, vm::p int jstrchk(vm::ptr jstr) { - cellL10n->Warning("jstrchk(jstr_addr=0x%x) -> utf8", jstr.addr()); + cellL10n.Warning("jstrchk(jstr_addr=0x%x) -> utf8", jstr.addr()); return L10N_STR_UTF8; } @@ -283,9 +283,9 @@ int _L10nConvertStr(int src_code, const void* src, size_t * src_len, int dst_cod //TODO: Check the code in emulation. If support for UTF8/UTF16/UTF32/UCS2/UCS4 should use wider chars.. awful. int L10nConvertStr(int src_code, vm::ptr src, vm::ptr src_len, int dst_code, vm::ptr dst, vm::ptr dst_len) { - cellL10n->Error("L10nConvertStr(src_code=%d, srca_addr=0x%x, src_len_addr=0x%x, dst_code=%d, dst_addr=0x%x, dst_len_addr=0x%x)", + cellL10n.Error("L10nConvertStr(src_code=%d, srca_addr=0x%x, src_len_addr=0x%x, dst_code=%d, dst_addr=0x%x, dst_len_addr=0x%x)", src_code, src.addr(), src_len.addr(), dst_code, dst.addr(), dst_len.addr()); - //cellL10n->Todo("L10nConvertStr: 1st char at dst: 0x%x", *((char*)src.get_ptr())); + //cellL10n.Todo("L10nConvertStr: 1st char at dst: 0x%x", *((char*)src.get_ptr())); #ifdef _MSC_VER unsigned int srcCode = 0, dstCode = 0; //OEM code pages bool src_page_converted = _L10nCodeParse(src_code, srcCode); //Check if code is in list. @@ -335,175 +335,173 @@ int L10nConvertStr(int src_code, vm::ptr src, vm::ptr src_len, #endif } -void cellL10n_init(Module *pxThis) +Module cellL10n("cellL10n", []() { - cellL10n = pxThis; - // NOTE: I think this module should be LLE'd instead of implementing all its functions - // cellL10n->AddFunc(0x005200e6, UCS2toEUCJP); - // cellL10n->AddFunc(0x01b0cbf4, l10n_convert); - // cellL10n->AddFunc(0x0356038c, UCS2toUTF32); - // cellL10n->AddFunc(0x05028763, jis2kuten); - // cellL10n->AddFunc(0x058addc8, UTF8toGB18030); - // cellL10n->AddFunc(0x060ee3b2, JISstoUTF8s); - // cellL10n->AddFunc(0x07168a83, SjisZen2Han); - // cellL10n->AddFunc(0x0bc386c8, ToSjisLower); - // cellL10n->AddFunc(0x0bedf77d, UCS2toGB18030); - // cellL10n->AddFunc(0x0bf867e2, HZstoUCS2s); - // cellL10n->AddFunc(0x0ce278fd, UCS2stoHZs); - // cellL10n->AddFunc(0x0d90a48d, UCS2stoSJISs); - // cellL10n->AddFunc(0x0f624540, kuten2eucjp); - // cellL10n->AddFunc(0x14ee3649, sjis2jis); - // cellL10n->AddFunc(0x14f504b8, EUCKRstoUCS2s); - // cellL10n->AddFunc(0x16eaf5f1, UHCstoEUCKRs); - // cellL10n->AddFunc(0x1758053c, jis2sjis); - // cellL10n->AddFunc(0x1906ce6b, jstrnchk); - // cellL10n->AddFunc(0x1ac0d23d, L10nConvert); - // cellL10n->AddFunc(0x1ae2acee, EUCCNstoUTF8s); - // cellL10n->AddFunc(0x1cb1138f, GBKstoUCS2s); - // cellL10n->AddFunc(0x1da42d70, eucjphan2zen); - // cellL10n->AddFunc(0x1ec712e0, ToSjisHira); - // cellL10n->AddFunc(0x1fb50183, GBKtoUCS2); - // cellL10n->AddFunc(0x21948c03, eucjp2jis); - // cellL10n->AddFunc(0x21aa3045, UTF32stoUTF8s); - // cellL10n->AddFunc(0x24fd32a9, sjishan2zen); - // cellL10n->AddFunc(0x256b6861, UCS2toSBCS); - // cellL10n->AddFunc(0x262a5ae2, UTF8stoGBKs); - // cellL10n->AddFunc(0x28724522, UTF8toUCS2); - // cellL10n->AddFunc(0x2ad091c6, UCS2stoUTF8s); - // cellL10n->AddFunc(0x2b84030c, EUCKRstoUTF8s); - // cellL10n->AddFunc(0x2efa7294, UTF16stoUTF32s); - // cellL10n->AddFunc(0x2f9eb543, UTF8toEUCKR); - // cellL10n->AddFunc(0x317ab7c2, UTF16toUTF8); - // cellL10n->AddFunc(0x32689828, ARIBstoUTF8s); - // cellL10n->AddFunc(0x33435818, SJISstoUTF8s); - // cellL10n->AddFunc(0x33f8b35c, sjiszen2han); - // cellL10n->AddFunc(0x3968f176, ToEucJpLower); - // cellL10n->AddFunc(0x398a3dee, MSJIStoUTF8); - // cellL10n->AddFunc(0x3a20bc34, UCS2stoMSJISs); - // cellL10n->AddFunc(0x3dabd5a7, EUCJPtoUTF8); - // cellL10n->AddFunc(0x3df65b64, eucjp2sjis); - // cellL10n->AddFunc(0x408a622b, ToEucJpHira); - // cellL10n->AddFunc(0x41b4a5ae, UHCstoUCS2s); - // cellL10n->AddFunc(0x41ccf033, ToEucJpKata); - // cellL10n->AddFunc(0x42838145, HZstoUTF8s); - // cellL10n->AddFunc(0x4931b44e, UTF8toMSJIS); - // cellL10n->AddFunc(0x4b3bbacb, BIG5toUTF8); - // cellL10n->AddFunc(0x511d386b, EUCJPstoSJISs); - // cellL10n->AddFunc(0x52b7883f, UTF8stoBIG5s); - // cellL10n->AddFunc(0x53558b6b, UTF16stoUCS2s); - // cellL10n->AddFunc(0x53764725, UCS2stoGB18030s); - // cellL10n->AddFunc(0x53c71ac2, EUCJPtoSJIS); - // cellL10n->AddFunc(0x54f59807, EUCJPtoUCS2); - // cellL10n->AddFunc(0x55f6921c, UCS2stoGBKs); - // cellL10n->AddFunc(0x58246762, EUCKRtoUHC); - // cellL10n->AddFunc(0x596df41c, UCS2toSJIS); - // cellL10n->AddFunc(0x5a4ab223, MSJISstoUTF8s); - // cellL10n->AddFunc(0x5ac783dc, EUCJPstoUTF8s); - // cellL10n->AddFunc(0x5b684dfb, UCS2toBIG5); - // cellL10n->AddFunc(0x5cd29270, UTF8stoEUCKRs); - // cellL10n->AddFunc(0x5e1d9330, UHCstoUTF8s); - // cellL10n->AddFunc(0x60ffa0ec, GB18030stoUCS2s); - // cellL10n->AddFunc(0x6122e000, SJIStoUTF8); - // cellL10n->AddFunc(0x6169f205, JISstoSJISs); - // cellL10n->AddFunc(0x61fb9442, UTF8toUTF16); - // cellL10n->AddFunc(0x62b36bcf, UTF8stoMSJISs); - // cellL10n->AddFunc(0x63219199, EUCKRtoUTF8); - // cellL10n->AddFunc(0x638c2fc1, SjisHan2Zen); - // cellL10n->AddFunc(0x64a10ec8, UCS2toUTF16); - // cellL10n->AddFunc(0x65444204, UCS2toMSJIS); - // cellL10n->AddFunc(0x6621a82c, sjis2kuten); - // cellL10n->AddFunc(0x6a6f25d1, UCS2toUHC); - // cellL10n->AddFunc(0x6c62d879, UTF32toUCS2); - // cellL10n->AddFunc(0x6de4b508, ToSjisUpper); - // cellL10n->AddFunc(0x6e0705c4, UTF8toEUCJP); - // cellL10n->AddFunc(0x6e5906fd, UCS2stoEUCJPs); - // cellL10n->AddFunc(0x6fc530b3, UTF16toUCS2); - // cellL10n->AddFunc(0x714a9b4a, UCS2stoUTF16s); - // cellL10n->AddFunc(0x71804d64, UCS2stoEUCCNs); - // cellL10n->AddFunc(0x72632e53, SBCSstoUTF8s); - // cellL10n->AddFunc(0x73f2cd21, SJISstoJISs); - // cellL10n->AddFunc(0x74496718, SBCStoUTF8); - // cellL10n->AddFunc(0x74871fe0, UTF8toUTF32); - cellL10n->AddFunc(0x750c363d, jstrchk); - // cellL10n->AddFunc(0x7c5bde1c, UHCtoEUCKR); - // cellL10n->AddFunc(0x7c912bda, kuten2jis); - // cellL10n->AddFunc(0x7d07a1c2, UTF8toEUCCN); - // cellL10n->AddFunc(0x8171c1cc, EUCCNtoUTF8); - // cellL10n->AddFunc(0x82d5ecdf, EucJpZen2Han); - // cellL10n->AddFunc(0x8555fe15, UTF32stoUTF16s); - // cellL10n->AddFunc(0x860fc741, GBKtoUTF8); - // cellL10n->AddFunc(0x867f7b8b, ToEucJpUpper); - // cellL10n->AddFunc(0x88f8340b, UCS2stoJISs); - // cellL10n->AddFunc(0x89236c86, UTF8stoGB18030s); - // cellL10n->AddFunc(0x8a56f148, EUCKRstoUHCs); - // cellL10n->AddFunc(0x8ccdba38, UTF8stoUTF32s); - // cellL10n->AddFunc(0x8f472054, UTF8stoEUCCNs); - // cellL10n->AddFunc(0x90e9b5d2, EUCJPstoUCS2s); - // cellL10n->AddFunc(0x91a99765, UHCtoUCS2); - cellL10n->AddFunc(0x931ff25a, L10nConvertStr); - // cellL10n->AddFunc(0x949bb14c, GBKstoUTF8s); - // cellL10n->AddFunc(0x9557ac9b, UTF8toUHC); - // cellL10n->AddFunc(0x9768b6d3, UTF32toUTF8); - // cellL10n->AddFunc(0x9874020d, sjis2eucjp); - // cellL10n->AddFunc(0x9a0e7d23, UCS2toEUCCN); - // cellL10n->AddFunc(0x9a13d6b8, UTF8stoUHCs); - // cellL10n->AddFunc(0x9a72059d, EUCKRtoUCS2); - // cellL10n->AddFunc(0x9b1210c6, UTF32toUTF16); - // cellL10n->AddFunc(0x9cd8135b, EUCCNstoUCS2s); - // cellL10n->AddFunc(0x9ce52809, SBCSstoUCS2s); - // cellL10n->AddFunc(0x9cf1ab77, UTF8stoJISs); - // cellL10n->AddFunc(0x9d14dc46, ToSjisKata); - // cellL10n->AddFunc(0x9dcde367, jis2eucjp); - // cellL10n->AddFunc(0x9ec52258, BIG5toUCS2); - // cellL10n->AddFunc(0xa0d463c0, UCS2toGBK); - // cellL10n->AddFunc(0xa19fb9de, UTF16toUTF32); - // cellL10n->AddFunc(0xa298cad2, l10n_convert_str); - // cellL10n->AddFunc(0xa34fa0eb, EUCJPstoJISs); - // cellL10n->AddFunc(0xa5146299, UTF8stoARIBs); - // cellL10n->AddFunc(0xa609f3e9, JISstoEUCJPs); - // cellL10n->AddFunc(0xa60ff5c9, EucJpHan2Zen); - // cellL10n->AddFunc(0xa963619c, isEucJpKigou); - // cellL10n->AddFunc(0xa9a76fb8, UCS2toUTF8); - // cellL10n->AddFunc(0xaf18d499, GB18030toUCS2); - // cellL10n->AddFunc(0xb3361be6, UHCtoUTF8); - // cellL10n->AddFunc(0xb6e45343, MSJIStoUCS2); - // cellL10n->AddFunc(0xb7cef4a6, UTF8toGBK); - // cellL10n->AddFunc(0xb7e08f7a, kuten2sjis); - // cellL10n->AddFunc(0xb9cf473d, UTF8toSBCS); - // cellL10n->AddFunc(0xbdd44ee3, SJIStoUCS2); - // cellL10n->AddFunc(0xbe42e661, eucjpzen2han); - // cellL10n->AddFunc(0xbe8d5485, UCS2stoARIBs); - // cellL10n->AddFunc(0xbefe3869, isSjisKigou); - // cellL10n->AddFunc(0xc62b758d, UTF8stoEUCJPs); - // cellL10n->AddFunc(0xc7bdcb4c, UCS2toEUCKR); - // cellL10n->AddFunc(0xc944fa56, SBCStoUCS2); - // cellL10n->AddFunc(0xc9b78f58, MSJISstoUCS2s); - // cellL10n->AddFunc(0xcc1633cc, l10n_get_converter); - // cellL10n->AddFunc(0xd02ef83d, GB18030stoUTF8s); - // cellL10n->AddFunc(0xd8721e2c, SJISstoEUCJPs); - // cellL10n->AddFunc(0xd8cb24cb, UTF32stoUCS2s); - // cellL10n->AddFunc(0xd990858b, BIG5stoUTF8s); - // cellL10n->AddFunc(0xd9fb1224, EUCCNtoUCS2); - // cellL10n->AddFunc(0xda67b37f, UTF8stoSBCSs); - // cellL10n->AddFunc(0xdc54886c, UCS2stoEUCKRs); - // cellL10n->AddFunc(0xdd5ebdeb, UTF8stoSJISs); - // cellL10n->AddFunc(0xdefa1c17, UTF8stoHZs); - // cellL10n->AddFunc(0xe2eabb32, eucjp2kuten); - // cellL10n->AddFunc(0xe6d9e234, UTF8toBIG5); - // cellL10n->AddFunc(0xe6f5711b, UTF16stoUTF8s); - // cellL10n->AddFunc(0xe956dc64, JISstoUCS2s); - // cellL10n->AddFunc(0xeabc3d00, GB18030toUTF8); - // cellL10n->AddFunc(0xeb3dc670, UTF8toSJIS); - // cellL10n->AddFunc(0xeb41cc68, ARIBstoUCS2s); - // cellL10n->AddFunc(0xeb685b83, UCS2stoUTF32s); - // cellL10n->AddFunc(0xebae29c0, UCS2stoSBCSs); - // cellL10n->AddFunc(0xee6c6a39, UCS2stoBIG5s); - // cellL10n->AddFunc(0xf1dcfa71, UCS2stoUHCs); - // cellL10n->AddFunc(0xf439728e, SJIStoEUCJP); - // cellL10n->AddFunc(0xf7681b9a, UTF8stoUTF16s); - // cellL10n->AddFunc(0xf9b1896d, SJISstoUCS2s); - // cellL10n->AddFunc(0xfa4a675a, BIG5stoUCS2s); - // cellL10n->AddFunc(0xfdbf6ac5, UTF8stoUCS2s); -} + // cellL10n.AddFunc(0x005200e6, UCS2toEUCJP); + // cellL10n.AddFunc(0x01b0cbf4, l10n_convert); + // cellL10n.AddFunc(0x0356038c, UCS2toUTF32); + // cellL10n.AddFunc(0x05028763, jis2kuten); + // cellL10n.AddFunc(0x058addc8, UTF8toGB18030); + // cellL10n.AddFunc(0x060ee3b2, JISstoUTF8s); + // cellL10n.AddFunc(0x07168a83, SjisZen2Han); + // cellL10n.AddFunc(0x0bc386c8, ToSjisLower); + // cellL10n.AddFunc(0x0bedf77d, UCS2toGB18030); + // cellL10n.AddFunc(0x0bf867e2, HZstoUCS2s); + // cellL10n.AddFunc(0x0ce278fd, UCS2stoHZs); + // cellL10n.AddFunc(0x0d90a48d, UCS2stoSJISs); + // cellL10n.AddFunc(0x0f624540, kuten2eucjp); + // cellL10n.AddFunc(0x14ee3649, sjis2jis); + // cellL10n.AddFunc(0x14f504b8, EUCKRstoUCS2s); + // cellL10n.AddFunc(0x16eaf5f1, UHCstoEUCKRs); + // cellL10n.AddFunc(0x1758053c, jis2sjis); + // cellL10n.AddFunc(0x1906ce6b, jstrnchk); + // cellL10n.AddFunc(0x1ac0d23d, L10nConvert); + // cellL10n.AddFunc(0x1ae2acee, EUCCNstoUTF8s); + // cellL10n.AddFunc(0x1cb1138f, GBKstoUCS2s); + // cellL10n.AddFunc(0x1da42d70, eucjphan2zen); + // cellL10n.AddFunc(0x1ec712e0, ToSjisHira); + // cellL10n.AddFunc(0x1fb50183, GBKtoUCS2); + // cellL10n.AddFunc(0x21948c03, eucjp2jis); + // cellL10n.AddFunc(0x21aa3045, UTF32stoUTF8s); + // cellL10n.AddFunc(0x24fd32a9, sjishan2zen); + // cellL10n.AddFunc(0x256b6861, UCS2toSBCS); + // cellL10n.AddFunc(0x262a5ae2, UTF8stoGBKs); + // cellL10n.AddFunc(0x28724522, UTF8toUCS2); + // cellL10n.AddFunc(0x2ad091c6, UCS2stoUTF8s); + // cellL10n.AddFunc(0x2b84030c, EUCKRstoUTF8s); + // cellL10n.AddFunc(0x2efa7294, UTF16stoUTF32s); + // cellL10n.AddFunc(0x2f9eb543, UTF8toEUCKR); + // cellL10n.AddFunc(0x317ab7c2, UTF16toUTF8); + // cellL10n.AddFunc(0x32689828, ARIBstoUTF8s); + // cellL10n.AddFunc(0x33435818, SJISstoUTF8s); + // cellL10n.AddFunc(0x33f8b35c, sjiszen2han); + // cellL10n.AddFunc(0x3968f176, ToEucJpLower); + // cellL10n.AddFunc(0x398a3dee, MSJIStoUTF8); + // cellL10n.AddFunc(0x3a20bc34, UCS2stoMSJISs); + // cellL10n.AddFunc(0x3dabd5a7, EUCJPtoUTF8); + // cellL10n.AddFunc(0x3df65b64, eucjp2sjis); + // cellL10n.AddFunc(0x408a622b, ToEucJpHira); + // cellL10n.AddFunc(0x41b4a5ae, UHCstoUCS2s); + // cellL10n.AddFunc(0x41ccf033, ToEucJpKata); + // cellL10n.AddFunc(0x42838145, HZstoUTF8s); + // cellL10n.AddFunc(0x4931b44e, UTF8toMSJIS); + // cellL10n.AddFunc(0x4b3bbacb, BIG5toUTF8); + // cellL10n.AddFunc(0x511d386b, EUCJPstoSJISs); + // cellL10n.AddFunc(0x52b7883f, UTF8stoBIG5s); + // cellL10n.AddFunc(0x53558b6b, UTF16stoUCS2s); + // cellL10n.AddFunc(0x53764725, UCS2stoGB18030s); + // cellL10n.AddFunc(0x53c71ac2, EUCJPtoSJIS); + // cellL10n.AddFunc(0x54f59807, EUCJPtoUCS2); + // cellL10n.AddFunc(0x55f6921c, UCS2stoGBKs); + // cellL10n.AddFunc(0x58246762, EUCKRtoUHC); + // cellL10n.AddFunc(0x596df41c, UCS2toSJIS); + // cellL10n.AddFunc(0x5a4ab223, MSJISstoUTF8s); + // cellL10n.AddFunc(0x5ac783dc, EUCJPstoUTF8s); + // cellL10n.AddFunc(0x5b684dfb, UCS2toBIG5); + // cellL10n.AddFunc(0x5cd29270, UTF8stoEUCKRs); + // cellL10n.AddFunc(0x5e1d9330, UHCstoUTF8s); + // cellL10n.AddFunc(0x60ffa0ec, GB18030stoUCS2s); + // cellL10n.AddFunc(0x6122e000, SJIStoUTF8); + // cellL10n.AddFunc(0x6169f205, JISstoSJISs); + // cellL10n.AddFunc(0x61fb9442, UTF8toUTF16); + // cellL10n.AddFunc(0x62b36bcf, UTF8stoMSJISs); + // cellL10n.AddFunc(0x63219199, EUCKRtoUTF8); + // cellL10n.AddFunc(0x638c2fc1, SjisHan2Zen); + // cellL10n.AddFunc(0x64a10ec8, UCS2toUTF16); + // cellL10n.AddFunc(0x65444204, UCS2toMSJIS); + // cellL10n.AddFunc(0x6621a82c, sjis2kuten); + // cellL10n.AddFunc(0x6a6f25d1, UCS2toUHC); + // cellL10n.AddFunc(0x6c62d879, UTF32toUCS2); + // cellL10n.AddFunc(0x6de4b508, ToSjisUpper); + // cellL10n.AddFunc(0x6e0705c4, UTF8toEUCJP); + // cellL10n.AddFunc(0x6e5906fd, UCS2stoEUCJPs); + // cellL10n.AddFunc(0x6fc530b3, UTF16toUCS2); + // cellL10n.AddFunc(0x714a9b4a, UCS2stoUTF16s); + // cellL10n.AddFunc(0x71804d64, UCS2stoEUCCNs); + // cellL10n.AddFunc(0x72632e53, SBCSstoUTF8s); + // cellL10n.AddFunc(0x73f2cd21, SJISstoJISs); + // cellL10n.AddFunc(0x74496718, SBCStoUTF8); + // cellL10n.AddFunc(0x74871fe0, UTF8toUTF32); + cellL10n.AddFunc(0x750c363d, jstrchk); + // cellL10n.AddFunc(0x7c5bde1c, UHCtoEUCKR); + // cellL10n.AddFunc(0x7c912bda, kuten2jis); + // cellL10n.AddFunc(0x7d07a1c2, UTF8toEUCCN); + // cellL10n.AddFunc(0x8171c1cc, EUCCNtoUTF8); + // cellL10n.AddFunc(0x82d5ecdf, EucJpZen2Han); + // cellL10n.AddFunc(0x8555fe15, UTF32stoUTF16s); + // cellL10n.AddFunc(0x860fc741, GBKtoUTF8); + // cellL10n.AddFunc(0x867f7b8b, ToEucJpUpper); + // cellL10n.AddFunc(0x88f8340b, UCS2stoJISs); + // cellL10n.AddFunc(0x89236c86, UTF8stoGB18030s); + // cellL10n.AddFunc(0x8a56f148, EUCKRstoUHCs); + // cellL10n.AddFunc(0x8ccdba38, UTF8stoUTF32s); + // cellL10n.AddFunc(0x8f472054, UTF8stoEUCCNs); + // cellL10n.AddFunc(0x90e9b5d2, EUCJPstoUCS2s); + // cellL10n.AddFunc(0x91a99765, UHCtoUCS2); + cellL10n.AddFunc(0x931ff25a, L10nConvertStr); + // cellL10n.AddFunc(0x949bb14c, GBKstoUTF8s); + // cellL10n.AddFunc(0x9557ac9b, UTF8toUHC); + // cellL10n.AddFunc(0x9768b6d3, UTF32toUTF8); + // cellL10n.AddFunc(0x9874020d, sjis2eucjp); + // cellL10n.AddFunc(0x9a0e7d23, UCS2toEUCCN); + // cellL10n.AddFunc(0x9a13d6b8, UTF8stoUHCs); + // cellL10n.AddFunc(0x9a72059d, EUCKRtoUCS2); + // cellL10n.AddFunc(0x9b1210c6, UTF32toUTF16); + // cellL10n.AddFunc(0x9cd8135b, EUCCNstoUCS2s); + // cellL10n.AddFunc(0x9ce52809, SBCSstoUCS2s); + // cellL10n.AddFunc(0x9cf1ab77, UTF8stoJISs); + // cellL10n.AddFunc(0x9d14dc46, ToSjisKata); + // cellL10n.AddFunc(0x9dcde367, jis2eucjp); + // cellL10n.AddFunc(0x9ec52258, BIG5toUCS2); + // cellL10n.AddFunc(0xa0d463c0, UCS2toGBK); + // cellL10n.AddFunc(0xa19fb9de, UTF16toUTF32); + // cellL10n.AddFunc(0xa298cad2, l10n_convert_str); + // cellL10n.AddFunc(0xa34fa0eb, EUCJPstoJISs); + // cellL10n.AddFunc(0xa5146299, UTF8stoARIBs); + // cellL10n.AddFunc(0xa609f3e9, JISstoEUCJPs); + // cellL10n.AddFunc(0xa60ff5c9, EucJpHan2Zen); + // cellL10n.AddFunc(0xa963619c, isEucJpKigou); + // cellL10n.AddFunc(0xa9a76fb8, UCS2toUTF8); + // cellL10n.AddFunc(0xaf18d499, GB18030toUCS2); + // cellL10n.AddFunc(0xb3361be6, UHCtoUTF8); + // cellL10n.AddFunc(0xb6e45343, MSJIStoUCS2); + // cellL10n.AddFunc(0xb7cef4a6, UTF8toGBK); + // cellL10n.AddFunc(0xb7e08f7a, kuten2sjis); + // cellL10n.AddFunc(0xb9cf473d, UTF8toSBCS); + // cellL10n.AddFunc(0xbdd44ee3, SJIStoUCS2); + // cellL10n.AddFunc(0xbe42e661, eucjpzen2han); + // cellL10n.AddFunc(0xbe8d5485, UCS2stoARIBs); + // cellL10n.AddFunc(0xbefe3869, isSjisKigou); + // cellL10n.AddFunc(0xc62b758d, UTF8stoEUCJPs); + // cellL10n.AddFunc(0xc7bdcb4c, UCS2toEUCKR); + // cellL10n.AddFunc(0xc944fa56, SBCStoUCS2); + // cellL10n.AddFunc(0xc9b78f58, MSJISstoUCS2s); + // cellL10n.AddFunc(0xcc1633cc, l10n_get_converter); + // cellL10n.AddFunc(0xd02ef83d, GB18030stoUTF8s); + // cellL10n.AddFunc(0xd8721e2c, SJISstoEUCJPs); + // cellL10n.AddFunc(0xd8cb24cb, UTF32stoUCS2s); + // cellL10n.AddFunc(0xd990858b, BIG5stoUTF8s); + // cellL10n.AddFunc(0xd9fb1224, EUCCNtoUCS2); + // cellL10n.AddFunc(0xda67b37f, UTF8stoSBCSs); + // cellL10n.AddFunc(0xdc54886c, UCS2stoEUCKRs); + // cellL10n.AddFunc(0xdd5ebdeb, UTF8stoSJISs); + // cellL10n.AddFunc(0xdefa1c17, UTF8stoHZs); + // cellL10n.AddFunc(0xe2eabb32, eucjp2kuten); + // cellL10n.AddFunc(0xe6d9e234, UTF8toBIG5); + // cellL10n.AddFunc(0xe6f5711b, UTF16stoUTF8s); + // cellL10n.AddFunc(0xe956dc64, JISstoUCS2s); + // cellL10n.AddFunc(0xeabc3d00, GB18030toUTF8); + // cellL10n.AddFunc(0xeb3dc670, UTF8toSJIS); + // cellL10n.AddFunc(0xeb41cc68, ARIBstoUCS2s); + // cellL10n.AddFunc(0xeb685b83, UCS2stoUTF32s); + // cellL10n.AddFunc(0xebae29c0, UCS2stoSBCSs); + // cellL10n.AddFunc(0xee6c6a39, UCS2stoBIG5s); + // cellL10n.AddFunc(0xf1dcfa71, UCS2stoUHCs); + // cellL10n.AddFunc(0xf439728e, SJIStoEUCJP); + // cellL10n.AddFunc(0xf7681b9a, UTF8stoUTF16s); + // cellL10n.AddFunc(0xf9b1896d, SJISstoUCS2s); + // cellL10n.AddFunc(0xfa4a675a, BIG5stoUCS2s); + // cellL10n.AddFunc(0xfdbf6ac5, UTF8stoUCS2s); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp index 6841e37ccf..59d6803df8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMic.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMic.cpp @@ -5,7 +5,7 @@ #include "cellMic.h" -Module *cellMic = nullptr; +extern Module cellMic; struct cellMicInternal { @@ -21,7 +21,7 @@ cellMicInternal CellMicInstance; int cellMicInit() { - cellMic->Warning("cellMicInit()"); + cellMic.Warning("cellMicInit()"); if (CellMicInstance.m_bCellMicInitialized) return CELL_MICIN_ERROR_ALREADY_INIT; @@ -33,7 +33,7 @@ int cellMicInit() int cellMicEnd() { - cellMic->Warning("cellMicEnd()"); + cellMic.Warning("cellMicEnd()"); if (!CellMicInstance.m_bCellMicInitialized) return CELL_MICIN_ERROR_NOT_INIT; @@ -288,55 +288,53 @@ void cellMic_unload() CellMicInstance.m_bCellMicInitialized = false; } -void cellMic_init(Module *pxThis) +Module cellMic("cellMic", []() { - cellMic = pxThis; + cellMic.AddFunc(0x8325e02d, cellMicInit); + cellMic.AddFunc(0xc6328caa, cellMicEnd); + cellMic.AddFunc(0xdd1b59f0, cellMicOpen); + cellMic.AddFunc(0x8d229f8e, cellMicClose); - cellMic->AddFunc(0x8325e02d, cellMicInit); - cellMic->AddFunc(0xc6328caa, cellMicEnd); - cellMic->AddFunc(0xdd1b59f0, cellMicOpen); - cellMic->AddFunc(0x8d229f8e, cellMicClose); + cellMic.AddFunc(0x017024a8, cellMicGetDeviceGUID); + cellMic.AddFunc(0xa52d2ae4, cellMicGetType); + cellMic.AddFunc(0x1b42101b, cellMicIsAttached); + cellMic.AddFunc(0x186cb1fb, cellMicIsOpen); + cellMic.AddFunc(0x6a024aa0, cellMicGetDeviceAttr); + cellMic.AddFunc(0xb2c16321, cellMicSetDeviceAttr); + cellMic.AddFunc(0xac5ba03a, cellMicGetSignalAttr); + cellMic.AddFunc(0x323deb41, cellMicSetSignalAttr); + cellMic.AddFunc(0xb30780eb, cellMicGetSignalState); - cellMic->AddFunc(0x017024a8, cellMicGetDeviceGUID); - cellMic->AddFunc(0xa52d2ae4, cellMicGetType); - cellMic->AddFunc(0x1b42101b, cellMicIsAttached); - cellMic->AddFunc(0x186cb1fb, cellMicIsOpen); - cellMic->AddFunc(0x6a024aa0, cellMicGetDeviceAttr); - cellMic->AddFunc(0xb2c16321, cellMicSetDeviceAttr); - cellMic->AddFunc(0xac5ba03a, cellMicGetSignalAttr); - cellMic->AddFunc(0x323deb41, cellMicSetSignalAttr); - cellMic->AddFunc(0xb30780eb, cellMicGetSignalState); + cellMic.AddFunc(0xdd724314, cellMicStart); + cellMic.AddFunc(0x07e1b12c, cellMicRead); + cellMic.AddFunc(0xfcfaf246, cellMicStop); + cellMic.AddFunc(0x6bc46aab, cellMicReset); - cellMic->AddFunc(0xdd724314, cellMicStart); - cellMic->AddFunc(0x07e1b12c, cellMicRead); - cellMic->AddFunc(0xfcfaf246, cellMicStop); - cellMic->AddFunc(0x6bc46aab, cellMicReset); + cellMic.AddFunc(0x7903400e, cellMicSetNotifyEventQueue); + cellMic.AddFunc(0x6cc7ae00, cellMicSetNotifyEventQueue2); + cellMic.AddFunc(0x65336418, cellMicRemoveNotifyEventQueue); - cellMic->AddFunc(0x7903400e, cellMicSetNotifyEventQueue); - cellMic->AddFunc(0x6cc7ae00, cellMicSetNotifyEventQueue2); - cellMic->AddFunc(0x65336418, cellMicRemoveNotifyEventQueue); + cellMic.AddFunc(0x05709bbf, cellMicOpenEx); + cellMic.AddFunc(0xddd19a89, cellMicStartEx); + cellMic.AddFunc(0x4e0b69ee, cellMicGetFormatRaw); + cellMic.AddFunc(0xfda12276, cellMicGetFormatAux); + cellMic.AddFunc(0x87a08d29, cellMicGetFormatDsp); + cellMic.AddFunc(0xa42ac07a, cellMicOpenRaw); + cellMic.AddFunc(0x72165a7f, cellMicReadRaw); + cellMic.AddFunc(0x3acc118e, cellMicReadAux); + cellMic.AddFunc(0xc414faa5, cellMicReadDsp); - cellMic->AddFunc(0x05709bbf, cellMicOpenEx); - cellMic->AddFunc(0xddd19a89, cellMicStartEx); - cellMic->AddFunc(0x4e0b69ee, cellMicGetFormatRaw); - cellMic->AddFunc(0xfda12276, cellMicGetFormatAux); - cellMic->AddFunc(0x87a08d29, cellMicGetFormatDsp); - cellMic->AddFunc(0xa42ac07a, cellMicOpenRaw); - cellMic->AddFunc(0x72165a7f, cellMicReadRaw); - cellMic->AddFunc(0x3acc118e, cellMicReadAux); - cellMic->AddFunc(0xc414faa5, cellMicReadDsp); - - cellMic->AddFunc(0x25c5723f, cellMicGetStatus); - cellMic->AddFunc(0xe839380f, cellMicStopEx); - cellMic->AddFunc(0x3ace58f3, cellMicSysShareClose); - cellMic->AddFunc(0x48108a23, cellMicGetFormat); - cellMic->AddFunc(0x891c6291, cellMicSetMultiMicNotifyEventQueue); - cellMic->AddFunc(0xad049ecf, cellMicGetFormatEx); - cellMic->AddFunc(0xbdfd51e2, cellMicSysShareStop); - cellMic->AddFunc(0xc3610dbd, cellMicSysShareOpen); - cellMic->AddFunc(0xc461563c, cellMicCommand); - cellMic->AddFunc(0xcac7e7d7, cellMicSysShareStart); - cellMic->AddFunc(0xd127cd3e, cellMicSysShareInit); - cellMic->AddFunc(0xf82bbf7c, cellMicSysShareEnd); - cellMic->AddFunc(0xfdbbe469, cellMicGetDeviceIdentifier); -} + cellMic.AddFunc(0x25c5723f, cellMicGetStatus); + cellMic.AddFunc(0xe839380f, cellMicStopEx); + cellMic.AddFunc(0x3ace58f3, cellMicSysShareClose); + cellMic.AddFunc(0x48108a23, cellMicGetFormat); + cellMic.AddFunc(0x891c6291, cellMicSetMultiMicNotifyEventQueue); + cellMic.AddFunc(0xad049ecf, cellMicGetFormatEx); + cellMic.AddFunc(0xbdfd51e2, cellMicSysShareStop); + cellMic.AddFunc(0xc3610dbd, cellMicSysShareOpen); + cellMic.AddFunc(0xc461563c, cellMicCommand); + cellMic.AddFunc(0xcac7e7d7, cellMicSysShareStart); + cellMic.AddFunc(0xd127cd3e, cellMicSysShareInit); + cellMic.AddFunc(0xf82bbf7c, cellMicSysShareEnd); + cellMic.AddFunc(0xfdbbe469, cellMicGetDeviceIdentifier); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp index 4d6d4f1dec..56945faf21 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMouse.cpp @@ -6,11 +6,11 @@ #include "Emu/Io/Mouse.h" #include "cellMouse.h" -extern Module *sys_io; +extern Module sys_io; int cellMouseInit(u32 max_connect) { - sys_io->Warning("cellMouseInit(max_connect=%d)", max_connect); + sys_io.Warning("cellMouseInit(max_connect=%d)", max_connect); if(Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_ALREADY_INITIALIZED; if(max_connect > 7) return CELL_MOUSE_ERROR_INVALID_PARAMETER; @@ -21,7 +21,7 @@ int cellMouseInit(u32 max_connect) int cellMouseClearBuf(u32 port_no) { - sys_io->Log("cellMouseClearBuf(port_no=%d)", port_no); + sys_io.Log("cellMouseClearBuf(port_no=%d)", port_no); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_INVALID_PARAMETER; @@ -32,7 +32,7 @@ int cellMouseClearBuf(u32 port_no) int cellMouseEnd() { - sys_io->Log("cellMouseEnd()"); + sys_io.Log("cellMouseEnd()"); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; Emu.GetMouseManager().Close(); return CELL_OK; @@ -40,7 +40,7 @@ int cellMouseEnd() int cellMouseGetInfo(vm::ptr info) { - sys_io->Log("cellMouseGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellMouseGetInfo(info_addr=0x%x)", info.addr()); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; const MouseInfo& current_info = Emu.GetMouseManager().GetInfo(); @@ -56,7 +56,7 @@ int cellMouseGetInfo(vm::ptr info) int cellMouseInfoTabletMode(u32 port_no, vm::ptr info) { - sys_io->Log("cellMouseInfoTabletMode(port_no=%d,info_addr=0x%x)", port_no, info.addr()); + sys_io.Log("cellMouseInfoTabletMode(port_no=%d,info_addr=0x%x)", port_no, info.addr()); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_INVALID_PARAMETER; @@ -68,7 +68,7 @@ int cellMouseInfoTabletMode(u32 port_no, vm::ptr info) int cellMouseGetData(u32 port_no, vm::ptr data) { - sys_io->Log("cellMouseGetData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellMouseGetData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; @@ -113,7 +113,7 @@ int cellMouseGetRawData(u32 port_no, u32 data_addr) { UNIMPLEMENTED_FUNC(sys_io); - /*sys_io->Log("cellMouseGetRawData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); + /*sys_io.Log("cellMouseGetRawData(port_no=%d,data_addr=0x%x)", port_no, data.addr()); if(!Emu.GetMouseManager().IsInited()) return CELL_MOUSE_ERROR_UNINITIALIZED; if(port_no >= Emu.GetMouseManager().GetMice().size()) return CELL_MOUSE_ERROR_NO_DEVICE; @@ -131,14 +131,14 @@ int cellMouseGetRawData(u32 port_no, u32 data_addr) void cellMouse_init() { - sys_io->AddFunc(0xc9030138, cellMouseInit); - sys_io->AddFunc(0x3ef66b95, cellMouseClearBuf); - sys_io->AddFunc(0xe10183ce, cellMouseEnd); - sys_io->AddFunc(0x5baf30fb, cellMouseGetInfo); - sys_io->AddFunc(0x4d0b3b1f, cellMouseInfoTabletMode); - sys_io->AddFunc(0x3138e632, cellMouseGetData); - sys_io->AddFunc(0x6bd131f0, cellMouseGetDataList); - sys_io->AddFunc(0x2d16da4f, cellMouseSetTabletMode); - sys_io->AddFunc(0x21a62e9b, cellMouseGetTabletDataList); - sys_io->AddFunc(0xa328cc35, cellMouseGetRawData); + sys_io.AddFunc(0xc9030138, cellMouseInit); + sys_io.AddFunc(0x3ef66b95, cellMouseClearBuf); + sys_io.AddFunc(0xe10183ce, cellMouseEnd); + sys_io.AddFunc(0x5baf30fb, cellMouseGetInfo); + sys_io.AddFunc(0x4d0b3b1f, cellMouseInfoTabletMode); + sys_io.AddFunc(0x3138e632, cellMouseGetData); + sys_io.AddFunc(0x6bd131f0, cellMouseGetDataList); + sys_io.AddFunc(0x2d16da4f, cellMouseSetTabletMode); + sys_io.AddFunc(0x21a62e9b, cellMouseGetTabletDataList); + sys_io.AddFunc(0xa328cc35, cellMouseGetRawData); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 31e3114a3b..7b96cefec4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -11,7 +11,7 @@ #include "cellSysutil.h" #include "cellMsgDialog.h" -extern Module *cellSysutil; +extern Module cellSysutil; enum MsgDialogState { @@ -49,7 +49,7 @@ void MsgDialogClose() s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam) { - cellSysutil->Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", + cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", type, msgString.addr(), callback.addr(), userData, extParam); if (!msgString || strlen(msgString.get_ptr()) >= 0x200 || type & -0x33f8) @@ -153,7 +153,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrWarning("MsgDialog thread aborted"); + cellSysutil.Warning("MsgDialog thread aborted"); return; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack @@ -192,7 +192,7 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam) { - cellSysutil->Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=0x%x, extParam=%d)", + cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=0x%x, extParam=%d)", errorCode, callback.addr(), userData, extParam); std::string errorMessage; @@ -295,7 +295,7 @@ s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr cal s32 cellMsgDialogClose(float delay) { - cellSysutil->Warning("cellMsgDialogClose(delay=%f)", delay); + cellSysutil.Warning("cellMsgDialogClose(delay=%f)", delay); MsgDialogState old = msgDialogOpen; if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogClose)) @@ -317,7 +317,7 @@ s32 cellMsgDialogClose(float delay) s32 cellMsgDialogAbort() { - cellSysutil->Warning("cellMsgDialogAbort()"); + cellSysutil.Warning("cellMsgDialogAbort()"); MsgDialogState old = msgDialogOpen; if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogAbort)) @@ -338,7 +338,7 @@ s32 cellMsgDialogAbort() s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString) { - cellSysutil->Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x ['%s'])", + cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x ['%s'])", progressBarIndex, msgString.addr(), msgString.get_ptr()); if (g_msg_dialog_state != msgDialogOpen) @@ -362,7 +362,7 @@ s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msg s32 cellMsgDialogProgressBarReset(u32 progressBarIndex) { - cellSysutil->Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex); + cellSysutil.Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex); if (g_msg_dialog_state != msgDialogOpen) { @@ -383,7 +383,7 @@ s32 cellMsgDialogProgressBarReset(u32 progressBarIndex) s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) { - cellSysutil->Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta); + cellSysutil.Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta); if (g_msg_dialog_state != msgDialogOpen) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp index 87b31b94dd..de4aca27dc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellNetCtl.cpp @@ -6,7 +6,7 @@ #include "cellSysutil.h" #include "cellNetCtl.h" -Module *cellNetCtl; +extern Module cellNetCtl; struct cellNetCtlInternal { @@ -22,7 +22,7 @@ cellNetCtlInternal cellNetCtlInstance; int cellNetCtlInit() { - cellNetCtl->Warning("cellNetCtlInit()"); + cellNetCtl.Warning("cellNetCtlInit()"); if (cellNetCtlInstance.m_bInitialized) return CELL_NET_CTL_ERROR_NOT_TERMINATED; @@ -34,7 +34,7 @@ int cellNetCtlInit() int cellNetCtlTerm() { - cellNetCtl->Warning("cellNetCtlTerm()"); + cellNetCtl.Warning("cellNetCtlTerm()"); if (!cellNetCtlInstance.m_bInitialized) return CELL_NET_CTL_ERROR_NOT_INITIALIZED; @@ -46,7 +46,7 @@ int cellNetCtlTerm() int cellNetCtlGetState(vm::ptr state) { - cellNetCtl->Warning("cellNetCtlGetState(state_addr=0x%x)", state.addr()); + cellNetCtl.Warning("cellNetCtlGetState(state_addr=0x%x)", state.addr()); *state = CELL_NET_CTL_STATE_Disconnected; // TODO: Allow other states @@ -55,28 +55,33 @@ int cellNetCtlGetState(vm::ptr state) int cellNetCtlAddHandler(vm::ptr handler, vm::ptr arg, vm::ptr hid) { - cellNetCtl->Todo("cellNetCtlAddHandler(handler_addr=0x%x, arg_addr=0x%x, hid_addr=0x%x)", handler.addr(), arg.addr(), hid.addr()); + cellNetCtl.Todo("cellNetCtlAddHandler(handler_addr=0x%x, arg_addr=0x%x, hid_addr=0x%x)", handler.addr(), arg.addr(), hid.addr()); return CELL_OK; } int cellNetCtlDelHandler(s32 hid) { - cellNetCtl->Todo("cellNetCtlDelHandler(hid=0x%x)", hid); + cellNetCtl.Todo("cellNetCtlDelHandler(hid=0x%x)", hid); return CELL_OK; } int cellNetCtlGetInfo(s32 code, vm::ptr info) { - cellNetCtl->Todo("cellNetCtlGetInfo(code=0x%x, info_addr=0x%x)", code, info.addr()); + cellNetCtl.Todo("cellNetCtlGetInfo(code=0x%x, info_addr=0x%x)", code, info.addr()); + + if (code == CELL_NET_CTL_INFO_IP_ADDRESS) + { + strcpy_trunc(info->ip_address, "192.168.1.1"); + } return CELL_OK; } int cellNetCtlNetStartDialogLoadAsync(vm::ptr param) { - cellNetCtl->Warning("cellNetCtlNetStartDialogLoadAsync(param_addr=0x%x)", param.addr()); + cellNetCtl.Warning("cellNetCtlNetStartDialogLoadAsync(param_addr=0x%x)", param.addr()); // TODO: Actually sign into PSN sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_FINISHED, 0); @@ -85,14 +90,14 @@ int cellNetCtlNetStartDialogLoadAsync(vm::ptr par int cellNetCtlNetStartDialogAbortAsync() { - cellNetCtl->Todo("cellNetCtlNetStartDialogAbortAsync()"); + cellNetCtl.Todo("cellNetCtlNetStartDialogAbortAsync()"); return CELL_OK; } int cellNetCtlNetStartDialogUnloadAsync(vm::ptr result) { - cellNetCtl->Warning("cellNetCtlNetStartDialogUnloadAsync(result_addr=0x%x)", result.addr()); + cellNetCtl.Warning("cellNetCtlNetStartDialogUnloadAsync(result_addr=0x%x)", result.addr()); sysutilSendSystemCommand(CELL_SYSUTIL_NET_CTL_NETSTART_UNLOADED, 0); return CELL_OK; @@ -100,11 +105,11 @@ int cellNetCtlNetStartDialogUnloadAsync(vm::ptr int cellNetCtlGetNatInfo(vm::ptr natInfo) { - cellNetCtl->Todo("cellNetCtlGetNatInfo(natInfo_addr=0x%x)", natInfo.addr()); + cellNetCtl.Todo("cellNetCtlGetNatInfo(natInfo_addr=0x%x)", natInfo.addr()); if (natInfo->size == 0) { - cellNetCtl->Error("cellNetCtlGetNatInfo : CELL_NET_CTL_ERROR_INVALID_SIZE"); + cellNetCtl.Error("cellNetCtlGetNatInfo : CELL_NET_CTL_ERROR_INVALID_SIZE"); return CELL_NET_CTL_ERROR_INVALID_SIZE; } @@ -116,22 +121,20 @@ void cellNetCtl_unload() cellNetCtlInstance.m_bInitialized = false; } -void cellNetCtl_init(Module *pxThis) +Module cellNetCtl("cellNetCtl", []() { - cellNetCtl = pxThis; + cellNetCtl.AddFunc(0xbd5a59fc, cellNetCtlInit); + cellNetCtl.AddFunc(0x105ee2cb, cellNetCtlTerm); - cellNetCtl->AddFunc(0xbd5a59fc, cellNetCtlInit); - cellNetCtl->AddFunc(0x105ee2cb, cellNetCtlTerm); + cellNetCtl.AddFunc(0x8b3eba69, cellNetCtlGetState); + cellNetCtl.AddFunc(0x0ce13c6b, cellNetCtlAddHandler); + cellNetCtl.AddFunc(0x901815c3, cellNetCtlDelHandler); - cellNetCtl->AddFunc(0x8b3eba69, cellNetCtlGetState); - cellNetCtl->AddFunc(0x0ce13c6b, cellNetCtlAddHandler); - cellNetCtl->AddFunc(0x901815c3, cellNetCtlDelHandler); + cellNetCtl.AddFunc(0x1e585b5d, cellNetCtlGetInfo); - cellNetCtl->AddFunc(0x1e585b5d, cellNetCtlGetInfo); + cellNetCtl.AddFunc(0x04459230, cellNetCtlNetStartDialogLoadAsync); + cellNetCtl.AddFunc(0x71d53210, cellNetCtlNetStartDialogAbortAsync); + cellNetCtl.AddFunc(0x0f1f13d3, cellNetCtlNetStartDialogUnloadAsync); - cellNetCtl->AddFunc(0x04459230, cellNetCtlNetStartDialogLoadAsync); - cellNetCtl->AddFunc(0x71d53210, cellNetCtlNetStartDialogAbortAsync); - cellNetCtl->AddFunc(0x0f1f13d3, cellNetCtlNetStartDialogUnloadAsync); - - cellNetCtl->AddFunc(0x3a12865f, cellNetCtlGetNatInfo); -} + cellNetCtl.AddFunc(0x3a12865f, cellNetCtlGetNatInfo); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp index 6284596f73..24b2e7162e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellOvis.cpp @@ -2,7 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" -Module *cellOvis = nullptr; +extern Module cellOvis; // Return Codes enum @@ -14,7 +14,7 @@ enum int cellOvisGetOverlayTableSize(vm::ptr elf) { - cellOvis->Todo("cellOvisGetOverlayTableSize(elf_addr=0x%x)", elf.addr()); + cellOvis.Todo("cellOvisGetOverlayTableSize(elf_addr=0x%x)", elf.addr()); return CELL_OK; } @@ -36,12 +36,10 @@ int cellOvisInvalidateOverlappedSegments() return CELL_OK; } -void cellOvis_init(Module *pxThis) +Module cellOvis("cellOvis", []() { - cellOvis = pxThis; - - cellOvis->AddFunc(0x82f294b2, cellOvisGetOverlayTableSize); - cellOvis->AddFunc(0xa876c911, cellOvisInitializeOverlayTable); - cellOvis->AddFunc(0xce6cb776, cellOvisFixSpuSegments); - cellOvis->AddFunc(0x629ba0c0, cellOvisInvalidateOverlappedSegments); -} + cellOvis.AddFunc(0x82f294b2, cellOvisGetOverlayTableSize); + cellOvis.AddFunc(0xa876c911, cellOvisInitializeOverlayTable); + cellOvis.AddFunc(0xce6cb776, cellOvisFixSpuSegments); + cellOvis.AddFunc(0x629ba0c0, cellOvisInvalidateOverlappedSegments); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp index c9ea7239e0..88b6b2505f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPad.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPad.cpp @@ -6,11 +6,11 @@ #include "Emu/Io/Pad.h" #include "cellPad.h" -extern Module *sys_io; +extern Module sys_io; int cellPadInit(u32 max_connect) { - sys_io->Warning("cellPadInit(max_connect=%d)", max_connect); + sys_io.Warning("cellPadInit(max_connect=%d)", max_connect); if(Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_ALREADY_INITIALIZED; if (max_connect > CELL_PAD_MAX_PORT_NUM) return CELL_PAD_ERROR_INVALID_PARAMETER; Emu.GetPadManager().Init(max_connect); @@ -19,7 +19,7 @@ int cellPadInit(u32 max_connect) int cellPadEnd() { - sys_io->Log("cellPadEnd()"); + sys_io.Log("cellPadEnd()"); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; Emu.GetPadManager().Close(); return CELL_OK; @@ -27,7 +27,7 @@ int cellPadEnd() int cellPadClearBuf(u32 port_no) { - sys_io->Log("cellPadClearBuf(port_no=%d)", port_no); + sys_io.Log("cellPadClearBuf(port_no=%d)", port_no); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -56,7 +56,7 @@ int cellPadClearBuf(u32 port_no) int cellPadPeriphGetInfo(vm::ptr info) { - sys_io->Warning("cellPadPeriphGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Warning("cellPadPeriphGetInfo(info_addr=0x%x)", info.addr()); // TODO: Support other types of controllers for (int i = 0; i < info->now_connect; i++) @@ -69,7 +69,7 @@ int cellPadPeriphGetInfo(vm::ptr info) int cellPadGetData(u32 port_no, vm::ptr data) { - sys_io->Log("cellPadGetData(port_no=%d, data_addr=0x%x)", port_no, data.addr()); + sys_io.Log("cellPadGetData(port_no=%d, data_addr=0x%x)", port_no, data.addr()); std::vector& pads = Emu.GetPadManager().GetPads(); @@ -251,7 +251,7 @@ int cellPadGetData(u32 port_no, vm::ptr data) int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr) { - sys_io->Log("cellPadGetDataExtra(port_no=%d, device_type_addr=0x%x, device_type_addr=0x%x)", port_no, device_type_addr, data_addr); + sys_io.Log("cellPadGetDataExtra(port_no=%d, device_type_addr=0x%x, device_type_addr=0x%x)", port_no, device_type_addr, data_addr); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -262,7 +262,7 @@ int cellPadGetDataExtra(u32 port_no, u32 device_type_addr, u32 data_addr) int cellPadSetActDirect(u32 port_no, u32 param_addr) { - sys_io->Log("cellPadSetActDirect(port_no=%d, param_addr=0x%x)", port_no, param_addr); + sys_io.Log("cellPadSetActDirect(port_no=%d, param_addr=0x%x)", port_no, param_addr); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -273,7 +273,7 @@ int cellPadSetActDirect(u32 port_no, u32 param_addr) int cellPadGetInfo(vm::ptr info) { - sys_io->Log("cellPadGetInfo(info_addr=0x%x)", info.addr()); + sys_io.Log("cellPadGetInfo(info_addr=0x%x)", info.addr()); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -301,7 +301,7 @@ int cellPadGetInfo(vm::ptr info) int cellPadGetInfo2(vm::ptr info) { - sys_io->Log("cellPadGetInfo2(info_addr=0x%x)", info.addr()); + sys_io.Log("cellPadGetInfo2(info_addr=0x%x)", info.addr()); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; @@ -329,7 +329,7 @@ int cellPadGetInfo2(vm::ptr info) int cellPadGetCapabilityInfo(u32 port_no, vm::ptr info) { - sys_io->Log("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr()); + sys_io.Log("cellPadGetCapabilityInfo(port_no=%d, data_addr:=0x%x)", port_no, info.addr()); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); @@ -346,7 +346,7 @@ int cellPadGetCapabilityInfo(u32 port_no, vm::ptr info) int cellPadSetPortSetting(u32 port_no, u32 port_setting) { - sys_io->Log("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting); + sys_io.Log("cellPadSetPortSetting(port_no=%d, port_setting=0x%x)", port_no, port_setting); if(!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -360,7 +360,7 @@ int cellPadSetPortSetting(u32 port_no, u32 port_setting) int cellPadInfoPressMode(u32 port_no) { - sys_io->Log("cellPadInfoPressMode(port_no=%d)", port_no); + sys_io.Log("cellPadInfoPressMode(port_no=%d)", port_no); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -373,7 +373,7 @@ int cellPadInfoPressMode(u32 port_no) int cellPadInfoSensorMode(u32 port_no) { - sys_io->Log("cellPadInfoSensorMode(port_no=%d)", port_no); + sys_io.Log("cellPadInfoSensorMode(port_no=%d)", port_no); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; @@ -386,7 +386,7 @@ int cellPadInfoSensorMode(u32 port_no) int cellPadSetPressMode(u32 port_no, u32 mode) { - sys_io->Log("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode); + sys_io.Log("cellPadSetPressMode(port_no=%d, mode=%d)", port_no, mode); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; if (mode != 0 && mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); @@ -405,7 +405,7 @@ int cellPadSetPressMode(u32 port_no, u32 mode) int cellPadSetSensorMode(u32 port_no, u32 mode) { - sys_io->Log("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode); + sys_io.Log("cellPadSetSensorMode(port_no=%d, mode=%d)", port_no, mode); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; if (mode != 0 && mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); @@ -424,19 +424,19 @@ int cellPadSetSensorMode(u32 port_no, u32 mode) void cellPad_init() { - sys_io->AddFunc(0x1cf98800, cellPadInit); - sys_io->AddFunc(0x4d9b75d5, cellPadEnd); - sys_io->AddFunc(0x0d5f2c14, cellPadClearBuf); - sys_io->AddFunc(0x8b72cda1, cellPadGetData); - sys_io->AddFunc(0x6bc09c61, cellPadGetDataExtra); - sys_io->AddFunc(0xf65544ee, cellPadSetActDirect); - sys_io->AddFunc(0x3aaad464, cellPadGetInfo); - sys_io->AddFunc(0xa703a51d, cellPadGetInfo2); - sys_io->AddFunc(0x4cc9b68d, cellPadPeriphGetInfo); - sys_io->AddFunc(0x578e3c98, cellPadSetPortSetting); - sys_io->AddFunc(0x0e2dfaad, cellPadInfoPressMode); - sys_io->AddFunc(0x78200559, cellPadInfoSensorMode); - sys_io->AddFunc(0xf83f8182, cellPadSetPressMode); - sys_io->AddFunc(0xbe5be3ba, cellPadSetSensorMode); - sys_io->AddFunc(0xdbf4c59c, cellPadGetCapabilityInfo); + sys_io.AddFunc(0x1cf98800, cellPadInit); + sys_io.AddFunc(0x4d9b75d5, cellPadEnd); + sys_io.AddFunc(0x0d5f2c14, cellPadClearBuf); + sys_io.AddFunc(0x8b72cda1, cellPadGetData); + sys_io.AddFunc(0x6bc09c61, cellPadGetDataExtra); + sys_io.AddFunc(0xf65544ee, cellPadSetActDirect); + sys_io.AddFunc(0x3aaad464, cellPadGetInfo); + sys_io.AddFunc(0xa703a51d, cellPadGetInfo2); + sys_io.AddFunc(0x4cc9b68d, cellPadPeriphGetInfo); + sys_io.AddFunc(0x578e3c98, cellPadSetPortSetting); + sys_io.AddFunc(0x0e2dfaad, cellPadInfoPressMode); + sys_io.AddFunc(0x78200559, cellPadInfoSensorMode); + sys_io.AddFunc(0xf83f8182, cellPadSetPressMode); + sys_io.AddFunc(0xbe5be3ba, cellPadSetSensorMode); + sys_io.AddFunc(0xdbf4c59c, cellPadGetCapabilityInfo); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index f768cd7001..d0c6d04863 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -5,7 +5,7 @@ #include "cellPamf.h" -Module *cellPamf = nullptr; +extern Module cellPamf; s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) { @@ -98,7 +98,7 @@ s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) default: { - cellPamf->Error("pamfStreamTypeToEsFilterId(): unknown type (%d, ch=%d)", type, ch); + cellPamf.Error("pamfStreamTypeToEsFilterId(): unknown type (%d, ch=%d)", type, ch); Emu.Pause(); return CELL_PAMF_ERROR_INVALID_ARG; } @@ -123,7 +123,7 @@ u8 pamfGetStreamType(vm::ptr pSelf, u32 stream) case 0xdd: return CELL_PAMF_STREAM_TYPE_USER_DATA; } - cellPamf->Todo("pamfGetStreamType(): unsupported stream type found(0x%x)", header.type); + cellPamf.Todo("pamfGetStreamType(): unsupported stream type found(0x%x)", header.type); Emu.Pause(); return 0xff; } @@ -166,14 +166,14 @@ u8 pamfGetStreamChannel(vm::ptr pSelf, u32 stream) } } - cellPamf->Todo("pamfGetStreamChannel(): unsupported stream type found(0x%x)", header.type); + cellPamf.Todo("pamfGetStreamChannel(): unsupported stream type found(0x%x)", header.type); Emu.Pause(); return 0xff; } s32 cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr pSize) { - cellPamf->Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.addr(), fileSize, pSize.addr()); + cellPamf.Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.addr(), fileSize, pSize.addr()); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -184,7 +184,7 @@ s32 cellPamfGetHeaderSize(vm::ptr pAddr, u64 fileSize, vm::ptr s32 cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribute, vm::ptr pSize) { - cellPamf->Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, attribute, pSize.addr()); + cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, attribute, pSize.addr()); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -195,7 +195,7 @@ s32 cellPamfGetHeaderSize2(vm::ptr pAddr, u64 fileSize, u32 attribut s32 cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm::ptr pOffset, vm::ptr pSize) { - cellPamf->Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, pOffset.addr(), pSize.addr()); + cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.addr(), fileSize, pOffset.addr(), pSize.addr()); //if ((u32)pAddr->magic != 0x464d4150) return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -208,7 +208,7 @@ s32 cellPamfGetStreamOffsetAndSize(vm::ptr pAddr, u64 fileSize, vm:: s32 cellPamfVerify(vm::ptr pAddr, u64 fileSize) { - cellPamf->Todo("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize); + cellPamf.Todo("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.addr(), fileSize); // TODO return CELL_OK; @@ -216,7 +216,7 @@ s32 cellPamfVerify(vm::ptr pAddr, u64 fileSize) s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pAddr, u64 fileSize, u32 attribute) { - cellPamf->Warning("cellPamfReaderInitialize(pSelf=0x%x, pAddr=0x%x, fileSize=%d, attribute=0x%x)", pSelf.addr(), pAddr.addr(), fileSize, attribute); + cellPamf.Warning("cellPamfReaderInitialize(pSelf=0x%x, pAddr=0x%x, fileSize=%d, attribute=0x%x)", pSelf.addr(), pAddr.addr(), fileSize, attribute); if (fileSize) { @@ -231,7 +231,7 @@ s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptrTodo("cellPamfReaderInitialize(): verification"); + cellPamf.Todo("cellPamfReaderInitialize(): verification"); } pSelf->stream = 0; // currently set stream @@ -240,7 +240,7 @@ s32 cellPamfReaderInitialize(vm::ptr pSelf, vm::ptr pSelf, vm::ptr pTimeStamp) { - cellPamf->Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); + cellPamf.Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); // always returns CELL_OK @@ -251,7 +251,7 @@ s32 cellPamfReaderGetPresentationStartTime(vm::ptr pSelf, vm::pt s32 cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr pTimeStamp) { - cellPamf->Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); + cellPamf.Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.addr(), pTimeStamp.addr()); // always returns CELL_OK @@ -262,7 +262,7 @@ s32 cellPamfReaderGetPresentationEndTime(vm::ptr pSelf, vm::ptr< u32 cellPamfReaderGetMuxRateBound(vm::ptr pSelf) { - cellPamf->Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.addr()); + cellPamf.Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.addr()); // cannot return error code return pSelf->pAddr->mux_rate_max; @@ -270,7 +270,7 @@ u32 cellPamfReaderGetMuxRateBound(vm::ptr pSelf) u8 cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) { - cellPamf->Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.addr()); + cellPamf.Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.addr()); // cannot return error code return pSelf->pAddr->stream_count; @@ -278,7 +278,7 @@ u8 cellPamfReaderGetNumberOfStreams(vm::ptr pSelf) u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 streamType) { - cellPamf->Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.addr(), streamType); + cellPamf.Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.addr(), streamType); // cannot return error code @@ -312,14 +312,14 @@ u8 cellPamfReaderGetNumberOfSpecificStreams(vm::ptr pSelf, u8 st } } - cellPamf->Todo("cellPamfReaderGetNumberOfSpecificStreams(): unsupported stream type (0x%x)", streamType); + cellPamf.Todo("cellPamfReaderGetNumberOfSpecificStreams(): unsupported stream type (0x%x)", streamType); Emu.Pause(); return 0; } s32 cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamIndex) { - cellPamf->Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.addr(), streamIndex); + cellPamf.Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.addr(), streamIndex); if (streamIndex >= pSelf->pAddr->stream_count) { @@ -332,12 +332,12 @@ s32 cellPamfReaderSetStreamWithIndex(vm::ptr pSelf, u8 streamInd s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 streamType, u8 ch) { - cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.addr(), streamType, ch); + cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.addr(), streamType, ch); // it probably doesn't support "any audio" or "any video" argument if (streamType > 5 || ch >= 16) { - cellPamf->Error("cellPamfReaderSetStreamWithTypeAndChannel(): invalid arguments (streamType=%d, ch=%d)", streamType, ch); + cellPamf.Error("cellPamfReaderSetStreamWithTypeAndChannel(): invalid arguments (streamType=%d, ch=%d)", streamType, ch); Emu.Pause(); return CELL_PAMF_ERROR_INVALID_ARG; } @@ -359,7 +359,7 @@ s32 cellPamfReaderSetStreamWithTypeAndChannel(vm::ptr pSelf, u8 s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 streamType, u8 streamIndex) { - cellPamf->Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.addr(), streamType, streamIndex); + cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.addr(), streamType, streamIndex); u32 found = 0; @@ -412,7 +412,7 @@ s32 cellPamfReaderSetStreamWithTypeAndIndex(vm::ptr pSelf, u8 st s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr pEsFilterId) { - cellPamf->Warning("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId_addr=0x%x)", type, ch, pEsFilterId.addr()); + cellPamf.Warning("cellPamfStreamTypeToEsFilterId(type=%d, ch=%d, pEsFilterId_addr=0x%x)", type, ch, pEsFilterId.addr()); if (!pEsFilterId) { @@ -424,7 +424,7 @@ s32 cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, vm::ptr s32 cellPamfReaderGetStreamIndex(vm::ptr pSelf) { - cellPamf->Log("cellPamfReaderGetStreamIndex(pSelf=0x%x)", pSelf.addr()); + cellPamf.Log("cellPamfReaderGetStreamIndex(pSelf=0x%x)", pSelf.addr()); // seems that CELL_PAMF_ERROR_INVALID_PAMF must be already written in pSelf->stream if it's the case return pSelf->stream; @@ -432,7 +432,7 @@ s32 cellPamfReaderGetStreamIndex(vm::ptr pSelf) s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr pType, vm::ptr pCh) { - cellPamf->Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x", + cellPamf.Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x", pSelf.addr(), pSelf->stream, pType.addr(), pCh.addr()); // unclear @@ -444,7 +444,7 @@ s32 cellPamfReaderGetStreamTypeAndChannel(vm::ptr pSelf, vm::ptr s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pEsFilterId) { - cellPamf->Warning("cellPamfReaderGetEsFilterId(pSelf=0x%x (stream=%d), pEsFilterId_addr=0x%x)", pSelf.addr(), pSelf->stream, pEsFilterId.addr()); + cellPamf.Warning("cellPamfReaderGetEsFilterId(pSelf=0x%x (stream=%d), pEsFilterId_addr=0x%x)", pSelf.addr(), pSelf->stream, pEsFilterId.addr()); // always returns CELL_OK @@ -459,7 +459,7 @@ s32 cellPamfReaderGetEsFilterId(vm::ptr pSelf, vm::ptr pSelf, u32 pInfo_addr, u32 size) { - cellPamf->Warning("cellPamfReaderGetStreamInfo(pSelf=0x%x, stream=%d, pInfo_addr=0x%x, size=%d)", pSelf.addr(), pSelf->stream, pInfo_addr, size); + cellPamf.Warning("cellPamfReaderGetStreamInfo(pSelf=0x%x, stream=%d, pInfo_addr=0x%x, size=%d)", pSelf.addr(), pSelf->stream, pInfo_addr, size); assert((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; @@ -525,7 +525,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u info->nfwIdc = header.AVC.x18 & 0x03; info->maxMeanBitrate = header.AVC.maxMeanBitrate; - cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AVC"); + cellPamf.Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AVC"); break; } @@ -583,7 +583,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u info->matrixCoefficients = 0; } - cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_M2V"); + cellPamf.Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_M2V"); break; } @@ -599,7 +599,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u info->samplingFrequency = header.audio.freq & 0xf; info->numberOfChannels = header.audio.channels & 0xf; - cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_ATRAC3PLUS"); + cellPamf.Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_ATRAC3PLUS"); break; } @@ -616,7 +616,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u info->numberOfChannels = header.audio.channels & 0xf; info->bitsPerSample = header.audio.bps >> 6; - cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_PAMF_LPCM"); + cellPamf.Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_PAMF_LPCM"); break; } @@ -632,13 +632,13 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u info->samplingFrequency = header.audio.freq & 0xf; info->numberOfChannels = header.audio.channels & 0xf; - cellPamf->Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AC3"); + cellPamf.Notice("cellPamfReaderGetStreamInfo(): CELL_PAMF_STREAM_TYPE_AC3"); break; } case CELL_PAMF_STREAM_TYPE_USER_DATA: { - cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type CELL_PAMF_STREAM_TYPE_USER_DATA"); + cellPamf.Error("cellPamfReaderGetStreamInfo(): invalid type CELL_PAMF_STREAM_TYPE_USER_DATA"); return CELL_PAMF_ERROR_INVALID_ARG; } @@ -649,7 +649,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 6"); + cellPamf.Todo("cellPamfReaderGetStreamInfo(): type 6"); break; } @@ -660,7 +660,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 7"); + cellPamf.Todo("cellPamfReaderGetStreamInfo(): type 7"); break; } @@ -671,20 +671,20 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u return CELL_PAMF_ERROR_INVALID_ARG; } - cellPamf->Todo("cellPamfReaderGetStreamInfo(): type 8"); + cellPamf.Todo("cellPamfReaderGetStreamInfo(): type 8"); break; } case 9: { - cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type 9"); + cellPamf.Error("cellPamfReaderGetStreamInfo(): invalid type 9"); return CELL_PAMF_ERROR_INVALID_ARG; } default: { // invalid type or getting type/ch failed - cellPamf->Error("cellPamfReaderGetStreamInfo(): invalid type %d (ch=%d)", type, ch); + cellPamf.Error("cellPamfReaderGetStreamInfo(): invalid type %d (ch=%d)", type, ch); return CELL_PAMF_ERROR_INVALID_PAMF; } } @@ -694,7 +694,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr pSelf, u32 pInfo_addr, u u32 cellPamfReaderGetNumberOfEp(vm::ptr pSelf) { - cellPamf->Todo("cellPamfReaderGetNumberOfEp(pSelf=0x%x, stream=%d)", pSelf.addr(), pSelf->stream); + cellPamf.Todo("cellPamfReaderGetNumberOfEp(pSelf=0x%x, stream=%d)", pSelf.addr(), pSelf->stream); // cannot return error code return 0; //pSelf->pAddr->stream_headers[pSelf->stream].ep_num; @@ -702,7 +702,7 @@ u32 cellPamfReaderGetNumberOfEp(vm::ptr pSelf) s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIndex, vm::ptr pIt) { - cellPamf->Todo("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x, stream=%d, epIndex=%d, pIt_addr=0x%x)", pSelf.addr(), pSelf->stream, epIndex, pIt.addr()); + cellPamf.Todo("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x, stream=%d, epIndex=%d, pIt_addr=0x%x)", pSelf.addr(), pSelf->stream, epIndex, pIt.addr()); // TODO return CELL_OK; @@ -710,7 +710,7 @@ s32 cellPamfReaderGetEpIteratorWithIndex(vm::ptr pSelf, u32 epIn s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm::ptr pTimeStamp, vm::ptr pIt) { - cellPamf->Todo("cellPamfReaderGetEpIteratorWithTimeStamp(pSelf=0x%x, pTimeStamp_addr=0x%x, pIt_addr=0x%x)", pSelf.addr(), pTimeStamp.addr(), pIt.addr()); + cellPamf.Todo("cellPamfReaderGetEpIteratorWithTimeStamp(pSelf=0x%x, pTimeStamp_addr=0x%x, pIt_addr=0x%x)", pSelf.addr(), pTimeStamp.addr(), pIt.addr()); // TODO return CELL_OK; @@ -718,7 +718,7 @@ s32 cellPamfReaderGetEpIteratorWithTimeStamp(vm::ptr pSelf, vm:: s32 cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr pEp) { - cellPamf->Todo("cellPamfEpIteratorGetEp(pIt_addr=0x%x, pEp_addr=0x%x)", pIt.addr(), pEp.addr()); + cellPamf.Todo("cellPamfEpIteratorGetEp(pIt_addr=0x%x, pEp_addr=0x%x)", pIt.addr(), pEp.addr()); // always returns CELL_OK // TODO @@ -727,39 +727,36 @@ s32 cellPamfEpIteratorGetEp(vm::ptr pIt, vm::ptr s32 cellPamfEpIteratorMove(vm::ptr pIt, s32 steps, vm::ptr pEp) { - cellPamf->Todo("cellPamfEpIteratorMove(pIt_addr=0x%x, steps=%d, pEp_addr=0x%x)", pIt.addr(), steps, pEp.addr()); + cellPamf.Todo("cellPamfEpIteratorMove(pIt_addr=0x%x, steps=%d, pEp_addr=0x%x)", pIt.addr(), steps, pEp.addr()); // cannot return error code // TODO return 0; } -void cellPamf_init(Module *pxThis) +Module cellPamf("cellPamf", []() { - cellPamf = pxThis; - - cellPamf->AddFunc(0xca8181c1, cellPamfGetHeaderSize); - cellPamf->AddFunc(0x90fc9a59, cellPamfGetHeaderSize2); - cellPamf->AddFunc(0x44f5c9e3, cellPamfGetStreamOffsetAndSize); - cellPamf->AddFunc(0xd1a40ef4, cellPamfVerify); - cellPamf->AddFunc(0xb8436ee5, cellPamfReaderInitialize); - cellPamf->AddFunc(0x4de501b1, cellPamfReaderGetPresentationStartTime); - cellPamf->AddFunc(0xf61609d6, cellPamfReaderGetPresentationEndTime); - cellPamf->AddFunc(0xdb70296c, cellPamfReaderGetMuxRateBound); - cellPamf->AddFunc(0x37f723f7, cellPamfReaderGetNumberOfStreams); - cellPamf->AddFunc(0xd0230671, cellPamfReaderGetNumberOfSpecificStreams); - cellPamf->AddFunc(0x461534b4, cellPamfReaderSetStreamWithIndex); - cellPamf->AddFunc(0x03fd2caa, cellPamfReaderSetStreamWithTypeAndChannel); - cellPamf->AddFunc(0x28b4e2c1, cellPamfReaderSetStreamWithTypeAndIndex); - cellPamf->AddFunc(0x01067e22, cellPamfStreamTypeToEsFilterId); - cellPamf->AddFunc(0x041cc708, cellPamfReaderGetStreamIndex); - cellPamf->AddFunc(0x9ab20793, cellPamfReaderGetStreamTypeAndChannel); - cellPamf->AddFunc(0x71df326a, cellPamfReaderGetEsFilterId); - cellPamf->AddFunc(0x67fd273b, cellPamfReaderGetStreamInfo); - cellPamf->AddFunc(0xd9ea3457, cellPamfReaderGetNumberOfEp); - cellPamf->AddFunc(0xe8586ec6, cellPamfReaderGetEpIteratorWithIndex); - cellPamf->AddFunc(0x439fba17, cellPamfReaderGetEpIteratorWithTimeStamp); - cellPamf->AddFunc(0x1abeb9d6, cellPamfEpIteratorGetEp); - cellPamf->AddFunc(0x50b83205, cellPamfEpIteratorMove); -} - + cellPamf.AddFunc(0xca8181c1, cellPamfGetHeaderSize); + cellPamf.AddFunc(0x90fc9a59, cellPamfGetHeaderSize2); + cellPamf.AddFunc(0x44f5c9e3, cellPamfGetStreamOffsetAndSize); + cellPamf.AddFunc(0xd1a40ef4, cellPamfVerify); + cellPamf.AddFunc(0xb8436ee5, cellPamfReaderInitialize); + cellPamf.AddFunc(0x4de501b1, cellPamfReaderGetPresentationStartTime); + cellPamf.AddFunc(0xf61609d6, cellPamfReaderGetPresentationEndTime); + cellPamf.AddFunc(0xdb70296c, cellPamfReaderGetMuxRateBound); + cellPamf.AddFunc(0x37f723f7, cellPamfReaderGetNumberOfStreams); + cellPamf.AddFunc(0xd0230671, cellPamfReaderGetNumberOfSpecificStreams); + cellPamf.AddFunc(0x461534b4, cellPamfReaderSetStreamWithIndex); + cellPamf.AddFunc(0x03fd2caa, cellPamfReaderSetStreamWithTypeAndChannel); + cellPamf.AddFunc(0x28b4e2c1, cellPamfReaderSetStreamWithTypeAndIndex); + cellPamf.AddFunc(0x01067e22, cellPamfStreamTypeToEsFilterId); + cellPamf.AddFunc(0x041cc708, cellPamfReaderGetStreamIndex); + cellPamf.AddFunc(0x9ab20793, cellPamfReaderGetStreamTypeAndChannel); + cellPamf.AddFunc(0x71df326a, cellPamfReaderGetEsFilterId); + cellPamf.AddFunc(0x67fd273b, cellPamfReaderGetStreamInfo); + cellPamf.AddFunc(0xd9ea3457, cellPamfReaderGetNumberOfEp); + cellPamf.AddFunc(0xe8586ec6, cellPamfReaderGetEpIteratorWithIndex); + cellPamf.AddFunc(0x439fba17, cellPamfReaderGetEpIteratorWithTimeStamp); + cellPamf.AddFunc(0x1abeb9d6, cellPamfEpIteratorGetEp); + cellPamf.AddFunc(0x50b83205, cellPamfEpIteratorMove); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index eff513f66c..7607bf0236 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -8,7 +8,7 @@ #include "cellPngDec.h" #include -Module *cellPngDec = nullptr; +extern Module cellPngDec; #undef PRX_DEBUG @@ -171,7 +171,7 @@ s64 pngReadHeader( case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break; case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break; default: - cellPngDec->Error("cellPngDecDecodeData: Unsupported color space (%d)", (u32)buffer[25]); + cellPngDec.Error("cellPngDecDecodeData: Unsupported color space (%d)", (u32)buffer[25]); return CELL_PNGDEC_ERROR_HEADER; } @@ -223,7 +223,7 @@ s64 pngDecSetParameter( current_outParam.outputComponents = 4; break; default: - cellPngDec->Error("pngDecSetParameter: Unsupported color space (%d)", current_outParam.outputColorSpace); + cellPngDec.Error("pngDecSetParameter: Unsupported color space (%d)", current_outParam.outputColorSpace); return CELL_PNGDEC_ERROR_ARG; } @@ -275,7 +275,7 @@ s64 pngDecodeData( ); if (!image) { - cellPngDec->Error("pngDecodeData: stbi_load_from_memory failed"); + cellPngDec.Error("pngDecodeData: stbi_load_from_memory failed"); return CELL_PNGDEC_ERROR_STREAM_FORMAT; } @@ -352,11 +352,11 @@ s64 pngDecodeData( case se32(CELL_PNGDEC_GRAYSCALE): case se32(CELL_PNGDEC_PALETTE): case se32(CELL_PNGDEC_GRAYSCALE_ALPHA): - cellPngDec->Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); + cellPngDec.Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); break; default: - cellPngDec->Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); + cellPngDec.Error("pngDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace); return CELL_PNGDEC_ERROR_ARG; } @@ -368,11 +368,11 @@ s64 pngDecodeData( s64 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); const_cast(*threadInParam).spuThreadEnable = CELL_PNGDEC_SPU_THREAD_DISABLE; // hack return GetCurrentPPUThread().FastCall2(libpngdec + 0x295C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", + cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", mainHandle.addr(), threadInParam.addr(), threadOutParam.addr()); // create decoder @@ -393,10 +393,10 @@ s64 cellPngDecExtCreate( vm::ptr extThreadOutParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x296C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)", + cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)", mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr()); // create decoder @@ -414,10 +414,10 @@ s64 cellPngDecExtCreate( s64 cellPngDecDestroy(CellPngDecMainHandle mainHandle) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x1E6C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr()); + cellPngDec.Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr()); // destroy decoder return pngDecDestroy(mainHandle); @@ -431,10 +431,10 @@ s64 cellPngDecOpen( vm::ptr openInfo) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F3C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", + cellPngDec.Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr()); // create stream handle @@ -451,10 +451,10 @@ s64 cellPngDecExtOpen( vm::ptr opnParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F34, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)", + cellPngDec.Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr(), cbCtrlStrm.addr(), opnParam.addr()); // create stream handle @@ -465,10 +465,10 @@ s64 cellPngDecExtOpen( s64 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x066C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr()); + cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr()); return pngDecClose(subHandle); #endif @@ -477,10 +477,10 @@ s64 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHand s64 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A3C, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", + cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle.addr(), subHandle.addr(), info.addr()); return pngReadHeader(subHandle, info); @@ -494,10 +494,10 @@ s64 cellPngDecExtReadHeader( vm::ptr extInfo) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A34, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", + cellPngDec.Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), info.addr(), extInfo.addr()); return pngReadHeader(subHandle, info, extInfo); @@ -511,10 +511,10 @@ s64 cellPngDecSetParameter( vm::ptr outParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x33F4, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", + cellPngDec.Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr()); return pngDecSetParameter(subHandle, inParam, outParam); @@ -530,10 +530,10 @@ s64 cellPngDecExtSetParameter( vm::ptr extOutParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x33EC, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x", + cellPngDec.Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x", mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr(), extInParam.addr(), extOutParam.addr()); return pngDecSetParameter(subHandle, inParam, outParam, extInParam, extOutParam); @@ -548,10 +548,10 @@ s64 cellPngDecDecodeData( vm::ptr dataOutInfo) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D40, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", + cellPngDec.Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo); @@ -568,10 +568,10 @@ s64 cellPngDecExtDecodeData( vm::ptr dispParam) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D38, libpngdec_rtoc); #else - cellPngDec->Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam_addr=0x%x)", + cellPngDec.Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr(), cbCtrlDisp.addr(), dispParam.addr()); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo, cbCtrlDisp, dispParam); @@ -585,7 +585,7 @@ s64 cellPngDecGetUnknownChunks( vm::ptr unknownChunkNumber) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x03EC, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -596,7 +596,7 @@ s64 cellPngDecGetUnknownChunks( s64 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0730, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -607,7 +607,7 @@ s64 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0894, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -618,7 +618,7 @@ s64 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x09EC, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -629,7 +629,7 @@ s64 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0B14, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -640,7 +640,7 @@ s64 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0C58, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -651,7 +651,7 @@ s64 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0D9C, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -662,7 +662,7 @@ s64 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x0ED0, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -673,7 +673,7 @@ s64 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x1024, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -684,7 +684,7 @@ s64 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x116C, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -695,7 +695,7 @@ s64 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x12A4, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -706,7 +706,7 @@ s64 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x1420, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -717,7 +717,7 @@ s64 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x1574, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -728,7 +728,7 @@ s64 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x16B4, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -739,7 +739,7 @@ s64 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x17CC, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -750,7 +750,7 @@ s64 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHa s64 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x18E4, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -765,7 +765,7 @@ s64 cellPngDecGetTextChunk( vm::ptr> textInfo) { #ifdef PRX_DEBUG - cellPngDec->Warning("%s()", __FUNCTION__); + cellPngDec.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libpngdec + 0x19FC, libpngdec_rtoc); #else UNIMPLEMENTED_FUNC(cellPngDec); @@ -773,10 +773,8 @@ s64 cellPngDecGetTextChunk( #endif } -void cellPngDec_init(Module *pxThis) +Module cellPngDec("cellPngDec", []() { - cellPngDec = pxThis; - REG_FUNC(cellPngDec, cellPngDecGetUnknownChunks); REG_FUNC(cellPngDec, cellPngDecClose); REG_FUNC(cellPngDec, cellPngDecGetpCAL); @@ -853,4 +851,4 @@ void cellPngDec_init(Module *pxThis) fix_relocs(cellPngDec, libpngdec, 0x41C30, 0x47AB0, 0x40A00); }); #endif -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index ed9bbfbb85..9c92c8d60f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -8,7 +8,7 @@ #include "Emu/RSX/GSManager.h" #include "cellResc.h" -Module *cellResc = nullptr; +extern Module cellResc; extern s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent); extern s32 cellGcmSetFlipMode(u32 mode); @@ -569,17 +569,17 @@ void SetupSurfaces(vm::ptr& cntxt) // Module Functions int cellRescInit(vm::ptr initConfig) { - cellResc->Warning("cellRescInit(initConfig_addr=0x%x)", initConfig.addr()); + cellResc.Warning("cellRescInit(initConfig_addr=0x%x)", initConfig.addr()); if (s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescInit : CELL_RESC_ERROR_REINITIALIZED"); + cellResc.Error("cellRescInit : CELL_RESC_ERROR_REINITIALIZED"); return CELL_RESC_ERROR_REINITIALIZED; } if (InternalVersion(initConfig) == -1 || !CheckInitConfig(initConfig)) { - cellResc->Error("cellRescInit : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescInit : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -592,11 +592,11 @@ int cellRescInit(vm::ptr initConfig) void cellRescExit() { - cellResc->Warning("cellRescExit()"); + cellResc.Warning("cellRescExit()"); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescExit(): not initialized"); + cellResc.Error("cellRescExit(): not initialized"); return; } @@ -612,7 +612,7 @@ void cellRescExit() //int ret = ExitSystemResource(); //if (ret != CELL_OK) //{ - // cellResc->Error("failed to clean up system resources.. continue. 0x%x\n", ret); + // cellResc.Error("failed to clean up system resources.. continue. 0x%x\n", ret); //} } } @@ -622,7 +622,7 @@ void cellRescExit() int cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr bufferMode) { - cellResc->Log("cellRescVideoOutResolutionId2RescBufferMode(resolutionId=%d, bufferMode_addr=0x%x)", resolutionId, bufferMode.addr()); + cellResc.Log("cellRescVideoOutResolutionId2RescBufferMode(resolutionId=%d, bufferMode_addr=0x%x)", resolutionId, bufferMode.addr()); switch (resolutionId) { @@ -639,7 +639,7 @@ int cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr b *bufferMode = CELL_RESC_720x576; break; default: - cellResc->Error("cellRescVideoOutResolutionId2RescBufferMod : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescVideoOutResolutionId2RescBufferMod : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -648,17 +648,17 @@ int cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr b int cellRescSetDsts(u32 dstsMode, vm::ptr dsts) { - cellResc->Log("cellRescSetDsts(dstsMode=%d, CellRescDsts_addr=0x%x)", dstsMode, dsts.addr()); + cellResc.Log("cellRescSetDsts(dstsMode=%d, CellRescDsts_addr=0x%x)", dstsMode, dsts.addr()); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetDst : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetDst : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if ((dstsMode != CELL_RESC_720x480) && (dstsMode != CELL_RESC_720x576) && (dstsMode != CELL_RESC_1280x720) && (dstsMode != CELL_RESC_1920x1080)) { - cellResc->Error("cellRescSetDsts : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetDsts : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -715,24 +715,24 @@ void SetFlipHandler(vm::ptr handler) int cellRescSetDisplayMode(u32 displayMode) { - cellResc->Warning("cellRescSetDisplayMode(displayMode=%d)", displayMode); + cellResc.Warning("cellRescSetDisplayMode(displayMode=%d)", displayMode); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetDisplayMode : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetDisplayMode : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if (!(s_rescInternalInstance->m_initConfig.supportModes & displayMode)) { - cellResc->Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } if ((displayMode != CELL_RESC_720x480) && (displayMode != CELL_RESC_720x576) && (displayMode != CELL_RESC_1280x720) && (displayMode != CELL_RESC_1920x1080)) { - cellResc->Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -740,13 +740,13 @@ int cellRescSetDisplayMode(u32 displayMode) if ((IsPalInterpolate() || IsPalDrop()) && s_rescInternalInstance->m_initConfig.flipMode == CELL_RESC_DISPLAY_HSYNC) { - cellResc->Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_COMBINATIONT"); + cellResc.Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_COMBINATIONT"); return CELL_RESC_ERROR_BAD_COMBINATION; } if (IsPal60Hsync() && s_rescInternalInstance->m_initConfig.flipMode==CELL_RESC_DISPLAY_VSYNC) { - cellResc->Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_COMBINATIONT"); + cellResc.Error("cellRescSetDisplayMode : CELL_RESC_ERROR_BAD_COMBINATIONT"); return CELL_RESC_ERROR_BAD_COMBINATION; } @@ -805,17 +805,17 @@ int cellRescSetDisplayMode(u32 displayMode) int cellRescAdjustAspectRatio(float horizontal, float vertical) { - cellResc->Warning("cellRescAdjustAspectRatio(horizontal=%f, vertical=%f)", horizontal, vertical); + cellResc.Warning("cellRescAdjustAspectRatio(horizontal=%f, vertical=%f)", horizontal, vertical); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescAdjustAspectRatio : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescAdjustAspectRatio : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if ((horizontal < 0.5f || 2.f < horizontal) || (vertical < 0.5f || 2.f < vertical)) { - cellResc->Error("cellRescAdjustAspectRatio : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescAdjustAspectRatio : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -839,17 +839,17 @@ int cellRescAdjustAspectRatio(float horizontal, float vertical) int cellRescSetPalInterpolateDropFlexRatio(float ratio) { - cellResc->Warning("cellRescSetPalInterpolateDropFlexRatio(ratio=%f)", ratio); + cellResc.Warning("cellRescSetPalInterpolateDropFlexRatio(ratio=%f)", ratio); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetPalInterpolateDropFlexRatio : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetPalInterpolateDropFlexRatio : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if (ratio < 0.f || 1.f < ratio) { - cellResc->Error("cellRescSetPalInterpolateDropFlexRatio : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetPalInterpolateDropFlexRatio : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -860,12 +860,12 @@ int cellRescSetPalInterpolateDropFlexRatio(float ratio) int cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) { - cellResc->Warning("cellRescGetBufferSize(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", + cellResc.Warning("cellRescGetBufferSize(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr()); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescGetBufferSize : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescGetBufferSize : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } @@ -904,11 +904,11 @@ int cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, v int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) { - cellResc->Log("cellRescGetNumColorBuffers(dstMode=%d, palTemporalMode=%d, reserved=%d)", dstMode, palTemporalMode, reserved); + cellResc.Log("cellRescGetNumColorBuffers(dstMode=%d, palTemporalMode=%d, reserved=%d)", dstMode, palTemporalMode, reserved); if (reserved != 0) { - cellResc->Error("cellRescGetNumColorBuffers : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescGetNumColorBuffers : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -925,7 +925,7 @@ int cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) int cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr rescSrc) { - cellResc->Log("cellRescGcmSurface2RescSrc(gcmSurface_addr=0x%x, rescSrc_addr=0x%x)", gcmSurface.addr(), rescSrc.addr()); + cellResc.Log("cellRescGcmSurface2RescSrc(gcmSurface_addr=0x%x, rescSrc_addr=0x%x)", gcmSurface.addr(), rescSrc.addr()); u8 textureFormat = GcmSurfaceFormat2GcmTextureFormat(gcmSurface->colorFormat, gcmSurface->type); s32 xW = 1, xH = 1; @@ -956,25 +956,25 @@ int cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr src) { - cellResc->Log("cellRescSetSrc(idx=0x%x, src_addr=0x%x)", idx, src.addr()); + cellResc.Log("cellRescSetSrc(idx=0x%x, src_addr=0x%x)", idx, src.addr()); if(!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetSrc : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetSrc : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if (idx < 0 || idx >= SRC_BUFFER_NUM || src->width < 1 || src->width > 4096 || src->height < 1 || src->height > 4096) { - cellResc->Error("cellRescSetSrc : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetSrc : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } - cellResc->Log(" *** format=0x%x", src->format); - cellResc->Log(" *** pitch=%d", src->pitch); - cellResc->Log(" *** width=%d", src->width); - cellResc->Log(" *** height=%d", src->height); - cellResc->Log(" *** offset=0x%x", src->offset); + cellResc.Log(" *** format=0x%x", src->format); + cellResc.Log(" *** pitch=%d", src->pitch); + cellResc.Log(" *** width=%d", src->width); + cellResc.Log(" *** height=%d", src->height); + cellResc.Log(" *** offset=0x%x", src->offset); s_rescInternalInstance->m_rescSrc[idx] = *src; @@ -985,17 +985,17 @@ int cellRescSetSrc(s32 idx, vm::ptr src) int cellRescSetConvertAndFlip(vm::ptr cntxt, s32 idx) { - cellResc->Log("cellRescSetConvertAndFlip(cntxt_addr=0x%x, indx=0x%x)", cntxt.addr(), idx); + cellResc.Log("cellRescSetConvertAndFlip(cntxt_addr=0x%x, indx=0x%x)", cntxt.addr(), idx); if(!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetConvertAndFlip : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetConvertAndFlip : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if(idx < 0 || SRC_BUFFER_NUM <= idx) { - cellResc->Error("cellRescSetConvertAndFlip : CELL_RESC_ERROR_BAD_ARGUMENT"); + cellResc.Error("cellRescSetConvertAndFlip : CELL_RESC_ERROR_BAD_ARGUMENT"); return CELL_RESC_ERROR_BAD_ARGUMENT; } @@ -1023,7 +1023,7 @@ int cellRescSetConvertAndFlip(vm::ptr cntxt, s32 idx) int cellRescSetWaitFlip() { - cellResc->Log("cellRescSetWaitFlip()"); + cellResc.Log("cellRescSetWaitFlip()"); GSLockCurrent lock(GS_LOCK_WAIT_FLIP); return CELL_OK; @@ -1031,17 +1031,17 @@ int cellRescSetWaitFlip() int cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) { - cellResc->Warning("cellRescSetBufferAddress(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr()); + cellResc.Warning("cellRescSetBufferAddress(colorBuffers_addr=0x%x, vertexArray_addr=0x%x, fragmentShader_addr=0x%x)", colorBuffers.addr(), vertexArray.addr(), fragmentShader.addr()); if(!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescSetBufferAddress : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if(colorBuffers.addr() % COLOR_BUFFER_ALIGNMENT || vertexArray.addr() % VERTEX_BUFFER_ALIGNMENT || fragmentShader.addr() % FRAGMENT_SHADER_ALIGNMENT) { - cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ALIGNMENT"); + cellResc.Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ALIGNMENT"); return CELL_RESC_ERROR_BAD_ALIGNMENT; } @@ -1075,21 +1075,21 @@ int cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray void cellRescSetFlipHandler(vm::ptr handler) { - cellResc->Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler.addr()); + cellResc.Warning("cellRescSetFlipHandler(handler_addr=0x%x)", handler.addr()); Emu.GetGSManager().GetRender().m_flip_handler = handler; } void cellRescResetFlipStatus() { - cellResc->Log("cellRescResetFlipStatus()"); + cellResc.Log("cellRescResetFlipStatus()"); Emu.GetGSManager().GetRender().m_flip_status = 1; } int cellRescGetFlipStatus() { - cellResc->Log("cellRescGetFlipStatus()"); + cellResc.Log("cellRescGetFlipStatus()"); return Emu.GetGSManager().GetRender().m_flip_status; } @@ -1102,7 +1102,7 @@ int cellRescGetRegisterCount() u64 cellRescGetLastFlipTime() { - cellResc->Log("cellRescGetLastFlipTime()"); + cellResc.Log("cellRescGetLastFlipTime()"); return Emu.GetGSManager().GetRender().m_last_flip_time; } @@ -1115,7 +1115,7 @@ int cellRescSetRegisterCount() void cellRescSetVBlankHandler(vm::ptr handler) { - cellResc->Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler.addr()); + cellResc.Warning("cellRescSetVBlankHandler(handler_addr=0x%x)", handler.addr()); Emu.GetGSManager().GetRender().m_vblank_handler = handler; } @@ -1212,23 +1212,23 @@ int CreateInterlaceTable(u32 ea_addr, float srcH, float dstH, CellRescTableEleme int cellRescCreateInterlaceTable(u32 ea_addr, float srcH, CellRescTableElement depth, int length) { - cellResc->Warning("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, depth, length); + cellResc.Warning("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, depth, length); if (!s_rescInternalInstance->m_bInitialized) { - cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_NOT_INITIALIZED; } if ((ea_addr == 0) || (srcH <= 0.f) || (!(depth == CELL_RESC_ELEMENT_HALF || depth == CELL_RESC_ELEMENT_FLOAT)) || (length <= 0)) { - cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED"); + cellResc.Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_NOT_INITIALIZED"); return CELL_RESC_ERROR_BAD_ARGUMENT; } if (s_rescInternalInstance->m_dstHeight == 0) { - cellResc->Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_BAD_COMBINATION"); + cellResc.Error("cellRescCreateInterlaceTable : CELL_RESC_ERROR_BAD_COMBINATION"); return CELL_RESC_ERROR_BAD_COMBINATION; } @@ -1249,40 +1249,35 @@ int cellRescCreateInterlaceTable(u32 ea_addr, float srcH, CellRescTableElement d } -void cellResc_init(Module *pxThis) -{ - cellResc = pxThis; - - cellResc->AddFunc(0x25c107e6, cellRescSetConvertAndFlip); - cellResc->AddFunc(0x0d3c22ce, cellRescSetWaitFlip); - cellResc->AddFunc(0x2ea94661, cellRescSetFlipHandler); - cellResc->AddFunc(0x01220224, cellRescGcmSurface2RescSrc); - cellResc->AddFunc(0x0a2069c7, cellRescGetNumColorBuffers); - cellResc->AddFunc(0x10db5b1a, cellRescSetDsts); - cellResc->AddFunc(0x129922a0, cellRescResetFlipStatus); - cellResc->AddFunc(0x19a2a967, cellRescSetPalInterpolateDropFlexRatio); - cellResc->AddFunc(0x1dd3c4cd, cellRescGetRegisterCount); - cellResc->AddFunc(0x22ae06d8, cellRescAdjustAspectRatio); - cellResc->AddFunc(0x23134710, cellRescSetDisplayMode); - cellResc->AddFunc(0x2ea3061e, cellRescExit); - cellResc->AddFunc(0x516ee89e, cellRescInit); - cellResc->AddFunc(0x5a338cdb, cellRescGetBufferSize); - cellResc->AddFunc(0x66f5e388, cellRescGetLastFlipTime); - cellResc->AddFunc(0x6cd0f95f, cellRescSetSrc); - cellResc->AddFunc(0x7af8a37f, cellRescSetRegisterCount); - cellResc->AddFunc(0x8107277c, cellRescSetBufferAddress); - cellResc->AddFunc(0xc47c5c22, cellRescGetFlipStatus); - cellResc->AddFunc(0xd1ca0503, cellRescVideoOutResolutionId2RescBufferMode); - cellResc->AddFunc(0xd3758645, cellRescSetVBlankHandler); - cellResc->AddFunc(0xe0cef79e, cellRescCreateInterlaceTable); -} - -void cellResc_load() +Module cellResc("cellResc", []() { s_rescInternalInstance = new CCellRescInternal(); -} -void cellResc_unload() -{ - delete s_rescInternalInstance; -} + cellResc.on_stop = []() + { + delete s_rescInternalInstance; + }; + + cellResc.AddFunc(0x25c107e6, cellRescSetConvertAndFlip); + cellResc.AddFunc(0x0d3c22ce, cellRescSetWaitFlip); + cellResc.AddFunc(0x2ea94661, cellRescSetFlipHandler); + cellResc.AddFunc(0x01220224, cellRescGcmSurface2RescSrc); + cellResc.AddFunc(0x0a2069c7, cellRescGetNumColorBuffers); + cellResc.AddFunc(0x10db5b1a, cellRescSetDsts); + cellResc.AddFunc(0x129922a0, cellRescResetFlipStatus); + cellResc.AddFunc(0x19a2a967, cellRescSetPalInterpolateDropFlexRatio); + cellResc.AddFunc(0x1dd3c4cd, cellRescGetRegisterCount); + cellResc.AddFunc(0x22ae06d8, cellRescAdjustAspectRatio); + cellResc.AddFunc(0x23134710, cellRescSetDisplayMode); + cellResc.AddFunc(0x2ea3061e, cellRescExit); + cellResc.AddFunc(0x516ee89e, cellRescInit); + cellResc.AddFunc(0x5a338cdb, cellRescGetBufferSize); + cellResc.AddFunc(0x66f5e388, cellRescGetLastFlipTime); + cellResc.AddFunc(0x6cd0f95f, cellRescSetSrc); + cellResc.AddFunc(0x7af8a37f, cellRescSetRegisterCount); + cellResc.AddFunc(0x8107277c, cellRescSetBufferAddress); + cellResc.AddFunc(0xc47c5c22, cellRescGetFlipStatus); + cellResc.AddFunc(0xd1ca0503, cellRescVideoOutResolutionId2RescBufferMode); + cellResc.AddFunc(0xd3758645, cellRescSetVBlankHandler); + cellResc.AddFunc(0xe0cef79e, cellRescCreateInterlaceTable); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp index 59b166eee3..d4ef31021f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellRtc.cpp @@ -5,7 +5,7 @@ #include "Utilities/rTime.h" #include "cellRtc.h" -Module *cellRtc = nullptr; +extern Module cellRtc; s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, int years) { @@ -24,7 +24,7 @@ u64 convertToWin32FILETIME(u16 seconds, u16 minutes, u16 hours, u16 days, int ye int cellRtcGetCurrentTick(vm::ptr pTick) { - cellRtc->Log("cellRtcGetCurrentTick(pTick=0x%x)", pTick.addr()); + cellRtc.Log("cellRtcGetCurrentTick(pTick=0x%x)", pTick.addr()); rDateTime unow = rDateTime::UNow(); pTick->tick = unow.GetTicks(); @@ -33,7 +33,7 @@ int cellRtcGetCurrentTick(vm::ptr pTick) int cellRtcGetCurrentClock(vm::ptr pClock, s32 iTimeZone) { - cellRtc->Log("cellRtcGetCurrentClock(pClock=0x%x, time_zone=%d)", pClock.addr(), iTimeZone); + cellRtc.Log("cellRtcGetCurrentClock(pClock=0x%x, time_zone=%d)", pClock.addr(), iTimeZone); rDateTime unow = rDateTime::UNow(); @@ -54,7 +54,7 @@ int cellRtcGetCurrentClock(vm::ptr pClock, s32 iTimeZone) int cellRtcGetCurrentClockLocalTime(vm::ptr pClock) { - cellRtc->Log("cellRtcGetCurrentClockLocalTime(pClock=0x%x)", pClock.addr()); + cellRtc.Log("cellRtcGetCurrentClockLocalTime(pClock=0x%x)", pClock.addr()); rDateTime unow = rDateTime::UNow(); @@ -71,7 +71,7 @@ int cellRtcGetCurrentClockLocalTime(vm::ptr pClock) int cellRtcFormatRfc2822(vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) { - cellRtc->Log("cellRtcFormatRfc2822(pszDateTime_addr=0x%x, pUtc=0x%x, time_zone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); + cellRtc.Log("cellRtcFormatRfc2822(pszDateTime_addr=0x%x, pUtc=0x%x, time_zone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); // Add time_zone as offset in minutes. rTimeSpan tz = rTimeSpan(0, (long) iTimeZone, 0, 0); @@ -89,7 +89,7 @@ int cellRtcFormatRfc2822(vm::ptr pszDateTime, vm::ptr pUtc, s int cellRtcFormatRfc2822LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) { - cellRtc->Log("cellRtcFormatRfc2822LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); + cellRtc.Log("cellRtcFormatRfc2822LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); // Get date from ticks. rDateTime date = rDateTime((time_t)pUtc->tick); @@ -103,7 +103,7 @@ int cellRtcFormatRfc2822LocalTime(vm::ptr pszDateTime, vm::ptr pszDateTime, vm::ptr pUtc, s32 iTimeZone) { - cellRtc->Log("cellRtcFormatRfc3339(pszDateTime_addr=0x%x, pUtc=0x%x, iTimeZone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); + cellRtc.Log("cellRtcFormatRfc3339(pszDateTime_addr=0x%x, pUtc=0x%x, iTimeZone=%d)", pszDateTime.addr(), pUtc.addr(), iTimeZone); // Add time_zone as offset in minutes. rTimeSpan tz = rTimeSpan(0, (long) iTimeZone, 0, 0); @@ -121,7 +121,7 @@ int cellRtcFormatRfc3339(vm::ptr pszDateTime, vm::ptr pUtc, s int cellRtcFormatRfc3339LocalTime(vm::ptr pszDateTime, vm::ptr pUtc) { - cellRtc->Log("cellRtcFormatRfc3339LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); + cellRtc.Log("cellRtcFormatRfc3339LocalTime(pszDateTime_addr=0x%x, pUtc=0x%x)", pszDateTime.addr(), pUtc.addr()); // Get date from ticks. rDateTime date = rDateTime((time_t) pUtc->tick); @@ -135,7 +135,7 @@ int cellRtcFormatRfc3339LocalTime(vm::ptr pszDateTime, vm::ptr pUtc, vm::ptr pszDateTime) { - cellRtc->Log("cellRtcParseDateTime(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); + cellRtc.Log("cellRtcParseDateTime(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); // Get date from formatted string. rDateTime date; @@ -148,7 +148,7 @@ int cellRtcParseDateTime(vm::ptr pUtc, vm::ptr pszDateT int cellRtcParseRfc3339(vm::ptr pUtc, vm::ptr pszDateTime) { - cellRtc->Log("cellRtcParseRfc3339(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); + cellRtc.Log("cellRtcParseRfc3339(pUtc=0x%x, pszDateTime_addr=0x%x)", pUtc.addr(), pszDateTime.addr()); // Get date from RFC3339 formatted string. rDateTime date; @@ -161,7 +161,7 @@ int cellRtcParseRfc3339(vm::ptr pUtc, vm::ptr pszDateTi int cellRtcGetTick(vm::ptr pTime, vm::ptr pTick) { - cellRtc->Log("cellRtcGetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); + cellRtc.Log("cellRtcGetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); rDateTime datetime = rDateTime(pTime->day, (rDateTime::Month)pTime->month.value(), pTime->year, pTime->hour, pTime->minute, pTime->second, (pTime->microsecond / 1000)); pTick->tick = datetime.GetTicks(); @@ -171,7 +171,7 @@ int cellRtcGetTick(vm::ptr pTime, vm::ptr pTick) int cellRtcSetTick(vm::ptr pTime, vm::ptr pTick) { - cellRtc->Log("cellRtcSetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); + cellRtc.Log("cellRtcSetTick(pTime=0x%x, pTick=0x%x)", pTime.addr(), pTick.addr()); rDateTime date = rDateTime((time_t)pTick->tick); @@ -188,7 +188,7 @@ int cellRtcSetTick(vm::ptr pTime, vm::ptr pTick) int cellRtcTickAddTicks(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { - cellRtc->Log("cellRtcTickAddTicks(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); + cellRtc.Log("cellRtcTickAddTicks(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); pTick0->tick = pTick1->tick + lAdd; return CELL_OK; @@ -196,7 +196,7 @@ int cellRtcTickAddTicks(vm::ptr pTick0, vm::ptr pTick1 int cellRtcTickAddMicroseconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { - cellRtc->Log("cellRtcTickAddMicroseconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); + cellRtc.Log("cellRtcTickAddMicroseconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rTimeSpan microseconds = rTimeSpan(0, 0, 0, lAdd / 1000); @@ -208,7 +208,7 @@ int cellRtcTickAddMicroseconds(vm::ptr pTick0, vm::ptr int cellRtcTickAddSeconds(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { - cellRtc->Log("cellRtcTickAddSeconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); + cellRtc.Log("cellRtcTickAddSeconds(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rTimeSpan seconds = rTimeSpan(0, 0, lAdd, 0); @@ -220,7 +220,7 @@ int cellRtcTickAddSeconds(vm::ptr pTick0, vm::ptr pTic int cellRtcTickAddMinutes(vm::ptr pTick0, vm::ptr pTick1, s64 lAdd) { - cellRtc->Log("cellRtcTickAddMinutes(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); + cellRtc.Log("cellRtcTickAddMinutes(pTick0=0x%x, pTick1=0x%x, lAdd=%lld)", pTick0.addr(), pTick1.addr(), lAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rTimeSpan minutes = rTimeSpan(0, lAdd, 0, 0); // ??? @@ -232,7 +232,7 @@ int cellRtcTickAddMinutes(vm::ptr pTick0, vm::ptr pTic int cellRtcTickAddHours(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { - cellRtc->Log("cellRtcTickAddHours(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); + cellRtc.Log("cellRtcTickAddHours(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rTimeSpan hours = rTimeSpan(iAdd, 0, 0, 0); // ??? @@ -244,7 +244,7 @@ int cellRtcTickAddHours(vm::ptr pTick0, vm::ptr pTick1 int cellRtcTickAddDays(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { - cellRtc->Log("cellRtcTickAddDays(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); + cellRtc.Log("cellRtcTickAddDays(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rDateSpan days = rDateSpan(0, 0, 0, iAdd); // ??? @@ -256,7 +256,7 @@ int cellRtcTickAddDays(vm::ptr pTick0, vm::ptr pTick1, int cellRtcTickAddWeeks(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { - cellRtc->Log("cellRtcTickAddWeeks(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); + cellRtc.Log("cellRtcTickAddWeeks(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rDateSpan weeks = rDateSpan(0, 0, iAdd, 0); @@ -268,7 +268,7 @@ int cellRtcTickAddWeeks(vm::ptr pTick0, vm::ptr pTick1 int cellRtcTickAddMonths(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { - cellRtc->Log("cellRtcTickAddMonths(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); + cellRtc.Log("cellRtcTickAddMonths(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rDateSpan months = rDateSpan(0, iAdd, 0, 0); @@ -280,7 +280,7 @@ int cellRtcTickAddMonths(vm::ptr pTick0, vm::ptr pTick int cellRtcTickAddYears(vm::ptr pTick0, vm::ptr pTick1, s32 iAdd) { - cellRtc->Log("cellRtcTickAddYears(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); + cellRtc.Log("cellRtcTickAddYears(pTick0=0x%x, pTick1=0x%x, iAdd=%d)", pTick0.addr(), pTick1.addr(), iAdd); rDateTime date = rDateTime((time_t)pTick1->tick); rDateSpan years = rDateSpan(iAdd, 0, 0, 0); @@ -292,7 +292,7 @@ int cellRtcTickAddYears(vm::ptr pTick0, vm::ptr pTick1 int cellRtcConvertUtcToLocalTime(vm::ptr pUtc, vm::ptr pLocalTime) { - cellRtc->Log("cellRtcConvertUtcToLocalTime(pUtc=0x%x, pLocalTime=0x%x)", pUtc.addr(), pLocalTime.addr()); + cellRtc.Log("cellRtcConvertUtcToLocalTime(pUtc=0x%x, pLocalTime=0x%x)", pUtc.addr(), pLocalTime.addr()); rDateTime time = rDateTime((time_t)pUtc->tick); rDateTime local_time = time.FromUTC(false); @@ -302,7 +302,7 @@ int cellRtcConvertUtcToLocalTime(vm::ptr pUtc, vm::ptr int cellRtcConvertLocalTimeToUtc(vm::ptr pLocalTime, vm::ptr pUtc) { - cellRtc->Log("cellRtcConvertLocalTimeToUtc(pLocalTime=0x%x, pUtc=0x%x)", pLocalTime.addr(), pUtc.addr()); + cellRtc.Log("cellRtcConvertLocalTimeToUtc(pLocalTime=0x%x, pUtc=0x%x)", pLocalTime.addr(), pUtc.addr()); rDateTime time = rDateTime((time_t)pLocalTime->tick); rDateTime utc_time = time.ToUTC(false); @@ -312,7 +312,7 @@ int cellRtcConvertLocalTimeToUtc(vm::ptr pLocalTime, vm::ptr pDateTime, vm::ptr puiDosTime) { - cellRtc->Log("cellRtcGetDosTime(pDateTime=0x%x, puiDosTime=0x%x)", pDateTime.addr(), puiDosTime.addr()); + cellRtc.Log("cellRtcGetDosTime(pDateTime=0x%x, puiDosTime=0x%x)", pDateTime.addr(), puiDosTime.addr()); // Convert to DOS time. rDateTime date_time = rDateTime(pDateTime->day, (rDateTime::Month)pDateTime->month.value(), pDateTime->year, pDateTime->hour, pDateTime->minute, pDateTime->second, (pDateTime->microsecond / 1000)); @@ -323,7 +323,7 @@ int cellRtcGetDosTime(vm::ptr pDateTime, vm::ptr puiDosTim int cellRtcGetTime_t(vm::ptr pDateTime, vm::ptr piTime) { - cellRtc->Log("cellRtcGetTime_t(pDateTime=0x%x, piTime=0x%x)", pDateTime.addr(), piTime.addr()); + cellRtc.Log("cellRtcGetTime_t(pDateTime=0x%x, piTime=0x%x)", pDateTime.addr(), piTime.addr()); // Convert to POSIX time_t. rDateTime date_time = rDateTime(pDateTime->day, (rDateTime::Month)pDateTime->month.value(), pDateTime->year, pDateTime->hour, pDateTime->minute, pDateTime->second, (pDateTime->microsecond / 1000)); @@ -335,7 +335,7 @@ int cellRtcGetTime_t(vm::ptr pDateTime, vm::ptr piTime) int cellRtcGetWin32FileTime(vm::ptr pDateTime, vm::ptr pulWin32FileTime) { - cellRtc->Log("cellRtcGetWin32FileTime(pDateTime=0x%x, pulWin32FileTime=0x%x)", pDateTime.addr(), pulWin32FileTime.addr()); + cellRtc.Log("cellRtcGetWin32FileTime(pDateTime=0x%x, pulWin32FileTime=0x%x)", pDateTime.addr(), pulWin32FileTime.addr()); // Convert to WIN32 FILETIME. rDateTime date_time = rDateTime(pDateTime->day, (rDateTime::Month)pDateTime->month.value(), pDateTime->year, pDateTime->hour, pDateTime->minute, pDateTime->second, (pDateTime->microsecond / 1000)); @@ -347,7 +347,7 @@ int cellRtcGetWin32FileTime(vm::ptr pDateTime, vm::ptr pul int cellRtcSetDosTime(vm::ptr pDateTime, u32 uiDosTime) { - cellRtc->Log("cellRtcSetDosTime(pDateTime=0x%x, uiDosTime=0x%x)", pDateTime.addr(), uiDosTime); + cellRtc.Log("cellRtcSetDosTime(pDateTime=0x%x, uiDosTime=0x%x)", pDateTime.addr(), uiDosTime); rDateTime date_time; rDateTime dos_time = date_time.SetFromDOS(uiDosTime); @@ -365,7 +365,7 @@ int cellRtcSetDosTime(vm::ptr pDateTime, u32 uiDosTime) int cellRtcSetTime_t(vm::ptr pDateTime, u64 iTime) { - cellRtc->Log("cellRtcSetTime_t(pDateTime=0x%x, iTime=0x%llx)", pDateTime.addr(), iTime); + cellRtc.Log("cellRtcSetTime_t(pDateTime=0x%x, iTime=0x%llx)", pDateTime.addr(), iTime); rDateTime date_time = rDateTime((time_t)iTime); @@ -382,7 +382,7 @@ int cellRtcSetTime_t(vm::ptr pDateTime, u64 iTime) int cellRtcSetWin32FileTime(vm::ptr pDateTime, u64 ulWin32FileTime) { - cellRtc->Log("cellRtcSetWin32FileTime(pDateTime_addr=0x%x, ulWin32FileTime=0x%llx)", pDateTime.addr(), ulWin32FileTime); + cellRtc.Log("cellRtcSetWin32FileTime(pDateTime_addr=0x%x, ulWin32FileTime=0x%llx)", pDateTime.addr(), ulWin32FileTime); rDateTime date_time = rDateTime((time_t)ulWin32FileTime); @@ -399,7 +399,7 @@ int cellRtcSetWin32FileTime(vm::ptr pDateTime, u64 ulWin32FileT int cellRtcIsLeapYear(s32 year) { - cellRtc->Log("cellRtcIsLeapYear(year=%d)", year); + cellRtc.Log("cellRtcIsLeapYear(year=%d)", year); rDateTime datetime; return datetime.IsLeapYear(year, rDateTime::Gregorian); @@ -407,7 +407,7 @@ int cellRtcIsLeapYear(s32 year) int cellRtcGetDaysInMonth(s32 year, s32 month) { - cellRtc->Log("cellRtcGetDaysInMonth(year=%d, month=%d)", year, month); + cellRtc.Log("cellRtcGetDaysInMonth(year=%d, month=%d)", year, month); rDateTime datetime; return datetime.GetNumberOfDays((rDateTime::Month) month, year, rDateTime::Gregorian); @@ -415,7 +415,7 @@ int cellRtcGetDaysInMonth(s32 year, s32 month) int cellRtcGetDayOfWeek(s32 year, s32 month, s32 day) { - cellRtc->Log("cellRtcGetDayOfWeek(year=%d, month=%d, day=%d)", year, month, day); + cellRtc.Log("cellRtcGetDayOfWeek(year=%d, month=%d, day=%d)", year, month, day); rDateTime datetime; datetime.SetToWeekDay((rDateTime::WeekDay) day, 1, (rDateTime::Month) month, year); @@ -424,7 +424,7 @@ int cellRtcGetDayOfWeek(s32 year, s32 month, s32 day) int cellRtcCheckValid(vm::ptr pTime) { - cellRtc->Log("cellRtcCheckValid(pTime=0x%x)", pTime.addr()); + cellRtc.Log("cellRtcCheckValid(pTime=0x%x)", pTime.addr()); if ((pTime->year < 1) || (pTime->year > 9999)) return CELL_RTC_ERROR_INVALID_YEAR; else if ((pTime->month < 1) || (pTime->month > 12)) return CELL_RTC_ERROR_INVALID_MONTH; @@ -438,55 +438,53 @@ int cellRtcCheckValid(vm::ptr pTime) int cellRtcCompareTick(vm::ptr pTick0, vm::ptr pTick1) { - cellRtc->Log("cellRtcCompareTick(pTick0=0x%x, pTick1=0x%x)", pTick0.addr(), pTick1.addr()); + cellRtc.Log("cellRtcCompareTick(pTick0=0x%x, pTick1=0x%x)", pTick0.addr(), pTick1.addr()); if (pTick0->tick < pTick1->tick) return -1; else if (pTick0->tick > pTick1->tick) return 1; else return CELL_OK; } -void cellRtc_init(Module *pxThis) +Module cellRtc("cellRtc", []() { - cellRtc = pxThis; + cellRtc.AddFunc(0x9dafc0d9, cellRtcGetCurrentTick); + cellRtc.AddFunc(0x32c941cf, cellRtcGetCurrentClock); + cellRtc.AddFunc(0x2cce9cf5, cellRtcGetCurrentClockLocalTime); - cellRtc->AddFunc(0x9dafc0d9, cellRtcGetCurrentTick); - cellRtc->AddFunc(0x32c941cf, cellRtcGetCurrentClock); - cellRtc->AddFunc(0x2cce9cf5, cellRtcGetCurrentClockLocalTime); + cellRtc.AddFunc(0x5491b9d5, cellRtcFormatRfc2822); + cellRtc.AddFunc(0xa07c3d2f, cellRtcFormatRfc2822LocalTime); + cellRtc.AddFunc(0xd9c0b463, cellRtcFormatRfc3339); + cellRtc.AddFunc(0x1324948a, cellRtcFormatRfc3339LocalTime); + cellRtc.AddFunc(0xc5bc0fac, cellRtcParseDateTime); + cellRtc.AddFunc(0xcf11c3d6, cellRtcParseRfc3339); - cellRtc->AddFunc(0x5491b9d5, cellRtcFormatRfc2822); - cellRtc->AddFunc(0xa07c3d2f, cellRtcFormatRfc2822LocalTime); - cellRtc->AddFunc(0xd9c0b463, cellRtcFormatRfc3339); - cellRtc->AddFunc(0x1324948a, cellRtcFormatRfc3339LocalTime); - cellRtc->AddFunc(0xc5bc0fac, cellRtcParseDateTime); - cellRtc->AddFunc(0xcf11c3d6, cellRtcParseRfc3339); - - cellRtc->AddFunc(0xc7bdb7eb, cellRtcGetTick); - cellRtc->AddFunc(0x99b13034, cellRtcSetTick); - cellRtc->AddFunc(0x269a1882, cellRtcTickAddTicks); - cellRtc->AddFunc(0xf8509925, cellRtcTickAddMicroseconds); - cellRtc->AddFunc(0xccce71bd, cellRtcTickAddSeconds); - cellRtc->AddFunc(0x2f010bfa, cellRtcTickAddMinutes); - cellRtc->AddFunc(0xd41d3bd2, cellRtcTickAddHours); - cellRtc->AddFunc(0x75744e2a, cellRtcTickAddDays); - cellRtc->AddFunc(0x64c63fd5, cellRtcTickAddWeeks); - cellRtc->AddFunc(0xe0ecbb45, cellRtcTickAddMonths); - cellRtc->AddFunc(0x332a74dd, cellRtcTickAddYears); - cellRtc->AddFunc(0xc48d5002, cellRtcConvertUtcToLocalTime); - cellRtc->AddFunc(0x46ca7fe0, cellRtcConvertLocalTimeToUtc); + cellRtc.AddFunc(0xc7bdb7eb, cellRtcGetTick); + cellRtc.AddFunc(0x99b13034, cellRtcSetTick); + cellRtc.AddFunc(0x269a1882, cellRtcTickAddTicks); + cellRtc.AddFunc(0xf8509925, cellRtcTickAddMicroseconds); + cellRtc.AddFunc(0xccce71bd, cellRtcTickAddSeconds); + cellRtc.AddFunc(0x2f010bfa, cellRtcTickAddMinutes); + cellRtc.AddFunc(0xd41d3bd2, cellRtcTickAddHours); + cellRtc.AddFunc(0x75744e2a, cellRtcTickAddDays); + cellRtc.AddFunc(0x64c63fd5, cellRtcTickAddWeeks); + cellRtc.AddFunc(0xe0ecbb45, cellRtcTickAddMonths); + cellRtc.AddFunc(0x332a74dd, cellRtcTickAddYears); + cellRtc.AddFunc(0xc48d5002, cellRtcConvertUtcToLocalTime); + cellRtc.AddFunc(0x46ca7fe0, cellRtcConvertLocalTimeToUtc); // (TODO: Time Information Manipulation Functions missing) - cellRtc->AddFunc(0xdfff32cf, cellRtcGetDosTime); - cellRtc->AddFunc(0xcb90c761, cellRtcGetTime_t); - cellRtc->AddFunc(0xe7086f05, cellRtcGetWin32FileTime); - cellRtc->AddFunc(0x9598d4b3, cellRtcSetDosTime); - cellRtc->AddFunc(0xbb543189, cellRtcSetTime_t); - cellRtc->AddFunc(0x5f68c268, cellRtcSetWin32FileTime); + cellRtc.AddFunc(0xdfff32cf, cellRtcGetDosTime); + cellRtc.AddFunc(0xcb90c761, cellRtcGetTime_t); + cellRtc.AddFunc(0xe7086f05, cellRtcGetWin32FileTime); + cellRtc.AddFunc(0x9598d4b3, cellRtcSetDosTime); + cellRtc.AddFunc(0xbb543189, cellRtcSetTime_t); + cellRtc.AddFunc(0x5f68c268, cellRtcSetWin32FileTime); - cellRtc->AddFunc(0x5316b4a8, cellRtcIsLeapYear); - cellRtc->AddFunc(0x5b6a0a1d, cellRtcGetDaysInMonth); - cellRtc->AddFunc(0xc2d8cf95, cellRtcGetDayOfWeek); - cellRtc->AddFunc(0x7f1086e6, cellRtcCheckValid); + cellRtc.AddFunc(0x5316b4a8, cellRtcIsLeapYear); + cellRtc.AddFunc(0x5b6a0a1d, cellRtcGetDaysInMonth); + cellRtc.AddFunc(0xc2d8cf95, cellRtcGetDayOfWeek); + cellRtc.AddFunc(0x7f1086e6, cellRtcCheckValid); - cellRtc->AddFunc(0xfb51fc61, cellRtcCompareTick); -} + cellRtc.AddFunc(0xfb51fc61, cellRtcCompareTick); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp index 1e4cdc6741..77c71102db 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSail.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSail.cpp @@ -6,11 +6,11 @@ #include "cellSail.h" #include "cellPamf.h" -Module *cellSail = nullptr; +extern Module cellSail; int cellSailMemAllocatorInitialize(vm::ptr pSelf, vm::ptr pCallbacks) { - cellSail->Warning("cellSailMemAllocatorInitialize(pSelf_addr=0x%x, pCallbacks_addr=0x%x)", pSelf.addr(), pCallbacks.addr()); + cellSail.Warning("cellSailMemAllocatorInitialize(pSelf_addr=0x%x, pCallbacks_addr=0x%x)", pSelf.addr(), pCallbacks.addr()); pSelf->callbacks = pCallbacks; // TODO: Create a cellSail thread @@ -74,7 +74,7 @@ int cellSailDescriptorGetMediaInfo() int cellSailDescriptorSetAutoSelection(vm::ptr pSelf, bool autoSelection) { - cellSail->Warning("cellSailDescriptorSetAutoSelection(pSelf_addr=0x%x, autoSelection=%s)", pSelf.addr(), autoSelection ? "true" : "false"); + cellSail.Warning("cellSailDescriptorSetAutoSelection(pSelf_addr=0x%x, autoSelection=%s)", pSelf.addr(), autoSelection ? "true" : "false"); if (pSelf) { pSelf->autoSelection = autoSelection; @@ -86,7 +86,7 @@ int cellSailDescriptorSetAutoSelection(vm::ptr pSelf, bool a int cellSailDescriptorIsAutoSelection(vm::ptr pSelf) { - cellSail->Warning("cellSailDescriptorIsAutoSelection(pSelf_addr=0x%x)", pSelf.addr()); + cellSail.Warning("cellSailDescriptorIsAutoSelection(pSelf_addr=0x%x)", pSelf.addr()); if (pSelf) return pSelf->autoSelection; @@ -96,7 +96,7 @@ int cellSailDescriptorIsAutoSelection(vm::ptr pSelf) int cellSailDescriptorCreateDatabase(vm::ptr pSelf, vm::ptr pDatabase, u32 size, u64 arg) { - cellSail->Warning("cellSailDescriptorCreateDatabase(pSelf=0x%x, pDatabase=0x%x, size=0x%x, arg=0x%x", pSelf.addr(), pDatabase.addr(), size, arg); + cellSail.Warning("cellSailDescriptorCreateDatabase(pSelf=0x%x, pDatabase=0x%x, size=0x%x, arg=0x%x", pSelf.addr(), pDatabase.addr(), size, arg); switch ((s32)pSelf->streamType) { case CELL_SAIL_STREAM_PAMF: @@ -107,7 +107,7 @@ int cellSailDescriptorCreateDatabase(vm::ptr pSelf, vm::ptr< break; } default: - cellSail->Error("Unhandled stream type: %d", pSelf->streamType); + cellSail.Error("Unhandled stream type: %d", pSelf->streamType); } return CELL_OK; @@ -518,7 +518,7 @@ int cellSailPlayerInitialize() int cellSailPlayerInitialize2(vm::ptr pSelf, vm::ptr pAllocator, vm::ptr pCallback, u64 callbackArg, vm::ptr pAttribute, vm::ptr pResource) { - cellSail->Warning("cellSailPlayerInitialize2(pSelf_addr=0x%x, pAllocator_addr=0x%x, pCallback=0x%x, callbackArg=%d, pAttribute_addr=0x%x, pResource=0x%x)", pSelf.addr(), + cellSail.Warning("cellSailPlayerInitialize2(pSelf_addr=0x%x, pAllocator_addr=0x%x, pCallback=0x%x, callbackArg=%d, pAttribute_addr=0x%x, pResource=0x%x)", pSelf.addr(), pAllocator.addr(), pCallback.addr(), callbackArg, pAttribute.addr(), pResource.addr()); pSelf->allocator = pAllocator; @@ -616,7 +616,7 @@ int cellSailPlayerBoot() int cellSailPlayerAddDescriptor(vm::ptr pSelf, vm::ptr pDesc) { - cellSail->Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); + cellSail.Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); if (pSelf && pSelf->descriptors < 3 && pDesc) { @@ -626,7 +626,7 @@ int cellSailPlayerAddDescriptor(vm::ptr pSelf, vm::ptrError("Descriptor limit reached or the descriptor is unspecified! This should never happen, report this to a developer."); + cellSail.Error("Descriptor limit reached or the descriptor is unspecified! This should never happen, report this to a developer."); } return CELL_OK; @@ -634,7 +634,7 @@ int cellSailPlayerAddDescriptor(vm::ptr pSelf, vm::ptr pSelf, s32 streamType, vm::ptr pMediaInfo, vm::ptr pUri, vm::ptr ppDesc) { - cellSail->Warning("cellSailPlayerCreateDescriptor(pSelf_addr=0x%x, streamType=%d, pMediaInfo_addr=0x%x, pUri_addr=0x%x, ppDesc_addr=0x%x)", pSelf.addr(), streamType, + cellSail.Warning("cellSailPlayerCreateDescriptor(pSelf_addr=0x%x, streamType=%d, pMediaInfo_addr=0x%x, pUri_addr=0x%x, ppDesc_addr=0x%x)", pSelf.addr(), streamType, pMediaInfo.addr(), pUri.addr(), ppDesc.addr()); u32 descriptorAddress = Memory.Alloc(sizeof(CellSailDescriptor), 1); @@ -668,18 +668,18 @@ int cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType descriptor->internalData[1] = sp_; } else - cellSail->Warning("Couldn't open PAMF: %s", uri.c_str()); + cellSail.Warning("Couldn't open PAMF: %s", uri.c_str()); } else - cellSail->Warning("Unhandled uri: %s", uri.c_str()); + cellSail.Warning("Unhandled uri: %s", uri.c_str()); break; } default: - cellSail->Error("Unhandled stream type: %d", streamType); + cellSail.Error("Unhandled stream type: %d", streamType); } - //cellSail->Todo("pSelf_addr=0x%x, pDesc_addr=0x%x", pSelf.addr(), descriptor.addr()); + //cellSail.Todo("pSelf_addr=0x%x, pDesc_addr=0x%x", pSelf.addr(), descriptor.addr()); //cellSailPlayerAddDescriptor(pSelf, ppDesc); return CELL_OK; @@ -687,7 +687,7 @@ int cellSailPlayerCreateDescriptor(vm::ptr pSelf, s32 streamType int cellSailPlayerDestroyDescriptor(vm::ptr pSelf, vm::ptr pDesc) { - cellSail->Todo("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); + cellSail.Todo("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), pDesc.addr()); if (pDesc->registered) return CELL_SAIL_ERROR_INVALID_STATE; @@ -697,7 +697,7 @@ int cellSailPlayerDestroyDescriptor(vm::ptr pSelf, vm::ptr pSelf, vm::ptr ppDesc) { - cellSail->Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), ppDesc.addr()); + cellSail.Warning("cellSailPlayerAddDescriptor(pSelf_addr=0x%x, pDesc_addr=0x%x)", pSelf.addr(), ppDesc.addr()); if (pSelf->descriptors > 0) { @@ -711,7 +711,7 @@ int cellSailPlayerRemoveDescriptor(vm::ptr pSelf, vm::ptr pSelf) { - cellSail->Warning("cellSailPlayerGetDescriptorCount(pSelf_addr=0x%x)", pSelf.addr()); + cellSail.Warning("cellSailPlayerGetDescriptorCount(pSelf_addr=0x%x)", pSelf.addr()); return pSelf->descriptors; } @@ -813,19 +813,19 @@ int cellSailPlayerCancel() int cellSailPlayerSetPaused(vm::ptr pSelf, bool paused) { - cellSail->Todo("cellSailPlayerSetPaused(pSelf_addr=0x%x, paused=)", pSelf.addr(), paused); + cellSail.Todo("cellSailPlayerSetPaused(pSelf_addr=0x%x, paused=)", pSelf.addr(), paused); return CELL_OK; } int cellSailPlayerIsPaused(vm::ptr pSelf) { - cellSail->Warning("cellSailPlayerIsPaused(pSelf_addr=0x%x)", pSelf.addr()); + cellSail.Warning("cellSailPlayerIsPaused(pSelf_addr=0x%x)", pSelf.addr()); return pSelf->paused; } int cellSailPlayerSetRepeatMode(vm::ptr pSelf, s32 repeatMode, vm::ptr pCommand) { - cellSail->Warning("cellSailPlayerSetRepeatMode(pSelf_addr=0x%x, repeatMode=%d, pCommand_addr=0x%x)", pSelf.addr(), repeatMode, pCommand.addr()); + cellSail.Warning("cellSailPlayerSetRepeatMode(pSelf_addr=0x%x, repeatMode=%d, pCommand_addr=0x%x)", pSelf.addr(), repeatMode, pCommand.addr()); pSelf->repeatMode = repeatMode; pSelf->playbackCommand = pCommand; @@ -835,7 +835,7 @@ int cellSailPlayerSetRepeatMode(vm::ptr pSelf, s32 repeatMode, v int cellSailPlayerGetRepeatMode(vm::ptr pSelf, vm::ptr pCommand) { - cellSail->Warning("cellSailPlayerGetRepeatMode(pSelf_addr=0x%x, pCommand_addr=0x%x)", pSelf.addr(), pCommand.addr()); + cellSail.Warning("cellSailPlayerGetRepeatMode(pSelf_addr=0x%x, pCommand_addr=0x%x)", pSelf.addr(), pCommand.addr()); pCommand = pSelf->playbackCommand; @@ -878,146 +878,143 @@ int cellSailPlayerUnregisterSource() return CELL_OK; } -void cellSail_init(Module *pxThis) +Module cellSail("cellSail", []() { - cellSail = pxThis; + cellSail.AddFunc(0x346ebba3, cellSailMemAllocatorInitialize); - cellSail->AddFunc(0x346ebba3, cellSailMemAllocatorInitialize); + cellSail.AddFunc(0x4cc54f8e, cellSailFutureInitialize); + cellSail.AddFunc(0x9553af65, cellSailFutureFinalize); + cellSail.AddFunc(0x0c4cb439, cellSailFutureReset); + cellSail.AddFunc(0xa37fed15, cellSailFutureSet); + cellSail.AddFunc(0x3a2d806c, cellSailFutureGet); + cellSail.AddFunc(0x51ecf361, cellSailFutureIsDone); - cellSail->AddFunc(0x4cc54f8e, cellSailFutureInitialize); - cellSail->AddFunc(0x9553af65, cellSailFutureFinalize); - cellSail->AddFunc(0x0c4cb439, cellSailFutureReset); - cellSail->AddFunc(0xa37fed15, cellSailFutureSet); - cellSail->AddFunc(0x3a2d806c, cellSailFutureGet); - cellSail->AddFunc(0x51ecf361, cellSailFutureIsDone); + cellSail.AddFunc(0xd5f9a15b, cellSailDescriptorGetStreamType); + cellSail.AddFunc(0x4c191088, cellSailDescriptorGetUri); + cellSail.AddFunc(0xbd1635f4, cellSailDescriptorGetMediaInfo); + cellSail.AddFunc(0x76b1a425, cellSailDescriptorSetAutoSelection); + cellSail.AddFunc(0x277adf21, cellSailDescriptorIsAutoSelection); + cellSail.AddFunc(0x0abb318b, cellSailDescriptorCreateDatabase); + cellSail.AddFunc(0x28336e89, cellSailDescriptorDestroyDatabase); + cellSail.AddFunc(0xc044fab1, cellSailDescriptorOpen); + cellSail.AddFunc(0x15fd6a2a, cellSailDescriptorClose); + cellSail.AddFunc(0x0d0c2f0c, cellSailDescriptorSetEs); + cellSail.AddFunc(0xdf5553ef, cellSailDescriptorClearEs); + cellSail.AddFunc(0xac9c3b1f, cellSailDescriptorGetCapabilities); + cellSail.AddFunc(0x92590d52, cellSailDescriptorInquireCapability); + cellSail.AddFunc(0xee94b99b, cellSailDescriptorSetParameter); - cellSail->AddFunc(0xd5f9a15b, cellSailDescriptorGetStreamType); - cellSail->AddFunc(0x4c191088, cellSailDescriptorGetUri); - cellSail->AddFunc(0xbd1635f4, cellSailDescriptorGetMediaInfo); - cellSail->AddFunc(0x76b1a425, cellSailDescriptorSetAutoSelection); - cellSail->AddFunc(0x277adf21, cellSailDescriptorIsAutoSelection); - cellSail->AddFunc(0x0abb318b, cellSailDescriptorCreateDatabase); - cellSail->AddFunc(0x28336e89, cellSailDescriptorDestroyDatabase); - cellSail->AddFunc(0xc044fab1, cellSailDescriptorOpen); - cellSail->AddFunc(0x15fd6a2a, cellSailDescriptorClose); - cellSail->AddFunc(0x0d0c2f0c, cellSailDescriptorSetEs); - cellSail->AddFunc(0xdf5553ef, cellSailDescriptorClearEs); - cellSail->AddFunc(0xac9c3b1f, cellSailDescriptorGetCapabilities); - cellSail->AddFunc(0x92590d52, cellSailDescriptorInquireCapability); - cellSail->AddFunc(0xee94b99b, cellSailDescriptorSetParameter); + cellSail.AddFunc(0x3d0d3b72, cellSailSoundAdapterInitialize); + cellSail.AddFunc(0xd1462438, cellSailSoundAdapterFinalize); + cellSail.AddFunc(0x1c9d5e5a, cellSailSoundAdapterSetPreferredFormat); + cellSail.AddFunc(0x7eb8d6b5, cellSailSoundAdapterGetFrame); + cellSail.AddFunc(0xf25f197d, cellSailSoundAdapterGetFormat); + cellSail.AddFunc(0xeec22809, cellSailSoundAdapterUpdateAvSync); + cellSail.AddFunc(0x4ae979df, cellSailSoundAdapterPtsToTimePosition); - cellSail->AddFunc(0x3d0d3b72, cellSailSoundAdapterInitialize); - cellSail->AddFunc(0xd1462438, cellSailSoundAdapterFinalize); - cellSail->AddFunc(0x1c9d5e5a, cellSailSoundAdapterSetPreferredFormat); - cellSail->AddFunc(0x7eb8d6b5, cellSailSoundAdapterGetFrame); - cellSail->AddFunc(0xf25f197d, cellSailSoundAdapterGetFormat); - cellSail->AddFunc(0xeec22809, cellSailSoundAdapterUpdateAvSync); - cellSail->AddFunc(0x4ae979df, cellSailSoundAdapterPtsToTimePosition); + cellSail.AddFunc(0x1c983864, cellSailGraphicsAdapterInitialize); + cellSail.AddFunc(0x76488bb1, cellSailGraphicsAdapterFinalize); + cellSail.AddFunc(0x2e3ccb5e, cellSailGraphicsAdapterSetPreferredFormat); + cellSail.AddFunc(0x0247c69e, cellSailGraphicsAdapterGetFrame); + cellSail.AddFunc(0x018281a8, cellSailGraphicsAdapterGetFrame2); + cellSail.AddFunc(0xffd58aa4, cellSailGraphicsAdapterGetFormat); + cellSail.AddFunc(0x44a20e79, cellSailGraphicsAdapterUpdateAvSync); + cellSail.AddFunc(0x1872331b, cellSailGraphicsAdapterPtsToTimePosition); - cellSail->AddFunc(0x1c983864, cellSailGraphicsAdapterInitialize); - cellSail->AddFunc(0x76488bb1, cellSailGraphicsAdapterFinalize); - cellSail->AddFunc(0x2e3ccb5e, cellSailGraphicsAdapterSetPreferredFormat); - cellSail->AddFunc(0x0247c69e, cellSailGraphicsAdapterGetFrame); - cellSail->AddFunc(0x018281a8, cellSailGraphicsAdapterGetFrame2); - cellSail->AddFunc(0xffd58aa4, cellSailGraphicsAdapterGetFormat); - cellSail->AddFunc(0x44a20e79, cellSailGraphicsAdapterUpdateAvSync); - cellSail->AddFunc(0x1872331b, cellSailGraphicsAdapterPtsToTimePosition); + cellSail.AddFunc(0x3dd9639a, cellSailAuReceiverInitialize); + cellSail.AddFunc(0xed58e3ec, cellSailAuReceiverFinalize); + cellSail.AddFunc(0x3a1132ed, cellSailAuReceiverGet); - cellSail->AddFunc(0x3dd9639a, cellSailAuReceiverInitialize); - cellSail->AddFunc(0xed58e3ec, cellSailAuReceiverFinalize); - cellSail->AddFunc(0x3a1132ed, cellSailAuReceiverGet); + cellSail.AddFunc(0x67b4d01f, cellSailRendererAudioInitialize); + cellSail.AddFunc(0x06dd4174, cellSailRendererAudioFinalize); + cellSail.AddFunc(0xb7b4ecee, cellSailRendererAudioNotifyCallCompleted); + cellSail.AddFunc(0xf841a537, cellSailRendererAudioNotifyFrameDone); + cellSail.AddFunc(0x325039b9, cellSailRendererAudioNotifyOutputEos); - cellSail->AddFunc(0x67b4d01f, cellSailRendererAudioInitialize); - cellSail->AddFunc(0x06dd4174, cellSailRendererAudioFinalize); - cellSail->AddFunc(0xb7b4ecee, cellSailRendererAudioNotifyCallCompleted); - cellSail->AddFunc(0xf841a537, cellSailRendererAudioNotifyFrameDone); - cellSail->AddFunc(0x325039b9, cellSailRendererAudioNotifyOutputEos); + cellSail.AddFunc(0x8d1ff475, cellSailRendererVideoInitialize); + cellSail.AddFunc(0x47055fea, cellSailRendererVideoFinalize); + cellSail.AddFunc(0x954f48f8, cellSailRendererVideoNotifyCallCompleted); + cellSail.AddFunc(0x5f77e8df, cellSailRendererVideoNotifyFrameDone); + cellSail.AddFunc(0xdff1cda2, cellSailRendererVideoNotifyOutputEos); - cellSail->AddFunc(0x8d1ff475, cellSailRendererVideoInitialize); - cellSail->AddFunc(0x47055fea, cellSailRendererVideoFinalize); - cellSail->AddFunc(0x954f48f8, cellSailRendererVideoNotifyCallCompleted); - cellSail->AddFunc(0x5f77e8df, cellSailRendererVideoNotifyFrameDone); - cellSail->AddFunc(0xdff1cda2, cellSailRendererVideoNotifyOutputEos); + cellSail.AddFunc(0x9d30bdce, cellSailSourceInitialize); + cellSail.AddFunc(0xee724c99, cellSailSourceFinalize); + cellSail.AddFunc(0x764ec2d2, cellSailSourceNotifyCallCompleted); + cellSail.AddFunc(0x54c53688, cellSailSourceNotifyInputEos); + cellSail.AddFunc(0x95ee1695, cellSailSourceNotifyStreamOut); + cellSail.AddFunc(0xf289f0cd, cellSailSourceNotifySessionError); + cellSail.AddFunc(0xf4009a94, cellSailSourceNotifyMediaStateChanged); + //cellSail.AddFunc(, cellSailSourceCheck); + cellSail.AddFunc(0x3df98d41, cellSailSourceNotifyOpenCompleted); + cellSail.AddFunc(0x640c7278, cellSailSourceNotifyStartCompleted); + cellSail.AddFunc(0x7473970a, cellSailSourceNotifyStopCompleted); + cellSail.AddFunc(0x946ecca0, cellSailSourceNotifyReadCompleted); + cellSail.AddFunc(0xbdb2251a, cellSailSourceSetDiagHandler); + cellSail.AddFunc(0xc457b203, cellSailSourceNotifyCloseCompleted); - cellSail->AddFunc(0x9d30bdce, cellSailSourceInitialize); - cellSail->AddFunc(0xee724c99, cellSailSourceFinalize); - cellSail->AddFunc(0x764ec2d2, cellSailSourceNotifyCallCompleted); - cellSail->AddFunc(0x54c53688, cellSailSourceNotifyInputEos); - cellSail->AddFunc(0x95ee1695, cellSailSourceNotifyStreamOut); - cellSail->AddFunc(0xf289f0cd, cellSailSourceNotifySessionError); - cellSail->AddFunc(0xf4009a94, cellSailSourceNotifyMediaStateChanged); - //cellSail->AddFunc(, cellSailSourceCheck); - cellSail->AddFunc(0x3df98d41, cellSailSourceNotifyOpenCompleted); - cellSail->AddFunc(0x640c7278, cellSailSourceNotifyStartCompleted); - cellSail->AddFunc(0x7473970a, cellSailSourceNotifyStopCompleted); - cellSail->AddFunc(0x946ecca0, cellSailSourceNotifyReadCompleted); - cellSail->AddFunc(0xbdb2251a, cellSailSourceSetDiagHandler); - cellSail->AddFunc(0xc457b203, cellSailSourceNotifyCloseCompleted); + cellSail.AddFunc(0xb980b76e, cellSailMp4MovieGetBrand); + cellSail.AddFunc(0xd4049de0, cellSailMp4MovieIsCompatibleBrand); + cellSail.AddFunc(0x5783a454, cellSailMp4MovieGetMovieInfo); + cellSail.AddFunc(0x5faf802b, cellSailMp4MovieGetTrackByIndex); + cellSail.AddFunc(0x85b07126, cellSailMp4MovieGetTrackById); + cellSail.AddFunc(0xc2d90ec9, cellSailMp4MovieGetTrackByTypeAndIndex); + cellSail.AddFunc(0xa48be428, cellSailMp4TrackGetTrackInfo); + cellSail.AddFunc(0x72236ec1, cellSailMp4TrackGetTrackReferenceCount); + cellSail.AddFunc(0x5f44f64f, cellSailMp4TrackGetTrackReference); + //cellSail.AddFunc(, cellSailMp4ConvertTimeScale); - cellSail->AddFunc(0xb980b76e, cellSailMp4MovieGetBrand); - cellSail->AddFunc(0xd4049de0, cellSailMp4MovieIsCompatibleBrand); - cellSail->AddFunc(0x5783a454, cellSailMp4MovieGetMovieInfo); - cellSail->AddFunc(0x5faf802b, cellSailMp4MovieGetTrackByIndex); - cellSail->AddFunc(0x85b07126, cellSailMp4MovieGetTrackById); - cellSail->AddFunc(0xc2d90ec9, cellSailMp4MovieGetTrackByTypeAndIndex); - cellSail->AddFunc(0xa48be428, cellSailMp4TrackGetTrackInfo); - cellSail->AddFunc(0x72236ec1, cellSailMp4TrackGetTrackReferenceCount); - cellSail->AddFunc(0x5f44f64f, cellSailMp4TrackGetTrackReference); - //cellSail->AddFunc(, cellSailMp4ConvertTimeScale); - - cellSail->AddFunc(0x6e83f5c0, cellSailAviMovieGetMovieInfo); - cellSail->AddFunc(0x3e908c56, cellSailAviMovieGetStreamByIndex); - cellSail->AddFunc(0xddebd2a5, cellSailAviMovieGetStreamByTypeAndIndex); - cellSail->AddFunc(0x10298371, cellSailAviMovieGetHeader); - cellSail->AddFunc(0xc09e2f23, cellSailAviStreamGetMediaType); - cellSail->AddFunc(0xcc3cca60, cellSailAviStreamGetHeader); - - cellSail->AddFunc(0x17932b26, cellSailPlayerInitialize); - cellSail->AddFunc(0x23654375, cellSailPlayerInitialize2); - cellSail->AddFunc(0x18b4629d, cellSailPlayerFinalize); - cellSail->AddFunc(0xbedccc74, cellSailPlayerRegisterSource); - cellSail->AddFunc(0x186b98d3, cellSailPlayerGetRegisteredProtocols); - cellSail->AddFunc(0x1139a206, cellSailPlayerSetSoundAdapter); - cellSail->AddFunc(0x18bcd21b, cellSailPlayerSetGraphicsAdapter); - cellSail->AddFunc(0xf5747e1f, cellSailPlayerSetAuReceiver); - cellSail->AddFunc(0x92eaf6ca, cellSailPlayerSetRendererAudio); - cellSail->AddFunc(0xecf56150, cellSailPlayerSetRendererVideo); - cellSail->AddFunc(0x5f7c7a6f, cellSailPlayerSetParameter); - cellSail->AddFunc(0x952269c9, cellSailPlayerGetParameter); - cellSail->AddFunc(0x6f0b1002, cellSailPlayerSubscribeEvent); - cellSail->AddFunc(0x69793952, cellSailPlayerUnsubscribeEvent); - cellSail->AddFunc(0x47632810, cellSailPlayerReplaceEventHandler); - cellSail->AddFunc(0xbdf21b0f, cellSailPlayerBoot); - cellSail->AddFunc(0xd7938b8d, cellSailPlayerCreateDescriptor); - cellSail->AddFunc(0xfc839bd4, cellSailPlayerDestroyDescriptor); - cellSail->AddFunc(0x7c8dff3b, cellSailPlayerAddDescriptor); - cellSail->AddFunc(0x9897fbd1, cellSailPlayerRemoveDescriptor); - cellSail->AddFunc(0x752f8585, cellSailPlayerGetDescriptorCount); - cellSail->AddFunc(0x75fca288, cellSailPlayerGetCurrentDescriptor); - cellSail->AddFunc(0x34ecc1b9, cellSailPlayerOpenStream); - cellSail->AddFunc(0x85beffcc, cellSailPlayerCloseStream); - cellSail->AddFunc(0x145f9b11, cellSailPlayerOpenEsAudio); - cellSail->AddFunc(0x477501f6, cellSailPlayerOpenEsVideo); - cellSail->AddFunc(0xa849d0a7, cellSailPlayerOpenEsUser); - cellSail->AddFunc(0x4fa5ad09, cellSailPlayerReopenEsAudio); - cellSail->AddFunc(0xf60a8a69, cellSailPlayerReopenEsVideo); - cellSail->AddFunc(0x7b6fa92e, cellSailPlayerReopenEsUser); - cellSail->AddFunc(0xbf9b8d72, cellSailPlayerCloseEsAudio); - cellSail->AddFunc(0x07924359, cellSailPlayerCloseEsVideo); - cellSail->AddFunc(0xaed9d6cd, cellSailPlayerCloseEsUser); - cellSail->AddFunc(0xe535b0d3, cellSailPlayerStart); - cellSail->AddFunc(0xeba8d4ec, cellSailPlayerStop); - cellSail->AddFunc(0x26563ddc, cellSailPlayerNext); - cellSail->AddFunc(0x950d53c1, cellSailPlayerCancel); - cellSail->AddFunc(0xd1d55a90, cellSailPlayerSetPaused); - cellSail->AddFunc(0xaafa17b8, cellSailPlayerIsPaused); - cellSail->AddFunc(0xfc5baf8a, cellSailPlayerSetRepeatMode); - cellSail->AddFunc(0x38144ecf, cellSailPlayerGetRepeatMode); - cellSail->AddFunc(0x91d287f6, cellSailPlayerSetEsAudioMuted); - cellSail->AddFunc(0xf1446a40, cellSailPlayerSetEsVideoMuted); - cellSail->AddFunc(0x09de25fd, cellSailPlayerIsEsAudioMuted); - cellSail->AddFunc(0xdbe32ed4, cellSailPlayerIsEsVideoMuted); - cellSail->AddFunc(0xcc987ba6, cellSailPlayerDumpImage); - cellSail->AddFunc(0x025b4974, cellSailPlayerUnregisterSource); -} + cellSail.AddFunc(0x6e83f5c0, cellSailAviMovieGetMovieInfo); + cellSail.AddFunc(0x3e908c56, cellSailAviMovieGetStreamByIndex); + cellSail.AddFunc(0xddebd2a5, cellSailAviMovieGetStreamByTypeAndIndex); + cellSail.AddFunc(0x10298371, cellSailAviMovieGetHeader); + cellSail.AddFunc(0xc09e2f23, cellSailAviStreamGetMediaType); + cellSail.AddFunc(0xcc3cca60, cellSailAviStreamGetHeader); + cellSail.AddFunc(0x17932b26, cellSailPlayerInitialize); + cellSail.AddFunc(0x23654375, cellSailPlayerInitialize2); + cellSail.AddFunc(0x18b4629d, cellSailPlayerFinalize); + cellSail.AddFunc(0xbedccc74, cellSailPlayerRegisterSource); + cellSail.AddFunc(0x186b98d3, cellSailPlayerGetRegisteredProtocols); + cellSail.AddFunc(0x1139a206, cellSailPlayerSetSoundAdapter); + cellSail.AddFunc(0x18bcd21b, cellSailPlayerSetGraphicsAdapter); + cellSail.AddFunc(0xf5747e1f, cellSailPlayerSetAuReceiver); + cellSail.AddFunc(0x92eaf6ca, cellSailPlayerSetRendererAudio); + cellSail.AddFunc(0xecf56150, cellSailPlayerSetRendererVideo); + cellSail.AddFunc(0x5f7c7a6f, cellSailPlayerSetParameter); + cellSail.AddFunc(0x952269c9, cellSailPlayerGetParameter); + cellSail.AddFunc(0x6f0b1002, cellSailPlayerSubscribeEvent); + cellSail.AddFunc(0x69793952, cellSailPlayerUnsubscribeEvent); + cellSail.AddFunc(0x47632810, cellSailPlayerReplaceEventHandler); + cellSail.AddFunc(0xbdf21b0f, cellSailPlayerBoot); + cellSail.AddFunc(0xd7938b8d, cellSailPlayerCreateDescriptor); + cellSail.AddFunc(0xfc839bd4, cellSailPlayerDestroyDescriptor); + cellSail.AddFunc(0x7c8dff3b, cellSailPlayerAddDescriptor); + cellSail.AddFunc(0x9897fbd1, cellSailPlayerRemoveDescriptor); + cellSail.AddFunc(0x752f8585, cellSailPlayerGetDescriptorCount); + cellSail.AddFunc(0x75fca288, cellSailPlayerGetCurrentDescriptor); + cellSail.AddFunc(0x34ecc1b9, cellSailPlayerOpenStream); + cellSail.AddFunc(0x85beffcc, cellSailPlayerCloseStream); + cellSail.AddFunc(0x145f9b11, cellSailPlayerOpenEsAudio); + cellSail.AddFunc(0x477501f6, cellSailPlayerOpenEsVideo); + cellSail.AddFunc(0xa849d0a7, cellSailPlayerOpenEsUser); + cellSail.AddFunc(0x4fa5ad09, cellSailPlayerReopenEsAudio); + cellSail.AddFunc(0xf60a8a69, cellSailPlayerReopenEsVideo); + cellSail.AddFunc(0x7b6fa92e, cellSailPlayerReopenEsUser); + cellSail.AddFunc(0xbf9b8d72, cellSailPlayerCloseEsAudio); + cellSail.AddFunc(0x07924359, cellSailPlayerCloseEsVideo); + cellSail.AddFunc(0xaed9d6cd, cellSailPlayerCloseEsUser); + cellSail.AddFunc(0xe535b0d3, cellSailPlayerStart); + cellSail.AddFunc(0xeba8d4ec, cellSailPlayerStop); + cellSail.AddFunc(0x26563ddc, cellSailPlayerNext); + cellSail.AddFunc(0x950d53c1, cellSailPlayerCancel); + cellSail.AddFunc(0xd1d55a90, cellSailPlayerSetPaused); + cellSail.AddFunc(0xaafa17b8, cellSailPlayerIsPaused); + cellSail.AddFunc(0xfc5baf8a, cellSailPlayerSetRepeatMode); + cellSail.AddFunc(0x38144ecf, cellSailPlayerGetRepeatMode); + cellSail.AddFunc(0x91d287f6, cellSailPlayerSetEsAudioMuted); + cellSail.AddFunc(0xf1446a40, cellSailPlayerSetEsVideoMuted); + cellSail.AddFunc(0x09de25fd, cellSailPlayerIsEsAudioMuted); + cellSail.AddFunc(0xdbe32ed4, cellSailPlayerIsEsVideoMuted); + cellSail.AddFunc(0xcc987ba6, cellSailPlayerDumpImage); + cellSail.AddFunc(0x025b4974, cellSailPlayerUnregisterSource); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index 79ad2d72bc..7c45075861 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -18,7 +18,7 @@ #include #endif -extern Module *cellSysutil; +extern Module cellSysutil; // Auxiliary Classes class sortSaveDataEntry @@ -80,7 +80,7 @@ void addSaveDataEntry(std::vector& saveEntries, const std::string u64 mtime = 0; u64 ctime = 0; - cellSysutil->Error("Running _stat in cellSaveData. Please report this to a RPCS3 developer!"); + cellSysutil.Error("Running _stat in cellSaveData. Please report this to a RPCS3 developer!"); std::string real_path; struct stat buf; @@ -88,7 +88,7 @@ void addSaveDataEntry(std::vector& saveEntries, const std::string Emu.GetVFS().GetDevice(f.GetPath(), real_path); if (stat(real_path.c_str(), &buf) != 0) - cellSysutil->Error("stat failed! (%s)", real_path.c_str()); + cellSysutil.Error("stat failed! (%s)", real_path.c_str()); else { atime = buf.st_atime; @@ -262,7 +262,7 @@ s32 modifySaveDataFiles(vm::ptr funcFile, vm::ptrresult < 0) { - cellSysutil->Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM) { @@ -283,7 +283,7 @@ s32 modifySaveDataFiles(vm::ptr funcFile, vm::ptrError("modifySaveDataFiles: Unknown fileType! Aborting..."); + cellSysutil.Error("modifySaveDataFiles: Unknown fileType! Aborting..."); return CELL_SAVEDATA_ERROR_PARAM; } @@ -306,11 +306,11 @@ s32 modifySaveDataFiles(vm::ptr funcFile, vm::ptrTodo("modifySaveDataFiles: CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC"); + cellSysutil.Todo("modifySaveDataFiles: CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC"); break; default: - cellSysutil->Error("modifySaveDataFiles: Unknown fileOperation! Aborting..."); + cellSysutil.Error("modifySaveDataFiles: Unknown fileOperation! Aborting..."); return CELL_SAVEDATA_ERROR_PARAM; } @@ -332,7 +332,7 @@ s32 cellSaveDataListSave2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataListSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataListSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -378,7 +378,7 @@ s32 cellSaveDataListSave2( funcList(result, listGet, listSet); if (result->result < 0) { - cellSysutil->Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -386,7 +386,7 @@ s32 cellSaveDataListSave2( if (listSet->newData) addNewSaveDataEntry(saveEntries, listSet->newData.to_le()); if (saveEntries.size() == 0) { - cellSysutil->Error("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil.Error("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error return CELL_OK; } @@ -399,7 +399,7 @@ s32 cellSaveDataListSave2( funcStat(result, statGet, statSet); Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -423,7 +423,7 @@ s32 cellSaveDataListLoad2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -470,7 +470,7 @@ s32 cellSaveDataListLoad2( funcList(result, listGet, listSet); if (result->result < 0) { - cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -478,7 +478,7 @@ s32 cellSaveDataListLoad2( if (listSet->newData) addNewSaveDataEntry(saveEntries, listSet->newData.to_le()); if (saveEntries.size() == 0) { - cellSysutil->Error("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error + cellSysutil.Error("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error return CELL_OK; } @@ -491,7 +491,7 @@ s32 cellSaveDataListLoad2( funcStat(result, statGet, statSet); Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } @@ -515,7 +515,7 @@ s32 cellSaveDataFixedSave2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataFixedSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataFixedSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -557,7 +557,7 @@ s32 cellSaveDataFixedSave2( } funcFixed(result, listGet, fixedSet); if (result->result < 0) { - cellSysutil->Error("cellSaveDataFixedSave2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataFixedSave2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } setSaveDataFixed(saveEntries, fixedSet); @@ -568,7 +568,7 @@ s32 cellSaveDataFixedSave2( funcStat(result, statGet, statSet); Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataFixedSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataFixedSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam) @@ -591,7 +591,7 @@ s32 cellSaveDataFixedLoad2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataFixedLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataFixedLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -633,7 +633,7 @@ s32 cellSaveDataFixedLoad2( } funcFixed(result, listGet, fixedSet); if (result->result < 0) { - cellSysutil->Error("cellSaveDataFixedLoad2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } setSaveDataFixed(saveEntries, fixedSet); @@ -644,7 +644,7 @@ s32 cellSaveDataFixedLoad2( funcStat(result, statGet, statSet); Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam) @@ -667,7 +667,7 @@ s32 cellSaveDataAutoSave2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataAutoSave2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataAutoSave2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -705,7 +705,7 @@ s32 cellSaveDataAutoSave2( Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataAutoSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataAutoSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam) @@ -728,7 +728,7 @@ s32 cellSaveDataAutoLoad2( u32 container, vm::ptr userdata) { - cellSysutil->Warning("cellSaveDataAutoLoad2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Warning("cellSaveDataAutoLoad2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); vm::var result; @@ -751,7 +751,7 @@ s32 cellSaveDataAutoLoad2( // The target entry does not exist if (saveEntries.size() == 0) { - cellSysutil->Error("cellSaveDataAutoLoad2: Couldn't find save entry (%s)", dirN.c_str()); + cellSysutil.Error("cellSaveDataAutoLoad2: Couldn't find save entry (%s)", dirN.c_str()); return CELL_OK; // TODO: Can anyone check the actual behaviour of a PS3 when saves are not found? } @@ -761,7 +761,7 @@ s32 cellSaveDataAutoLoad2( Memory.Free(statGet->fileList.addr()); if (result->result < 0) { - cellSysutil->Error("cellSaveDataAutoLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + cellSysutil.Error("cellSaveDataAutoLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. return CELL_SAVEDATA_ERROR_CBRESULT; } /*if (statSet->setParam) @@ -785,7 +785,7 @@ s32 cellSaveDataListAutoSave( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataListAutoSave(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataListAutoSave(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); //vm::var result; @@ -832,7 +832,7 @@ s32 cellSaveDataListAutoSave( //funcFixed(result, listGet, fixedSet); //if (result->result < 0) { - // cellSysutil->Error("cellSaveDataListAutoSave: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + // cellSysutil.Error("cellSaveDataListAutoSave: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. // return CELL_SAVEDATA_ERROR_CBRESULT; //} @@ -844,7 +844,7 @@ s32 cellSaveDataListAutoSave( //funcStat(result, statGet, statSet); //Memory.Free(statGet->fileList.addr()); //if (result->result < 0) { - // cellSysutil->Error("cellSaveDataListAutoSave: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + // cellSysutil.Error("cellSaveDataListAutoSave: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. // return CELL_SAVEDATA_ERROR_CBRESULT; //} @@ -868,7 +868,7 @@ s32 cellSaveDataListAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataListAutoLoad(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataListAutoLoad(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); //vm::var result; @@ -915,7 +915,7 @@ s32 cellSaveDataListAutoLoad( //funcFixed(result, listGet, fixedSet); //if (result->result < 0) { - // cellSysutil->Error("cellSaveDataListAutoLoad: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + // cellSysutil.Error("cellSaveDataListAutoLoad: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. // return CELL_SAVEDATA_ERROR_CBRESULT; //} @@ -927,7 +927,7 @@ s32 cellSaveDataListAutoLoad( //funcStat(result, statGet, statSet); //Memory.Free(statGet->fileList.addr()); //if (result->result < 0) { - // cellSysutil->Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + // cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. // return CELL_SAVEDATA_ERROR_CBRESULT; //} ///*if (statSet->setParam) @@ -941,7 +941,7 @@ s32 cellSaveDataListAutoLoad( s32 cellSaveDataDelete2(u32 container) { - cellSysutil->Todo("cellSaveDataDelete2(container=%d)", container); + cellSysutil.Todo("cellSaveDataDelete2(container=%d)", container); return CELL_SAVEDATA_RET_CANCEL; } @@ -954,7 +954,7 @@ s32 cellSaveDataFixedDelete( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataFixedDelete(setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataFixedDelete(setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", setList.addr(), setBuf.addr(), funcFixed.addr(), funcDone.addr(), container, userdata.addr()); return CELL_OK; @@ -971,7 +971,7 @@ s32 cellSaveDataUserListSave( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserListSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserListSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -988,7 +988,7 @@ s32 cellSaveDataUserListLoad( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserListLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserListLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1005,7 +1005,7 @@ s32 cellSaveDataUserFixedSave( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserFixedSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserFixedSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1022,7 +1022,7 @@ s32 cellSaveDataUserFixedLoad( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserFixedLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserFixedLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1039,7 +1039,7 @@ s32 cellSaveDataUserAutoSave( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserAutoSave(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserAutoSave(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", version, userId, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1056,7 +1056,7 @@ s32 cellSaveDataUserAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserAutoLoad(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserAutoLoad(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", version, userId, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1074,7 +1074,7 @@ s32 cellSaveDataUserListAutoSave( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserListAutoSave(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserListAutoSave(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1092,7 +1092,7 @@ s32 cellSaveDataUserListAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserListAutoLoad(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserListAutoLoad(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", version, userId, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); return CELL_OK; @@ -1107,7 +1107,7 @@ s32 cellSaveDataUserFixedDelete( u32 container, vm::ptr userdata) { - cellSysutil->Todo("cellSaveDataUserFixedDelete(userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", + cellSysutil.Todo("cellSaveDataUserFixedDelete(userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcDone.addr(), container, userdata.addr()); return CELL_OK; @@ -1115,7 +1115,7 @@ s32 cellSaveDataUserFixedDelete( void cellSaveDataEnableOverlay(s32 enable) { - cellSysutil->Todo("cellSaveDataEnableOverlay(enable=%d)", enable); + cellSysutil.Todo("cellSaveDataEnableOverlay(enable=%d)", enable); return; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 48669968f1..54422a30a4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -19,7 +19,7 @@ #include "sysPrxForUser.h" #include "cellSpurs.h" -Module *cellSpurs = nullptr; +extern Module cellSpurs; #ifdef PRX_DEBUG extern u32 libsre; @@ -247,7 +247,7 @@ s64 spursInit( { if (Emu.IsStopped()) { - cellSpurs->Warning("SPURS Handler Thread 0 aborted"); + cellSpurs.Warning("SPURS Handler Thread 0 aborted"); return; } @@ -408,7 +408,7 @@ s64 spursInit( s64 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs->Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", + cellSpurs.Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc); @@ -432,7 +432,7 @@ s64 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s3 s64 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptr attr) { - cellSpurs->Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); + cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc); #endif @@ -468,7 +468,7 @@ s64 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptr spurs, vm::ptr attr) { - cellSpurs->Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); + cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc); #endif @@ -504,7 +504,7 @@ s64 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { - cellSpurs->Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", + cellSpurs.Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", attr.addr(), revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x72CC, libsre_rtoc); @@ -531,7 +531,7 @@ s64 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container) { - cellSpurs->Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=%d)", attr.addr(), container); + cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=%d)", attr.addr(), container); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x6FF8, libsre_rtoc); #endif @@ -557,7 +557,7 @@ s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr s64 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr prefix, u32 size) { - cellSpurs->Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size); + cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x7234, libsre_rtoc); #endif @@ -583,7 +583,7 @@ s64 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr attr) { - cellSpurs->Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr()); + cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x7150, libsre_rtoc); #endif @@ -603,7 +603,7 @@ s64 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr att s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s32 type) { - cellSpurs->Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type); + cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x70C8, libsre_rtoc); #endif @@ -638,7 +638,7 @@ s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s3 s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) { - cellSpurs->Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", + cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", attr.addr(), priority.addr(), maxSpu, isPreemptible.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xF410, libsre_rtoc); @@ -696,7 +696,7 @@ s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: s64 cellSpursFinalize(vm::ptr spurs) { - cellSpurs->Todo("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr()); + cellSpurs.Todo("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x8568, libsre_rtoc); #endif @@ -786,7 +786,7 @@ s64 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po s64 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) { - cellSpurs->Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=%d, port_addr=0x%x, isDynamic=%d)", + cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=%d, port_addr=0x%x, isDynamic=%d)", spurs.addr(), queue, port.addr(), isDynamic); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xAFE0, libsre_rtoc); @@ -798,7 +798,7 @@ s64 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr spurs, u8 port) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=%d)", spurs.addr(), port); + cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=%d)", spurs.addr(), port); return GetCurrentPPUThread().FastCall2(libsre + 0xB144, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -809,7 +809,7 @@ s64 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port) s64 cellSpursGetSpuGuid() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xEFB0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -819,7 +819,7 @@ s64 cellSpursGetSpuGuid() s64 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) { - cellSpurs->Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.addr(), group.addr()); + cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.addr(), group.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x8B30, libsre_rtoc); #endif @@ -839,7 +839,7 @@ s64 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) s64 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) { - cellSpurs->Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), nThreads.addr()); + cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), nThreads.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x8B78, libsre_rtoc); #endif @@ -859,7 +859,7 @@ s64 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) s64 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::ptr nThreads) { - cellSpurs->Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), thread.addr(), nThreads.addr()); + cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), thread.addr(), nThreads.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x8A98, libsre_rtoc); #endif @@ -885,7 +885,7 @@ s64 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::p s64 cellSpursSetMaxContention(vm::ptr spurs, u32 workloadId, u32 maxContention) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%d, maxContention=%d)", spurs.addr(), workloadId, maxContention); + cellSpurs.Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%d, maxContention=%d)", spurs.addr(), workloadId, maxContention); return GetCurrentPPUThread().FastCall2(libsre + 0x8E90, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -896,7 +896,7 @@ s64 cellSpursSetMaxContention(vm::ptr spurs, u32 workloadId, u32 maxC s64 cellSpursSetPriorities(vm::ptr spurs, u32 workloadId, vm::ptr priorities) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%d, priorities_addr=0x%x)", spurs.addr(), workloadId, priorities.addr()); + cellSpurs.Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%d, priorities_addr=0x%x)", spurs.addr(), workloadId, priorities.addr()); return GetCurrentPPUThread().FastCall2(libsre + 0x8BC0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -907,7 +907,7 @@ s64 cellSpursSetPriorities(vm::ptr spurs, u32 workloadId, vm::ptr spurs, vm::ptr isPreemptible) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible_addr=0x%x)", spurs.addr(), isPreemptible.addr()); + cellSpurs.Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible_addr=0x%x)", spurs.addr(), isPreemptible.addr()); return GetCurrentPPUThread().FastCall2(libsre + 0xF5A4, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -918,7 +918,7 @@ s64 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::ptr spurs, bool flag) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%d)", spurs.addr(), flag); + cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%d)", spurs.addr(), flag); return GetCurrentPPUThread().FastCall2(libsre + 0xDCC0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -929,7 +929,7 @@ s64 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag) s64 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, u32 eaHandler_addr, u32 arg_addr) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursSetGlobalExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x)", + cellSpurs.Warning("cellSpursSetGlobalExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x)", spurs.addr(), eaHandler_addr, arg_addr); return GetCurrentPPUThread().FastCall2(libsre + 0xD6D0, libsre_rtoc); #else @@ -941,7 +941,7 @@ s64 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, u32 eaHand s64 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.addr()); + cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.addr()); return GetCurrentPPUThread().FastCall2(libsre + 0xD674, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -952,7 +952,7 @@ s64 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs) s64 cellSpursGetInfo(vm::ptr spurs, vm::ptr info) { #ifdef PRX_DEBUG - cellSpurs->Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.addr(), info.addr()); + cellSpurs.Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.addr(), info.addr()); return GetCurrentPPUThread().FastCall2(libsre + 0xE540, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1000,7 +1000,7 @@ s64 spursWakeUp(PPUThread& CPU, vm::ptr spurs) s64 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) { - cellSpurs->Warning("%s(spurs_addr=0x%x)", __FUNCTION__, spurs.addr()); + cellSpurs.Warning("%s(spurs_addr=0x%x)", __FUNCTION__, spurs.addr()); return spursWakeUp(CPU, spurs); } @@ -1186,7 +1186,7 @@ s64 cellSpursAddWorkload( u32 minContention, u32 maxContention) { - cellSpurs->Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", + cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x9ED0, libsre_rtoc); @@ -1218,7 +1218,7 @@ s64 _cellSpursWorkloadAttributeInitialize( u32 minContention, u32 maxContention) { - cellSpurs->Warning("%s(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", + cellSpurs.Warning("%s(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", __FUNCTION__, attr.addr(), revision, sdkVersion, pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x9F08, libsre_rtoc); @@ -1259,7 +1259,7 @@ s64 _cellSpursWorkloadAttributeInitialize( s64 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::ptr nameClass, vm::ptr nameInstance) { - cellSpurs->Warning("%s(attr_addr=0x%x, nameClass_addr=0x%x, nameInstance_addr=0x%x)", __FUNCTION__, attr.addr(), nameClass.addr(), nameInstance.addr()); + cellSpurs.Warning("%s(attr_addr=0x%x, nameClass_addr=0x%x, nameInstance_addr=0x%x)", __FUNCTION__, attr.addr(), nameClass.addr(), nameInstance.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x9664, libsre_rtoc); #endif @@ -1280,7 +1280,7 @@ s64 cellSpursWorkloadAttributeSetName(vm::ptr attr, s64 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg) { - cellSpurs->Warning("%s(attr_addr=0x%x, hook_addr=0x%x, arg=0x%x)", __FUNCTION__, attr.addr(), hook.addr(), arg.addr()); + cellSpurs.Warning("%s(attr_addr=0x%x, hook_addr=0x%x, arg=0x%x)", __FUNCTION__, attr.addr(), hook.addr(), arg.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x96A4, libsre_rtoc); #endif @@ -1301,7 +1301,7 @@ s64 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr spurs, const vm::ptr wid, vm::ptr attr) { - cellSpurs->Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, attr_addr=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), attr.addr()); + cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, attr_addr=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), attr.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0x9E14, libsre_rtoc); #endif @@ -1337,7 +1337,7 @@ s64 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptrWarning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xA414, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1348,7 +1348,7 @@ s64 cellSpursRemoveWorkload() s64 cellSpursWaitForWorkloadShutdown() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xA20C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1359,7 +1359,7 @@ s64 cellSpursWaitForWorkloadShutdown() s64 cellSpursShutdownWorkload() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xA060, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1369,7 +1369,7 @@ s64 cellSpursShutdownWorkload() s64 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set) { - cellSpurs->Warning("%s(spurs_addr=0x%x, wid=%d, is_set=%d)", __FUNCTION__, spurs.addr(), wid, is_set); + cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, is_set=%d)", __FUNCTION__, spurs.addr(), wid, is_set); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xF158, libsre_rtoc); #endif @@ -1439,7 +1439,7 @@ s64 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set s64 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::ptr> flag) { - cellSpurs->Warning("%s(spurs_addr=0x%x, flag_addr=0x%x)", __FUNCTION__, spurs.addr(), flag.addr()); + cellSpurs.Warning("%s(spurs_addr=0x%x, flag_addr=0x%x)", __FUNCTION__, spurs.addr(), flag.addr()); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xEC00, libsre_rtoc); #endif @@ -1459,7 +1459,7 @@ s64 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::ptr spurs, u32 workloadId) { - cellSpurs->Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId); + cellSpurs.Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0xA658, libsre_rtoc); @@ -1519,7 +1519,7 @@ s64 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) s64 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 workloadId) { - cellSpurs->Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId); + cellSpurs.Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0xA78C, libsre_rtoc); @@ -1564,7 +1564,7 @@ s64 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 wo s64 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) { - cellSpurs->Warning("%s(spurs_addr=0x%x, wid=%d, value=0x%x)", __FUNCTION__, spurs.addr(), wid, value); + cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, value=0x%x)", __FUNCTION__, spurs.addr(), wid, value); #ifdef PRX_DEBUG_XXX return GetCurrentPPUThread().FastCall2(libsre + 0xAB2C, libsre_rtoc); #endif @@ -1604,7 +1604,7 @@ s64 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) s64 cellSpursReadyCountAdd() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xA868, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1615,7 +1615,7 @@ s64 cellSpursReadyCountAdd() s64 cellSpursReadyCountCompareAndSwap() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xA9CC, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1626,7 +1626,7 @@ s64 cellSpursReadyCountCompareAndSwap() s64 cellSpursReadyCountSwap() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xAC34, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1637,7 +1637,7 @@ s64 cellSpursReadyCountSwap() s64 cellSpursRequestIdleSpu() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xAD88, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1648,7 +1648,7 @@ s64 cellSpursRequestIdleSpu() s64 cellSpursGetWorkloadInfo() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xE70C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1659,7 +1659,7 @@ s64 cellSpursGetWorkloadInfo() s64 _cellSpursWorkloadFlagReceiver2() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xF298, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1670,7 +1670,7 @@ s64 _cellSpursWorkloadFlagReceiver2() s64 cellSpursSetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xDB54, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1681,7 +1681,7 @@ s64 cellSpursSetExceptionEventHandler() s64 cellSpursUnsetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0xD77C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -1691,7 +1691,7 @@ s64 cellSpursUnsetExceptionEventHandler() s64 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection) { - cellSpurs->Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)", + cellSpurs.Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)", spurs.addr(), taskset.addr(), eventFlag.addr(), flagClearMode, flagDirection); #ifdef PRX_DEBUG @@ -1743,7 +1743,7 @@ s64 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr eventFlag) { - cellSpurs->Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); + cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x157B8, libsre_rtoc); @@ -1823,7 +1823,7 @@ success: s64 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) { - cellSpurs->Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); + cellSpurs.Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15998, libsre_rtoc); @@ -2034,7 +2034,7 @@ s64 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr s64 cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) { - cellSpurs->Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.addr(), mask.addr(), mode); + cellSpurs.Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.addr(), mask.addr(), mode); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15E68, libsre_rtoc); @@ -2045,7 +2045,7 @@ s64 cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr m s64 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) { - cellSpurs->Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); + cellSpurs.Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15E9C, libsre_rtoc); @@ -2067,7 +2067,7 @@ s64 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) s64 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) { - cellSpurs->Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); + cellSpurs.Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15F04, libsre_rtoc); @@ -2195,7 +2195,7 @@ s64 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) s64 cellSpursEventFlagTryWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) { - cellSpurs->Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.addr(), mask.addr(), mode); + cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.addr(), mask.addr(), mode); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15E70, libsre_rtoc); @@ -2206,7 +2206,7 @@ s64 cellSpursEventFlagTryWait(vm::ptr eventFlag, vm::ptr eventFlag, vm::ptr direction) { - cellSpurs->Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr()); + cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x162C4, libsre_rtoc); @@ -2228,7 +2228,7 @@ s64 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::pt s64 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode) { - cellSpurs->Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr()); + cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x16310, libsre_rtoc); @@ -2250,7 +2250,7 @@ s64 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::pt s64 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::ptr taskset) { - cellSpurs->Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr()); + cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1635C, libsre_rtoc); @@ -2273,7 +2273,7 @@ s64 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, v s64 _cellSpursLFQueueInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17028, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2284,7 +2284,7 @@ s64 _cellSpursLFQueueInitialize() s64 _cellSpursLFQueuePushBody() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x170AC, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2295,7 +2295,7 @@ s64 _cellSpursLFQueuePushBody() s64 cellSpursLFQueueDetachLv2EventQueue() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x177CC, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2306,7 +2306,7 @@ s64 cellSpursLFQueueDetachLv2EventQueue() s64 cellSpursLFQueueAttachLv2EventQueue() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x173EC, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2317,7 +2317,7 @@ s64 cellSpursLFQueueAttachLv2EventQueue() s64 _cellSpursLFQueuePopBody() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17238, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2328,7 +2328,7 @@ s64 _cellSpursLFQueuePopBody() s64 cellSpursLFQueueGetTasksetAddress() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17C34, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2339,7 +2339,7 @@ s64 cellSpursLFQueueGetTasksetAddress() s64 _cellSpursQueueInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x163B4, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2350,7 +2350,7 @@ s64 _cellSpursQueueInitialize() s64 cellSpursQueuePopBody() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x16BF0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2361,7 +2361,7 @@ s64 cellSpursQueuePopBody() s64 cellSpursQueuePushBody() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x168C4, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2372,7 +2372,7 @@ s64 cellSpursQueuePushBody() s64 cellSpursQueueAttachLv2EventQueue() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1666C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2383,7 +2383,7 @@ s64 cellSpursQueueAttachLv2EventQueue() s64 cellSpursQueueDetachLv2EventQueue() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x16524, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2394,7 +2394,7 @@ s64 cellSpursQueueDetachLv2EventQueue() s64 cellSpursQueueGetTasksetAddress() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x16F50, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2405,7 +2405,7 @@ s64 cellSpursQueueGetTasksetAddress() s64 cellSpursQueueClear() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1675C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2416,7 +2416,7 @@ s64 cellSpursQueueClear() s64 cellSpursQueueDepth() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1687C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2427,7 +2427,7 @@ s64 cellSpursQueueDepth() s64 cellSpursQueueGetEntrySize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x16FE0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2438,7 +2438,7 @@ s64 cellSpursQueueGetEntrySize() s64 cellSpursQueueSize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x167F0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2449,7 +2449,7 @@ s64 cellSpursQueueSize() s64 cellSpursQueueGetDirection() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x16F98, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2460,7 +2460,7 @@ s64 cellSpursQueueGetDirection() s64 cellSpursCreateJobChainWithAttribute() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1898C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2471,7 +2471,7 @@ s64 cellSpursCreateJobChainWithAttribute() s64 cellSpursCreateJobChain() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18B84, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2482,7 +2482,7 @@ s64 cellSpursCreateJobChain() s64 cellSpursJoinJobChain() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18DB0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2493,7 +2493,7 @@ s64 cellSpursJoinJobChain() s64 cellSpursKickJobChain() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18E8C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2504,7 +2504,7 @@ s64 cellSpursKickJobChain() s64 _cellSpursJobChainAttributeInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1845C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2515,7 +2515,7 @@ s64 _cellSpursJobChainAttributeInitialize() s64 cellSpursGetJobChainId() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x19064, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2526,7 +2526,7 @@ s64 cellSpursGetJobChainId() s64 cellSpursJobChainSetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1A5A0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2537,7 +2537,7 @@ s64 cellSpursJobChainSetExceptionEventHandler() s64 cellSpursJobChainUnsetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1A614, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2548,7 +2548,7 @@ s64 cellSpursJobChainUnsetExceptionEventHandler() s64 cellSpursGetJobChainInfo() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1A7A0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2559,7 +2559,7 @@ s64 cellSpursGetJobChainInfo() s64 cellSpursJobChainGetSpursAddress() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1A900, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -2612,7 +2612,7 @@ s64 spursCreateTaskset(vm::ptr spurs, vm::ptr tasks s64 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { - cellSpurs->Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); + cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14BEC, libsre_rtoc); @@ -2646,7 +2646,7 @@ s64 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, u32 maxContention) { - cellSpurs->Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", + cellSpurs.Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", spurs.addr(), taskset.addr(), args, priority.addr(), maxContention); #ifdef PRX_DEBUG @@ -2665,7 +2665,7 @@ s64 cellSpursCreateTaskset(vm::ptr spurs, vm::ptr t s64 cellSpursJoinTaskset(vm::ptr taskset) { - cellSpurs->Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.addr()); + cellSpurs.Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x152F8, libsre_rtoc); @@ -2677,7 +2677,7 @@ s64 cellSpursJoinTaskset(vm::ptr taskset) s64 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) { - cellSpurs->Warning("cellSpursGetTasksetId(taskset_addr=0x%x, wid=0x%x)", taskset.addr(), wid.addr()); + cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, wid=0x%x)", taskset.addr(), wid.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14EA0, libsre_rtoc); @@ -2704,7 +2704,7 @@ s64 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) s64 cellSpursShutdownTaskset(vm::ptr taskset) { - cellSpurs->Warning("cellSpursShutdownTaskset(taskset_addr=0x%x)", taskset.addr()); + cellSpurs.Warning("cellSpursShutdownTaskset(taskset_addr=0x%x)", taskset.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14868, libsre_rtoc); @@ -2851,7 +2851,7 @@ s64 spursTaskStart(vm::ptr taskset, u32 taskId) s64 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, u32 elf_addr, u32 context_addr, u32 context_size, vm::ptr lsPattern, vm::ptr argument) { - cellSpurs->Warning("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%d, lsPattern_addr=0x%x, argument_addr=0x%x)", + cellSpurs.Warning("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%d, lsPattern_addr=0x%x, argument_addr=0x%x)", taskset.addr(), taskId.addr(), elf_addr, context_addr, context_size, lsPattern.addr(), argument.addr()); #ifdef PRX_DEBUG @@ -2888,7 +2888,7 @@ s64 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, s64 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) { #ifdef PRX_DEBUG - cellSpurs->Warning("_cellSpursSendSignal(taskset_addr=0x%x, taskId=%d)", taskset.addr(), taskId); + cellSpurs.Warning("_cellSpursSendSignal(taskset_addr=0x%x, taskId=%d)", taskset.addr(), taskId); return GetCurrentPPUThread().FastCall2(libsre + 0x124CC, libsre_rtoc); #else if (!taskset) @@ -2941,7 +2941,7 @@ s64 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) s64 cellSpursCreateTaskWithAttribute() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x12204, libsre_rtoc); @@ -2953,7 +2953,7 @@ s64 cellSpursCreateTaskWithAttribute() s64 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::ptr name) { - cellSpurs->Warning("%s(attr=0x%x, name=0x%x)", __FUNCTION__, attr.addr(), name.addr()); + cellSpurs.Warning("%s(attr=0x%x, name=0x%x)", __FUNCTION__, attr.addr(), name.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14210, libsre_rtoc); @@ -2975,7 +2975,7 @@ s64 cellSpursTasksetAttributeSetName(vm::ptr attr, vm s64 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size) { - cellSpurs->Warning("%s(attr=0x%x, size=0x%x)", __FUNCTION__, attr.addr(), size); + cellSpurs.Warning("%s(attr=0x%x, size=0x%x)", __FUNCTION__, attr.addr(), size); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14254, libsre_rtoc); @@ -3002,7 +3002,7 @@ s64 cellSpursTasksetAttributeSetTasksetSize(vm::ptr a s64 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable) { - cellSpurs->Warning("%s(attr=0x%x, enable=%d)", __FUNCTION__, attr.addr(), enable); + cellSpurs.Warning("%s(attr=0x%x, enable=%d)", __FUNCTION__, attr.addr(), enable); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x142AC, libsre_rtoc); @@ -3024,7 +3024,7 @@ s64 cellSpursTasksetAttributeEnableClearLS(vm::ptr at s64 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision) { - cellSpurs->Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); + cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1474C, libsre_rtoc); @@ -3048,7 +3048,7 @@ s64 _cellSpursTasksetAttribute2Initialize(vm::ptr at s64 cellSpursTaskExitCodeGet() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1397C, libsre_rtoc); @@ -3060,7 +3060,7 @@ s64 cellSpursTaskExitCodeGet() s64 cellSpursTaskExitCodeInitialize() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1352C, libsre_rtoc); @@ -3072,7 +3072,7 @@ s64 cellSpursTaskExitCodeInitialize() s64 cellSpursTaskExitCodeTryGet() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13974, libsre_rtoc); @@ -3084,7 +3084,7 @@ s64 cellSpursTaskExitCodeTryGet() s64 cellSpursTaskGetLoadableSegmentPattern() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13ED4, libsre_rtoc); @@ -3096,7 +3096,7 @@ s64 cellSpursTaskGetLoadableSegmentPattern() s64 cellSpursTaskGetReadOnlyAreaPattern() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13CFC, libsre_rtoc); @@ -3108,7 +3108,7 @@ s64 cellSpursTaskGetReadOnlyAreaPattern() s64 cellSpursTaskGenerateLsPattern() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13B78, libsre_rtoc); @@ -3120,7 +3120,7 @@ s64 cellSpursTaskGenerateLsPattern() s64 _cellSpursTaskAttributeInitialize() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x10C30, libsre_rtoc); @@ -3132,7 +3132,7 @@ s64 _cellSpursTaskAttributeInitialize() s64 cellSpursTaskAttributeSetExitCodeContainer() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x10A98, libsre_rtoc); @@ -3144,7 +3144,7 @@ s64 cellSpursTaskAttributeSetExitCodeContainer() s64 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision) { - cellSpurs->Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); + cellSpurs.Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x10B00, libsre_rtoc); @@ -3166,7 +3166,7 @@ s64 _cellSpursTaskAttribute2Initialize(vm::ptr attribut s64 cellSpursTaskGetContextSaveAreaSize() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1409C, libsre_rtoc); @@ -3178,7 +3178,7 @@ s64 cellSpursTaskGetContextSaveAreaSize() s64 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { - cellSpurs->Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); + cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x15108, libsre_rtoc); @@ -3211,7 +3211,7 @@ s64 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr s64 cellSpursCreateTask2() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x11E54, libsre_rtoc); @@ -3223,7 +3223,7 @@ s64 cellSpursCreateTask2() s64 cellSpursJoinTask2() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x11378, libsre_rtoc); @@ -3235,7 +3235,7 @@ s64 cellSpursJoinTask2() s64 cellSpursTryJoinTask2() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x11748, libsre_rtoc); @@ -3247,7 +3247,7 @@ s64 cellSpursTryJoinTask2() s64 cellSpursDestroyTaskset2() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14EE8, libsre_rtoc); @@ -3259,7 +3259,7 @@ s64 cellSpursDestroyTaskset2() s64 cellSpursCreateTask2WithBinInfo() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x120E0, libsre_rtoc); @@ -3271,7 +3271,7 @@ s64 cellSpursCreateTask2WithBinInfo() s64 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg) { - cellSpurs->Warning("%s(taskset=0x5x, handler=0x%x, arg=0x%x)", __FUNCTION__, taskset.addr(), handler.addr(), arg.addr()); + cellSpurs.Warning("%s(taskset=0x5x, handler=0x%x, arg=0x%x)", __FUNCTION__, taskset.addr(), handler.addr(), arg.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13124, libsre_rtoc); @@ -3304,7 +3304,7 @@ s64 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, s64 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset) { - cellSpurs->Warning("%s(taskset=0x%x)", __FUNCTION__, taskset.addr()); + cellSpurs.Warning("%s(taskset=0x%x)", __FUNCTION__, taskset.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x13194, libsre_rtoc); @@ -3332,7 +3332,7 @@ s64 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset s64 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id) { - cellSpurs->Warning("%s(spurs=0x%x, taskset=0x%x, id=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), id); + cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, id=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), id); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x133AC, libsre_rtoc); @@ -3357,7 +3357,7 @@ s64 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, vm::ptr spurs) { - cellSpurs->Warning("%s(taskset=0x%x, spurs=0x%x)", __FUNCTION__, taskset.addr(), spurs.addr()); + cellSpurs.Warning("%s(taskset=0x%x, spurs=0x%x)", __FUNCTION__, taskset.addr(), spurs.addr()); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x14408, libsre_rtoc); @@ -3384,7 +3384,7 @@ s64 cellSpursTasksetGetSpursAddress(vm::ptr taskset, vm: s64 cellSpursGetTasksetInfo() { - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); #ifdef PRX_DEBUG return GetCurrentPPUThread().FastCall2(libsre + 0x1445C, libsre_rtoc); @@ -3396,7 +3396,7 @@ s64 cellSpursGetTasksetInfo() s64 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::ptr priority, u32 max_contention) { - cellSpurs->Warning("%s(attribute=0x%x, revision=%d, skd_version=%d, args=0x%llx, priority=0x%x, max_contention=%d)", + cellSpurs.Warning("%s(attribute=0x%x, revision=%d, skd_version=%d, args=0x%llx, priority=0x%x, max_contention=%d)", __FUNCTION__, attribute.addr(), revision, sdk_version, args, priority.addr(), max_contention); #ifdef PRX_DEBUG @@ -3434,7 +3434,7 @@ s64 _cellSpursTasksetAttributeInitialize(vm::ptr attr s64 cellSpursJobGuardInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1807C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3445,7 +3445,7 @@ s64 cellSpursJobGuardInitialize() s64 cellSpursJobChainAttributeSetName() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1861C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3456,7 +3456,7 @@ s64 cellSpursJobChainAttributeSetName() s64 cellSpursShutdownJobChain() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18D2C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3467,7 +3467,7 @@ s64 cellSpursShutdownJobChain() s64 cellSpursJobChainAttributeSetHaltOnError() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18660, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3478,7 +3478,7 @@ s64 cellSpursJobChainAttributeSetHaltOnError() s64 cellSpursJobChainAttributeSetJobTypeMemoryCheck() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x186A4, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3489,7 +3489,7 @@ s64 cellSpursJobChainAttributeSetJobTypeMemoryCheck() s64 cellSpursJobGuardNotify() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17FA4, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3500,7 +3500,7 @@ s64 cellSpursJobGuardNotify() s64 cellSpursJobGuardReset() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17F60, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3511,7 +3511,7 @@ s64 cellSpursJobGuardReset() s64 cellSpursRunJobChain() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18F94, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3522,7 +3522,7 @@ s64 cellSpursRunJobChain() s64 cellSpursJobChainGetError() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x190AC, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3533,7 +3533,7 @@ s64 cellSpursJobChainGetError() s64 cellSpursGetJobPipelineInfo() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1A954, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3544,7 +3544,7 @@ s64 cellSpursGetJobPipelineInfo() s64 cellSpursJobSetMaxGrab() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1AC88, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3555,7 +3555,7 @@ s64 cellSpursJobSetMaxGrab() s64 cellSpursJobHeaderSetJobbin2Param() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1AD58, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3566,7 +3566,7 @@ s64 cellSpursJobHeaderSetJobbin2Param() s64 cellSpursAddUrgentCommand() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x18160, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3577,7 +3577,7 @@ s64 cellSpursAddUrgentCommand() s64 cellSpursAddUrgentCall() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x1823C, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3588,7 +3588,7 @@ s64 cellSpursAddUrgentCall() s64 cellSpursBarrierInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17CD8, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3599,7 +3599,7 @@ s64 cellSpursBarrierInitialize() s64 cellSpursBarrierGetTasksetAddress() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17DB0, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3610,7 +3610,7 @@ s64 cellSpursBarrierGetTasksetAddress() s64 _cellSpursSemaphoreInitialize() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17DF8, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3621,7 +3621,7 @@ s64 _cellSpursSemaphoreInitialize() s64 cellSpursSemaphoreGetTasksetAddress() { #ifdef PRX_DEBUG - cellSpurs->Warning("%s()", __FUNCTION__); + cellSpurs.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsre + 0x17F18, libsre_rtoc); #else UNIMPLEMENTED_FUNC(cellSpurs); @@ -3813,10 +3813,8 @@ s64 cellSpursTraceFinalize(vm::ptr spurs) return CELL_OK; } -void cellSpurs_init(Module *pxThis) +Module cellSpurs("cellSpurs", []() { - cellSpurs = pxThis; - // Core REG_FUNC(cellSpurs, cellSpursInitialize); REG_FUNC(cellSpurs, cellSpursInitializeWithAttribute); @@ -3975,4 +3973,4 @@ void cellSpurs_init(Module *pxThis) REG_FUNC(cellSpurs, cellSpursTraceStart); REG_FUNC(cellSpurs, cellSpursTraceStop); REG_FUNC(cellSpurs, cellSpursTraceFinalize); -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp index e15c8be5f6..8878858ea5 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp @@ -11,7 +11,7 @@ #include "cellSpurs.h" #include "cellSpursJq.h" -Module* cellSpursJq = nullptr; +extern Module cellSpursJq; #ifdef PRX_DEBUG #include "prx_libspurs_jq.h" @@ -22,7 +22,7 @@ u32 libspurs_jq_rtoc; s64 cellSpursJobQueueAttributeInitialize() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000010, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -33,7 +33,7 @@ s64 cellSpursJobQueueAttributeInitialize() s64 cellSpursJobQueueAttributeSetMaxGrab() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000058, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -44,7 +44,7 @@ s64 cellSpursJobQueueAttributeSetMaxGrab() s64 cellSpursJobQueueAttributeSetSubmitWithEntryLock() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000098, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -55,7 +55,7 @@ s64 cellSpursJobQueueAttributeSetSubmitWithEntryLock() s64 cellSpursJobQueueAttributeSetDoBusyWaiting() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0000BC, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -66,7 +66,7 @@ s64 cellSpursJobQueueAttributeSetDoBusyWaiting() s64 cellSpursJobQueueAttributeSetIsHaltOnError() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0000E0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -77,7 +77,7 @@ s64 cellSpursJobQueueAttributeSetIsHaltOnError() s64 cellSpursJobQueueAttributeSetIsJobTypeMemoryCheck() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000104, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -88,7 +88,7 @@ s64 cellSpursJobQueueAttributeSetIsJobTypeMemoryCheck() s64 cellSpursJobQueueAttributeSetMaxSizeJobDescriptor() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000128, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -99,7 +99,7 @@ s64 cellSpursJobQueueAttributeSetMaxSizeJobDescriptor() s64 cellSpursJobQueueAttributeSetGrabParameters() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000178, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -110,7 +110,7 @@ s64 cellSpursJobQueueAttributeSetGrabParameters() s64 cellSpursJobQueueSetWaitingMode() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0001C8, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -121,7 +121,7 @@ s64 cellSpursJobQueueSetWaitingMode() s64 cellSpursShutdownJobQueue() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0002F0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -132,7 +132,7 @@ s64 cellSpursShutdownJobQueue() s64 _cellSpursCreateJobQueueWithJobDescriptorPool() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0003CC, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -143,7 +143,7 @@ s64 _cellSpursCreateJobQueueWithJobDescriptorPool() s64 _cellSpursCreateJobQueue() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000CA8, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -154,7 +154,7 @@ s64 _cellSpursCreateJobQueue() s64 cellSpursJoinJobQueue() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000CF0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -165,7 +165,7 @@ s64 cellSpursJoinJobQueue() s64 _cellSpursJobQueuePushJobListBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001B24, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -176,7 +176,7 @@ s64 _cellSpursJobQueuePushJobListBody() s64 _cellSpursJobQueuePushJobBody2() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001BF0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -187,7 +187,7 @@ s64 _cellSpursJobQueuePushJobBody2() s64 _cellSpursJobQueuePushJob2Body() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001CD0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -198,7 +198,7 @@ s64 _cellSpursJobQueuePushJob2Body() s64 _cellSpursJobQueuePushAndReleaseJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001DC8, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -209,7 +209,7 @@ s64 _cellSpursJobQueuePushAndReleaseJobBody() s64 _cellSpursJobQueuePushJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001EC8, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -220,7 +220,7 @@ s64 _cellSpursJobQueuePushJobBody() s64 _cellSpursJobQueuePushBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001F90, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -231,7 +231,7 @@ s64 _cellSpursJobQueuePushBody() s64 _cellSpursJobQueueAllocateJobDescriptorBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002434, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -242,7 +242,7 @@ s64 _cellSpursJobQueueAllocateJobDescriptorBody() s64 _cellSpursJobQueuePushSync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002498, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -253,7 +253,7 @@ s64 _cellSpursJobQueuePushSync() s64 _cellSpursJobQueuePushFlush() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002528, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -264,7 +264,7 @@ s64 _cellSpursJobQueuePushFlush() s64 cellSpursJobQueueGetSpurs() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002598, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -275,7 +275,7 @@ s64 cellSpursJobQueueGetSpurs() s64 cellSpursJobQueueGetHandleCount() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0025C4, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -286,7 +286,7 @@ s64 cellSpursJobQueueGetHandleCount() s64 cellSpursJobQueueGetError() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002600, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -297,7 +297,7 @@ s64 cellSpursJobQueueGetError() s64 cellSpursJobQueueGetMaxSizeJobDescriptor() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002668, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -308,7 +308,7 @@ s64 cellSpursJobQueueGetMaxSizeJobDescriptor() s64 cellSpursGetJobQueueId() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0026A4, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -319,7 +319,7 @@ s64 cellSpursGetJobQueueId() s64 cellSpursJobQueueGetSuspendedJobSize() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002700, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -330,7 +330,7 @@ s64 cellSpursJobQueueGetSuspendedJobSize() s64 cellSpursJobQueueClose() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002D70, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -341,7 +341,7 @@ s64 cellSpursJobQueueClose() s64 cellSpursJobQueueOpen() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002E50, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -352,7 +352,7 @@ s64 cellSpursJobQueueOpen() s64 cellSpursJobQueueSemaphoreTryAcquire() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003370, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -363,7 +363,7 @@ s64 cellSpursJobQueueSemaphoreTryAcquire() s64 cellSpursJobQueueSemaphoreAcquire() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003378, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -374,7 +374,7 @@ s64 cellSpursJobQueueSemaphoreAcquire() s64 cellSpursJobQueueSemaphoreInitialize() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003380, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -385,7 +385,7 @@ s64 cellSpursJobQueueSemaphoreInitialize() s64 cellSpursJobQueueSendSignal() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0033E0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -396,7 +396,7 @@ s64 cellSpursJobQueueSendSignal() s64 cellSpursJobQueuePortGetJobQueue() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x00354C, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -407,7 +407,7 @@ s64 cellSpursJobQueuePortGetJobQueue() s64 _cellSpursJobQueuePortPushSync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003554, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -418,7 +418,7 @@ s64 _cellSpursJobQueuePortPushSync() s64 _cellSpursJobQueuePortPushFlush() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0035C0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -429,7 +429,7 @@ s64 _cellSpursJobQueuePortPushFlush() s64 _cellSpursJobQueuePortPushJobListBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003624, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -440,7 +440,7 @@ s64 _cellSpursJobQueuePortPushJobListBody() s64 _cellSpursJobQueuePortPushJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A88, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -451,7 +451,7 @@ s64 _cellSpursJobQueuePortPushJobBody() s64 _cellSpursJobQueuePortPushJobBody2() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A94, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -462,7 +462,7 @@ s64 _cellSpursJobQueuePortPushJobBody2() s64 _cellSpursJobQueuePortPushBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A98, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -473,7 +473,7 @@ s64 _cellSpursJobQueuePortPushBody() s64 cellSpursJobQueuePortTrySync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C38, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -484,7 +484,7 @@ s64 cellSpursJobQueuePortTrySync() s64 cellSpursJobQueuePortSync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C40, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -495,7 +495,7 @@ s64 cellSpursJobQueuePortSync() s64 cellSpursJobQueuePortInitialize() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C48, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -506,7 +506,7 @@ s64 cellSpursJobQueuePortInitialize() s64 cellSpursJobQueuePortInitializeWithDescriptorBuffer() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003D78, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -517,7 +517,7 @@ s64 cellSpursJobQueuePortInitializeWithDescriptorBuffer() s64 cellSpursJobQueuePortFinalize() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003E40, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -528,7 +528,7 @@ s64 cellSpursJobQueuePortFinalize() s64 _cellSpursJobQueuePortCopyPushJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004280, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -539,7 +539,7 @@ s64 _cellSpursJobQueuePortCopyPushJobBody() s64 _cellSpursJobQueuePortCopyPushJobBody2() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x00428C, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -550,7 +550,7 @@ s64 _cellSpursJobQueuePortCopyPushJobBody2() s64 _cellSpursJobQueuePortCopyPushBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004290, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -561,7 +561,7 @@ s64 _cellSpursJobQueuePortCopyPushBody() s64 cellSpursJobQueuePort2GetJobQueue() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0042A4, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -572,7 +572,7 @@ s64 cellSpursJobQueuePort2GetJobQueue() s64 cellSpursJobQueuePort2PushSync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0042AC, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -583,7 +583,7 @@ s64 cellSpursJobQueuePort2PushSync() s64 cellSpursJobQueuePort2PushFlush() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004330, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -594,7 +594,7 @@ s64 cellSpursJobQueuePort2PushFlush() s64 _cellSpursJobQueuePort2PushJobListBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0043B0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -605,7 +605,7 @@ s64 _cellSpursJobQueuePort2PushJobListBody() s64 cellSpursJobQueuePort2Sync() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0045AC, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -616,7 +616,7 @@ s64 cellSpursJobQueuePort2Sync() s64 cellSpursJobQueuePort2Create() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0046C4, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -627,7 +627,7 @@ s64 cellSpursJobQueuePort2Create() s64 cellSpursJobQueuePort2Destroy() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0047E4, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -638,7 +638,7 @@ s64 cellSpursJobQueuePort2Destroy() s64 cellSpursJobQueuePort2AllocateJobDescriptor() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004928, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -649,7 +649,7 @@ s64 cellSpursJobQueuePort2AllocateJobDescriptor() s64 _cellSpursJobQueuePort2PushAndReleaseJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004D94, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -660,7 +660,7 @@ s64 _cellSpursJobQueuePort2PushAndReleaseJobBody() s64 _cellSpursJobQueuePort2CopyPushJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004DD0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -671,7 +671,7 @@ s64 _cellSpursJobQueuePort2CopyPushJobBody() s64 _cellSpursJobQueuePort2PushJobBody() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004E0C, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -682,7 +682,7 @@ s64 _cellSpursJobQueuePort2PushJobBody() s64 cellSpursJobQueueSetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004E48, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -693,7 +693,7 @@ s64 cellSpursJobQueueSetExceptionEventHandler() s64 cellSpursJobQueueUnsetExceptionEventHandler() { #ifdef PRX_DEBUG - cellSpursJq->Warning("%s()", __FUNCTION__); + cellSpursJq.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004EC0, libspurs_jq_rtoc); #else UNIMPLEMENTED_FUNC(cellSpursJq); @@ -701,10 +701,8 @@ s64 cellSpursJobQueueUnsetExceptionEventHandler() #endif } -void cellSpursJq_init(Module *pxThis) +Module cellSpursJq("cellSpursJq", []() { - cellSpursJq = pxThis; - REG_FUNC(cellSpursJq, cellSpursJobQueueAttributeInitialize); REG_FUNC(cellSpursJq, cellSpursJobQueueAttributeSetMaxGrab); REG_FUNC(cellSpursJq, cellSpursJobQueueAttributeSetSubmitWithEntryLock); @@ -806,4 +804,4 @@ void cellSpursJq_init(Module *pxThis) fix_relocs(cellSpursJq, libspurs_jq, 0xFF70, 0x12370, 0xED00); }); #endif -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp index 67f07e0bd3..c3934b8d74 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursSpu.cpp @@ -66,7 +66,7 @@ s32 spursTasksetProcessSyscall(SPUThread & spu, u32 syscallNum, u32 args); void spursTasksetInit(SPUThread & spu, u32 pollStatus); s32 spursTasksetLoadElf(SPUThread & spu, u32 * entryPoint, u32 * lowestLoadAddr, u64 elfAddr, bool skipWriteableSegments); -extern Module *cellSpurs; +extern Module cellSpurs; ////////////////////////////////////////////////////////////////////////////// // SPURS utility functions diff --git a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp index 98f71097f4..b5d389ff32 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSubdisplay.cpp @@ -4,7 +4,7 @@ #include "cellSubdisplay.h" -Module *cellSubdisplay = nullptr; +extern Module cellSubdisplay; int cellSubDisplayInit() { @@ -20,7 +20,7 @@ int cellSubDisplayEnd() int cellSubDisplayGetRequiredMemory(vm::ptr pParam) { - cellSubdisplay->Warning("cellSubDisplayGetRequiredMemory(pParam_addr=0x%x)", pParam.addr()); + cellSubdisplay.Warning("cellSubDisplayGetRequiredMemory(pParam_addr=0x%x)", pParam.addr()); if (pParam->version == CELL_SUBDISPLAY_VERSION_0002) { @@ -74,20 +74,18 @@ int cellSubDisplayGetPeerList() return CELL_OK; } -void cellSubdisplay_init(Module *pxThis) +Module cellSubdisplay("cellSubdisplay", []() { - cellSubdisplay = pxThis; + cellSubdisplay.AddFunc(0xf9a7e8a5, cellSubDisplayInit); + cellSubdisplay.AddFunc(0x551d80a5, cellSubDisplayEnd); + cellSubdisplay.AddFunc(0x6595ce22, cellSubDisplayGetRequiredMemory); + cellSubdisplay.AddFunc(0xa5bccb47, cellSubDisplayStart); + cellSubdisplay.AddFunc(0x6d85ddb3, cellSubDisplayStop); - cellSubdisplay->AddFunc(0xf9a7e8a5, cellSubDisplayInit); - cellSubdisplay->AddFunc(0x551d80a5, cellSubDisplayEnd); - cellSubdisplay->AddFunc(0x6595ce22, cellSubDisplayGetRequiredMemory); - cellSubdisplay->AddFunc(0xa5bccb47, cellSubDisplayStart); - cellSubdisplay->AddFunc(0x6d85ddb3, cellSubDisplayStop); + cellSubdisplay.AddFunc(0x938ac642, cellSubDisplayGetVideoBuffer); + cellSubdisplay.AddFunc(0xaee1e0c2, cellSubDisplayAudioOutBlocking); + cellSubdisplay.AddFunc(0x5468d6b0, cellSubDisplayAudioOutNonBlocking); - cellSubdisplay->AddFunc(0x938ac642, cellSubDisplayGetVideoBuffer); - cellSubdisplay->AddFunc(0xaee1e0c2, cellSubDisplayAudioOutBlocking); - cellSubdisplay->AddFunc(0x5468d6b0, cellSubDisplayAudioOutNonBlocking); - - cellSubdisplay->AddFunc(0x8a264d71, cellSubDisplayGetPeerNum); - cellSubdisplay->AddFunc(0xe2485f79, cellSubDisplayGetPeerList); -} + cellSubdisplay.AddFunc(0x8a264d71, cellSubDisplayGetPeerNum); + cellSubdisplay.AddFunc(0xe2485f79, cellSubDisplayGetPeerList); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 121147d385..502b51c1eb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -11,7 +11,7 @@ #include "Emu/Event.h" #include "cellSync.h" -Module *cellSync = nullptr; +extern Module cellSync; #ifdef PRX_DEBUG #include "prx_libsre.h" @@ -44,14 +44,14 @@ s32 syncMutexInitialize(vm::ptr mutex) s32 cellSyncMutexInitialize(vm::ptr mutex) { - cellSync->Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexInitialize(mutex_addr=0x%x)", mutex.addr()); return syncMutexInitialize(mutex); } s32 cellSyncMutexLock(vm::ptr mutex) { - cellSync->Log("cellSyncMutexLock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexLock(mutex_addr=0x%x)", mutex.addr()); if (!mutex) { @@ -82,7 +82,7 @@ s32 cellSyncMutexLock(vm::ptr mutex) s32 cellSyncMutexTryLock(vm::ptr mutex) { - cellSync->Log("cellSyncMutexTryLock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexTryLock(mutex_addr=0x%x)", mutex.addr()); if (!mutex) { @@ -106,7 +106,7 @@ s32 cellSyncMutexTryLock(vm::ptr mutex) s32 cellSyncMutexUnlock(vm::ptr mutex) { - cellSync->Log("cellSyncMutexUnlock(mutex_addr=0x%x)", mutex.addr()); + cellSync.Log("cellSyncMutexUnlock(mutex_addr=0x%x)", mutex.addr()); if (!mutex) { @@ -148,7 +148,7 @@ s32 syncBarrierInitialize(vm::ptr barrier, u16 total_count) s32 cellSyncBarrierInitialize(vm::ptr barrier, u16 total_count) { - cellSync->Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.addr(), total_count); + cellSync.Log("cellSyncBarrierInitialize(barrier_addr=0x%x, total_count=%d)", barrier.addr(), total_count); return syncBarrierInitialize(barrier, total_count); } @@ -173,7 +173,7 @@ s32 syncBarrierTryNotifyOp(CellSyncBarrier::data_t& barrier) s32 cellSyncBarrierNotify(vm::ptr barrier) { - cellSync->Log("cellSyncBarrierNotify(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierNotify(barrier_addr=0x%x)", barrier.addr()); if (!barrier) { @@ -195,7 +195,7 @@ s32 cellSyncBarrierNotify(vm::ptr barrier) s32 cellSyncBarrierTryNotify(vm::ptr barrier) { - cellSync->Log("cellSyncBarrierTryNotify(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierTryNotify(barrier_addr=0x%x)", barrier.addr()); if (!barrier) { @@ -235,7 +235,7 @@ s32 syncBarrierTryWaitOp(CellSyncBarrier::data_t& barrier) s32 cellSyncBarrierWait(vm::ptr barrier) { - cellSync->Log("cellSyncBarrierWait(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierWait(barrier_addr=0x%x)", barrier.addr()); if (!barrier) { @@ -257,7 +257,7 @@ s32 cellSyncBarrierWait(vm::ptr barrier) s32 cellSyncBarrierTryWait(vm::ptr barrier) { - cellSync->Log("cellSyncBarrierTryWait(barrier_addr=0x%x)", barrier.addr()); + cellSync.Log("cellSyncBarrierTryWait(barrier_addr=0x%x)", barrier.addr()); if (!barrier) { @@ -301,7 +301,7 @@ s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer s32 cellSyncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer_size) { - cellSync->Log("cellSyncRwmInitialize(rwm_addr=0x%x, buffer_addr=0x%x, buffer_size=0x%x)", rwm.addr(), buffer.addr(), buffer_size); + cellSync.Log("cellSyncRwmInitialize(rwm_addr=0x%x, buffer_addr=0x%x, buffer_size=0x%x)", rwm.addr(), buffer.addr(), buffer_size); return syncRwmInitialize(rwm, buffer, buffer_size); } @@ -330,7 +330,7 @@ s32 syncRwmReadEndOp(CellSyncRwm::data_t& rwm) s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) { - cellSync->Log("cellSyncRwmRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); if (!rwm || !buffer) { @@ -353,7 +353,7 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) // prx: decrease m_readers (return 0x8041010C if already zero) if (s32 res = rwm->data.atomic_op(CELL_OK, syncRwmReadEndOp)) { - cellSync->Error("syncRwmReadEndOp(rwm=0x%x) failed: m_readers == 0", rwm); + cellSync.Error("syncRwmReadEndOp(rwm=0x%x) failed: m_readers == 0", rwm); return res; } @@ -363,7 +363,7 @@ s32 cellSyncRwmRead(vm::ptr rwm, vm::ptr buffer) s32 cellSyncRwmTryRead(vm::ptr rwm, vm::ptr buffer) { - cellSync->Log("cellSyncRwmTryRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmTryRead(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); if (!rwm || !buffer) { @@ -403,7 +403,7 @@ s32 syncRwmTryWriteBeginOp(CellSyncRwm::data_t& rwm) s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) { - cellSync->Log("cellSyncRwmWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); if (!rwm || !buffer) { @@ -436,7 +436,7 @@ s32 cellSyncRwmWrite(vm::ptr rwm, vm::ptr buffer) s32 cellSyncRwmTryWrite(vm::ptr rwm, vm::ptr buffer) { - cellSync->Log("cellSyncRwmTryWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); + cellSync.Log("cellSyncRwmTryWrite(rwm_addr=0x%x, buffer_addr=0x%x)", rwm.addr(), buffer.addr()); if (!rwm || !buffer) { @@ -491,7 +491,7 @@ s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 si s32 cellSyncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth) { - cellSync->Log("cellSyncQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x)", queue.addr(), buffer.addr(), size, depth); + cellSync.Log("cellSyncQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x)", queue.addr(), buffer.addr(), size, depth); return syncQueueInitialize(queue, buffer, size, depth); } @@ -518,7 +518,7 @@ s32 syncQueueTryPushOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueuePush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -554,7 +554,7 @@ s32 cellSyncQueuePush(vm::ptr queue, vm::ptr buffer) s32 cellSyncQueueTryPush(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueueTryPush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPush(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -608,7 +608,7 @@ s32 syncQueueTryPopOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueuePop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -644,7 +644,7 @@ s32 cellSyncQueuePop(vm::ptr queue, vm::ptr buffer) s32 cellSyncQueueTryPop(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueueTryPop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPop(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -692,7 +692,7 @@ s32 syncQueueTryPeekOp(CellSyncQueue::data_t& queue, u32 depth, u32& position) s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueuePeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueuePeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -725,7 +725,7 @@ s32 cellSyncQueuePeek(vm::ptr queue, vm::ptr buffer) s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) { - cellSync->Log("cellSyncQueueTryPeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); + cellSync.Log("cellSyncQueueTryPeek(queue_addr=0x%x, buffer_addr=0x%x)", queue.addr(), buffer.addr()); if (!queue || !buffer) { @@ -759,7 +759,7 @@ s32 cellSyncQueueTryPeek(vm::ptr queue, vm::ptr buffer) s32 cellSyncQueueSize(vm::ptr queue) { - cellSync->Log("cellSyncQueueSize(queue_addr=0x%x)", queue.addr()); + cellSync.Log("cellSyncQueueSize(queue_addr=0x%x)", queue.addr()); if (!queue) { @@ -780,7 +780,7 @@ s32 cellSyncQueueSize(vm::ptr queue) s32 cellSyncQueueClear(vm::ptr queue) { - cellSync->Log("cellSyncQueueClear(queue_addr=0x%x)", queue.addr()); + cellSync.Log("cellSyncQueueClear(queue_addr=0x%x)", queue.addr()); if (!queue) { @@ -837,10 +837,10 @@ s32 cellSyncQueueClear(vm::ptr queue) void syncLFQueueDump(vm::ptr queue) { - cellSync->Notice("CellSyncLFQueue dump: addr = 0x%x", queue.addr()); + cellSync.Notice("CellSyncLFQueue dump: addr = 0x%x", queue.addr()); for (u32 i = 0; i < sizeof(CellSyncLFQueue) / 16; i++) { - cellSync->Notice("*** 0x%.16llx 0x%.16llx", vm::read64(queue.addr() + i * 16), vm::read64(queue.addr() + i * 16 + 8)); + cellSync.Notice("*** 0x%.16llx 0x%.16llx", vm::read64(queue.addr() + i * 16), vm::read64(queue.addr() + i * 16 + 8)); } } @@ -992,7 +992,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 s32 cellSyncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { - cellSync->Warning("cellSyncLFQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)", + cellSync.Warning("cellSyncLFQueueInitialize(queue_addr=0x%x, buffer_addr=0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal_addr=0x%x)", queue.addr(), buffer.addr(), size, depth, direction, eaSignal.addr()); return syncLFQueueInitialize(queue, buffer, size, depth, direction, eaSignal); @@ -1101,7 +1101,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPushPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { - cellSync->Todo("_cellSyncLFQueueGetPushPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + cellSync.Todo("_cellSyncLFQueueGetPushPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", queue.addr(), pointer.addr(), isBlocking, useEventQueue); s32 pointer_value; @@ -1121,7 +1121,7 @@ s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPushPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPushPointer - cellSync->Todo("_cellSyncLFQueueGetPushPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + cellSync.Todo("_cellSyncLFQueueGetPushPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", queue.addr(), pointer.addr(), isBlocking, useEventQueue); s32 pointer_value; @@ -1266,7 +1266,7 @@ s32 syncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePushPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { - cellSync->Todo("_cellSyncLFQueueCompletePushPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", + cellSync.Todo("_cellSyncLFQueueCompletePushPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", queue.addr(), pointer, fpSendSignal.addr()); return syncLFQueueCompletePushPointer(queue, pointer, fpSendSignal); @@ -1283,7 +1283,7 @@ s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) { // arguments copied from _cellSyncLFQueueCompletePushPointer - cellSync->Todo("_cellSyncLFQueueCompletePushPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", + cellSync.Todo("_cellSyncLFQueueCompletePushPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x)", queue.addr(), pointer, fpSendSignal.addr()); return syncLFQueueCompletePushPointer2(queue, pointer, fpSendSignal); @@ -1292,7 +1292,7 @@ s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 poi s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 - cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); + cellSync.Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); if (!queue || !buffer) { @@ -1344,7 +1344,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - cellSync->Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x) aborted", queue.addr()); + cellSync.Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x) aborted", queue.addr()); return CELL_OK; } } @@ -1480,7 +1480,7 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i s32 _cellSyncLFQueueGetPopPointer(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 arg4, u32 useEventQueue) { - cellSync->Todo("_cellSyncLFQueueGetPopPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", + cellSync.Todo("_cellSyncLFQueueGetPopPointer(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue.addr(), pointer.addr(), isBlocking, arg4, useEventQueue); s32 pointer_value; @@ -1500,7 +1500,7 @@ s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 s32 _cellSyncLFQueueGetPopPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) { // arguments copied from _cellSyncLFQueueGetPopPointer - cellSync->Todo("_cellSyncLFQueueGetPopPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", + cellSync.Todo("_cellSyncLFQueueGetPopPointer2(queue_addr=0x%x, pointer_addr=0x%x, isBlocking=%d, useEventQueue=%d)", queue.addr(), pointer.addr(), isBlocking, useEventQueue); s32 pointer_value; @@ -1645,7 +1645,7 @@ s32 syncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, c s32 _cellSyncLFQueueCompletePopPointer(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) - cellSync->Todo("_cellSyncLFQueueCompletePopPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", + cellSync.Todo("_cellSyncLFQueueCompletePopPointer(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", queue.addr(), pointer, fpSendSignal.addr(), noQueueFull); return syncLFQueueCompletePopPointer(queue, pointer, fpSendSignal, noQueueFull); @@ -1662,7 +1662,7 @@ s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) { // arguments copied from _cellSyncLFQueueCompletePopPointer - cellSync->Todo("_cellSyncLFQueueCompletePopPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", + cellSync.Todo("_cellSyncLFQueueCompletePopPointer2(queue_addr=0x%x, pointer=%d, fpSendSignal_addr=0x%x, noQueueFull=%d)", queue.addr(), pointer, fpSendSignal.addr(), noQueueFull); return syncLFQueueCompletePopPointer2(queue, pointer, fpSendSignal, noQueueFull); @@ -1671,7 +1671,7 @@ s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 poin s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm::ptr buffer, u32 isBlocking) { // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 - cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); + cellSync.Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x, buffer_addr=0x%x, isBlocking=%d)", queue.addr(), buffer.addr(), isBlocking); if (!queue || !buffer) { @@ -1722,7 +1722,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack if (Emu.IsStopped()) { - cellSync->Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x) aborted", queue.addr()); + cellSync.Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x) aborted", queue.addr()); return CELL_OK; } } @@ -1757,7 +1757,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: s32 cellSyncLFQueueClear(vm::ptr queue) { - cellSync->Warning("cellSyncLFQueueClear(queue_addr=0x%x)", queue.addr()); + cellSync.Warning("cellSyncLFQueueClear(queue_addr=0x%x)", queue.addr()); if (!queue) { @@ -1807,7 +1807,7 @@ s32 cellSyncLFQueueClear(vm::ptr queue) s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) { - cellSync->Warning("cellSyncLFQueueSize(queue_addr=0x%x, size_addr=0x%x)", queue.addr(), size.addr()); + cellSync.Warning("cellSyncLFQueueSize(queue_addr=0x%x, size_addr=0x%x)", queue.addr(), size.addr()); if (!queue || !size) { @@ -1842,7 +1842,7 @@ s32 cellSyncLFQueueSize(vm::ptr queue, vm::ptr size) s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) { - cellSync->Log("cellSyncLFQueueDepth(queue_addr=0x%x, depth_addr=0x%x)", queue.addr(), depth.addr()); + cellSync.Log("cellSyncLFQueueDepth(queue_addr=0x%x, depth_addr=0x%x)", queue.addr(), depth.addr()); if (!queue || !depth) { @@ -1859,7 +1859,7 @@ s32 cellSyncLFQueueDepth(vm::ptr queue, vm::ptr depth) s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::ptr ppSignal) { - cellSync->Log("_cellSyncLFQueueGetSignalAddress(queue_addr=0x%x, ppSignal_addr=0x%x)", queue.addr(), ppSignal.addr()); + cellSync.Log("_cellSyncLFQueueGetSignalAddress(queue_addr=0x%x, ppSignal_addr=0x%x)", queue.addr(), ppSignal.addr()); if (!queue || !ppSignal) { @@ -1876,7 +1876,7 @@ s32 _cellSyncLFQueueGetSignalAddress(vm::ptr queue, vm::p s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr direction) { - cellSync->Log("cellSyncLFQueueGetDirection(queue_addr=0x%x, direction_addr=0x%x)", queue.addr(), direction.addr()); + cellSync.Log("cellSyncLFQueueGetDirection(queue_addr=0x%x, direction_addr=0x%x)", queue.addr(), direction.addr()); if (!queue || !direction) { @@ -1893,7 +1893,7 @@ s32 cellSyncLFQueueGetDirection(vm::ptr queue, vm::ptr queue, vm::ptr entry_size) { - cellSync->Log("cellSyncLFQueueGetEntrySize(queue_addr=0x%x, entry_size_addr=0x%x)", queue.addr(), entry_size.addr()); + cellSync.Log("cellSyncLFQueueGetEntrySize(queue_addr=0x%x, entry_size_addr=0x%x)", queue.addr(), entry_size.addr()); if (!queue || !entry_size) { @@ -1921,7 +1921,7 @@ s32 syncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr queue) { - cellSync->Todo("_cellSyncLFQueueAttachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); + cellSync.Todo("_cellSyncLFQueueAttachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); return syncLFQueueAttachLv2EventQueue(spus, num, queue); } @@ -1939,61 +1939,59 @@ s32 syncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr queue) { - cellSync->Todo("_cellSyncLFQueueDetachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); + cellSync.Todo("_cellSyncLFQueueDetachLv2EventQueue(spus_addr=0x%x, num=%d, queue_addr=0x%x)", spus.addr(), num, queue.addr()); return syncLFQueueDetachLv2EventQueue(spus, num, queue); } -void cellSync_init(Module *pxThis) +Module cellSync("cellSync", []() { - cellSync = pxThis; + cellSync.AddFunc(0xa9072dee, cellSyncMutexInitialize); + cellSync.AddFunc(0x1bb675c2, cellSyncMutexLock); + cellSync.AddFunc(0xd06918c4, cellSyncMutexTryLock); + cellSync.AddFunc(0x91f2b7b0, cellSyncMutexUnlock); - cellSync->AddFunc(0xa9072dee, cellSyncMutexInitialize); - cellSync->AddFunc(0x1bb675c2, cellSyncMutexLock); - cellSync->AddFunc(0xd06918c4, cellSyncMutexTryLock); - cellSync->AddFunc(0x91f2b7b0, cellSyncMutexUnlock); + cellSync.AddFunc(0x07254fda, cellSyncBarrierInitialize); + cellSync.AddFunc(0xf06a6415, cellSyncBarrierNotify); + cellSync.AddFunc(0x268edd6d, cellSyncBarrierTryNotify); + cellSync.AddFunc(0x35f21355, cellSyncBarrierWait); + cellSync.AddFunc(0x6c272124, cellSyncBarrierTryWait); - cellSync->AddFunc(0x07254fda, cellSyncBarrierInitialize); - cellSync->AddFunc(0xf06a6415, cellSyncBarrierNotify); - cellSync->AddFunc(0x268edd6d, cellSyncBarrierTryNotify); - cellSync->AddFunc(0x35f21355, cellSyncBarrierWait); - cellSync->AddFunc(0x6c272124, cellSyncBarrierTryWait); + cellSync.AddFunc(0xfc48b03f, cellSyncRwmInitialize); + cellSync.AddFunc(0xcece771f, cellSyncRwmRead); + cellSync.AddFunc(0xa6669751, cellSyncRwmTryRead); + cellSync.AddFunc(0xed773f5f, cellSyncRwmWrite); + cellSync.AddFunc(0xba5bee48, cellSyncRwmTryWrite); - cellSync->AddFunc(0xfc48b03f, cellSyncRwmInitialize); - cellSync->AddFunc(0xcece771f, cellSyncRwmRead); - cellSync->AddFunc(0xa6669751, cellSyncRwmTryRead); - cellSync->AddFunc(0xed773f5f, cellSyncRwmWrite); - cellSync->AddFunc(0xba5bee48, cellSyncRwmTryWrite); + cellSync.AddFunc(0x3929948d, cellSyncQueueInitialize); + cellSync.AddFunc(0x5ae841e5, cellSyncQueuePush); + cellSync.AddFunc(0x705985cd, cellSyncQueueTryPush); + cellSync.AddFunc(0x4da6d7e0, cellSyncQueuePop); + cellSync.AddFunc(0xa58df87f, cellSyncQueueTryPop); + cellSync.AddFunc(0x48154c9b, cellSyncQueuePeek); + cellSync.AddFunc(0x68af923c, cellSyncQueueTryPeek); + cellSync.AddFunc(0x4da349b2, cellSyncQueueSize); + cellSync.AddFunc(0xa5362e73, cellSyncQueueClear); - cellSync->AddFunc(0x3929948d, cellSyncQueueInitialize); - cellSync->AddFunc(0x5ae841e5, cellSyncQueuePush); - cellSync->AddFunc(0x705985cd, cellSyncQueueTryPush); - cellSync->AddFunc(0x4da6d7e0, cellSyncQueuePop); - cellSync->AddFunc(0xa58df87f, cellSyncQueueTryPop); - cellSync->AddFunc(0x48154c9b, cellSyncQueuePeek); - cellSync->AddFunc(0x68af923c, cellSyncQueueTryPeek); - cellSync->AddFunc(0x4da349b2, cellSyncQueueSize); - cellSync->AddFunc(0xa5362e73, cellSyncQueueClear); - - cellSync->AddFunc(0x0c7cb9f7, cellSyncLFQueueGetEntrySize); - cellSync->AddFunc(0x167ea63e, cellSyncLFQueueSize); - cellSync->AddFunc(0x2af0c515, cellSyncLFQueueClear); - cellSync->AddFunc(0x35bbdad2, _cellSyncLFQueueCompletePushPointer2); - cellSync->AddFunc(0x46356fe0, _cellSyncLFQueueGetPopPointer2); - cellSync->AddFunc(0x4e88c68d, _cellSyncLFQueueCompletePushPointer); - cellSync->AddFunc(0x54fc2032, _cellSyncLFQueueAttachLv2EventQueue); - cellSync->AddFunc(0x6bb4ef9d, _cellSyncLFQueueGetPushPointer2); - cellSync->AddFunc(0x74c37666, _cellSyncLFQueueGetPopPointer); - cellSync->AddFunc(0x7a51deee, _cellSyncLFQueueCompletePopPointer2); - cellSync->AddFunc(0x811d148e, _cellSyncLFQueueDetachLv2EventQueue); - cellSync->AddFunc(0xaa355278, cellSyncLFQueueInitialize); - cellSync->AddFunc(0xaff7627a, _cellSyncLFQueueGetSignalAddress); - cellSync->AddFunc(0xba5961ca, _cellSyncLFQueuePushBody); - cellSync->AddFunc(0xd59aa307, cellSyncLFQueueGetDirection); - cellSync->AddFunc(0xe18c273c, cellSyncLFQueueDepth); - cellSync->AddFunc(0xe1bc7add, _cellSyncLFQueuePopBody); - cellSync->AddFunc(0xe9bf2110, _cellSyncLFQueueGetPushPointer); - cellSync->AddFunc(0xfe74e8e7, _cellSyncLFQueueCompletePopPointer); + cellSync.AddFunc(0x0c7cb9f7, cellSyncLFQueueGetEntrySize); + cellSync.AddFunc(0x167ea63e, cellSyncLFQueueSize); + cellSync.AddFunc(0x2af0c515, cellSyncLFQueueClear); + cellSync.AddFunc(0x35bbdad2, _cellSyncLFQueueCompletePushPointer2); + cellSync.AddFunc(0x46356fe0, _cellSyncLFQueueGetPopPointer2); + cellSync.AddFunc(0x4e88c68d, _cellSyncLFQueueCompletePushPointer); + cellSync.AddFunc(0x54fc2032, _cellSyncLFQueueAttachLv2EventQueue); + cellSync.AddFunc(0x6bb4ef9d, _cellSyncLFQueueGetPushPointer2); + cellSync.AddFunc(0x74c37666, _cellSyncLFQueueGetPopPointer); + cellSync.AddFunc(0x7a51deee, _cellSyncLFQueueCompletePopPointer2); + cellSync.AddFunc(0x811d148e, _cellSyncLFQueueDetachLv2EventQueue); + cellSync.AddFunc(0xaa355278, cellSyncLFQueueInitialize); + cellSync.AddFunc(0xaff7627a, _cellSyncLFQueueGetSignalAddress); + cellSync.AddFunc(0xba5961ca, _cellSyncLFQueuePushBody); + cellSync.AddFunc(0xd59aa307, cellSyncLFQueueGetDirection); + cellSync.AddFunc(0xe18c273c, cellSyncLFQueueDepth); + cellSync.AddFunc(0xe1bc7add, _cellSyncLFQueuePopBody); + cellSync.AddFunc(0xe9bf2110, _cellSyncLFQueueGetPushPointer); + cellSync.AddFunc(0xfe74e8e7, _cellSyncLFQueueCompletePopPointer); #ifdef PRX_DEBUG CallAfter([]() @@ -2043,4 +2041,4 @@ void cellSync_init(Module *pxThis) fix_relocs(cellSync, libsre, 0x31EE0, 0x3A4F0, 0x2DF00); }); #endif -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp index fb39449614..0f229cf3fa 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp @@ -5,7 +5,7 @@ #include "cellSync2.h" -Module* cellSync2 = nullptr; +extern Module cellSync2; #ifdef PRX_DEBUG #include "prx_libsync2.h" @@ -16,10 +16,10 @@ u32 libsync2_rtoc; s64 _cellSync2MutexAttributeInitialize(vm::ptr attr, u32 sdkVersion) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x16A0, libsync2_rtoc); #else - cellSync2->Warning("_cellSync2MutexAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2MutexAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -36,10 +36,10 @@ s64 _cellSync2MutexAttributeInitialize(vm::ptr attr, u3 s64 cellSync2MutexEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0xC3C, libsync2_rtoc); #else - cellSync2->Todo("cellSync2MutexEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2MutexEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -51,7 +51,7 @@ s64 cellSync2MutexEstimateBufferSize(vm::ptr attr s64 cellSync2MutexInitialize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x1584, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -62,7 +62,7 @@ s64 cellSync2MutexInitialize() s64 cellSync2MutexFinalize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x142C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -73,7 +73,7 @@ s64 cellSync2MutexFinalize() s64 cellSync2MutexLock() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x1734, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -84,7 +84,7 @@ s64 cellSync2MutexLock() s64 cellSync2MutexTryLock() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x1A2C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -95,7 +95,7 @@ s64 cellSync2MutexTryLock() s64 cellSync2MutexUnlock() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x186C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -106,10 +106,10 @@ s64 cellSync2MutexUnlock() s64 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 sdkVersion) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x26DC, libsync2_rtoc); #else - cellSync2->Warning("_cellSync2CondAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2CondAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; attr->maxWaiters = 15; @@ -122,10 +122,10 @@ s64 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 s64 cellSync2CondEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x1B90, libsync2_rtoc); #else - cellSync2->Todo("cellSync2CondEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2CondEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -137,7 +137,7 @@ s64 cellSync2CondEstimateBufferSize(vm::ptr attr, s64 cellSync2CondInitialize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x25DC, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -148,7 +148,7 @@ s64 cellSync2CondInitialize() s64 cellSync2CondFinalize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x23E0, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -159,7 +159,7 @@ s64 cellSync2CondFinalize() s64 cellSync2CondWait() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x283C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -170,7 +170,7 @@ s64 cellSync2CondWait() s64 cellSync2CondSignal() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x2768, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -181,7 +181,7 @@ s64 cellSync2CondSignal() s64 cellSync2CondSignalAll() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x2910, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -192,10 +192,10 @@ s64 cellSync2CondSignalAll() s64 _cellSync2SemaphoreAttributeInitialize(vm::ptr attr, u32 sdkVersion) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x5644, libsync2_rtoc); #else - cellSync2->Warning("_cellSync2SemaphoreAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2SemaphoreAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -211,10 +211,10 @@ s64 _cellSync2SemaphoreAttributeInitialize(vm::ptr s64 cellSync2SemaphoreEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x4AC4, libsync2_rtoc); #else - cellSync2->Todo("cellSync2SemaphoreEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2SemaphoreEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; @@ -226,7 +226,7 @@ s64 cellSync2SemaphoreEstimateBufferSize(vm::ptrWarning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x54E0, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -237,7 +237,7 @@ s64 cellSync2SemaphoreInitialize() s64 cellSync2SemaphoreFinalize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x52F0, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -248,7 +248,7 @@ s64 cellSync2SemaphoreFinalize() s64 cellSync2SemaphoreAcquire() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x57A4, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -259,7 +259,7 @@ s64 cellSync2SemaphoreAcquire() s64 cellSync2SemaphoreTryAcquire() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x56D8, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -270,7 +270,7 @@ s64 cellSync2SemaphoreTryAcquire() s64 cellSync2SemaphoreRelease() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x5870, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -281,7 +281,7 @@ s64 cellSync2SemaphoreRelease() s64 cellSync2SemaphoreGetCount() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x4B4C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -292,10 +292,10 @@ s64 cellSync2SemaphoreGetCount() s64 _cellSync2QueueAttributeInitialize(vm::ptr attr, u32 sdkVersion) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x3C5C, libsync2_rtoc); #else - cellSync2->Warning("_cellSync2QueueAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); + cellSync2.Warning("_cellSync2QueueAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; attr->threadTypes = CELL_SYNC2_THREAD_TYPE_PPU_THREAD | CELL_SYNC2_THREAD_TYPE_PPU_FIBER | @@ -314,10 +314,10 @@ s64 _cellSync2QueueAttributeInitialize(vm::ptr attr, u3 s64 cellSync2QueueEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x2A98, libsync2_rtoc); #else - cellSync2->Todo("cellSync2QueueEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); + cellSync2.Todo("cellSync2QueueEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->elementSize == 0 || attr->elementSize > 16384 || attr->elementSize % 16 || attr->depth == 0 || attr->depth > 4294967292 || attr->maxPushWaiters > 32768 || attr->maxPopWaiters > 32768) @@ -330,7 +330,7 @@ s64 cellSync2QueueEstimateBufferSize(vm::ptr attr s64 cellSync2QueueInitialize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x3F98, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -341,7 +341,7 @@ s64 cellSync2QueueInitialize() s64 cellSync2QueueFinalize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x3C28, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -352,7 +352,7 @@ s64 cellSync2QueueFinalize() s64 cellSync2QueuePush() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x478C, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -363,7 +363,7 @@ s64 cellSync2QueuePush() s64 cellSync2QueueTryPush() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x4680, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -374,7 +374,7 @@ s64 cellSync2QueueTryPush() s64 cellSync2QueuePop() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x4974, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -385,7 +385,7 @@ s64 cellSync2QueuePop() s64 cellSync2QueueTryPop() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x4880, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -396,7 +396,7 @@ s64 cellSync2QueueTryPop() s64 cellSync2QueueGetSize() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x2C00, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -407,7 +407,7 @@ s64 cellSync2QueueGetSize() s64 cellSync2QueueGetDepth() { #ifdef PRX_DEBUG - cellSync2->Warning("%s()", __FUNCTION__); + cellSync2.Warning("%s()", __FUNCTION__); return GetCurrentPPUThread().FastCall2(libsync2 + 0x2B90, libsync2_rtoc); #else UNIMPLEMENTED_FUNC(cellSync2); @@ -415,45 +415,43 @@ s64 cellSync2QueueGetDepth() #endif } -void cellSync2_init(Module *pxThis) +Module cellSync2("cellSync2", []() { - cellSync2 = pxThis; + cellSync2.AddFunc(0x55836e73, _cellSync2MutexAttributeInitialize); + cellSync2.AddFunc(0xd51bfae7, cellSync2MutexEstimateBufferSize); + cellSync2.AddFunc(0xeb81a467, cellSync2MutexInitialize); + cellSync2.AddFunc(0x27f2d61c, cellSync2MutexFinalize); + cellSync2.AddFunc(0xa400d82e, cellSync2MutexLock); + cellSync2.AddFunc(0xa69c749c, cellSync2MutexTryLock); + cellSync2.AddFunc(0x0080fe88, cellSync2MutexUnlock); - cellSync2->AddFunc(0x55836e73, _cellSync2MutexAttributeInitialize); - cellSync2->AddFunc(0xd51bfae7, cellSync2MutexEstimateBufferSize); - cellSync2->AddFunc(0xeb81a467, cellSync2MutexInitialize); - cellSync2->AddFunc(0x27f2d61c, cellSync2MutexFinalize); - cellSync2->AddFunc(0xa400d82e, cellSync2MutexLock); - cellSync2->AddFunc(0xa69c749c, cellSync2MutexTryLock); - cellSync2->AddFunc(0x0080fe88, cellSync2MutexUnlock); + cellSync2.AddFunc(0xdf3c532a, _cellSync2CondAttributeInitialize); + cellSync2.AddFunc(0x5b1e4d7a, cellSync2CondEstimateBufferSize); + cellSync2.AddFunc(0x58be9a0f, cellSync2CondInitialize); + cellSync2.AddFunc(0x63062249, cellSync2CondFinalize); + cellSync2.AddFunc(0xbc96d751, cellSync2CondWait); + cellSync2.AddFunc(0x871af804, cellSync2CondSignal); + cellSync2.AddFunc(0x8aae07c2, cellSync2CondSignalAll); - cellSync2->AddFunc(0xdf3c532a, _cellSync2CondAttributeInitialize); - cellSync2->AddFunc(0x5b1e4d7a, cellSync2CondEstimateBufferSize); - cellSync2->AddFunc(0x58be9a0f, cellSync2CondInitialize); - cellSync2->AddFunc(0x63062249, cellSync2CondFinalize); - cellSync2->AddFunc(0xbc96d751, cellSync2CondWait); - cellSync2->AddFunc(0x871af804, cellSync2CondSignal); - cellSync2->AddFunc(0x8aae07c2, cellSync2CondSignalAll); + cellSync2.AddFunc(0x2d77fe17, _cellSync2SemaphoreAttributeInitialize); + cellSync2.AddFunc(0x74c2780f, cellSync2SemaphoreEstimateBufferSize); + cellSync2.AddFunc(0xc5dee254, cellSync2SemaphoreInitialize); + cellSync2.AddFunc(0x164843a7, cellSync2SemaphoreFinalize); + cellSync2.AddFunc(0xd1b0d146, cellSync2SemaphoreAcquire); + cellSync2.AddFunc(0x5e4b0f87, cellSync2SemaphoreTryAcquire); + cellSync2.AddFunc(0x0c2983ac, cellSync2SemaphoreRelease); + cellSync2.AddFunc(0x4e2ee031, cellSync2SemaphoreGetCount); - cellSync2->AddFunc(0x2d77fe17, _cellSync2SemaphoreAttributeInitialize); - cellSync2->AddFunc(0x74c2780f, cellSync2SemaphoreEstimateBufferSize); - cellSync2->AddFunc(0xc5dee254, cellSync2SemaphoreInitialize); - cellSync2->AddFunc(0x164843a7, cellSync2SemaphoreFinalize); - cellSync2->AddFunc(0xd1b0d146, cellSync2SemaphoreAcquire); - cellSync2->AddFunc(0x5e4b0f87, cellSync2SemaphoreTryAcquire); - cellSync2->AddFunc(0x0c2983ac, cellSync2SemaphoreRelease); - cellSync2->AddFunc(0x4e2ee031, cellSync2SemaphoreGetCount); - - cellSync2->AddFunc(0x5e00d433, _cellSync2QueueAttributeInitialize); - cellSync2->AddFunc(0xc08cc0f9, cellSync2QueueEstimateBufferSize); - cellSync2->AddFunc(0xf125e044, cellSync2QueueInitialize); - cellSync2->AddFunc(0x6af85cdf, cellSync2QueueFinalize); - cellSync2->AddFunc(0x7d967d91, cellSync2QueuePush); - cellSync2->AddFunc(0x7fd479fe, cellSync2QueueTryPush); - cellSync2->AddFunc(0xd83ab0c9, cellSync2QueuePop); - cellSync2->AddFunc(0x0c9a0ea9, cellSync2QueueTryPop); - cellSync2->AddFunc(0x12f0a27d, cellSync2QueueGetSize); - cellSync2->AddFunc(0xf0e1471c, cellSync2QueueGetDepth); + cellSync2.AddFunc(0x5e00d433, _cellSync2QueueAttributeInitialize); + cellSync2.AddFunc(0xc08cc0f9, cellSync2QueueEstimateBufferSize); + cellSync2.AddFunc(0xf125e044, cellSync2QueueInitialize); + cellSync2.AddFunc(0x6af85cdf, cellSync2QueueFinalize); + cellSync2.AddFunc(0x7d967d91, cellSync2QueuePush); + cellSync2.AddFunc(0x7fd479fe, cellSync2QueueTryPush); + cellSync2.AddFunc(0xd83ab0c9, cellSync2QueuePop); + cellSync2.AddFunc(0x0c9a0ea9, cellSync2QueueTryPop); + cellSync2.AddFunc(0x12f0a27d, cellSync2QueueGetSize); + cellSync2.AddFunc(0xf0e1471c, cellSync2QueueGetDepth); #ifdef PRX_DEBUG CallAfter([]() @@ -487,4 +485,4 @@ void cellSync2_init(Module *pxThis) fix_relocs(cellSync2, libsync2, 0x73A0, 0x95A0, 0x6B90); }); #endif -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp index 28828c9d38..ea377cbb40 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -4,7 +4,7 @@ #include "Emu/SysCalls/ModuleManager.h" #include "Emu/SysCalls/Modules.h" -Module *cellSysmodule = nullptr; +extern Module cellSysmodule; enum { @@ -139,88 +139,95 @@ const char *getModuleName(int id) { return "UNKNOWN MODULE"; } -int cellSysmoduleInitialize() +s32 cellSysmoduleInitialize() { - cellSysmodule->Log("cellSysmoduleInitialize()"); + cellSysmodule.Warning("cellSysmoduleInitialize()"); return CELL_OK; } -int cellSysmoduleFinalize() +s32 cellSysmoduleFinalize() { - cellSysmodule->Log("cellSysmoduleFinalize()"); + cellSysmodule.Warning("cellSysmoduleFinalize()"); return CELL_OK; } -int cellSysmoduleSetMemcontainer(u32 ct_id) +s32 cellSysmoduleSetMemcontainer(u32 ct_id) { - cellSysmodule->Todo("cellSysmoduleSetMemcontainer(ct_id=0x%x)", ct_id); + cellSysmodule.Todo("cellSysmoduleSetMemcontainer(ct_id=0x%x)", ct_id); return CELL_OK; } -int cellSysmoduleLoadModule(u16 id) +s32 cellSysmoduleLoadModule(u16 id) { - cellSysmodule->Warning("cellSysmoduleLoadModule(id=0x%04x: %s)", id, getModuleName(id)); + cellSysmodule.Warning("cellSysmoduleLoadModule(id=0x%04x: %s)", id, getModuleName(id)); - if (id == 0xf054) + if (!Emu.GetModuleManager().CheckModuleId(id)) { - cellSysmodule->Todo("cellSysmoduleLoadModule: CELL_SYSMODULE_LIBATRAC3MULTI"); + cellSysmodule.Error("cellSysmoduleLoadModule() failed: unknown module (id=0x%04x)", id); + return CELL_SYSMODULE_ERROR_UNKNOWN; } if (Module* m = Emu.GetModuleManager().GetModuleById(id)) { - // CELL_SYSMODULE_ERROR_DUPLICATED shouldn't be returned (it breaks some games) - // If some game requires it yet, there probably should be a configurable hack or something. + // CELL_SYSMODULE_ERROR_DUPLICATED shouldn't be returned m->Load(); - return CELL_OK; - } - else - { - return CELL_SYSMODULE_ERROR_UNKNOWN; - } -} - -int cellSysmoduleUnloadModule(u16 id) -{ - cellSysmodule->Warning("cellSysmoduleUnloadModule(id=0x%04x: %s)", id, getModuleName(id)); - - Module* m = Emu.GetModuleManager().GetModuleById(id); - - if(!m) - { - return CELL_SYSMODULE_ERROR_UNKNOWN; } - if(!m->IsLoaded()) - { - return CELL_SYSMODULE_ERROR_UNLOADED; - } - - m->UnLoad(); return CELL_OK; } -int cellSysmoduleIsLoaded(u16 id) +s32 cellSysmoduleUnloadModule(u16 id) { - cellSysmodule->Warning("cellSysmoduleIsLoaded(id=0x%04x: %s)", id, getModuleName(id)); + cellSysmodule.Warning("cellSysmoduleUnloadModule(id=0x%04x: %s)", id, getModuleName(id)); - Module* m = Emu.GetModuleManager().GetModuleById(id); - - if(!m) + if (!Emu.GetModuleManager().CheckModuleId(id)) { + cellSysmodule.Error("cellSysmoduleUnloadModule() failed: unknown module (id=0x%04x)", id); return CELL_SYSMODULE_ERROR_UNKNOWN; } - return m->IsLoaded() ? CELL_SYSMODULE_LOADED : CELL_SYSMODULE_ERROR_UNLOADED; + if (Module* m = Emu.GetModuleManager().GetModuleById(id)) + { + if (!m->IsLoaded()) + { + cellSysmodule.Error("cellSysmoduleUnloadModule() failed: module not loaded (id=0x%04x)", id); + return CELL_SYSMODULE_ERROR_FATAL; + } + + m->Unload(); + } + + return CELL_OK; } -void cellSysmodule_init(Module *pxThis) +s32 cellSysmoduleIsLoaded(u16 id) { - cellSysmodule = pxThis; + cellSysmodule.Warning("cellSysmoduleIsLoaded(id=0x%04x: %s)", id, getModuleName(id)); - cellSysmodule->AddFunc(0x63ff6ff9, cellSysmoduleInitialize); - cellSysmodule->AddFunc(0x96c07adf, cellSysmoduleFinalize); - cellSysmodule->AddFunc(0xa193143c, cellSysmoduleSetMemcontainer); - cellSysmodule->AddFunc(0x32267a31, cellSysmoduleLoadModule); - cellSysmodule->AddFunc(0x112a5ee9, cellSysmoduleUnloadModule); - cellSysmodule->AddFunc(0x5a59e258, cellSysmoduleIsLoaded); + if (!Emu.GetModuleManager().CheckModuleId(id)) + { + cellSysmodule.Error("cellSysmoduleIsLoaded() failed: unknown module (id=0x%04x)", id); + return CELL_SYSMODULE_ERROR_UNKNOWN; + } + + if (Module* m = Emu.GetModuleManager().GetModuleById(id)) + { + if (!m->IsLoaded()) + { + cellSysmodule.Error("cellSysmoduleIsLoaded() failed: module not loaded (id=0x%04x)", id); + return CELL_SYSMODULE_ERROR_UNLOADED; + } + } + + return CELL_SYSMODULE_LOADED; } + +Module cellSysmodule("cellSysmodule", []() +{ + cellSysmodule.AddFunc(0x63ff6ff9, cellSysmoduleInitialize); + cellSysmodule.AddFunc(0x96c07adf, cellSysmoduleFinalize); + cellSysmodule.AddFunc(0xa193143c, cellSysmoduleSetMemcontainer); + cellSysmodule.AddFunc(0x32267a31, cellSysmoduleLoadModule); + cellSysmodule.AddFunc(0x112a5ee9, cellSysmoduleUnloadModule); + cellSysmodule.AddFunc(0x5a59e258, cellSysmoduleIsLoaded); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index f38865db09..aa9ddc10d2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -21,86 +21,86 @@ typedef void (CellHddGameStatCallback)(vm::ptr cbResult, vm::ptr get, vm::ptr set); -Module *cellSysutil = nullptr; +extern Module cellSysutil; int cellSysutilGetSystemParamInt(int id, vm::ptr value) { - cellSysutil->Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.addr()); + cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.addr()); switch(id) { case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_LANG"); *value = Ini.SysLanguage.GetValue(); break; case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN"); *value = CELL_SYSUTIL_ENTER_BUTTON_ASSIGN_CROSS; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT"); *value = CELL_SYSUTIL_DATE_FMT_DDMMYYYY; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT"); *value = CELL_SYSUTIL_TIME_FMT_CLOCK24; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE"); *value = 3; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME"); *value = 1; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL"); *value = CELL_SYSUTIL_GAME_PARENTAL_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT"); *value = CELL_SYSUTIL_GAME_PARENTAL_LEVEL0_RESTRICT_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ"); *value = CELL_SYSUTIL_CAMERA_PLFREQ_DISABLED; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE"); *value = CELL_SYSUTIL_PAD_RUMBLE_OFF; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD"); *value = 0; break; case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: - cellSysutil->Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF"); + cellSysutil.Warning("cellSysutilGetSystemParamInt: CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF"); *value = 0; break; @@ -113,19 +113,19 @@ int cellSysutilGetSystemParamInt(int id, vm::ptr value) int cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) { - cellSysutil->Log("cellSysutilGetSystemParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); + cellSysutil.Log("cellSysutilGetSystemParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); memset(buf.get_ptr(), 0, bufsize); switch(id) { case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: - cellSysutil->Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); + cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME"); memcpy(buf.get_ptr(), "Unknown", 8); // for example break; case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: - cellSysutil->Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); + cellSysutil.Warning("cellSysutilGetSystemParamString: CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME"); memcpy(buf.get_ptr(), "Unknown", 8); break; @@ -138,7 +138,7 @@ int cellSysutilGetSystemParamString(s32 id, vm::ptr buf, u32 bufsize) int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr state) { - cellSysutil->Log("cellVideoOutGetState(videoOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", videoOut, deviceIndex, state.addr()); + cellSysutil.Log("cellVideoOutGetState(videoOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", videoOut, deviceIndex, state.addr()); if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -164,7 +164,7 @@ int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, vm::ptr resolution) { - cellSysutil->Log("cellVideoOutGetResolution(resolutionId=%d, resolution_addr=0x%x)", + cellSysutil.Log("cellVideoOutGetResolution(resolutionId=%d, resolution_addr=0x%x)", resolutionId, resolution.addr()); u32 num = ResolutionIdToNum(resolutionId); @@ -179,7 +179,7 @@ int cellVideoOutGetResolution(u32 resolutionId, vm::ptr s32 cellVideoOutConfigure(u32 videoOut, vm::ptr config, vm::ptr option, u32 waitForEvent) { - cellSysutil->Warning("cellVideoOutConfigure(videoOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=0x%x)", + cellSysutil.Warning("cellVideoOutConfigure(videoOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=0x%x)", videoOut, config.addr(), option.addr(), waitForEvent); switch(videoOut) @@ -213,7 +213,7 @@ s32 cellVideoOutConfigure(u32 videoOut, vm::ptr confi int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr config, vm::ptr option) { - cellSysutil->Warning("cellVideoOutGetConfiguration(videoOut=%d, config_addr=0x%x, option_addr=0x%x)", + cellSysutil.Warning("cellVideoOutGetConfiguration(videoOut=%d, config_addr=0x%x, option_addr=0x%x)", videoOut, config.addr(), option.addr()); if (option) *option = {}; @@ -239,7 +239,7 @@ int cellVideoOutGetConfiguration(u32 videoOut, vm::ptr info) { - cellSysutil->Warning("cellVideoOutGetDeviceInfo(videoOut=%d, deviceIndex=%d, info_addr=0x%x)", + cellSysutil.Warning("cellVideoOutGetDeviceInfo(videoOut=%d, deviceIndex=%d, info_addr=0x%x)", videoOut, deviceIndex, info.addr()); if(deviceIndex) return CELL_VIDEO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -271,7 +271,7 @@ int cellVideoOutGetDeviceInfo(u32 videoOut, u32 deviceIndex, vm::ptrWarning("cellVideoOutGetNumberOfDevice(videoOut=%d)", videoOut); + cellSysutil.Warning("cellVideoOutGetNumberOfDevice(videoOut=%d)", videoOut); switch(videoOut) { @@ -284,7 +284,7 @@ int cellVideoOutGetNumberOfDevice(u32 videoOut) int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 aspect, u32 option) { - cellSysutil->Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, aspect=%d, option=%d)", videoOut, resolutionId, aspect, option); + cellSysutil.Warning("cellVideoOutGetResolutionAvailability(videoOut=%d, resolutionId=0x%x, aspect=%d, option=%d)", videoOut, resolutionId, aspect, option); if (!Ini.GS3DTV.GetValue() && (resolutionId == CELL_VIDEO_OUT_RESOLUTION_720_3D_FRAME_PACKING || resolutionId == CELL_VIDEO_OUT_RESOLUTION_1024x720_3D_FRAME_PACKING || resolutionId == CELL_VIDEO_OUT_RESOLUTION_960x720_3D_FRAME_PACKING || resolutionId == CELL_VIDEO_OUT_RESOLUTION_800x720_3D_FRAME_PACKING || @@ -325,7 +325,7 @@ void sysutilSendSystemCommand(u64 status, u64 param) s32 cellSysutilCheckCallback(PPUThread& CPU) { - cellSysutil->Log("cellSysutilCheckCallback()"); + cellSysutil.Log("cellSysutilCheckCallback()"); s32 res; u32 count = 0; @@ -336,7 +336,7 @@ s32 cellSysutilCheckCallback(PPUThread& CPU) if (Emu.IsStopped()) { - cellSysutil->Warning("cellSysutilCheckCallback() aborted"); + cellSysutil.Warning("cellSysutilCheckCallback() aborted"); return CELL_OK; } @@ -356,7 +356,7 @@ s32 cellSysutilCheckCallback(PPUThread& CPU) s32 cellSysutilRegisterCallback(s32 slot, vm::ptr func, vm::ptr userdata) { - cellSysutil->Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%x, userdata=0x%x)", slot, func.addr(), userdata.addr()); + cellSysutil.Warning("cellSysutilRegisterCallback(slot=%d, func_addr=0x%x, userdata=0x%x)", slot, func.addr(), userdata.addr()); if ((u32)slot > 3) { @@ -370,7 +370,7 @@ s32 cellSysutilRegisterCallback(s32 slot, vm::ptr func, vm: s32 cellSysutilUnregisterCallback(s32 slot) { - cellSysutil->Warning("cellSysutilUnregisterCallback(slot=%d)", slot); + cellSysutil.Warning("cellSysutilUnregisterCallback(slot=%d)", slot); if ((u32)slot > 3) { @@ -384,7 +384,7 @@ s32 cellSysutilUnregisterCallback(s32 slot) int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) { - cellSysutil->Warning("cellAudioOutGetSoundAvailability(audioOut=%d, type=%d, fs=0x%x, option=%d)", + cellSysutil.Warning("cellAudioOutGetSoundAvailability(audioOut=%d, type=%d, fs=0x%x, option=%d)", audioOut, type, fs, option); option = 0; @@ -425,7 +425,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option) { - cellSysutil->Warning("cellAudioOutGetSoundAvailability2(audioOut=%d, type=%d, fs=0x%x, ch=%d, option=%d)", + cellSysutil.Warning("cellAudioOutGetSoundAvailability2(audioOut=%d, type=%d, fs=0x%x, ch=%d, option=%d)", audioOut, type, fs, ch, option); option = 0; @@ -475,7 +475,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr state) { - cellSysutil->Warning("cellAudioOutGetState(audioOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", audioOut, deviceIndex, state.addr()); + cellSysutil.Warning("cellAudioOutGetState(audioOut=0x%x, deviceIndex=0x%x, state_addr=0x%x)", audioOut, deviceIndex, state.addr()); *state = {}; @@ -504,7 +504,7 @@ int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, vm::ptr config, vm::ptr option, u32 waitForEvent) { - cellSysutil->Warning("cellAudioOutConfigure(audioOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=%d)", + cellSysutil.Warning("cellAudioOutConfigure(audioOut=%d, config_addr=0x%x, option_addr=0x%x, waitForEvent=%d)", audioOut, config.addr(), option.addr(), waitForEvent); switch(audioOut) @@ -533,7 +533,7 @@ int cellAudioOutConfigure(u32 audioOut, vm::ptr confi int cellAudioOutGetConfiguration(u32 audioOut, vm::ptr config, vm::ptr option) { - cellSysutil->Warning("cellAudioOutGetConfiguration(audioOut=%d, config_addr=0x%x, option_addr=0x%x)", audioOut, config.addr(), option.addr()); + cellSysutil.Warning("cellAudioOutGetConfiguration(audioOut=%d, config_addr=0x%x, option_addr=0x%x)", audioOut, config.addr(), option.addr()); if (option) *option = {}; *config = {}; @@ -557,7 +557,7 @@ int cellAudioOutGetConfiguration(u32 audioOut, vm::ptrWarning("cellAudioOutGetNumberOfDevice(audioOut=%d)", audioOut); + cellSysutil.Warning("cellAudioOutGetNumberOfDevice(audioOut=%d)", audioOut); switch(audioOut) { @@ -570,7 +570,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut) int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptr info) { - cellSysutil->Todo("cellAudioOutGetDeviceInfo(audioOut=%d, deviceIndex=%d, info_addr=0x%x)", audioOut, deviceIndex, info.addr()); + cellSysutil.Todo("cellAudioOutGetDeviceInfo(audioOut=%d, deviceIndex=%d, info_addr=0x%x)", audioOut, deviceIndex, info.addr()); if(deviceIndex) return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND; @@ -588,7 +588,7 @@ int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, vm::ptrWarning("cellAudioOutSetCopyControl(audioOut=%d,control=%d)",audioOut,control); + cellSysutil.Warning("cellAudioOutSetCopyControl(audioOut=%d,control=%d)",audioOut,control); switch(audioOut) { @@ -628,7 +628,7 @@ typedef struct{ // virtual wxDirTraverseResult OnFile(const wxString& filename) // { // if (!wxRemoveFile(filename)){ -// cellSysutil->Error("Couldn't delete File: %s", fmt::ToUTF8(filename).c_str()); +// cellSysutil.Error("Couldn't delete File: %s", fmt::ToUTF8(filename).c_str()); // } // return wxDIR_CONTINUE; // } @@ -647,7 +647,7 @@ typedef struct{ int cellSysCacheClear(void) { - cellSysutil->Warning("cellSysCacheClear()"); + cellSysutil.Warning("cellSysCacheClear()"); //if some software expects CELL_SYSCACHE_ERROR_NOTMOUNTED we need to check whether //it was mounted before, for that we would need to save the state which I don't know @@ -676,7 +676,7 @@ int cellSysCacheClear(void) int cellSysCacheMount(vm::ptr param) { - cellSysutil->Warning("cellSysCacheMount(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysCacheMount(param_addr=0x%x)", param.addr()); //TODO: implement char id[CELL_SYSCACHE_ID_SIZE]; @@ -690,7 +690,7 @@ int cellSysCacheMount(vm::ptr param) int cellHddGameCheck(u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { - cellSysutil->Warning("cellHddGameCheck(version=%d, dirName_addr=0x%x, errDialog=%d, funcStat_addr=0x%x, container=%d)", + cellSysutil.Warning("cellHddGameCheck(version=%d, dirName_addr=0x%x, errDialog=%d, funcStat_addr=0x%x, container=%d)", version, dirName.addr(), errDialog, funcStat.addr(), container); std::string dir = dirName.get_ptr(); @@ -762,7 +762,7 @@ bool bgm_playback_enabled = true; int cellSysutilEnableBgmPlayback() { - cellSysutil->Warning("cellSysutilEnableBgmPlayback()"); + cellSysutil.Warning("cellSysutilEnableBgmPlayback()"); // TODO bgm_playback_enabled = true; @@ -772,7 +772,7 @@ int cellSysutilEnableBgmPlayback() int cellSysutilEnableBgmPlaybackEx(vm::ptr param) { - cellSysutil->Warning("cellSysutilEnableBgmPlaybackEx(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysutilEnableBgmPlaybackEx(param_addr=0x%x)", param.addr()); // TODO bgm_playback_enabled = true; @@ -782,7 +782,7 @@ int cellSysutilEnableBgmPlaybackEx(vm::ptr par int cellSysutilDisableBgmPlayback() { - cellSysutil->Warning("cellSysutilDisableBgmPlayback()"); + cellSysutil.Warning("cellSysutilDisableBgmPlayback()"); // TODO bgm_playback_enabled = false; @@ -792,7 +792,7 @@ int cellSysutilDisableBgmPlayback() int cellSysutilDisableBgmPlaybackEx(vm::ptr param) { - cellSysutil->Warning("cellSysutilDisableBgmPlaybackEx(param_addr=0x%x)", param.addr()); + cellSysutil.Warning("cellSysutilDisableBgmPlaybackEx(param_addr=0x%x)", param.addr()); // TODO bgm_playback_enabled = false; @@ -802,7 +802,7 @@ int cellSysutilDisableBgmPlaybackEx(vm::ptr pa int cellSysutilGetBgmPlaybackStatus(vm::ptr status) { - cellSysutil->Log("cellSysutilGetBgmPlaybackStatus(status_addr=0x%x)", status.addr()); + cellSysutil.Log("cellSysutilGetBgmPlaybackStatus(status_addr=0x%x)", status.addr()); // TODO status->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; @@ -816,7 +816,7 @@ int cellSysutilGetBgmPlaybackStatus(vm::ptr status int cellSysutilGetBgmPlaybackStatus2(vm::ptr status2) { - cellSysutil->Log("cellSysutilGetBgmPlaybackStatus2(status2_addr=0x%x)", status2.addr()); + cellSysutil.Log("cellSysutilGetBgmPlaybackStatus2(status2_addr=0x%x)", status2.addr()); // TODO status2->playerState = CELL_SYSUTIL_BGMPLAYBACK_STATUS_STOP; @@ -827,7 +827,7 @@ int cellSysutilGetBgmPlaybackStatus2(vm::ptr stat int cellWebBrowserEstimate2(const vm::ptr config, vm::ptr memSize) { - cellSysutil->Warning("cellWebBrowserEstimate2(config_addr=0x%x, memSize_addr=0x%x)", config.addr(), memSize.addr()); + cellSysutil.Warning("cellWebBrowserEstimate2(config_addr=0x%x, memSize_addr=0x%x)", config.addr(), memSize.addr()); // TODO: When cellWebBrowser stuff is implemented, change this to some real // needed memory buffer size. @@ -843,77 +843,72 @@ extern int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptrAddFunc(0x40e895d3, cellSysutilGetSystemParamInt); - cellSysutil->AddFunc(0x938013a0, cellSysutilGetSystemParamString); - - cellSysutil->AddFunc(0x887572d5, cellVideoOutGetState); - cellSysutil->AddFunc(0xe558748d, cellVideoOutGetResolution); - cellSysutil->AddFunc(0x0bae8772, cellVideoOutConfigure); - cellSysutil->AddFunc(0x15b0b0cd, cellVideoOutGetConfiguration); - cellSysutil->AddFunc(0x1e930eef, cellVideoOutGetDeviceInfo); - cellSysutil->AddFunc(0x75bbb672, cellVideoOutGetNumberOfDevice); - cellSysutil->AddFunc(0xa322db75, cellVideoOutGetResolutionAvailability); - - cellSysutil->AddFunc(0x189a74da, cellSysutilCheckCallback); - cellSysutil->AddFunc(0x9d98afa0, cellSysutilRegisterCallback); - cellSysutil->AddFunc(0x02ff3c1b, cellSysutilUnregisterCallback); - - cellSysutil->AddFunc(0x7603d3db, cellMsgDialogOpen2); - cellSysutil->AddFunc(0x3e22cb4b, cellMsgDialogOpenErrorCode); - cellSysutil->AddFunc(0x9d6af72a, cellMsgDialogProgressBarSetMsg); - cellSysutil->AddFunc(0x7bc2c8a8, cellMsgDialogProgressBarReset); - cellSysutil->AddFunc(0x94862702, cellMsgDialogProgressBarInc); - cellSysutil->AddFunc(0x20543730, cellMsgDialogClose); - cellSysutil->AddFunc(0x62b0f803, cellMsgDialogAbort); - - cellSysutil->AddFunc(0xf4e3caa0, cellAudioOutGetState); - cellSysutil->AddFunc(0x4692ab35, cellAudioOutConfigure); - cellSysutil->AddFunc(0xc01b4e7c, cellAudioOutGetSoundAvailability); - cellSysutil->AddFunc(0x2beac488, cellAudioOutGetSoundAvailability2); - cellSysutil->AddFunc(0x7663e368, cellAudioOutGetDeviceInfo); - cellSysutil->AddFunc(0xe5e2b09d, cellAudioOutGetNumberOfDevice); - cellSysutil->AddFunc(0xed5d96af, cellAudioOutGetConfiguration); - cellSysutil->AddFunc(0xc96e89e9, cellAudioOutSetCopyControl); - - cellSysutil->AddFunc(0xa11552f6, cellSysutilGetBgmPlaybackStatus); - cellSysutil->AddFunc(0x6cfd856f, cellSysutilGetBgmPlaybackStatus2); - cellSysutil->AddFunc(0x220894e3, cellSysutilEnableBgmPlayback); - cellSysutil->AddFunc(0xac58ad2b, cellSysutilEnableBgmPlaybackEx); - cellSysutil->AddFunc(0xcfdd8e87, cellSysutilDisableBgmPlayback); - cellSysutil->AddFunc(0xa36335a5, cellSysutilDisableBgmPlaybackEx); - - cellSysutil->AddFunc(0x1e7bff94, cellSysCacheMount); - cellSysutil->AddFunc(0x744c1544, cellSysCacheClear); - - cellSysutil->AddFunc(0x9117df20, cellHddGameCheck); - //cellSysutil->AddFunc(0x4bdec82a, cellHddGameCheck2); - //cellSysutil->AddFunc(0xf82e2ef7, cellHddGameGetSizeKB); - //cellSysutil->AddFunc(0x9ca9ffa7, cellHddGameSetSystemVer); - //cellSysutil->AddFunc(0xafd605b3, cellHddGameExitBroken); - - //cellSysutil->AddFunc(0x886D0747, cellSysutilRegisterCallbackDispatcher); - //cellSysutil->AddFunc(0xA2720DF2, cellSysutilPacketWrite); - //cellSysutil->AddFunc(0x75AA7373, doc.write); - //cellSysutil->AddFunc(0x2D96313F, packet_read); - - // cellSaveData functions - cellSysutil_SaveData_init(); - - cellSysutil->AddFunc(0x6d087930, cellWebBrowserEstimate2); - - cellSysutil->AddFunc(0xe7951dee, cellGameDataCheckCreate); - cellSysutil->AddFunc(0xc9645c41, cellGameDataCheckCreate2); -} - -void cellSysutil_load() +Module cellSysutil("cellSysutil", []() { for (auto& v : g_sys_callback) { v.func.set(0); v.arg.set(0); } -} + + cellSysutil.AddFunc(0x40e895d3, cellSysutilGetSystemParamInt); + cellSysutil.AddFunc(0x938013a0, cellSysutilGetSystemParamString); + + cellSysutil.AddFunc(0x887572d5, cellVideoOutGetState); + cellSysutil.AddFunc(0xe558748d, cellVideoOutGetResolution); + cellSysutil.AddFunc(0x0bae8772, cellVideoOutConfigure); + cellSysutil.AddFunc(0x15b0b0cd, cellVideoOutGetConfiguration); + cellSysutil.AddFunc(0x1e930eef, cellVideoOutGetDeviceInfo); + cellSysutil.AddFunc(0x75bbb672, cellVideoOutGetNumberOfDevice); + cellSysutil.AddFunc(0xa322db75, cellVideoOutGetResolutionAvailability); + + cellSysutil.AddFunc(0x189a74da, cellSysutilCheckCallback); + cellSysutil.AddFunc(0x9d98afa0, cellSysutilRegisterCallback); + cellSysutil.AddFunc(0x02ff3c1b, cellSysutilUnregisterCallback); + + cellSysutil.AddFunc(0x7603d3db, cellMsgDialogOpen2); + cellSysutil.AddFunc(0x3e22cb4b, cellMsgDialogOpenErrorCode); + cellSysutil.AddFunc(0x9d6af72a, cellMsgDialogProgressBarSetMsg); + cellSysutil.AddFunc(0x7bc2c8a8, cellMsgDialogProgressBarReset); + cellSysutil.AddFunc(0x94862702, cellMsgDialogProgressBarInc); + cellSysutil.AddFunc(0x20543730, cellMsgDialogClose); + cellSysutil.AddFunc(0x62b0f803, cellMsgDialogAbort); + + cellSysutil.AddFunc(0xf4e3caa0, cellAudioOutGetState); + cellSysutil.AddFunc(0x4692ab35, cellAudioOutConfigure); + cellSysutil.AddFunc(0xc01b4e7c, cellAudioOutGetSoundAvailability); + cellSysutil.AddFunc(0x2beac488, cellAudioOutGetSoundAvailability2); + cellSysutil.AddFunc(0x7663e368, cellAudioOutGetDeviceInfo); + cellSysutil.AddFunc(0xe5e2b09d, cellAudioOutGetNumberOfDevice); + cellSysutil.AddFunc(0xed5d96af, cellAudioOutGetConfiguration); + cellSysutil.AddFunc(0xc96e89e9, cellAudioOutSetCopyControl); + + cellSysutil.AddFunc(0xa11552f6, cellSysutilGetBgmPlaybackStatus); + cellSysutil.AddFunc(0x6cfd856f, cellSysutilGetBgmPlaybackStatus2); + cellSysutil.AddFunc(0x220894e3, cellSysutilEnableBgmPlayback); + cellSysutil.AddFunc(0xac58ad2b, cellSysutilEnableBgmPlaybackEx); + cellSysutil.AddFunc(0xcfdd8e87, cellSysutilDisableBgmPlayback); + cellSysutil.AddFunc(0xa36335a5, cellSysutilDisableBgmPlaybackEx); + + cellSysutil.AddFunc(0x1e7bff94, cellSysCacheMount); + cellSysutil.AddFunc(0x744c1544, cellSysCacheClear); + + cellSysutil.AddFunc(0x9117df20, cellHddGameCheck); + //cellSysutil.AddFunc(0x4bdec82a, cellHddGameCheck2); + //cellSysutil.AddFunc(0xf82e2ef7, cellHddGameGetSizeKB); + //cellSysutil.AddFunc(0x9ca9ffa7, cellHddGameSetSystemVer); + //cellSysutil.AddFunc(0xafd605b3, cellHddGameExitBroken); + + //cellSysutil.AddFunc(0x886D0747, cellSysutilRegisterCallbackDispatcher); + //cellSysutil.AddFunc(0xA2720DF2, cellSysutilPacketWrite); + //cellSysutil.AddFunc(0x75AA7373, doc.write); + //cellSysutil.AddFunc(0x2D96313F, packet_read); + + // cellSaveData functions + cellSysutil_SaveData_init(); + + cellSysutil.AddFunc(0x6d087930, cellWebBrowserEstimate2); + + cellSysutil.AddFunc(0xe7951dee, cellGameDataCheckCreate); + cellSysutil.AddFunc(0xc9645c41, cellGameDataCheckCreate2); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp index 07a29a9be1..67cb8dfedc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutilAp.cpp @@ -2,7 +2,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/Modules.h" -Module *cellSysutilAp = nullptr; +extern Module cellSysutilAp; // Return Codes enum @@ -19,7 +19,7 @@ enum s32 cellSysutilApGetRequiredMemSize() { - cellSysutilAp->Log("cellSysutilApGetRequiredMemSize()"); + cellSysutilAp.Log("cellSysutilApGetRequiredMemSize()"); return 1024*1024; // Return 1 MB as required size } @@ -35,11 +35,9 @@ int cellSysutilApOff() return CELL_OK; } -void cellSysutilAp_init(Module *pxThis) +Module cellSysutilAp("cellSysutilAp", []() { - cellSysutilAp = pxThis; - - cellSysutilAp->AddFunc(0x9e67e0dd, cellSysutilApGetRequiredMemSize); - cellSysutilAp->AddFunc(0x3343824c, cellSysutilApOn); - cellSysutilAp->AddFunc(0x90c2bb19, cellSysutilApOff); -} + cellSysutilAp.AddFunc(0x9e67e0dd, cellSysutilApGetRequiredMemSize); + cellSysutilAp.AddFunc(0x3343824c, cellSysutilApOn); + cellSysutilAp.AddFunc(0x90c2bb19, cellSysutilApOff); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp index 8815280edc..5d8ed6b814 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp @@ -7,11 +7,11 @@ #include "Emu/FS/vfsFileBase.h" #include "cellUserInfo.h" -Module *cellUserInfo = nullptr; +extern Module cellUserInfo; int cellUserInfoGetStat(u32 id, vm::ptr stat) { - cellUserInfo->Warning("cellUserInfoGetStat(id=%d, stat_addr=0x%x)", id, stat.addr()); + cellUserInfo.Warning("cellUserInfoGetStat(id=%d, stat_addr=0x%x)", id, stat.addr()); if (id > CELL_USERINFO_USER_MAX) return CELL_USERINFO_ERROR_NOUSER; @@ -57,7 +57,7 @@ int cellUserInfoEnableOverlay() int cellUserInfoGetList(vm::ptr listNum, vm::ptr listBuf, vm::ptr currentUserId) { - cellUserInfo->Warning("cellUserInfoGetList(listNum_addr=0x%x, listBuf_addr=0x%x, currentUserId_addr=0x%x)", + cellUserInfo.Warning("cellUserInfoGetList(listNum_addr=0x%x, listBuf_addr=0x%x, currentUserId_addr=0x%x)", listNum.addr(), listBuf.addr(), currentUserId.addr()); // If only listNum is NULL, an error will be returned @@ -74,13 +74,11 @@ int cellUserInfoGetList(vm::ptr listNum, vm::ptr list return CELL_OK; } -void cellUserInfo_init(Module *pxThis) +Module cellUserInfo("cellUserInfo", []() { - cellUserInfo = pxThis; - - cellUserInfo->AddFunc(0x2b761140, cellUserInfoGetStat); - cellUserInfo->AddFunc(0x3097cc1c, cellUserInfoSelectUser_ListType); - cellUserInfo->AddFunc(0x55123a25, cellUserInfoSelectUser_SetList); - cellUserInfo->AddFunc(0xb3516536, cellUserInfoEnableOverlay); - cellUserInfo->AddFunc(0xc55e338b, cellUserInfoGetList); -} + cellUserInfo.AddFunc(0x2b761140, cellUserInfoGetStat); + cellUserInfo.AddFunc(0x3097cc1c, cellUserInfoSelectUser_ListType); + cellUserInfo.AddFunc(0x55123a25, cellUserInfoSelectUser_SetList); + cellUserInfo.AddFunc(0xb3516536, cellUserInfoEnableOverlay); + cellUserInfo.AddFunc(0xc55e338b, cellUserInfoGetList); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index f2a0d62c40..9bd76dacc0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -17,9 +17,9 @@ extern "C" #include "cellPamf.h" #include "cellVdec.h" -Module *cellVdec = nullptr; +extern Module cellVdec; -#define VDEC_ERROR(...) { cellVdec->Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread +#define VDEC_ERROR(...) { cellVdec.Error(__VA_ARGS__); Emu.Pause(); return; } // only for decoder thread VideoDecoder::VideoDecoder(CellVdecCodecType type, u32 profile, u32 addr, u32 size, vm::ptr func, u32 arg) : type(type) @@ -126,7 +126,7 @@ next: VdecTask task; if (!vdec.job.peek(task, 0, &vdec.is_closed)) { - if (Emu.IsStopped()) cellVdec->Warning("vdecRead() aborted"); + if (Emu.IsStopped()) cellVdec.Warning("vdecRead() aborted"); return 0; } @@ -159,7 +159,7 @@ next: default: { - cellVdec->Error("vdecRead(): unknown task (%d)", task.type); + cellVdec.Error("vdecRead(): unknown task (%d)", task.type); Emu.Pause(); return -1; } @@ -190,9 +190,9 @@ u32 vdecQueryAttr(CellVdecCodecType type, u32 profile, u32 spec_addr /* may be 0 { switch (type) // TODO: check profile levels { - case CELL_VDEC_CODEC_TYPE_AVC: cellVdec->Warning("cellVdecQueryAttr: AVC (profile=%d)", profile); break; - case CELL_VDEC_CODEC_TYPE_MPEG2: cellVdec->Warning("cellVdecQueryAttr: MPEG2 (profile=%d)", profile); break; - case CELL_VDEC_CODEC_TYPE_DIVX: cellVdec->Warning("cellVdecQueryAttr: DivX (profile=%d)", profile); break; + case CELL_VDEC_CODEC_TYPE_AVC: cellVdec.Warning("cellVdecQueryAttr: AVC (profile=%d)", profile); break; + case CELL_VDEC_CODEC_TYPE_MPEG2: cellVdec.Warning("cellVdecQueryAttr: MPEG2 (profile=%d)", profile); break; + case CELL_VDEC_CODEC_TYPE_DIVX: cellVdec.Warning("cellVdecQueryAttr: DivX (profile=%d)", profile); break; default: return CELL_VDEC_ERROR_ARG; } @@ -209,7 +209,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) std::shared_ptr sptr(vdec_ptr); VideoDecoder& vdec = *vdec_ptr; - u32 vdec_id = cellVdec->GetNewId(sptr); + u32 vdec_id = cellVdec.GetNewId(sptr); vdec.id = vdec_id; @@ -244,7 +244,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) case vdecStartSeq: { // TODO: reset data - cellVdec->Warning("vdecStartSeq:"); + cellVdec.Warning("vdecStartSeq:"); vdec.reader = {}; vdec.frc_set = 0; @@ -255,7 +255,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) case vdecEndSeq: { // TODO: finalize - cellVdec->Warning("vdecEndSeq:"); + cellVdec.Warning("vdecEndSeq:"); vdec.cbFunc(*vdec.vdecCb, vdec.id, CELL_VDEC_MSG_TYPE_SEQDONE, CELL_OK, vdec.cbArg); @@ -269,7 +269,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) if (task.mode != CELL_VDEC_DEC_MODE_NORMAL) { - cellVdec->Error("vdecDecodeAu: unsupported decoding mode(%d)", task.mode); + cellVdec.Error("vdecDecodeAu: unsupported decoding mode(%d)", task.mode); break; } @@ -364,7 +364,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) { if (Emu.IsStopped() || vdec.is_closed) { - if (Emu.IsStopped()) cellVdec->Warning("vdecDecodeAu: aborted"); + if (Emu.IsStopped()) cellVdec.Warning("vdecDecodeAu: aborted"); break; } @@ -408,7 +408,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) { if (decode < 0) { - cellVdec->Error("vdecDecodeAu: AU decoding error(0x%x)", decode); + cellVdec.Error("vdecDecodeAu: AU decoding error(0x%x)", decode); } if (!got_picture && vdec.reader.size == 0) break; // video end? } @@ -533,7 +533,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) case vdecSetFrameRate: { - cellVdec->Warning("vdecSetFrameRate(0x%x)", task.frc); + cellVdec.Warning("vdecSetFrameRate(0x%x)", task.frc); vdec.frc_set = task.frc; break; } @@ -558,21 +558,21 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) int cellVdecQueryAttr(vm::ptr type, vm::ptr attr) { - cellVdec->Warning("cellVdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellVdec.Warning("cellVdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr); } int cellVdecQueryAttrEx(vm::ptr type, vm::ptr attr) { - cellVdec->Warning("cellVdecQueryAttrEx(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellVdec.Warning("cellVdecQueryAttrEx(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr); } int cellVdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellVdec->Warning("cellVdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellVdec.Warning("cellVdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.addr(), res.addr(), cb.addr(), handle.addr()); *handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc.to_le(), cb->cbArg)); @@ -582,7 +582,7 @@ int cellVdecOpen(vm::ptr type, vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellVdec->Warning("cellVdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", + cellVdec.Warning("cellVdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", type.addr(), res.addr(), cb.addr(), handle.addr()); *handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc.to_le(), cb->cbArg)); @@ -592,7 +592,7 @@ int cellVdecOpenEx(vm::ptr type, vm::ptrWarning("cellVdecClose(handle=%d)", handle); + cellVdec.Warning("cellVdecClose(handle=%d)", handle); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -607,7 +607,7 @@ int cellVdecClose(u32 handle) { if (Emu.IsStopped()) { - cellVdec->Warning("cellVdecClose(%d) aborted", handle); + cellVdec.Warning("cellVdecClose(%d) aborted", handle); break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack @@ -620,7 +620,7 @@ int cellVdecClose(u32 handle) int cellVdecStartSeq(u32 handle) { - cellVdec->Log("cellVdecStartSeq(handle=%d)", handle); + cellVdec.Log("cellVdecStartSeq(handle=%d)", handle); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -634,7 +634,7 @@ int cellVdecStartSeq(u32 handle) int cellVdecEndSeq(u32 handle) { - cellVdec->Warning("cellVdecEndSeq(handle=%d)", handle); + cellVdec.Warning("cellVdecEndSeq(handle=%d)", handle); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -648,7 +648,7 @@ int cellVdecEndSeq(u32 handle) int cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr auInfo) { - cellVdec->Log("cellVdecDecodeAu(handle=%d, mode=0x%x, auInfo_addr=0x%x)", handle, mode, auInfo.addr()); + cellVdec.Log("cellVdecDecodeAu(handle=%d, mode=0x%x, auInfo_addr=0x%x)", handle, mode, auInfo.addr()); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -672,7 +672,7 @@ int cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr format, vm::ptr outBuff) { - cellVdec->Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, outBuff_addr=0x%x)", handle, format.addr(), outBuff.addr()); + cellVdec.Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, outBuff_addr=0x%x)", handle, format.addr(), outBuff.addr()); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -703,12 +703,12 @@ int cellVdecGetPicture(u32 handle, vm::ptr format, vm:: { if (format->formatType != CELL_VDEC_PICFMT_YUV420_PLANAR) { - cellVdec->Fatal("cellVdecGetPicture: unknown formatType(%d)", format->formatType); + cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", format->formatType); } if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709) { - cellVdec->Fatal("cellVdecGetPicture: unknown colorMatrixType(%d)", format->colorMatrixType); + cellVdec.Fatal("cellVdecGetPicture: unknown colorMatrixType(%d)", format->colorMatrixType); } const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128); @@ -718,7 +718,7 @@ int cellVdecGetPicture(u32 handle, vm::ptr format, vm:: int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame->data, frame->linesize, vdec->ctx->pix_fmt, frame->width, frame->height, 1); if (err < 0) { - cellVdec->Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err); + cellVdec.Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err); } } @@ -727,7 +727,7 @@ int cellVdecGetPicture(u32 handle, vm::ptr format, vm:: int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) { - cellVdec->Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.addr()); + cellVdec.Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.addr()); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -781,7 +781,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) case AV_PICTURE_TYPE_I: avc->pictureType[0] = CELL_VDEC_AVC_PCT_I; break; case AV_PICTURE_TYPE_P: avc->pictureType[0] = CELL_VDEC_AVC_PCT_P; break; case AV_PICTURE_TYPE_B: avc->pictureType[0] = CELL_VDEC_AVC_PCT_B; break; - default: cellVdec->Error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame.pict_type); + default: cellVdec.Error("cellVdecGetPicItem(AVC): unknown pict_type value (0x%x)", frame.pict_type); } avc->pictureType[1] = CELL_VDEC_AVC_PCT_UNKNOWN; // ??? avc->idrPictureFlag = false; // ??? @@ -812,7 +812,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) case CELL_VDEC_FRC_50: avc->frameRateCode = CELL_VDEC_AVC_FRC_50; break; case CELL_VDEC_FRC_60000DIV1001: avc->frameRateCode = CELL_VDEC_AVC_FRC_60000DIV1001; break; case CELL_VDEC_FRC_60: avc->frameRateCode = CELL_VDEC_AVC_FRC_60; break; - default: cellVdec->Error("cellVdecGetPicItem(AVC): unknown frc value (0x%x)", vf.frc); + default: cellVdec.Error("cellVdecGetPicItem(AVC): unknown frc value (0x%x)", vf.frc); } avc->fixed_frame_rate_flag = true; @@ -833,7 +833,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) case AV_PICTURE_TYPE_I: dvx->pictureType = CELL_VDEC_DIVX_VCT_I; break; case AV_PICTURE_TYPE_P: dvx->pictureType = CELL_VDEC_DIVX_VCT_P; break; case AV_PICTURE_TYPE_B: dvx->pictureType = CELL_VDEC_DIVX_VCT_B; break; - default: cellVdec->Error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame.pict_type); + default: cellVdec.Error("cellVdecGetPicItem(DivX): unknown pict_type value (0x%x)", frame.pict_type); } dvx->horizontalSize = frame.width; dvx->verticalSize = frame.height; @@ -855,14 +855,14 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) case CELL_VDEC_FRC_50: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_50; break; case CELL_VDEC_FRC_60000DIV1001: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60000DIV1001; break; case CELL_VDEC_FRC_60: dvx->frameRateCode = CELL_VDEC_DIVX_FRC_60; break; - default: cellVdec->Error("cellVdecGetPicItem(DivX): unknown frc value (0x%x)", vf.frc); + default: cellVdec.Error("cellVdecGetPicItem(DivX): unknown frc value (0x%x)", vf.frc); } } else if (vdec->type == CELL_VDEC_CODEC_TYPE_MPEG2) { auto mp2 = vm::ptr::make(info.addr() + sizeof(CellVdecPicItem)); - cellVdec->Fatal("cellVdecGetPicItem(MPEG2)"); + cellVdec.Fatal("cellVdecGetPicItem(MPEG2)"); } *picItem_ptr = info.addr(); @@ -871,7 +871,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) int cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) { - cellVdec->Log("cellVdecSetFrameRate(handle=%d, frc=0x%x)", handle, frc); + cellVdec.Log("cellVdecSetFrameRate(handle=%d, frc=0x%x)", handle, frc); std::shared_ptr vdec; if (!Emu.GetIdManager().GetIDData(handle, vdec)) @@ -887,19 +887,17 @@ int cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) return CELL_OK; } -void cellVdec_init(Module *pxThis) +Module cellVdec("cellVdec", []() { - cellVdec = pxThis; - - cellVdec->AddFunc(0xff6f6ebe, cellVdecQueryAttr); - cellVdec->AddFunc(0xc982a84a, cellVdecQueryAttrEx); - cellVdec->AddFunc(0xb6bbcd5d, cellVdecOpen); - cellVdec->AddFunc(0x0053e2d8, cellVdecOpenEx); - cellVdec->AddFunc(0x16698e83, cellVdecClose); - cellVdec->AddFunc(0xc757c2aa, cellVdecStartSeq); - cellVdec->AddFunc(0x824433f0, cellVdecEndSeq); - cellVdec->AddFunc(0x2bf4ddd2, cellVdecDecodeAu); - cellVdec->AddFunc(0x807c861a, cellVdecGetPicture); - cellVdec->AddFunc(0x17c702b9, cellVdecGetPicItem); - cellVdec->AddFunc(0xe13ef6fc, cellVdecSetFrameRate); -} + cellVdec.AddFunc(0xff6f6ebe, cellVdecQueryAttr); + cellVdec.AddFunc(0xc982a84a, cellVdecQueryAttrEx); + cellVdec.AddFunc(0xb6bbcd5d, cellVdecOpen); + cellVdec.AddFunc(0x0053e2d8, cellVdecOpenEx); + cellVdec.AddFunc(0x16698e83, cellVdecClose); + cellVdec.AddFunc(0xc757c2aa, cellVdecStartSeq); + cellVdec.AddFunc(0x824433f0, cellVdecEndSeq); + cellVdec.AddFunc(0x2bf4ddd2, cellVdecDecodeAu); + cellVdec.AddFunc(0x807c861a, cellVdecGetPicture); + cellVdec.AddFunc(0x17c702b9, cellVdecGetPicItem); + cellVdec.AddFunc(0xe13ef6fc, cellVdecSetFrameRate); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index fea5149548..eb0cad507e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -10,11 +10,11 @@ extern "C" #include "cellVpost.h" -Module *cellVpost = nullptr; +extern Module cellVpost; int cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr attr) { - cellVpost->Warning("cellVpostQueryAttr(cfgParam_addr=0x%x, attr_addr=0x%x)", cfgParam.addr(), attr.addr()); + cellVpost.Warning("cellVpostQueryAttr(cfgParam_addr=0x%x, attr_addr=0x%x)", cfgParam.addr(), attr.addr()); // TODO: check cfgParam and output values @@ -29,16 +29,16 @@ int cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr data_ptr(data); - u32 id = cellVpost->GetNewId(data_ptr); + u32 id = cellVpost.GetNewId(data_ptr); - cellVpost->Notice("*** Vpost instance created (to_rgba=%d): id = %d", data->to_rgba, id); + cellVpost.Notice("*** Vpost instance created (to_rgba=%d): id = %d", data->to_rgba, id); return id; } int cellVpostOpen(vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) { - cellVpost->Warning("cellVpostOpen(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", + cellVpost.Warning("cellVpostOpen(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", cfgParam.addr(), resource.addr(), handle.addr()); // TODO: check values @@ -48,7 +48,7 @@ int cellVpostOpen(vm::ptr cfgParam, vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) { - cellVpost->Warning("cellVpostOpenEx(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", + cellVpost.Warning("cellVpostOpenEx(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", cfgParam.addr(), resource.addr(), handle.addr()); // TODO: check values @@ -58,7 +58,7 @@ int cellVpostOpenEx(vm::ptr cfgParam, vm::ptrWarning("cellVpostClose(handle=0x%x)", handle); + cellVpost.Warning("cellVpostClose(handle=0x%x)", handle); std::shared_ptr vpost; if (!Emu.GetIdManager().GetIDData(handle, vpost)) @@ -73,7 +73,7 @@ int cellVpostClose(u32 handle) int cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptr ctrlParam, vm::ptr outPicBuff, vm::ptr picInfo) { - cellVpost->Log("cellVpostExec(handle=0x%x, inPicBuff_addr=0x%x, ctrlParam_addr=0x%x, outPicBuff_addr=0x%x, picInfo_addr=0x%x)", + cellVpost.Log("cellVpostExec(handle=0x%x, inPicBuff_addr=0x%x, ctrlParam_addr=0x%x, outPicBuff_addr=0x%x, picInfo_addr=0x%x)", handle, inPicBuff.addr(), ctrlParam.addr(), outPicBuff.addr(), picInfo.addr()); std::shared_ptr vpost; @@ -88,15 +88,15 @@ int cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptroutHeight; ctrlParam->inWindow; // ignored - if (ctrlParam->inWindow.x) cellVpost->Notice("*** inWindow.x = %d", (u32)ctrlParam->inWindow.x); - if (ctrlParam->inWindow.y) cellVpost->Notice("*** inWindow.y = %d", (u32)ctrlParam->inWindow.y); - if (ctrlParam->inWindow.width != w) cellVpost->Notice("*** inWindow.width = %d", (u32)ctrlParam->inWindow.width); - if (ctrlParam->inWindow.height != h) cellVpost->Notice("*** inWindow.height = %d", (u32)ctrlParam->inWindow.height); + if (ctrlParam->inWindow.x) cellVpost.Notice("*** inWindow.x = %d", (u32)ctrlParam->inWindow.x); + if (ctrlParam->inWindow.y) cellVpost.Notice("*** inWindow.y = %d", (u32)ctrlParam->inWindow.y); + if (ctrlParam->inWindow.width != w) cellVpost.Notice("*** inWindow.width = %d", (u32)ctrlParam->inWindow.width); + if (ctrlParam->inWindow.height != h) cellVpost.Notice("*** inWindow.height = %d", (u32)ctrlParam->inWindow.height); ctrlParam->outWindow; // ignored - if (ctrlParam->outWindow.x) cellVpost->Notice("*** outWindow.x = %d", (u32)ctrlParam->outWindow.x); - if (ctrlParam->outWindow.y) cellVpost->Notice("*** outWindow.y = %d", (u32)ctrlParam->outWindow.y); - if (ctrlParam->outWindow.width != ow) cellVpost->Notice("*** outWindow.width = %d", (u32)ctrlParam->outWindow.width); - if (ctrlParam->outWindow.height != oh) cellVpost->Notice("*** outWindow.height = %d", (u32)ctrlParam->outWindow.height); + if (ctrlParam->outWindow.x) cellVpost.Notice("*** outWindow.x = %d", (u32)ctrlParam->outWindow.x); + if (ctrlParam->outWindow.y) cellVpost.Notice("*** outWindow.y = %d", (u32)ctrlParam->outWindow.y); + if (ctrlParam->outWindow.width != ow) cellVpost.Notice("*** outWindow.width = %d", (u32)ctrlParam->outWindow.width); + if (ctrlParam->outWindow.height != oh) cellVpost.Notice("*** outWindow.height = %d", (u32)ctrlParam->outWindow.height); ctrlParam->execType; // ignored ctrlParam->scalerType; // ignored ctrlParam->ipcType; // ignored @@ -148,13 +148,11 @@ int cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptrAddFunc(0x95e788c3, cellVpostQueryAttr); - cellVpost->AddFunc(0xcd33f3e2, cellVpostOpen); - cellVpost->AddFunc(0x40524325, cellVpostOpenEx); - cellVpost->AddFunc(0x10ef39f6, cellVpostClose); - cellVpost->AddFunc(0xabb8cc3d, cellVpostExec); -} + cellVpost.AddFunc(0x95e788c3, cellVpostQueryAttr); + cellVpost.AddFunc(0xcd33f3e2, cellVpostOpen); + cellVpost.AddFunc(0x40524325, cellVpostOpenEx); + cellVpost.AddFunc(0x10ef39f6, cellVpostClose); + cellVpost.AddFunc(0xabb8cc3d, cellVpostExec); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 0030923d06..81d3aa55c9 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -8,7 +8,7 @@ #include "cellAudio.h" #include "libmixer.h" -Module *libmixer = nullptr; +extern Module libmixer; SurMixerConfig g_surmx; vm::ptr surMixerCb; @@ -21,7 +21,7 @@ std::vector ssp; int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) { - libmixer->Log("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d)", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Log("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d)", aan_handle, aan_port, offset, addr.addr(), samples); u32 type = aan_port >> 16; u32 port = aan_port & 0xffff; @@ -42,7 +42,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0) { - libmixer->Error("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Error("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr.addr(), samples); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -102,14 +102,14 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer->Warning("cellAANConnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", + libmixer.Warning("cellAANConnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", receive, receivePortNo, source, sourcePortNo); std::lock_guard lock(mixer_mutex); if (source >= ssp.size() || !ssp[source].m_created) { - libmixer->Error("cellAANConnect(): invalid source (%d)", source); + libmixer.Error("cellAANConnect(): invalid source (%d)", source); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -120,14 +120,14 @@ int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer->Warning("cellAANDisconnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", + libmixer.Warning("cellAANDisconnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", receive, receivePortNo, source, sourcePortNo); std::lock_guard lock(mixer_mutex); if (source >= ssp.size() || !ssp[source].m_created) { - libmixer->Error("cellAANDisconnect(): invalid source (%d)", source); + libmixer.Error("cellAANDisconnect(): invalid source (%d)", source); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -138,12 +138,12 @@ int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePort int cellSSPlayerCreate(vm::ptr handle, vm::ptr config) { - libmixer->Warning("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)", + libmixer.Warning("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)", handle.addr(), config.addr()); if (config->outputMode != 0 || config->channels - 1 >= 2) { - libmixer->Error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", + libmixer.Error("cellSSPlayerCreate(config.outputMode=%d, config.channels=%d): invalid parameters", (u32)config->outputMode, (u32)config->channels); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -163,13 +163,13 @@ int cellSSPlayerCreate(vm::ptr handle, vm::ptr config) int cellSSPlayerRemove(u32 handle) { - libmixer->Warning("cellSSPlayerRemove(handle=%d)", handle); + libmixer.Warning("cellSSPlayerRemove(handle=%d)", handle); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Error("cellSSPlayerRemove(): SSPlayer not found (%d)", handle); + libmixer.Error("cellSSPlayerRemove(): SSPlayer not found (%d)", handle); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -182,14 +182,14 @@ int cellSSPlayerRemove(u32 handle) int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) { - libmixer->Warning("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", + libmixer.Warning("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", handle, waveInfo.addr(), commonInfo.addr()); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Error("cellSSPlayerSetWave(): SSPlayer not found (%d)", handle); + libmixer.Error("cellSSPlayerSetWave(): SSPlayer not found (%d)", handle); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -206,13 +206,13 @@ int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm: int cellSSPlayerPlay(u32 handle, vm::ptr info) { - libmixer->Warning("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.addr()); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Error("cellSSPlayerPlay(): SSPlayer not found (%d)", handle); + libmixer.Error("cellSSPlayerPlay(): SSPlayer not found (%d)", handle); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -230,13 +230,13 @@ int cellSSPlayerPlay(u32 handle, vm::ptr info) int cellSSPlayerStop(u32 handle, u32 mode) { - libmixer->Warning("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode); + libmixer.Warning("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Error("cellSSPlayerStop(): SSPlayer not found (%d)", handle); + libmixer.Error("cellSSPlayerStop(): SSPlayer not found (%d)", handle); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -249,13 +249,13 @@ int cellSSPlayerStop(u32 handle, u32 mode) int cellSSPlayerSetParam(u32 handle, vm::ptr info) { - libmixer->Warning("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.addr()); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Error("cellSSPlayerSetParam(): SSPlayer not found (%d)", handle); + libmixer.Error("cellSSPlayerSetParam(): SSPlayer not found (%d)", handle); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -272,13 +272,13 @@ int cellSSPlayerSetParam(u32 handle, vm::ptr info) int cellSSPlayerGetState(u32 handle) { - libmixer->Warning("cellSSPlayerGetState(handle=%d)", handle); + libmixer.Warning("cellSSPlayerGetState(handle=%d)", handle); std::lock_guard lock(mixer_mutex); if (handle >= ssp.size() || !ssp[handle].m_created) { - libmixer->Warning("cellSSPlayerGetState(): SSPlayer not found (%d)", handle); + libmixer.Warning("cellSSPlayerGetState(): SSPlayer not found (%d)", handle); return CELL_SSPLAYER_STATE_ERROR; } @@ -292,7 +292,7 @@ int cellSSPlayerGetState(u32 handle) int cellSurMixerCreate(vm::ptr config) { - libmixer->Warning("cellSurMixerCreate(config_addr=0x%x)", config.addr()); + libmixer.Warning("cellSurMixerCreate(config_addr=0x%x)", config.addr()); g_surmx.audio_port = g_audio.open_port(); @@ -315,12 +315,12 @@ int cellSurMixerCreate(vm::ptr config) port.level = 1.0f; port.tag = 0; - libmixer->Warning("*** audio port opened(default)"); + libmixer.Warning("*** audio port opened(default)"); mixcount = 0; surMixerCb.set(0); - libmixer->Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); + libmixer.Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", config->chStrips1, config->chStrips2, config->chStrips6, config->chStrips8); thread_t t("Surmixer Thread", []() { @@ -464,25 +464,25 @@ int cellSurMixerCreate(vm::ptr config) int cellSurMixerGetAANHandle(vm::ptr handle) { - libmixer->Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> %d", handle.addr(), 0x11111111); + libmixer.Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> %d", handle.addr(), 0x11111111); *handle = 0x11111111; return CELL_OK; } int cellSurMixerChStripGetAANPortNo(vm::ptr port, u32 type, u32 index) { - libmixer->Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.addr(), type, index, (type << 16) | index); + libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.addr(), type, index, (type << 16) | index); *port = (type << 16) | index; return CELL_OK; } int cellSurMixerSetNotifyCallback(vm::ptr func, vm::ptr arg) { - libmixer->Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func.addr(), arg.addr()); + libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func.addr(), arg.addr()); if (surMixerCb) { - libmixer->Error("cellSurMixerSetNotifyCallback: surMixerCb already set (addr=0x%x)", surMixerCb.addr()); + libmixer.Error("cellSurMixerSetNotifyCallback: surMixerCb already set (addr=0x%x)", surMixerCb.addr()); } surMixerCb = func; surMixerCbArg = arg; @@ -491,11 +491,11 @@ int cellSurMixerSetNotifyCallback(vm::ptr fu int cellSurMixerRemoveNotifyCallback(vm::ptr func) { - libmixer->Warning("cellSurMixerRemoveNotifyCallback(func_addr=0x%x)", func.addr()); + libmixer.Warning("cellSurMixerRemoveNotifyCallback(func_addr=0x%x)", func.addr()); if (surMixerCb.addr() != func.addr()) { - libmixer->Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (addr=0x%x)", surMixerCb.addr()); + libmixer.Error("cellSurMixerRemoveNotifyCallback: surMixerCb had different value (addr=0x%x)", surMixerCb.addr()); } else { @@ -506,7 +506,7 @@ int cellSurMixerRemoveNotifyCallback(vm::ptr int cellSurMixerStart() { - libmixer->Warning("cellSurMixerStart()"); + libmixer.Warning("cellSurMixerStart()"); if (g_surmx.audio_port >= AUDIO_PORT_COUNT) { @@ -520,13 +520,13 @@ int cellSurMixerStart() int cellSurMixerSetParameter(u32 param, float value) { - libmixer->Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + libmixer.Todo("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); return CELL_OK; } int cellSurMixerFinalize() { - libmixer->Warning("cellSurMixerFinalize()"); + libmixer.Warning("cellSurMixerFinalize()"); if (g_surmx.audio_port >= AUDIO_PORT_COUNT) { @@ -542,11 +542,11 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 sa { if (busNo < 8 && samples == 256 && offset == 0) { - libmixer->Log("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + libmixer.Log("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); } else { - libmixer->Todo("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + libmixer.Todo("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); return CELL_OK; } @@ -563,13 +563,13 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, vm::ptr addr, u32 sa int cellSurMixerChStripSetParameter(u32 type, u32 index, vm::ptr param) { - libmixer->Todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param_addr=0x%x)", type, index, param.addr()); + libmixer.Todo("cellSurMixerChStripSetParameter(type=%d, index=%d, param_addr=0x%x)", type, index, param.addr()); return CELL_OK; } int cellSurMixerPause(u32 type) { - libmixer->Warning("cellSurMixerPause(type=%d)", type); + libmixer.Warning("cellSurMixerPause(type=%d)", type); if (g_surmx.audio_port >= AUDIO_PORT_COUNT) { @@ -583,7 +583,7 @@ int cellSurMixerPause(u32 type) int cellSurMixerGetCurrentBlockTag(vm::ptr tag) { - libmixer->Log("cellSurMixerGetCurrentBlockTag(tag_addr=0x%x)", tag.addr()); + libmixer.Log("cellSurMixerGetCurrentBlockTag(tag_addr=0x%x)", tag.addr()); *tag = mixcount; return CELL_OK; @@ -591,7 +591,7 @@ int cellSurMixerGetCurrentBlockTag(vm::ptr tag) int cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) { - libmixer->Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr()); + libmixer.Log("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.addr()); *stamp = g_audio.start_time + (tag) * 256000000 / 48000; // ??? return CELL_OK; @@ -599,35 +599,33 @@ int cellSurMixerGetTimestamp(u64 tag, vm::ptr stamp) void cellSurMixerBeep(u32 arg) { - libmixer->Todo("cellSurMixerBeep(arg=%d)", arg); + libmixer.Todo("cellSurMixerBeep(arg=%d)", arg); return; } float cellSurMixerUtilGetLevelFromDB(float dB) { // not hooked, probably unnecessary - libmixer->Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); + libmixer.Todo("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); return 0.0f; } float cellSurMixerUtilGetLevelFromDBIndex(s32 index) { // not hooked, probably unnecessary - libmixer->Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); + libmixer.Todo("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); return 0.0f; } float cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) { // not hooked, probably unnecessary - libmixer->Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); + libmixer.Todo("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); return 0.0f; } -void libmixer_init(Module *pxThis) +Module libmixer("libmixer", []() { - libmixer = pxThis; - g_surmx.audio_port = ~0; REG_SUB(libmixer, "surmxAAN", cellAANAddData, @@ -1195,4 +1193,4 @@ void libmixer_init(Module *pxThis) REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDB, 0); REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex, 0); REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio, 0); -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 5b6ac6cd11..729305be2c 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -10,7 +10,7 @@ #include "Crypto/unedat.h" #include "sceNp.h" -Module *sceNp = nullptr; +extern Module sceNp; struct sceNpInternal { @@ -34,7 +34,7 @@ sceNpInternal sceNpInstance; int sceNpInit(u32 mem_size, u32 mem_addr) { - sceNp->Warning("sceNpInit(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); + sceNp.Warning("sceNpInit(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); if (sceNpInstance.m_bSceNpInitialized) return SCE_NP_ERROR_ALREADY_INITIALIZED; @@ -46,7 +46,7 @@ int sceNpInit(u32 mem_size, u32 mem_addr) int sceNp2Init(u32 mem_size, u32 mem_addr) { - sceNp->Warning("sceNp2Init(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); + sceNp.Warning("sceNp2Init(mem_size=0x%x, mem_addr=0x%x)", mem_size, mem_addr); if (sceNpInstance.m_bSceNp2Initialized) return SCE_NP_ERROR_ALREADY_INITIALIZED; @@ -58,7 +58,7 @@ int sceNp2Init(u32 mem_size, u32 mem_addr) int sceNpTerm() { - sceNp->Warning("sceNpTerm()"); + sceNp.Warning("sceNpTerm()"); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_ERROR_NOT_INITIALIZED; @@ -70,7 +70,7 @@ int sceNpTerm() int sceNp2Term() { - sceNp->Warning("sceNp2Term()"); + sceNp.Warning("sceNp2Term()"); if (!sceNpInstance.m_bSceNp2Initialized) return SCE_NP_ERROR_NOT_INITIALIZED; @@ -84,7 +84,7 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) { if (!Emu.GetVFS().ExistsFile(drm_path.get_ptr())) { - sceNp->Warning("npDrmIsAvailable(): '%s' not found", drm_path.get_ptr()); + sceNp.Warning("npDrmIsAvailable(): '%s' not found", drm_path.get_ptr()); return CELL_ENOENT; } @@ -100,8 +100,8 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) } } - sceNp->Warning("npDrmIsAvailable: Found DRM license file at %s", drm_path.get_ptr()); - sceNp->Warning("npDrmIsAvailable: Using k_licensee 0x%s", k_licensee_str.c_str()); + sceNp.Warning("npDrmIsAvailable: Found DRM license file at %s", drm_path.get_ptr()); + sceNp.Warning("npDrmIsAvailable: Using k_licensee 0x%s", k_licensee_str.c_str()); // Set the necessary file paths. std::string drm_file_name = fmt::AfterLast(drm_path.get_ptr(), '/'); @@ -118,7 +118,7 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) // Search dev_usb000 for a compatible RAP file. vfsDir raps_dir(rap_path); if (!raps_dir.IsOpened()) - sceNp->Warning("npDrmIsAvailable: Can't find RAP file for DRM!"); + sceNp.Warning("npDrmIsAvailable: Can't find RAP file for DRM!"); else { for (const DirEntryInfo *entry : raps_dir) @@ -149,28 +149,28 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) int sceNpDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) { - sceNp->Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); + sceNp.Warning("sceNpDrmIsAvailable(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); return npDrmIsAvailable(k_licensee_addr, drm_path); } int sceNpDrmIsAvailable2(u32 k_licensee_addr, vm::ptr drm_path) { - sceNp->Warning("sceNpDrmIsAvailable2(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); + sceNp.Warning("sceNpDrmIsAvailable2(k_licensee_addr=0x%x, drm_path_addr=0x%x('%s'))", k_licensee_addr, drm_path.addr(), drm_path.get_ptr()); return npDrmIsAvailable(k_licensee_addr, drm_path); } int sceNpDrmVerifyUpgradeLicense(vm::ptr content_id) { - sceNp->Todo("sceNpDrmVerifyUpgradeLicense(content_id_addr=0x%x)", content_id.addr()); + sceNp.Todo("sceNpDrmVerifyUpgradeLicense(content_id_addr=0x%x)", content_id.addr()); return CELL_OK; } int sceNpDrmVerifyUpgradeLicense2(vm::ptr content_id) { - sceNp->Todo("sceNpDrmVerifyUpgradeLicense2(content_id_addr=0x%x)", content_id.addr()); + sceNp.Todo("sceNpDrmVerifyUpgradeLicense2(content_id_addr=0x%x)", content_id.addr()); return CELL_OK; } @@ -189,14 +189,14 @@ int sceNpDrmGetTimelimit(u32 drm_path_addr, vm::ptr time_remain_usec) int sceNpDrmProcessExitSpawn(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { - sceNp->Warning("sceNpDrmProcessExitSpawn()"); - sceNp->Warning("path: %s", path.get_ptr()); - sceNp->Warning("argv: 0x%x", argv_addr); - sceNp->Warning("envp: 0x%x", envp_addr); - sceNp->Warning("data: 0x%x", data_addr); - sceNp->Warning("data_size: 0x%x", data_size); - sceNp->Warning("prio: %d", prio); - sceNp->Warning("flags: %d", flags); + sceNp.Warning("sceNpDrmProcessExitSpawn()"); + sceNp.Warning("path: %s", path.get_ptr()); + sceNp.Warning("argv: 0x%x", argv_addr); + sceNp.Warning("envp: 0x%x", envp_addr); + sceNp.Warning("data: 0x%x", data_addr); + sceNp.Warning("data_size: 0x%x", data_size); + sceNp.Warning("prio: %d", prio); + sceNp.Warning("flags: %d", flags); sys_game_process_exitspawn(path, argv_addr, envp_addr, data_addr, data_size, prio, flags); @@ -205,14 +205,14 @@ int sceNpDrmProcessExitSpawn(vm::ptr path, u32 argv_addr, u32 envp_a int sceNpDrmProcessExitSpawn2(vm::ptr path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { - sceNp->Warning("sceNpDrmProcessExitSpawn2()"); - sceNp->Warning("path: %s", path.get_ptr()); - sceNp->Warning("argv: 0x%x", argv_addr); - sceNp->Warning("envp: 0x%x", envp_addr); - sceNp->Warning("data: 0x%x", data_addr); - sceNp->Warning("data_size: 0x%x", data_size); - sceNp->Warning("prio: %d", prio); - sceNp->Warning("flags: %d", flags); + sceNp.Warning("sceNpDrmProcessExitSpawn2()"); + sceNp.Warning("path: %s", path.get_ptr()); + sceNp.Warning("argv: 0x%x", argv_addr); + sceNp.Warning("envp: 0x%x", envp_addr); + sceNp.Warning("data: 0x%x", data_addr); + sceNp.Warning("data_size: 0x%x", data_size); + sceNp.Warning("prio: %d", prio); + sceNp.Warning("flags: %d", flags); sys_game_process_exitspawn2(path, argv_addr, envp_addr, data_addr, data_size, prio, flags); @@ -311,7 +311,7 @@ int sceNpBasicAddFriend() int sceNpBasicGetFriendListEntryCount(vm::ptr count) { - sceNp->Warning("sceNpBasicGetFriendListEntryCount(count_addr=0x%x)", count.addr()); + sceNp.Warning("sceNpBasicGetFriendListEntryCount(count_addr=0x%x)", count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -366,7 +366,7 @@ int sceNpBasicAddPlayersHistoryAsync() int sceNpBasicGetPlayersHistoryEntryCount(u32 options, vm::ptr count) { - sceNp->Todo("sceNpBasicGetPlayersHistoryEntryCount(options=%d, count_addr=0x%x)", options, count.addr()); + sceNp.Todo("sceNpBasicGetPlayersHistoryEntryCount(options=%d, count_addr=0x%x)", options, count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -388,7 +388,7 @@ int sceNpBasicAddBlockListEntry() int sceNpBasicGetBlockListEntryCount(u32 count) { - sceNp->Todo("sceNpBasicGetBlockListEntryCount(count=%d)", count); + sceNp.Todo("sceNpBasicGetBlockListEntryCount(count=%d)", count); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -404,7 +404,7 @@ int sceNpBasicGetBlockListEntry() int sceNpBasicGetMessageAttachmentEntryCount(vm::ptr count) { - sceNp->Todo("sceNpBasicGetMessageAttachmentEntryCount(count_addr=0x%x)", count.addr()); + sceNp.Todo("sceNpBasicGetMessageAttachmentEntryCount(count_addr=0x%x)", count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -414,7 +414,7 @@ int sceNpBasicGetMessageAttachmentEntryCount(vm::ptr count) int sceNpBasicGetMessageAttachmentEntry(u32 index, vm::ptr from) { - sceNp->Todo("sceNpBasicGetMessageAttachmentEntry(index=%d, from_addr=0x%x)", index, from.addr()); + sceNp.Todo("sceNpBasicGetMessageAttachmentEntry(index=%d, from_addr=0x%x)", index, from.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -436,7 +436,7 @@ int sceNpBasicGetCustomInvitationEntry() int sceNpBasicGetMatchingInvitationEntryCount(vm::ptr count) { - sceNp->Todo("sceNpBasicGetMatchingInvitationEntryCount(count_addr=0x%x)", count.addr()); + sceNp.Todo("sceNpBasicGetMatchingInvitationEntryCount(count_addr=0x%x)", count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -446,7 +446,7 @@ int sceNpBasicGetMatchingInvitationEntryCount(vm::ptr count) int sceNpBasicGetMatchingInvitationEntry(u32 index, vm::ptr from) { - sceNp->Todo("sceNpBasicGetMatchingInvitationEntry(index=%d, from_addr=0x%x)", index, from.addr()); + sceNp.Todo("sceNpBasicGetMatchingInvitationEntry(index=%d, from_addr=0x%x)", index, from.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -456,7 +456,7 @@ int sceNpBasicGetMatchingInvitationEntry(u32 index, vm::ptr from) int sceNpBasicGetClanMessageEntryCount(vm::ptr count) { - sceNp->Todo("sceNpBasicGetClanMessageEntryCount(count_addr=0x%x)", count.addr()); + sceNp.Todo("sceNpBasicGetClanMessageEntryCount(count_addr=0x%x)", count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -466,7 +466,7 @@ int sceNpBasicGetClanMessageEntryCount(vm::ptr count) int sceNpBasicGetClanMessageEntry(u32 index, vm::ptr from) { - sceNp->Todo("sceNpBasicGetClanMessageEntry(index=%d, from_addr=0x%x)", index, from.addr()); + sceNp.Todo("sceNpBasicGetClanMessageEntry(index=%d, from_addr=0x%x)", index, from.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -476,7 +476,7 @@ int sceNpBasicGetClanMessageEntry(u32 index, vm::ptr from) int sceNpBasicGetMessageEntryCount(u32 type, vm::ptr count) { - sceNp->Warning("sceNpBasicGetMessageEntryCount(type=%d, count_addr=0x%x)", type, count.addr()); + sceNp.Warning("sceNpBasicGetMessageEntryCount(type=%d, count_addr=0x%x)", type, count.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -489,7 +489,7 @@ int sceNpBasicGetMessageEntryCount(u32 type, vm::ptr count) int sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr from) { - sceNp->Todo("sceNpBasicGetMessageEntry(type=%d, index=%d, from_addr=0x%x)", type, index, from.addr()); + sceNp.Todo("sceNpBasicGetMessageEntry(type=%d, index=%d, from_addr=0x%x)", type, index, from.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -499,7 +499,7 @@ int sceNpBasicGetMessageEntry(u32 type, u32 index, vm::ptr from) int sceNpBasicGetEvent(vm::ptr event, vm::ptr from, vm::ptr data, vm::ptr size) { - sceNp->Warning("sceNpBasicGetEvent(event_addr=0x%x, from_addr=0x%x, data_addr=0x%x, size_addr=0x%x)", event.addr(), from.addr(), data.addr(), size.addr()); + sceNp.Warning("sceNpBasicGetEvent(event_addr=0x%x, from_addr=0x%x, data_addr=0x%x, size_addr=0x%x)", event.addr(), from.addr(), data.addr(), size.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_BASIC_ERROR_NOT_INITIALIZED; @@ -764,7 +764,7 @@ int sceNpFriendlistAbortGui() int sceNpLookupInit() { - sceNp->Warning("sceNpLookupInit()"); + sceNp.Warning("sceNpLookupInit()"); // TODO: Make sure the error code returned is right, // since there are no error codes for Lookup utility. @@ -778,7 +778,7 @@ int sceNpLookupInit() int sceNpLookupTerm() { - sceNp->Warning("sceNpLookupTerm()"); + sceNp.Warning("sceNpLookupTerm()"); if (!sceNpInstance.m_bLookupInitialized) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; @@ -923,7 +923,7 @@ int sceNpManagerUnregisterCallback() int sceNpManagerGetStatus(vm::ptr status) { - sceNp->Log("sceNpManagerGetStatus(status_addr=0x%x)", status.addr()); + sceNp.Log("sceNpManagerGetStatus(status_addr=0x%x)", status.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_ERROR_NOT_INITIALIZED; @@ -984,7 +984,7 @@ int sceNpManagerGetAccountAge() int sceNpManagerGetContentRatingFlag(vm::ptr isRestricted, vm::ptr age) { - sceNp->Warning("sceNpManagerGetContentRatingFlag(isRestricted_addr=0x%x, age_addr=0x%x)", isRestricted.addr(), age.addr()); + sceNp.Warning("sceNpManagerGetContentRatingFlag(isRestricted_addr=0x%x, age_addr=0x%x)", isRestricted.addr(), age.addr()); if (!sceNpInstance.m_bSceNpInitialized) return SCE_NP_ERROR_NOT_INITIALIZED; @@ -1214,7 +1214,7 @@ int sceNpProfileAbortGui() int sceNpScoreInit() { - sceNp->Warning("sceNpScoreInit()"); + sceNp.Warning("sceNpScoreInit()"); if (sceNpInstance.m_bScoreInitialized) return SCE_NP_COMMUNITY_ERROR_ALREADY_INITIALIZED; @@ -1226,7 +1226,7 @@ int sceNpScoreInit() int sceNpScoreTerm() { - sceNp->Warning("sceNpScoreTerm()"); + sceNp.Warning("sceNpScoreTerm()"); if (!sceNpInstance.m_bScoreInitialized) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; @@ -1643,236 +1643,234 @@ void sceNp_unload() sceNpInstance.m_bSceNpUtilBandwidthTestInitialized = false; } -void sceNp_init(Module *pxThis) +Module sceNp("sceNp", []() { - sceNp = pxThis; - - sceNp->AddFunc(0xbd28fdbf, sceNpInit); - sceNp->AddFunc(0x41251f74, sceNp2Init); - sceNp->AddFunc(0xc2ced2b7, sceNpUtilBandwidthTestInitStart); - sceNp->AddFunc(0x4885aa18, sceNpTerm); - sceNp->AddFunc(0xaadb7c12, sceNp2Term); - sceNp->AddFunc(0x432b3cbf, sceNpUtilBandwidthTestShutdown); - sceNp->AddFunc(0xad218faf, sceNpDrmIsAvailable); - sceNp->AddFunc(0xf042b14f, sceNpDrmIsAvailable2); - sceNp->AddFunc(0x2ecd48ed, sceNpDrmVerifyUpgradeLicense); - sceNp->AddFunc(0xbe0e3ee2, sceNpDrmVerifyUpgradeLicense2); - sceNp->AddFunc(0xf283c143, sceNpDrmExecuteGamePurchase); - sceNp->AddFunc(0xcf51864b, sceNpDrmGetTimelimit); - sceNp->AddFunc(0xaa16695f, sceNpDrmProcessExitSpawn); - sceNp->AddFunc(0xe6c8f3f9, sceNpDrmProcessExitSpawn2); - sceNp->AddFunc(0xbcc09fe7, sceNpBasicRegisterHandler); - sceNp->AddFunc(0x4026eac5, sceNpBasicRegisterContextSensitiveHandler); - sceNp->AddFunc(0xacb9ee8e, sceNpBasicUnregisterHandler); - sceNp->AddFunc(0x3f0808aa, sceNpBasicSetPresence); - sceNp->AddFunc(0xbe81c71c, sceNpBasicSetPresenceDetails); - sceNp->AddFunc(0x5e849303, sceNpBasicSetPresenceDetails2); - sceNp->AddFunc(0xec0a1fbf, sceNpBasicSendMessage); - sceNp->AddFunc(0x01fbbc9b, sceNpBasicSendMessageGui); - sceNp->AddFunc(0x43b989f5, sceNpBasicSendMessageAttachment); - sceNp->AddFunc(0xb5cb2d56, sceNpBasicRecvMessageAttachment); - sceNp->AddFunc(0x64a704cc, sceNpBasicRecvMessageAttachmentLoad); - sceNp->AddFunc(0x806960ab, sceNpBasicRecvMessageCustom); - sceNp->AddFunc(0xe1c9f675, sceNpBasicMarkMessageAsUsed); - sceNp->AddFunc(0x481ce0e8, sceNpBasicAbortGui); - sceNp->AddFunc(0x27c69eba, sceNpBasicAddFriend); - sceNp->AddFunc(0xafef640d, sceNpBasicGetFriendListEntryCount); - sceNp->AddFunc(0x04372385, sceNpBasicGetFriendListEntry); - sceNp->AddFunc(0x32c78a6a, sceNpBasicGetFriendPresenceByIndex); - sceNp->AddFunc(0x6453b27b, sceNpBasicGetFriendPresenceByIndex2); - sceNp->AddFunc(0xfd39ae13, sceNpBasicGetFriendPresenceByNpId); - sceNp->AddFunc(0x260caedd, sceNpBasicGetFriendPresenceByNpId2); - sceNp->AddFunc(0x168a3117, sceNpBasicAddPlayersHistory); - sceNp->AddFunc(0xbcdbb2ab, sceNpBasicAddPlayersHistoryAsync); - sceNp->AddFunc(0xa15f35fe, sceNpBasicGetPlayersHistoryEntryCount); - sceNp->AddFunc(0xbab91fc9, sceNpBasicGetPlayersHistoryEntry); - sceNp->AddFunc(0x1ae8a549, sceNpBasicAddBlockListEntry); - sceNp->AddFunc(0x73931bd0, sceNpBasicGetBlockListEntryCount); - sceNp->AddFunc(0xf2b3338a, sceNpBasicGetBlockListEntry); - sceNp->AddFunc(0x9153bdf4, sceNpBasicGetMessageAttachmentEntryCount); - sceNp->AddFunc(0x5d543bbe, sceNpBasicGetMessageAttachmentEntry); - sceNp->AddFunc(0xa8afa7d4, sceNpBasicGetCustomInvitationEntryCount); - sceNp->AddFunc(0xd053f113, sceNpBasicGetCustomInvitationEntry); - sceNp->AddFunc(0xaf505def, sceNpBasicGetMatchingInvitationEntryCount); - sceNp->AddFunc(0x05af1cb8, sceNpBasicGetMatchingInvitationEntry); - sceNp->AddFunc(0xbf607ec6, sceNpBasicGetClanMessageEntryCount); - sceNp->AddFunc(0x4d9c615d, sceNpBasicGetClanMessageEntry); - sceNp->AddFunc(0xecd503de, sceNpBasicGetMessageEntryCount); - sceNp->AddFunc(0x30d1cbde, sceNpBasicGetMessageEntry); - sceNp->AddFunc(0xe035f7d6, sceNpBasicGetEvent); - sceNp->AddFunc(0xfcac355a, sceNpCommerceCreateCtx); - sceNp->AddFunc(0xe2877bea, sceNpCommerceDestroyCtx); - sceNp->AddFunc(0x8d1d096c, sceNpCommerceInitProductCategory); - sceNp->AddFunc(0x6cb81eb2, sceNpCommerceDestroyProductCategory); - sceNp->AddFunc(0x26f33146, sceNpCommerceGetProductCategoryStart); - sceNp->AddFunc(0xcfd469e4, sceNpCommerceGetProductCategoryFinish); - sceNp->AddFunc(0x3f195b3a, sceNpCommerceGetProductCategoryResult); - sceNp->AddFunc(0x674bb9ff, sceNpCommerceGetProductCategoryAbort); - sceNp->AddFunc(0x936df4aa, sceNpCommerceGetProductId); - sceNp->AddFunc(0xeb5f2544, sceNpCommerceGetProductName); - sceNp->AddFunc(0x359642a6, sceNpCommerceGetCategoryDescription); - sceNp->AddFunc(0xaee8cf71, sceNpCommerceGetCategoryId); - sceNp->AddFunc(0x9452f4f8, sceNpCommerceGetCategoryImageURL); - sceNp->AddFunc(0xeb9df054, sceNpCommerceGetCategoryInfo); - sceNp->AddFunc(0x6e2ab18b, sceNpCommerceGetCategoryName); - sceNp->AddFunc(0x79225aa3, sceNpCommerceGetCurrencyCode); - sceNp->AddFunc(0xaf57d9c9, sceNpCommerceGetCurrencyDecimals); - sceNp->AddFunc(0xb1c02d66, sceNpCommerceGetCurrencyInfo); - sceNp->AddFunc(0x2be41ece, sceNpCommerceGetNumOfChildCategory); - sceNp->AddFunc(0x7208dc08, sceNpCommerceGetNumOfChildProductSku); - sceNp->AddFunc(0xa85a4951, sceNpCommerceGetSkuDescription); - sceNp->AddFunc(0x39a69619, sceNpCommerceGetSkuId); - sceNp->AddFunc(0xccbe2e69, sceNpCommerceGetSkuImageURL); - sceNp->AddFunc(0xee530059, sceNpCommerceGetSkuName); - sceNp->AddFunc(0x78d7f9ad, sceNpCommerceGetSkuPrice); - sceNp->AddFunc(0x1a3fcb69, sceNpCommerceGetSkuUserData); - sceNp->AddFunc(0x99ac9952, sceNpCommerceSetDataFlagStart); - sceNp->AddFunc(0xdbdb909f, sceNpCommerceGetDataFlagStart); - sceNp->AddFunc(0x8d4518a0, sceNpCommerceSetDataFlagFinish); - sceNp->AddFunc(0x9281e87a, sceNpCommerceGetDataFlagFinish); - sceNp->AddFunc(0xd03cea35, sceNpCommerceGetDataFlagState); - sceNp->AddFunc(0x0561448b, sceNpCommerceGetDataFlagAbort); - sceNp->AddFunc(0xba65de6d, sceNpCommerceGetChildCategoryInfo); - sceNp->AddFunc(0x01cd9cfd, sceNpCommerceGetChildProductSkuInfo); - sceNp->AddFunc(0xe36c660e, sceNpCommerceDoCheckoutStartAsync); - sceNp->AddFunc(0xaf3eba5a, sceNpCommerceDoCheckoutFinishAsync); - sceNp->AddFunc(0x45f8f3aa, sceNpCustomMenuRegisterActions); - sceNp->AddFunc(0xf9732ac8, sceNpCustomMenuActionSetActivation); - sceNp->AddFunc(0x9458f464, sceNpCustomMenuRegisterExceptionList); - sceNp->AddFunc(0xf0a9182b, sceNpFriendlist); - sceNp->AddFunc(0xd7fb1fa6, sceNpFriendlistCustom); - sceNp->AddFunc(0xf59e1da8, sceNpFriendlistAbortGui); - sceNp->AddFunc(0x5f2d9257, sceNpLookupInit); - sceNp->AddFunc(0x8440537c, sceNpLookupTerm); - sceNp->AddFunc(0xce81c7f0, sceNpLookupCreateTitleCtx); - sceNp->AddFunc(0x5de61626, sceNpLookupDestroyTitleCtx); - sceNp->AddFunc(0xea2e9ffc, sceNpLookupCreateTransactionCtx); - sceNp->AddFunc(0xfb87cf5e, sceNpLookupDestroyTransactionCtx); - sceNp->AddFunc(0x71e5af7e, sceNpLookupSetTimeout); - sceNp->AddFunc(0x3d1760dc, sceNpLookupAbortTransaction); - sceNp->AddFunc(0xd737fd2d, sceNpLookupWaitAsync); - sceNp->AddFunc(0x7508112e, sceNpLookupPollAsync); - sceNp->AddFunc(0x166dcc11, sceNpLookupNpId); - sceNp->AddFunc(0xd12e40ae, sceNpLookupNpIdAsync); - sceNp->AddFunc(0xdfd63b62, sceNpLookupUserProfile); - sceNp->AddFunc(0xff0a2378, sceNpLookupUserProfileAsync); - sceNp->AddFunc(0x2fccbfe0, sceNpLookupUserProfileWithAvatarSize); - sceNp->AddFunc(0x1fdb3ec2, sceNpLookupUserProfileWithAvatarSizeAsync); - sceNp->AddFunc(0xb6017827, sceNpLookupAvatarImage); - sceNp->AddFunc(0xbf9eea93, sceNpLookupAvatarImageAsync); - sceNp->AddFunc(0x9ee9f97e, sceNpLookupTitleStorage); - sceNp->AddFunc(0x5e117ed5, sceNpLookupTitleStorageAsync); - sceNp->AddFunc(0xca39c4b2, sceNpLookupTitleSmallStorage); - sceNp->AddFunc(0x860b1756, sceNpLookupTitleSmallStorageAsync); - sceNp->AddFunc(0xe7dcd3b4, sceNpManagerRegisterCallback); - sceNp->AddFunc(0x52a6b523, sceNpManagerUnregisterCallback); - sceNp->AddFunc(0xa7bff757, sceNpManagerGetStatus); - sceNp->AddFunc(0xbdc07fd5, sceNpManagerGetNetworkTime); - sceNp->AddFunc(0xbe07c708, sceNpManagerGetOnlineId); - sceNp->AddFunc(0xfe37a7f4, sceNpManagerGetNpId); - sceNp->AddFunc(0xf42c0df8, sceNpManagerGetOnlineName); - sceNp->AddFunc(0x36d0c2c5, sceNpManagerGetAvatarUrl); - sceNp->AddFunc(0x32200389, sceNpManagerGetMyLanguages); - sceNp->AddFunc(0xb1e0718b, sceNpManagerGetAccountRegion); - sceNp->AddFunc(0x168fcece, sceNpManagerGetAccountAge); - sceNp->AddFunc(0x6ee62ed2, sceNpManagerGetContentRatingFlag); - sceNp->AddFunc(0xeb7a3d84, sceNpManagerGetChatRestrictionFlag); - sceNp->AddFunc(0x4b9efb7a, sceNpManagerGetCachedInfo); - sceNp->AddFunc(0x16f88a6f, sceNpManagerGetPsHandle); - sceNp->AddFunc(0x7e2fef28, sceNpManagerRequestTicket); - sceNp->AddFunc(0x8297f1ec, sceNpManagerRequestTicket2); - sceNp->AddFunc(0x0968aa36, sceNpManagerGetTicket); - sceNp->AddFunc(0x58fa4fcd, sceNpManagerGetTicketParam); - sceNp->AddFunc(0xb66d1c46, sceNpManagerGetEntitlementIdList); - sceNp->AddFunc(0xa1709abd, sceNpManagerGetEntitlementById); - sceNp->AddFunc(0x442381f7, sceNpManagerSubSignin); - sceNp->AddFunc(0x60440c73, sceNpManagerSubSigninAbortGui); - sceNp->AddFunc(0x000e53cc, sceNpManagerSubSignout); - sceNp->AddFunc(0xac66568c, sceNpMatchingCreateCtx); - sceNp->AddFunc(0x2e1c5068, sceNpMatchingDestroyCtx); - sceNp->AddFunc(0x03c741a7, sceNpMatchingGetResult); - sceNp->AddFunc(0x26b3bc94, sceNpMatchingGetResultGUI); - sceNp->AddFunc(0x6f8fd267, sceNpMatchingSetRoomInfo); - sceNp->AddFunc(0x4a18a89e, sceNpMatchingSetRoomInfoNoLimit); - sceNp->AddFunc(0x691f429d, sceNpMatchingGetRoomInfo); - sceNp->AddFunc(0xb020684e, sceNpMatchingGetRoomInfoNoLimit); - sceNp->AddFunc(0xa284bd1d, sceNpMatchingSetRoomSearchFlag); - sceNp->AddFunc(0xee64cf8e, sceNpMatchingGetRoomSearchFlag); - sceNp->AddFunc(0x73a2e36b, sceNpMatchingGetRoomMemberListLocal); - sceNp->AddFunc(0xe24eea19, sceNpMatchingGetRoomListLimitGUI); - sceNp->AddFunc(0x34cc0ca4, sceNpMatchingKickRoomMember); - sceNp->AddFunc(0xd20d7798, sceNpMatchingKickRoomMemberWithOpt); - sceNp->AddFunc(0x14497465, sceNpMatchingQuickMatchGUI); - sceNp->AddFunc(0x8b7bbd73, sceNpMatchingSendInvitationGUI); - sceNp->AddFunc(0x2ad7837d, sceNpMatchingAcceptInvitationGUI); - sceNp->AddFunc(0x3cc8588a, sceNpMatchingCreateRoomGUI); - sceNp->AddFunc(0x474b7b13, sceNpMatchingJoinRoomGUI); - sceNp->AddFunc(0xf806c54c, sceNpMatchingLeaveRoom); - sceNp->AddFunc(0x32febb4c, sceNpMatchingSearchJoinRoomGUI); - sceNp->AddFunc(0xdae2d351, sceNpMatchingGrantOwnership); - sceNp->AddFunc(0xceeebc7a, sceNpProfileCallGui); - sceNp->AddFunc(0x2f2c6b3e, sceNpProfileAbortGui); - sceNp->AddFunc(0x32cf311f, sceNpScoreInit); - sceNp->AddFunc(0x9851f805, sceNpScoreTerm); - sceNp->AddFunc(0xb9f93bbb, sceNpScoreCreateTitleCtx); - sceNp->AddFunc(0x259113b8, sceNpScoreDestroyTitleCtx); - sceNp->AddFunc(0x6f5e8143, sceNpScoreCreateTransactionCtx); - sceNp->AddFunc(0xc5f4cf82, sceNpScoreDestroyTransactionCtx); - sceNp->AddFunc(0x29dd45dc, sceNpScoreSetTimeout); - sceNp->AddFunc(0x2706eaa1, sceNpScoreSetPlayerCharacterId); - sceNp->AddFunc(0x1a2704f7, sceNpScoreWaitAsync); - sceNp->AddFunc(0xa7a090e5, sceNpScorePollAsync); - sceNp->AddFunc(0xf4e0f607, sceNpScoreGetBoardInfo); - sceNp->AddFunc(0xddce7d15, sceNpScoreGetBoardInfoAsync); - sceNp->AddFunc(0x1672170e, sceNpScoreRecordScore); - sceNp->AddFunc(0xf0b1e399, sceNpScoreRecordScoreAsync); - sceNp->AddFunc(0x04ca5e6a, sceNpScoreRecordGameData); - sceNp->AddFunc(0xf76847c2, sceNpScoreRecordGameDataAsync); - sceNp->AddFunc(0x3b02418d, sceNpScoreGetGameData); - sceNp->AddFunc(0xdb2e4dc2, sceNpScoreGetGameDataAsync); - sceNp->AddFunc(0x05d65dff, sceNpScoreGetRankingByNpId); - sceNp->AddFunc(0x3db7914d, sceNpScoreGetRankingByNpIdAsync); - sceNp->AddFunc(0xfbc82301, sceNpScoreGetRankingByRange); - sceNp->AddFunc(0x21206642, sceNpScoreGetRankingByRangeAsync); - sceNp->AddFunc(0x7deb244c, sceNpScoreCensorComment); - sceNp->AddFunc(0x7be47e61, sceNpScoreCensorCommentAsync); - sceNp->AddFunc(0xf1b77918, sceNpScoreSanitizeComment); - sceNp->AddFunc(0x2cd2a1af, sceNpScoreSanitizeCommentAsync); - sceNp->AddFunc(0xc3a991ee, sceNpScoreGetRankingByNpIdPcId); - sceNp->AddFunc(0xc4b6cd8f, sceNpScoreGetRankingByNpIdPcIdAsync); - sceNp->AddFunc(0xee5b20d9, sceNpScoreAbortTransaction); - sceNp->AddFunc(0xded17c26, sceNpScoreGetClansMembersRankingByNpId); - sceNp->AddFunc(0xe8a67160, sceNpScoreGetClansMembersRankingByNpIdAsync); - sceNp->AddFunc(0x41ffd4f2, sceNpScoreGetClansMembersRankingByNpIdPcId); - sceNp->AddFunc(0x433fcb30, sceNpScoreGetClansMembersRankingByNpIdPcIdAsync); - sceNp->AddFunc(0x6d4adc3b, sceNpScoreGetClansMembersRankingByRange); - sceNp->AddFunc(0x4d5e0670, sceNpScoreGetClansMembersRankingByRangeAsync); - sceNp->AddFunc(0x741fbf24, sceNpScoreGetClanMemberGameData); - sceNp->AddFunc(0xbef887e5, sceNpScoreGetClanMemberGameDataAsync); - sceNp->AddFunc(0x2a76895a, sceNpScoreGetClansRankingByClanId); - sceNp->AddFunc(0x227f8763, sceNpScoreGetClansRankingByClanIdAsync); - sceNp->AddFunc(0xb082003b, sceNpScoreGetClansRankingByRange); - sceNp->AddFunc(0x7b7e9137, sceNpScoreGetClansRankingByRangeAsync); - sceNp->AddFunc(0x6356082e, sceNpSignalingCreateCtx); - sceNp->AddFunc(0xa8cf8451, sceNpSignalingDestroyCtx); - sceNp->AddFunc(0x50b86d94, sceNpSignalingAddExtendedHandler); - sceNp->AddFunc(0x276c72b2, sceNpSignalingSetCtxOpt); - sceNp->AddFunc(0x2687a127, sceNpSignalingGetCtxOpt); - sceNp->AddFunc(0x60897c38, sceNpSignalingActivateConnection); - sceNp->AddFunc(0xfd0eb5ae, sceNpSignalingDeactivateConnection); - sceNp->AddFunc(0x95c7bba3, sceNpSignalingTerminateConnection); - sceNp->AddFunc(0xca0a2d04, sceNpSignalingGetConnectionStatus); - sceNp->AddFunc(0x155de760, sceNpSignalingGetConnectionInfo); - sceNp->AddFunc(0xe853d388, sceNpSignalingGetConnectionFromNpId); - sceNp->AddFunc(0x34ce82a0, sceNpSignalingGetConnectionFromPeerAddress); - sceNp->AddFunc(0x9ad7fbd1, sceNpSignalingGetLocalNetInfo); - sceNp->AddFunc(0x75eb50cb, sceNpSignalingGetPeerNetInfo); - sceNp->AddFunc(0x64dbb89d, sceNpSignalingCancelPeerNetInfo); - sceNp->AddFunc(0xd0958814, sceNpSignalingGetPeerNetInfoResult); - sceNp->AddFunc(0xd208f91d, sceNpUtilCmpNpId); - sceNp->AddFunc(0xf5ff5f31, sceNpUtilCmpNpIdInOrder); - sceNp->AddFunc(0xc880f37d, sceNpUtilBandwidthTestGetStatus); - sceNp->AddFunc(0xc99ee313, sceNpUtilBandwidthTestAbort); - sceNp->AddFunc(0xee0cc40c, _sceNpSysutilClientMalloc); - sceNp->AddFunc(0x816c6a5f, _sceNpSysutilClientFree); -} + sceNp.AddFunc(0xbd28fdbf, sceNpInit); + sceNp.AddFunc(0x41251f74, sceNp2Init); + sceNp.AddFunc(0xc2ced2b7, sceNpUtilBandwidthTestInitStart); + sceNp.AddFunc(0x4885aa18, sceNpTerm); + sceNp.AddFunc(0xaadb7c12, sceNp2Term); + sceNp.AddFunc(0x432b3cbf, sceNpUtilBandwidthTestShutdown); + sceNp.AddFunc(0xad218faf, sceNpDrmIsAvailable); + sceNp.AddFunc(0xf042b14f, sceNpDrmIsAvailable2); + sceNp.AddFunc(0x2ecd48ed, sceNpDrmVerifyUpgradeLicense); + sceNp.AddFunc(0xbe0e3ee2, sceNpDrmVerifyUpgradeLicense2); + sceNp.AddFunc(0xf283c143, sceNpDrmExecuteGamePurchase); + sceNp.AddFunc(0xcf51864b, sceNpDrmGetTimelimit); + sceNp.AddFunc(0xaa16695f, sceNpDrmProcessExitSpawn); + sceNp.AddFunc(0xe6c8f3f9, sceNpDrmProcessExitSpawn2); + sceNp.AddFunc(0xbcc09fe7, sceNpBasicRegisterHandler); + sceNp.AddFunc(0x4026eac5, sceNpBasicRegisterContextSensitiveHandler); + sceNp.AddFunc(0xacb9ee8e, sceNpBasicUnregisterHandler); + sceNp.AddFunc(0x3f0808aa, sceNpBasicSetPresence); + sceNp.AddFunc(0xbe81c71c, sceNpBasicSetPresenceDetails); + sceNp.AddFunc(0x5e849303, sceNpBasicSetPresenceDetails2); + sceNp.AddFunc(0xec0a1fbf, sceNpBasicSendMessage); + sceNp.AddFunc(0x01fbbc9b, sceNpBasicSendMessageGui); + sceNp.AddFunc(0x43b989f5, sceNpBasicSendMessageAttachment); + sceNp.AddFunc(0xb5cb2d56, sceNpBasicRecvMessageAttachment); + sceNp.AddFunc(0x64a704cc, sceNpBasicRecvMessageAttachmentLoad); + sceNp.AddFunc(0x806960ab, sceNpBasicRecvMessageCustom); + sceNp.AddFunc(0xe1c9f675, sceNpBasicMarkMessageAsUsed); + sceNp.AddFunc(0x481ce0e8, sceNpBasicAbortGui); + sceNp.AddFunc(0x27c69eba, sceNpBasicAddFriend); + sceNp.AddFunc(0xafef640d, sceNpBasicGetFriendListEntryCount); + sceNp.AddFunc(0x04372385, sceNpBasicGetFriendListEntry); + sceNp.AddFunc(0x32c78a6a, sceNpBasicGetFriendPresenceByIndex); + sceNp.AddFunc(0x6453b27b, sceNpBasicGetFriendPresenceByIndex2); + sceNp.AddFunc(0xfd39ae13, sceNpBasicGetFriendPresenceByNpId); + sceNp.AddFunc(0x260caedd, sceNpBasicGetFriendPresenceByNpId2); + sceNp.AddFunc(0x168a3117, sceNpBasicAddPlayersHistory); + sceNp.AddFunc(0xbcdbb2ab, sceNpBasicAddPlayersHistoryAsync); + sceNp.AddFunc(0xa15f35fe, sceNpBasicGetPlayersHistoryEntryCount); + sceNp.AddFunc(0xbab91fc9, sceNpBasicGetPlayersHistoryEntry); + sceNp.AddFunc(0x1ae8a549, sceNpBasicAddBlockListEntry); + sceNp.AddFunc(0x73931bd0, sceNpBasicGetBlockListEntryCount); + sceNp.AddFunc(0xf2b3338a, sceNpBasicGetBlockListEntry); + sceNp.AddFunc(0x9153bdf4, sceNpBasicGetMessageAttachmentEntryCount); + sceNp.AddFunc(0x5d543bbe, sceNpBasicGetMessageAttachmentEntry); + sceNp.AddFunc(0xa8afa7d4, sceNpBasicGetCustomInvitationEntryCount); + sceNp.AddFunc(0xd053f113, sceNpBasicGetCustomInvitationEntry); + sceNp.AddFunc(0xaf505def, sceNpBasicGetMatchingInvitationEntryCount); + sceNp.AddFunc(0x05af1cb8, sceNpBasicGetMatchingInvitationEntry); + sceNp.AddFunc(0xbf607ec6, sceNpBasicGetClanMessageEntryCount); + sceNp.AddFunc(0x4d9c615d, sceNpBasicGetClanMessageEntry); + sceNp.AddFunc(0xecd503de, sceNpBasicGetMessageEntryCount); + sceNp.AddFunc(0x30d1cbde, sceNpBasicGetMessageEntry); + sceNp.AddFunc(0xe035f7d6, sceNpBasicGetEvent); + sceNp.AddFunc(0xfcac355a, sceNpCommerceCreateCtx); + sceNp.AddFunc(0xe2877bea, sceNpCommerceDestroyCtx); + sceNp.AddFunc(0x8d1d096c, sceNpCommerceInitProductCategory); + sceNp.AddFunc(0x6cb81eb2, sceNpCommerceDestroyProductCategory); + sceNp.AddFunc(0x26f33146, sceNpCommerceGetProductCategoryStart); + sceNp.AddFunc(0xcfd469e4, sceNpCommerceGetProductCategoryFinish); + sceNp.AddFunc(0x3f195b3a, sceNpCommerceGetProductCategoryResult); + sceNp.AddFunc(0x674bb9ff, sceNpCommerceGetProductCategoryAbort); + sceNp.AddFunc(0x936df4aa, sceNpCommerceGetProductId); + sceNp.AddFunc(0xeb5f2544, sceNpCommerceGetProductName); + sceNp.AddFunc(0x359642a6, sceNpCommerceGetCategoryDescription); + sceNp.AddFunc(0xaee8cf71, sceNpCommerceGetCategoryId); + sceNp.AddFunc(0x9452f4f8, sceNpCommerceGetCategoryImageURL); + sceNp.AddFunc(0xeb9df054, sceNpCommerceGetCategoryInfo); + sceNp.AddFunc(0x6e2ab18b, sceNpCommerceGetCategoryName); + sceNp.AddFunc(0x79225aa3, sceNpCommerceGetCurrencyCode); + sceNp.AddFunc(0xaf57d9c9, sceNpCommerceGetCurrencyDecimals); + sceNp.AddFunc(0xb1c02d66, sceNpCommerceGetCurrencyInfo); + sceNp.AddFunc(0x2be41ece, sceNpCommerceGetNumOfChildCategory); + sceNp.AddFunc(0x7208dc08, sceNpCommerceGetNumOfChildProductSku); + sceNp.AddFunc(0xa85a4951, sceNpCommerceGetSkuDescription); + sceNp.AddFunc(0x39a69619, sceNpCommerceGetSkuId); + sceNp.AddFunc(0xccbe2e69, sceNpCommerceGetSkuImageURL); + sceNp.AddFunc(0xee530059, sceNpCommerceGetSkuName); + sceNp.AddFunc(0x78d7f9ad, sceNpCommerceGetSkuPrice); + sceNp.AddFunc(0x1a3fcb69, sceNpCommerceGetSkuUserData); + sceNp.AddFunc(0x99ac9952, sceNpCommerceSetDataFlagStart); + sceNp.AddFunc(0xdbdb909f, sceNpCommerceGetDataFlagStart); + sceNp.AddFunc(0x8d4518a0, sceNpCommerceSetDataFlagFinish); + sceNp.AddFunc(0x9281e87a, sceNpCommerceGetDataFlagFinish); + sceNp.AddFunc(0xd03cea35, sceNpCommerceGetDataFlagState); + sceNp.AddFunc(0x0561448b, sceNpCommerceGetDataFlagAbort); + sceNp.AddFunc(0xba65de6d, sceNpCommerceGetChildCategoryInfo); + sceNp.AddFunc(0x01cd9cfd, sceNpCommerceGetChildProductSkuInfo); + sceNp.AddFunc(0xe36c660e, sceNpCommerceDoCheckoutStartAsync); + sceNp.AddFunc(0xaf3eba5a, sceNpCommerceDoCheckoutFinishAsync); + sceNp.AddFunc(0x45f8f3aa, sceNpCustomMenuRegisterActions); + sceNp.AddFunc(0xf9732ac8, sceNpCustomMenuActionSetActivation); + sceNp.AddFunc(0x9458f464, sceNpCustomMenuRegisterExceptionList); + sceNp.AddFunc(0xf0a9182b, sceNpFriendlist); + sceNp.AddFunc(0xd7fb1fa6, sceNpFriendlistCustom); + sceNp.AddFunc(0xf59e1da8, sceNpFriendlistAbortGui); + sceNp.AddFunc(0x5f2d9257, sceNpLookupInit); + sceNp.AddFunc(0x8440537c, sceNpLookupTerm); + sceNp.AddFunc(0xce81c7f0, sceNpLookupCreateTitleCtx); + sceNp.AddFunc(0x5de61626, sceNpLookupDestroyTitleCtx); + sceNp.AddFunc(0xea2e9ffc, sceNpLookupCreateTransactionCtx); + sceNp.AddFunc(0xfb87cf5e, sceNpLookupDestroyTransactionCtx); + sceNp.AddFunc(0x71e5af7e, sceNpLookupSetTimeout); + sceNp.AddFunc(0x3d1760dc, sceNpLookupAbortTransaction); + sceNp.AddFunc(0xd737fd2d, sceNpLookupWaitAsync); + sceNp.AddFunc(0x7508112e, sceNpLookupPollAsync); + sceNp.AddFunc(0x166dcc11, sceNpLookupNpId); + sceNp.AddFunc(0xd12e40ae, sceNpLookupNpIdAsync); + sceNp.AddFunc(0xdfd63b62, sceNpLookupUserProfile); + sceNp.AddFunc(0xff0a2378, sceNpLookupUserProfileAsync); + sceNp.AddFunc(0x2fccbfe0, sceNpLookupUserProfileWithAvatarSize); + sceNp.AddFunc(0x1fdb3ec2, sceNpLookupUserProfileWithAvatarSizeAsync); + sceNp.AddFunc(0xb6017827, sceNpLookupAvatarImage); + sceNp.AddFunc(0xbf9eea93, sceNpLookupAvatarImageAsync); + sceNp.AddFunc(0x9ee9f97e, sceNpLookupTitleStorage); + sceNp.AddFunc(0x5e117ed5, sceNpLookupTitleStorageAsync); + sceNp.AddFunc(0xca39c4b2, sceNpLookupTitleSmallStorage); + sceNp.AddFunc(0x860b1756, sceNpLookupTitleSmallStorageAsync); + sceNp.AddFunc(0xe7dcd3b4, sceNpManagerRegisterCallback); + sceNp.AddFunc(0x52a6b523, sceNpManagerUnregisterCallback); + sceNp.AddFunc(0xa7bff757, sceNpManagerGetStatus); + sceNp.AddFunc(0xbdc07fd5, sceNpManagerGetNetworkTime); + sceNp.AddFunc(0xbe07c708, sceNpManagerGetOnlineId); + sceNp.AddFunc(0xfe37a7f4, sceNpManagerGetNpId); + sceNp.AddFunc(0xf42c0df8, sceNpManagerGetOnlineName); + sceNp.AddFunc(0x36d0c2c5, sceNpManagerGetAvatarUrl); + sceNp.AddFunc(0x32200389, sceNpManagerGetMyLanguages); + sceNp.AddFunc(0xb1e0718b, sceNpManagerGetAccountRegion); + sceNp.AddFunc(0x168fcece, sceNpManagerGetAccountAge); + sceNp.AddFunc(0x6ee62ed2, sceNpManagerGetContentRatingFlag); + sceNp.AddFunc(0xeb7a3d84, sceNpManagerGetChatRestrictionFlag); + sceNp.AddFunc(0x4b9efb7a, sceNpManagerGetCachedInfo); + sceNp.AddFunc(0x16f88a6f, sceNpManagerGetPsHandle); + sceNp.AddFunc(0x7e2fef28, sceNpManagerRequestTicket); + sceNp.AddFunc(0x8297f1ec, sceNpManagerRequestTicket2); + sceNp.AddFunc(0x0968aa36, sceNpManagerGetTicket); + sceNp.AddFunc(0x58fa4fcd, sceNpManagerGetTicketParam); + sceNp.AddFunc(0xb66d1c46, sceNpManagerGetEntitlementIdList); + sceNp.AddFunc(0xa1709abd, sceNpManagerGetEntitlementById); + sceNp.AddFunc(0x442381f7, sceNpManagerSubSignin); + sceNp.AddFunc(0x60440c73, sceNpManagerSubSigninAbortGui); + sceNp.AddFunc(0x000e53cc, sceNpManagerSubSignout); + sceNp.AddFunc(0xac66568c, sceNpMatchingCreateCtx); + sceNp.AddFunc(0x2e1c5068, sceNpMatchingDestroyCtx); + sceNp.AddFunc(0x03c741a7, sceNpMatchingGetResult); + sceNp.AddFunc(0x26b3bc94, sceNpMatchingGetResultGUI); + sceNp.AddFunc(0x6f8fd267, sceNpMatchingSetRoomInfo); + sceNp.AddFunc(0x4a18a89e, sceNpMatchingSetRoomInfoNoLimit); + sceNp.AddFunc(0x691f429d, sceNpMatchingGetRoomInfo); + sceNp.AddFunc(0xb020684e, sceNpMatchingGetRoomInfoNoLimit); + sceNp.AddFunc(0xa284bd1d, sceNpMatchingSetRoomSearchFlag); + sceNp.AddFunc(0xee64cf8e, sceNpMatchingGetRoomSearchFlag); + sceNp.AddFunc(0x73a2e36b, sceNpMatchingGetRoomMemberListLocal); + sceNp.AddFunc(0xe24eea19, sceNpMatchingGetRoomListLimitGUI); + sceNp.AddFunc(0x34cc0ca4, sceNpMatchingKickRoomMember); + sceNp.AddFunc(0xd20d7798, sceNpMatchingKickRoomMemberWithOpt); + sceNp.AddFunc(0x14497465, sceNpMatchingQuickMatchGUI); + sceNp.AddFunc(0x8b7bbd73, sceNpMatchingSendInvitationGUI); + sceNp.AddFunc(0x2ad7837d, sceNpMatchingAcceptInvitationGUI); + sceNp.AddFunc(0x3cc8588a, sceNpMatchingCreateRoomGUI); + sceNp.AddFunc(0x474b7b13, sceNpMatchingJoinRoomGUI); + sceNp.AddFunc(0xf806c54c, sceNpMatchingLeaveRoom); + sceNp.AddFunc(0x32febb4c, sceNpMatchingSearchJoinRoomGUI); + sceNp.AddFunc(0xdae2d351, sceNpMatchingGrantOwnership); + sceNp.AddFunc(0xceeebc7a, sceNpProfileCallGui); + sceNp.AddFunc(0x2f2c6b3e, sceNpProfileAbortGui); + sceNp.AddFunc(0x32cf311f, sceNpScoreInit); + sceNp.AddFunc(0x9851f805, sceNpScoreTerm); + sceNp.AddFunc(0xb9f93bbb, sceNpScoreCreateTitleCtx); + sceNp.AddFunc(0x259113b8, sceNpScoreDestroyTitleCtx); + sceNp.AddFunc(0x6f5e8143, sceNpScoreCreateTransactionCtx); + sceNp.AddFunc(0xc5f4cf82, sceNpScoreDestroyTransactionCtx); + sceNp.AddFunc(0x29dd45dc, sceNpScoreSetTimeout); + sceNp.AddFunc(0x2706eaa1, sceNpScoreSetPlayerCharacterId); + sceNp.AddFunc(0x1a2704f7, sceNpScoreWaitAsync); + sceNp.AddFunc(0xa7a090e5, sceNpScorePollAsync); + sceNp.AddFunc(0xf4e0f607, sceNpScoreGetBoardInfo); + sceNp.AddFunc(0xddce7d15, sceNpScoreGetBoardInfoAsync); + sceNp.AddFunc(0x1672170e, sceNpScoreRecordScore); + sceNp.AddFunc(0xf0b1e399, sceNpScoreRecordScoreAsync); + sceNp.AddFunc(0x04ca5e6a, sceNpScoreRecordGameData); + sceNp.AddFunc(0xf76847c2, sceNpScoreRecordGameDataAsync); + sceNp.AddFunc(0x3b02418d, sceNpScoreGetGameData); + sceNp.AddFunc(0xdb2e4dc2, sceNpScoreGetGameDataAsync); + sceNp.AddFunc(0x05d65dff, sceNpScoreGetRankingByNpId); + sceNp.AddFunc(0x3db7914d, sceNpScoreGetRankingByNpIdAsync); + sceNp.AddFunc(0xfbc82301, sceNpScoreGetRankingByRange); + sceNp.AddFunc(0x21206642, sceNpScoreGetRankingByRangeAsync); + sceNp.AddFunc(0x7deb244c, sceNpScoreCensorComment); + sceNp.AddFunc(0x7be47e61, sceNpScoreCensorCommentAsync); + sceNp.AddFunc(0xf1b77918, sceNpScoreSanitizeComment); + sceNp.AddFunc(0x2cd2a1af, sceNpScoreSanitizeCommentAsync); + sceNp.AddFunc(0xc3a991ee, sceNpScoreGetRankingByNpIdPcId); + sceNp.AddFunc(0xc4b6cd8f, sceNpScoreGetRankingByNpIdPcIdAsync); + sceNp.AddFunc(0xee5b20d9, sceNpScoreAbortTransaction); + sceNp.AddFunc(0xded17c26, sceNpScoreGetClansMembersRankingByNpId); + sceNp.AddFunc(0xe8a67160, sceNpScoreGetClansMembersRankingByNpIdAsync); + sceNp.AddFunc(0x41ffd4f2, sceNpScoreGetClansMembersRankingByNpIdPcId); + sceNp.AddFunc(0x433fcb30, sceNpScoreGetClansMembersRankingByNpIdPcIdAsync); + sceNp.AddFunc(0x6d4adc3b, sceNpScoreGetClansMembersRankingByRange); + sceNp.AddFunc(0x4d5e0670, sceNpScoreGetClansMembersRankingByRangeAsync); + sceNp.AddFunc(0x741fbf24, sceNpScoreGetClanMemberGameData); + sceNp.AddFunc(0xbef887e5, sceNpScoreGetClanMemberGameDataAsync); + sceNp.AddFunc(0x2a76895a, sceNpScoreGetClansRankingByClanId); + sceNp.AddFunc(0x227f8763, sceNpScoreGetClansRankingByClanIdAsync); + sceNp.AddFunc(0xb082003b, sceNpScoreGetClansRankingByRange); + sceNp.AddFunc(0x7b7e9137, sceNpScoreGetClansRankingByRangeAsync); + sceNp.AddFunc(0x6356082e, sceNpSignalingCreateCtx); + sceNp.AddFunc(0xa8cf8451, sceNpSignalingDestroyCtx); + sceNp.AddFunc(0x50b86d94, sceNpSignalingAddExtendedHandler); + sceNp.AddFunc(0x276c72b2, sceNpSignalingSetCtxOpt); + sceNp.AddFunc(0x2687a127, sceNpSignalingGetCtxOpt); + sceNp.AddFunc(0x60897c38, sceNpSignalingActivateConnection); + sceNp.AddFunc(0xfd0eb5ae, sceNpSignalingDeactivateConnection); + sceNp.AddFunc(0x95c7bba3, sceNpSignalingTerminateConnection); + sceNp.AddFunc(0xca0a2d04, sceNpSignalingGetConnectionStatus); + sceNp.AddFunc(0x155de760, sceNpSignalingGetConnectionInfo); + sceNp.AddFunc(0xe853d388, sceNpSignalingGetConnectionFromNpId); + sceNp.AddFunc(0x34ce82a0, sceNpSignalingGetConnectionFromPeerAddress); + sceNp.AddFunc(0x9ad7fbd1, sceNpSignalingGetLocalNetInfo); + sceNp.AddFunc(0x75eb50cb, sceNpSignalingGetPeerNetInfo); + sceNp.AddFunc(0x64dbb89d, sceNpSignalingCancelPeerNetInfo); + sceNp.AddFunc(0xd0958814, sceNpSignalingGetPeerNetInfoResult); + sceNp.AddFunc(0xd208f91d, sceNpUtilCmpNpId); + sceNp.AddFunc(0xf5ff5f31, sceNpUtilCmpNpIdInOrder); + sceNp.AddFunc(0xc880f37d, sceNpUtilBandwidthTestGetStatus); + sceNp.AddFunc(0xc99ee313, sceNpUtilBandwidthTestAbort); + sceNp.AddFunc(0xee0cc40c, _sceNpSysutilClientMalloc); + sceNp.AddFunc(0x816c6a5f, _sceNpSysutilClientFree); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp index 0c761ee2cc..4a3baff1b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpClans.cpp @@ -6,7 +6,7 @@ #include "sceNp.h" #include "sceNpClans.h" -Module *sceNpClans = nullptr; +extern Module sceNpClans; struct sceNpClansInternal { @@ -22,7 +22,7 @@ sceNpClansInternal sceNpClansInstance; int sceNpClansInit(vm::ptr commId, vm::ptr passphrase, vm::ptr pool, vm::ptr poolSize, u32 flags) { - sceNpClans->Warning("sceNpClansInit(commId_addr=0x%x, passphrase_addr=0x%x, pool_addr=0x%x,poolSize_addr=0x%x, flags=%d)", commId.addr(), passphrase.addr(), pool.addr(), poolSize.addr(), flags); + sceNpClans.Warning("sceNpClansInit(commId_addr=0x%x, passphrase_addr=0x%x, pool_addr=0x%x,poolSize_addr=0x%x, flags=%d)", commId.addr(), passphrase.addr(), pool.addr(), poolSize.addr(), flags); if (sceNpClansInstance.m_bSceNpClansInitialized) return SCE_NP_CLANS_ERROR_ALREADY_INITIALIZED; @@ -37,7 +37,7 @@ int sceNpClansInit(vm::ptr commId, vm::ptrWarning("sceNpClansTerm()"); + sceNpClans.Warning("sceNpClansTerm()"); if (!sceNpClansInstance.m_bSceNpClansInitialized) return SCE_NP_CLANS_ERROR_NOT_INITIALIZED; @@ -49,7 +49,7 @@ int sceNpClansTerm() int sceNpClansCreateRequest(vm::ptr handle,u64 flags) { - sceNpClans->Todo("sceNpClansCreateRequest(handle_addr=0x%x, flags=0x%llx)", handle.addr(), flags); + sceNpClans.Todo("sceNpClansCreateRequest(handle_addr=0x%x, flags=0x%llx)", handle.addr(), flags); if (!sceNpClansInstance.m_bSceNpClansInitialized) return SCE_NP_CLANS_ERROR_NOT_INITIALIZED; @@ -432,47 +432,45 @@ void sceNpClans_unload() sceNpClansInstance.m_bSceNpClansInitialized = false; } -void sceNpClans_init(Module *pxThis) +Module sceNpClans("sceNpClans", []() { - sceNpClans = pxThis; - - sceNpClans->AddFunc(0x9b820047, sceNpClansInit); - sceNpClans->AddFunc(0x42332cb7, sceNpClansTerm); - sceNpClans->AddFunc(0x9a72232d, sceNpClansCreateRequest); - sceNpClans->AddFunc(0xd6551cd1, sceNpClansDestroyRequest); - sceNpClans->AddFunc(0xe82969e2, sceNpClansAbortRequest); - sceNpClans->AddFunc(0xa6a31a38, sceNpClansCreateClan); - sceNpClans->AddFunc(0x4826f6d5, sceNpClansDisbandClan); - sceNpClans->AddFunc(0xca4181b4, sceNpClansGetClanList); - sceNpClans->AddFunc(0x672399a8, sceNpClansGetClanListByNpId); - sceNpClans->AddFunc(0x1221a1bf, sceNpClansSearchByProfile); - sceNpClans->AddFunc(0xace0cfba, sceNpClansSearchByName); - sceNpClans->AddFunc(0x487de998, sceNpClansGetClanInfo); - sceNpClans->AddFunc(0x09f9e1a9, sceNpClansUpdateClanInfo); - sceNpClans->AddFunc(0x856ff5c0, sceNpClansGetMemberList); - sceNpClans->AddFunc(0x20472da0, sceNpClansGetMemberInfo); - sceNpClans->AddFunc(0xf4a2d52b, sceNpClansUpdateMemberInfo); - sceNpClans->AddFunc(0x9cac2085, sceNpClansChangeMemberRole); - sceNpClans->AddFunc(0x38dadf1f, sceNpClansGetAutoAcceptStatus); - sceNpClans->AddFunc(0x5da94854, sceNpClansUpdateAutoAcceptStatus); - sceNpClans->AddFunc(0xdbf300ca, sceNpClansJoinClan); - sceNpClans->AddFunc(0x560f717b, sceNpClansLeaveClan); - sceNpClans->AddFunc(0xaa7912b5, sceNpClansKickMember); - sceNpClans->AddFunc(0xbc05ef31, sceNpClansSendInvitation); - sceNpClans->AddFunc(0x726dffd5, sceNpClansCancelInvitation); - sceNpClans->AddFunc(0x095e12c6, sceNpClansSendInvitationResponse); - sceNpClans->AddFunc(0x59743b2b, sceNpClansSendMembershipRequest); - sceNpClans->AddFunc(0x299ccc9b, sceNpClansCancelMembershipRequest); - sceNpClans->AddFunc(0x942dbdc4, sceNpClansSendMembershipResponse); - sceNpClans->AddFunc(0x56bc5a7c, sceNpClansGetBlacklist); - sceNpClans->AddFunc(0x4d06aef7, sceNpClansAddBlacklistEntry); - sceNpClans->AddFunc(0x5bff9da1, sceNpClansRemoveBlacklistEntry); - sceNpClans->AddFunc(0x727aa7f8, sceNpClansRetrieveAnnouncements); - sceNpClans->AddFunc(0xada45b84, sceNpClansPostAnnouncement); - sceNpClans->AddFunc(0xe2590f60, sceNpClansRemoveAnnouncement); - sceNpClans->AddFunc(0x83d65529, sceNpClansPostChallenge); - sceNpClans->AddFunc(0x8e785b97, sceNpClansRetrievePostedChallenges); - sceNpClans->AddFunc(0xd3346dc4, sceNpClansRemovePostedChallenge); - sceNpClans->AddFunc(0x0df25834, sceNpClansRetrieveChallenges); - sceNpClans->AddFunc(0xce6dc0f0, sceNpClansRemoveChallenge); -} \ No newline at end of file + sceNpClans.AddFunc(0x9b820047, sceNpClansInit); + sceNpClans.AddFunc(0x42332cb7, sceNpClansTerm); + sceNpClans.AddFunc(0x9a72232d, sceNpClansCreateRequest); + sceNpClans.AddFunc(0xd6551cd1, sceNpClansDestroyRequest); + sceNpClans.AddFunc(0xe82969e2, sceNpClansAbortRequest); + sceNpClans.AddFunc(0xa6a31a38, sceNpClansCreateClan); + sceNpClans.AddFunc(0x4826f6d5, sceNpClansDisbandClan); + sceNpClans.AddFunc(0xca4181b4, sceNpClansGetClanList); + sceNpClans.AddFunc(0x672399a8, sceNpClansGetClanListByNpId); + sceNpClans.AddFunc(0x1221a1bf, sceNpClansSearchByProfile); + sceNpClans.AddFunc(0xace0cfba, sceNpClansSearchByName); + sceNpClans.AddFunc(0x487de998, sceNpClansGetClanInfo); + sceNpClans.AddFunc(0x09f9e1a9, sceNpClansUpdateClanInfo); + sceNpClans.AddFunc(0x856ff5c0, sceNpClansGetMemberList); + sceNpClans.AddFunc(0x20472da0, sceNpClansGetMemberInfo); + sceNpClans.AddFunc(0xf4a2d52b, sceNpClansUpdateMemberInfo); + sceNpClans.AddFunc(0x9cac2085, sceNpClansChangeMemberRole); + sceNpClans.AddFunc(0x38dadf1f, sceNpClansGetAutoAcceptStatus); + sceNpClans.AddFunc(0x5da94854, sceNpClansUpdateAutoAcceptStatus); + sceNpClans.AddFunc(0xdbf300ca, sceNpClansJoinClan); + sceNpClans.AddFunc(0x560f717b, sceNpClansLeaveClan); + sceNpClans.AddFunc(0xaa7912b5, sceNpClansKickMember); + sceNpClans.AddFunc(0xbc05ef31, sceNpClansSendInvitation); + sceNpClans.AddFunc(0x726dffd5, sceNpClansCancelInvitation); + sceNpClans.AddFunc(0x095e12c6, sceNpClansSendInvitationResponse); + sceNpClans.AddFunc(0x59743b2b, sceNpClansSendMembershipRequest); + sceNpClans.AddFunc(0x299ccc9b, sceNpClansCancelMembershipRequest); + sceNpClans.AddFunc(0x942dbdc4, sceNpClansSendMembershipResponse); + sceNpClans.AddFunc(0x56bc5a7c, sceNpClansGetBlacklist); + sceNpClans.AddFunc(0x4d06aef7, sceNpClansAddBlacklistEntry); + sceNpClans.AddFunc(0x5bff9da1, sceNpClansRemoveBlacklistEntry); + sceNpClans.AddFunc(0x727aa7f8, sceNpClansRetrieveAnnouncements); + sceNpClans.AddFunc(0xada45b84, sceNpClansPostAnnouncement); + sceNpClans.AddFunc(0xe2590f60, sceNpClansRemoveAnnouncement); + sceNpClans.AddFunc(0x83d65529, sceNpClansPostChallenge); + sceNpClans.AddFunc(0x8e785b97, sceNpClansRetrievePostedChallenges); + sceNpClans.AddFunc(0xd3346dc4, sceNpClansRemovePostedChallenge); + sceNpClans.AddFunc(0x0df25834, sceNpClansRetrieveChallenges); + sceNpClans.AddFunc(0xce6dc0f0, sceNpClansRemoveChallenge); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp index 392de7166f..66ca23a258 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpCommerce2.cpp @@ -4,7 +4,7 @@ #include "sceNpCommerce2.h" -Module *sceNpCommerce2 = nullptr; +extern Module sceNpCommerce2; struct sceNpCommerce2Internal { @@ -32,7 +32,7 @@ int sceNpCommerce2GetStoreBrowseUserdata() int sceNpCommerce2Init() { - sceNpCommerce2->Warning("sceNpCommerce2Init()"); + sceNpCommerce2.Warning("sceNpCommerce2Init()"); if (sceNpCommerce2Instance.m_bSceNpCommerce2Initialized) return SCE_NP_COMMERCE2_ERROR_ALREADY_INITIALIZED; @@ -44,7 +44,7 @@ int sceNpCommerce2Init() int sceNpCommerce2Term() { - sceNpCommerce2->Warning("sceNpCommerce2Term()"); + sceNpCommerce2.Warning("sceNpCommerce2Term()"); if (!sceNpCommerce2Instance.m_bSceNpCommerce2Initialized) return SCE_NP_COMMERCE2_ERROR_NOT_INITIALIZED; @@ -317,55 +317,53 @@ void sceNpCommerce2_unload() sceNpCommerce2Instance.m_bSceNpCommerce2Initialized = false; } -void sceNpCommerce2_init(Module *pxThis) +Module sceNpCommerce2("sceNpCommerce2", []() { - sceNpCommerce2 = pxThis; - - sceNpCommerce2->AddFunc(0xeef51be0, sceNpCommerce2ExecuteStoreBrowse); - sceNpCommerce2->AddFunc(0x1fa1b312, sceNpCommerce2GetStoreBrowseUserdata); - sceNpCommerce2->AddFunc(0x3539d233, sceNpCommerce2Init); - sceNpCommerce2->AddFunc(0x4d4a094c, sceNpCommerce2Term); - sceNpCommerce2->AddFunc(0xd9fdcec2, sceNpCommerce2CreateCtx); - sceNpCommerce2->AddFunc(0x6f67ea80, sceNpCommerce2DestroyCtx); - sceNpCommerce2->AddFunc(0xcc18cd2c, sceNpCommerce2CreateSessionStart); - sceNpCommerce2->AddFunc(0x62023e98, sceNpCommerce2CreateSessionAbort); - sceNpCommerce2->AddFunc(0x91f8843d, sceNpCommerce2CreateSessionFinish); - sceNpCommerce2->AddFunc(0x7370d8d0, sceNpCommerce2GetCategoryContentsCreateReq); - sceNpCommerce2->AddFunc(0x371a2edd, sceNpCommerce2GetCategoryContentsStart); - sceNpCommerce2->AddFunc(0xca0ea996, sceNpCommerce2GetCategoryContentsGetResult); - sceNpCommerce2->AddFunc(0xd8a473a3, sceNpCommerce2InitGetCategoryContentsResult); - sceNpCommerce2->AddFunc(0xbd49eab2, sceNpCommerce2GetCategoryInfo); - sceNpCommerce2->AddFunc(0x972ab46c, sceNpCommerce2GetContentInfo); - sceNpCommerce2->AddFunc(0xfc216890, sceNpCommerce2GetCategoryInfoFromContentInfo); - sceNpCommerce2->AddFunc(0xe51a4944, sceNpCommerce2GetGameProductInfoFromContentInfo); - sceNpCommerce2->AddFunc(0x9d9cb96b, sceNpCommerce2DestroyGetCategoryContentsResult); - sceNpCommerce2->AddFunc(0xa975ebb4, sceNpCommerce2GetProductInfoCreateReq); - sceNpCommerce2->AddFunc(0x8f46325b, sceNpCommerce2GetProductInfoStart); - sceNpCommerce2->AddFunc(0xbf5f58ea, sceNpCommerce2GetProductInfoGetResult); - sceNpCommerce2->AddFunc(0xf798f5e3, sceNpCommerce2InitGetProductInfoResult); - sceNpCommerce2->AddFunc(0xef645654, sceNpCommerce2GetGameProductInfo); - sceNpCommerce2->AddFunc(0xef8eafcd, sceNpCommerce2DestroyGetProductInfoResult); - sceNpCommerce2->AddFunc(0xe1e7b5ac, sceNpCommerce2GetProductInfoListCreateReq); - sceNpCommerce2->AddFunc(0x9cde07cc, sceNpCommerce2GetProductInfoListStart); - sceNpCommerce2->AddFunc(0x146618df, sceNpCommerce2GetProductInfoListGetResult); - sceNpCommerce2->AddFunc(0xe0f90e44, sceNpCommerce2InitGetProductInfoListResult); - sceNpCommerce2->AddFunc(0xd9956ce7, sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult); - sceNpCommerce2->AddFunc(0xf6139b58, sceNpCommerce2DestroyGetProductInfoListResult); - sceNpCommerce2->AddFunc(0xec324c8f, sceNpCommerce2GetContentRatingInfoFromGameProductInfo); - sceNpCommerce2->AddFunc(0xac78c1f3, sceNpCommerce2GetContentRatingInfoFromCategoryInfo); - sceNpCommerce2->AddFunc(0x150fdca3, sceNpCommerce2GetContentRatingDescriptor); - sceNpCommerce2->AddFunc(0xdb19194c, sceNpCommerce2GetGameSkuInfoFromGameProductInfo); - sceNpCommerce2->AddFunc(0xda8e322d, sceNpCommerce2GetPrice); - sceNpCommerce2->AddFunc(0x104551a6, sceNpCommerce2DoCheckoutStartAsync); - sceNpCommerce2->AddFunc(0xd43a130e, sceNpCommerce2DoCheckoutFinishAsync); - sceNpCommerce2->AddFunc(0x9825a0fc, sceNpCommerce2DoProductBrowseStartAsync); - sceNpCommerce2->AddFunc(0xb23e3bd1, sceNpCommerce2DoProductBrowseFinishAsync); - sceNpCommerce2->AddFunc(0x6ca9efd4, sceNpCommerce2DoDlListStartAsync); - sceNpCommerce2->AddFunc(0x410d42be, sceNpCommerce2DoDlListFinishAsync); - sceNpCommerce2->AddFunc(0xde7ab33d, sceNpCommerce2DoProductCodeStartAsync); - sceNpCommerce2->AddFunc(0xa9f945b3, sceNpCommerce2DoProductCodeFinishAsync); - sceNpCommerce2->AddFunc(0x3d627d81, sceNpCommerce2GetBGDLAvailability); - sceNpCommerce2->AddFunc(0xa5a863fe, sceNpCommerce2SetBGDLAvailability); - sceNpCommerce2->AddFunc(0x8df0057f, sceNpCommerce2AbortReq); - sceNpCommerce2->AddFunc(0x2a910f05, sceNpCommerce2DestroyReq); -} \ No newline at end of file + sceNpCommerce2.AddFunc(0xeef51be0, sceNpCommerce2ExecuteStoreBrowse); + sceNpCommerce2.AddFunc(0x1fa1b312, sceNpCommerce2GetStoreBrowseUserdata); + sceNpCommerce2.AddFunc(0x3539d233, sceNpCommerce2Init); + sceNpCommerce2.AddFunc(0x4d4a094c, sceNpCommerce2Term); + sceNpCommerce2.AddFunc(0xd9fdcec2, sceNpCommerce2CreateCtx); + sceNpCommerce2.AddFunc(0x6f67ea80, sceNpCommerce2DestroyCtx); + sceNpCommerce2.AddFunc(0xcc18cd2c, sceNpCommerce2CreateSessionStart); + sceNpCommerce2.AddFunc(0x62023e98, sceNpCommerce2CreateSessionAbort); + sceNpCommerce2.AddFunc(0x91f8843d, sceNpCommerce2CreateSessionFinish); + sceNpCommerce2.AddFunc(0x7370d8d0, sceNpCommerce2GetCategoryContentsCreateReq); + sceNpCommerce2.AddFunc(0x371a2edd, sceNpCommerce2GetCategoryContentsStart); + sceNpCommerce2.AddFunc(0xca0ea996, sceNpCommerce2GetCategoryContentsGetResult); + sceNpCommerce2.AddFunc(0xd8a473a3, sceNpCommerce2InitGetCategoryContentsResult); + sceNpCommerce2.AddFunc(0xbd49eab2, sceNpCommerce2GetCategoryInfo); + sceNpCommerce2.AddFunc(0x972ab46c, sceNpCommerce2GetContentInfo); + sceNpCommerce2.AddFunc(0xfc216890, sceNpCommerce2GetCategoryInfoFromContentInfo); + sceNpCommerce2.AddFunc(0xe51a4944, sceNpCommerce2GetGameProductInfoFromContentInfo); + sceNpCommerce2.AddFunc(0x9d9cb96b, sceNpCommerce2DestroyGetCategoryContentsResult); + sceNpCommerce2.AddFunc(0xa975ebb4, sceNpCommerce2GetProductInfoCreateReq); + sceNpCommerce2.AddFunc(0x8f46325b, sceNpCommerce2GetProductInfoStart); + sceNpCommerce2.AddFunc(0xbf5f58ea, sceNpCommerce2GetProductInfoGetResult); + sceNpCommerce2.AddFunc(0xf798f5e3, sceNpCommerce2InitGetProductInfoResult); + sceNpCommerce2.AddFunc(0xef645654, sceNpCommerce2GetGameProductInfo); + sceNpCommerce2.AddFunc(0xef8eafcd, sceNpCommerce2DestroyGetProductInfoResult); + sceNpCommerce2.AddFunc(0xe1e7b5ac, sceNpCommerce2GetProductInfoListCreateReq); + sceNpCommerce2.AddFunc(0x9cde07cc, sceNpCommerce2GetProductInfoListStart); + sceNpCommerce2.AddFunc(0x146618df, sceNpCommerce2GetProductInfoListGetResult); + sceNpCommerce2.AddFunc(0xe0f90e44, sceNpCommerce2InitGetProductInfoListResult); + sceNpCommerce2.AddFunc(0xd9956ce7, sceNpCommerce2GetGameProductInfoFromGetProductInfoListResult); + sceNpCommerce2.AddFunc(0xf6139b58, sceNpCommerce2DestroyGetProductInfoListResult); + sceNpCommerce2.AddFunc(0xec324c8f, sceNpCommerce2GetContentRatingInfoFromGameProductInfo); + sceNpCommerce2.AddFunc(0xac78c1f3, sceNpCommerce2GetContentRatingInfoFromCategoryInfo); + sceNpCommerce2.AddFunc(0x150fdca3, sceNpCommerce2GetContentRatingDescriptor); + sceNpCommerce2.AddFunc(0xdb19194c, sceNpCommerce2GetGameSkuInfoFromGameProductInfo); + sceNpCommerce2.AddFunc(0xda8e322d, sceNpCommerce2GetPrice); + sceNpCommerce2.AddFunc(0x104551a6, sceNpCommerce2DoCheckoutStartAsync); + sceNpCommerce2.AddFunc(0xd43a130e, sceNpCommerce2DoCheckoutFinishAsync); + sceNpCommerce2.AddFunc(0x9825a0fc, sceNpCommerce2DoProductBrowseStartAsync); + sceNpCommerce2.AddFunc(0xb23e3bd1, sceNpCommerce2DoProductBrowseFinishAsync); + sceNpCommerce2.AddFunc(0x6ca9efd4, sceNpCommerce2DoDlListStartAsync); + sceNpCommerce2.AddFunc(0x410d42be, sceNpCommerce2DoDlListFinishAsync); + sceNpCommerce2.AddFunc(0xde7ab33d, sceNpCommerce2DoProductCodeStartAsync); + sceNpCommerce2.AddFunc(0xa9f945b3, sceNpCommerce2DoProductCodeFinishAsync); + sceNpCommerce2.AddFunc(0x3d627d81, sceNpCommerce2GetBGDLAvailability); + sceNpCommerce2.AddFunc(0xa5a863fe, sceNpCommerce2SetBGDLAvailability); + sceNpCommerce2.AddFunc(0x8df0057f, sceNpCommerce2AbortReq); + sceNpCommerce2.AddFunc(0x2a910f05, sceNpCommerce2DestroyReq); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp index 535b6b3f01..fff2e1fb18 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpSns.cpp @@ -2,16 +2,14 @@ #include "Emu/SysCalls/Modules.h" #include "sceNpSns.h" -Module *sceNpSns = nullptr; +extern Module sceNpSns; void sceNpSns_unload() { // TODO: Unload SNS module } -void sceNpSns_init(Module *pxThis) +Module sceNpSns("sceNpSns", []() { - sceNpSns = pxThis; - // TODO: Register SNS module functions here -} \ No newline at end of file +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index f72c74a1ea..eee6356a71 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -15,7 +15,7 @@ #include "sceNp.h" #include "sceNpTrophy.h" -Module *sceNpTrophy = nullptr; +extern Module sceNpTrophy; // Internal Structs struct sceNpTrophyInternalContext @@ -79,7 +79,7 @@ static sceNpTrophyInternalContext& getContext(u32 context) { // Functions int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options) { - sceNpTrophy->Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=%d, options=0x%llx)", pool_addr, poolSize, containerId, options); + sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=%d, options=0x%llx)", pool_addr, poolSize, containerId, options); if (sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED; @@ -93,7 +93,7 @@ int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options) int sceNpTrophyCreateContext(vm::ptr context, vm::ptr commID, vm::ptr commSign, u64 options) { - sceNpTrophy->Warning("sceNpTrophyCreateContext(context_addr=0x%x, commID_addr=0x%x, commSign_addr=0x%x, options=0x%llx)", + sceNpTrophy.Warning("sceNpTrophyCreateContext(context_addr=0x%x, commID_addr=0x%x, commSign_addr=0x%x, options=0x%llx)", context.addr(), commID.addr(), commSign.addr(), options); if (!sceNpTrophyInstance.m_bInitialized) @@ -132,7 +132,7 @@ int sceNpTrophyCreateContext(vm::ptr context, vm::ptr int sceNpTrophyCreateHandle(vm::ptr handle) { - sceNpTrophy->Todo("sceNpTrophyCreateHandle(handle_addr=0x%x)", handle.addr()); + sceNpTrophy.Todo("sceNpTrophyCreateHandle(handle_addr=0x%x)", handle.addr()); if (!sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; @@ -145,7 +145,7 @@ int sceNpTrophyCreateHandle(vm::ptr handle) int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptr statusCb, u32 arg_addr, u64 options) { - sceNpTrophy->Warning("sceNpTrophyRegisterContext(context=%d, handle=%d, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", + sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=%d, handle=%d, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", context, handle, statusCb.addr(), arg_addr, options); if (!(sceNpTrophyInstance.m_bInitialized)) @@ -153,7 +153,7 @@ int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptr sceNpTrophyInstance.contexts.size()) { - sceNpTrophy->Warning("sceNpTrophyRegisterContext: invalid context (%d)", context); + sceNpTrophy.Warning("sceNpTrophyRegisterContext: invalid context (%d)", context); return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } // TODO: There are other possible errors @@ -224,13 +224,13 @@ int sceNpTrophySetSoundLevel() int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspace, u64 options) { - sceNpTrophy->Warning("sceNpTrophyGetRequiredDiskSpace(context=%d, handle=%d, reqspace_addr=0x%x, options=0x%llx)", + sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=%d, handle=%d, reqspace_addr=0x%x, options=0x%llx)", context, handle, reqspace.addr(), options); if (!sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; if (context == 0 || context > sceNpTrophyInstance.contexts.size()) { - sceNpTrophy->Warning("sceNpTrophyGetRequiredDiskSpace: invalid context (%d)", context); + sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace: invalid context (%d)", context); return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } // TODO: There are other possible errors @@ -251,7 +251,7 @@ int sceNpTrophyDestroyContext() int sceNpTrophyAbortHandle(u32 handle) { - sceNpTrophy->Todo("sceNpTrophyAbortHandle(handle=%d)", handle); + sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=%d)", handle); // TODO: ? @@ -263,7 +263,7 @@ int sceNpTrophyAbortHandle(u32 handle) int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr details, vm::ptr data) { - sceNpTrophy->Warning("sceNpTrophyGetGameInfo(context=%d, handle=%d, details_addr=0x%x, data_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=%d, handle=%d, details_addr=0x%x, data_addr=0x%x)", context, handle, details.addr(), data.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -321,7 +321,7 @@ int sceNpTrophyDestroyHandle() int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr platinumId) { - sceNpTrophy->Warning("sceNpTrophyUnlockTrophy(context=%d, handle=%d, trophyId=%d, platinumId_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=%d, handle=%d, trophyId=%d, platinumId_addr=0x%x)", context, handle, trophyId, platinumId.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -346,7 +346,7 @@ int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr int sceNpTrophyTerm() { - sceNpTrophy->Warning("sceNpTrophyTerm()"); + sceNpTrophy.Warning("sceNpTrophyTerm()"); if (!sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; @@ -358,13 +358,13 @@ int sceNpTrophyTerm() int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr flags, vm::ptr count) { - sceNpTrophy->Warning("sceNpTrophyGetTrophyUnlockState(context=%d, handle=%d, flags_addr=0x%x, count_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=%d, handle=%d, flags_addr=0x%x, count_addr=0x%x)", context, handle, flags.addr(), count.addr()); if (!sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED; if (context == 0 || context > sceNpTrophyInstance.contexts.size()) { - sceNpTrophy->Warning("sceNpTrophyGetTrophyUnlockState: invalid context (%d)", context); + sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: invalid context (%d)", context); return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT; } // TODO: There are other possible errors @@ -373,7 +373,7 @@ int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptrGetTrophiesCount(); *count = count_; if (count_ > 128) - sceNpTrophy->Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); + sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!"); // Pack up to 128 bools in u32 flag_bits[4] for (u32 id = 0; id < count_; id++) @@ -395,7 +395,7 @@ int sceNpTrophyGetTrophyIcon() int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr details, vm::ptr data) { - sceNpTrophy->Warning("sceNpTrophyGetTrophyInfo(context=%d, handle=%d, trophyId=%d, details_addr=0x%x, data_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=%d, handle=%d, trophyId=%d, details_addr=0x%x, data_addr=0x%x)", context, handle, trophyId, details.addr(), data.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -453,25 +453,23 @@ void sceNpTrophy_unload() sceNpTrophyInstance.m_bInitialized = false; } -void sceNpTrophy_init(Module *pxThis) +Module sceNpTrophy("sceNpTrophy", []() { - sceNpTrophy = pxThis; - - sceNpTrophy->AddFunc(0x079f0e87, sceNpTrophyGetGameProgress); - sceNpTrophy->AddFunc(0x1197b52c, sceNpTrophyRegisterContext); - sceNpTrophy->AddFunc(0x1c25470d, sceNpTrophyCreateHandle); - sceNpTrophy->AddFunc(0x27deda93, sceNpTrophySetSoundLevel); - sceNpTrophy->AddFunc(0x370136fe, sceNpTrophyGetRequiredDiskSpace); - sceNpTrophy->AddFunc(0x3741ecc7, sceNpTrophyDestroyContext); - sceNpTrophy->AddFunc(0x39567781, sceNpTrophyInit); - sceNpTrophy->AddFunc(0x48bd97c7, sceNpTrophyAbortHandle); - sceNpTrophy->AddFunc(0x49d18217, sceNpTrophyGetGameInfo); - sceNpTrophy->AddFunc(0x623cd2dc, sceNpTrophyDestroyHandle); - sceNpTrophy->AddFunc(0x8ceedd21, sceNpTrophyUnlockTrophy); - sceNpTrophy->AddFunc(0xa7fabf4d, sceNpTrophyTerm); - sceNpTrophy->AddFunc(0xb3ac3478, sceNpTrophyGetTrophyUnlockState); - sceNpTrophy->AddFunc(0xbaedf689, sceNpTrophyGetTrophyIcon); - sceNpTrophy->AddFunc(0xe3bf9a28, sceNpTrophyCreateContext); - sceNpTrophy->AddFunc(0xfce6d30a, sceNpTrophyGetTrophyInfo); - sceNpTrophy->AddFunc(0xff299e03, sceNpTrophyGetGameIcon); -} + sceNpTrophy.AddFunc(0x079f0e87, sceNpTrophyGetGameProgress); + sceNpTrophy.AddFunc(0x1197b52c, sceNpTrophyRegisterContext); + sceNpTrophy.AddFunc(0x1c25470d, sceNpTrophyCreateHandle); + sceNpTrophy.AddFunc(0x27deda93, sceNpTrophySetSoundLevel); + sceNpTrophy.AddFunc(0x370136fe, sceNpTrophyGetRequiredDiskSpace); + sceNpTrophy.AddFunc(0x3741ecc7, sceNpTrophyDestroyContext); + sceNpTrophy.AddFunc(0x39567781, sceNpTrophyInit); + sceNpTrophy.AddFunc(0x48bd97c7, sceNpTrophyAbortHandle); + sceNpTrophy.AddFunc(0x49d18217, sceNpTrophyGetGameInfo); + sceNpTrophy.AddFunc(0x623cd2dc, sceNpTrophyDestroyHandle); + sceNpTrophy.AddFunc(0x8ceedd21, sceNpTrophyUnlockTrophy); + sceNpTrophy.AddFunc(0xa7fabf4d, sceNpTrophyTerm); + sceNpTrophy.AddFunc(0xb3ac3478, sceNpTrophyGetTrophyUnlockState); + sceNpTrophy.AddFunc(0xbaedf689, sceNpTrophyGetTrophyIcon); + sceNpTrophy.AddFunc(0xe3bf9a28, sceNpTrophyCreateContext); + sceNpTrophy.AddFunc(0xfce6d30a, sceNpTrophyGetTrophyInfo); + sceNpTrophy.AddFunc(0xff299e03, sceNpTrophyGetGameIcon); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp index 59c7dfe5fe..dc5dc3dcc9 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTus.cpp @@ -5,7 +5,7 @@ #include "sceNp.h" #include "sceNpTus.h" -Module *sceNpTus = nullptr; +extern Module sceNpTus; struct sceNpTusInternal { @@ -21,7 +21,7 @@ sceNpTusInternal sceNpTusInstance; int sceNpTusInit() { - sceNpTus->Warning("sceNpTusInit()"); + sceNpTus.Warning("sceNpTusInit()"); if (sceNpTusInstance.m_bSceNpTusInitialized) return SCE_NP_COMMUNITY_ERROR_ALREADY_INITIALIZED; @@ -33,7 +33,7 @@ int sceNpTusInit() int sceNpTusTerm() { - sceNpTus->Warning("sceNpTusTerm()"); + sceNpTus.Warning("sceNpTusTerm()"); if (!sceNpTusInstance.m_bSceNpTusInitialized) return SCE_NP_COMMUNITY_ERROR_NOT_INITIALIZED; @@ -568,62 +568,60 @@ void sceNpTus_unload() sceNpTusInstance.m_bSceNpTusInitialized = false; } -void sceNpTus_init(Module *pxThis) +Module sceNpTus("sceNpTus", []() { - sceNpTus = pxThis; - - sceNpTus->AddFunc(0x8f87a06b, sceNpTusInit); - sceNpTus->AddFunc(0x225aed26, sceNpTusTerm); - sceNpTus->AddFunc(0x7caf58ee, sceNpTusCreateTitleCtx); - sceNpTus->AddFunc(0x2e162a62, sceNpTusDestroyTitleCtx); - sceNpTus->AddFunc(0x1904435e, sceNpTusCreateTransactionCtx); - sceNpTus->AddFunc(0x44eca8b4, sceNpTusDestroyTransactionCtx); - sceNpTus->AddFunc(0x59432970, sceNpTusSetTimeout); - sceNpTus->AddFunc(0x325c6284, sceNpTusAbortTransaction); - sceNpTus->AddFunc(0xb8e8ff22, sceNpTusWaitAsync); - sceNpTus->AddFunc(0x19bce18c, sceNpTusPollAsync); - sceNpTus->AddFunc(0xcc86a8f6, sceNpTusSetMultiSlotVariable); - sceNpTus->AddFunc(0xf819be91, sceNpTusSetMultiSlotVariableVUser); - sceNpTus->AddFunc(0x065b610d, sceNpTusSetMultiSlotVariableAsync); - sceNpTus->AddFunc(0x96a06212, sceNpTusSetMultiSlotVariableVUserAsync); - sceNpTus->AddFunc(0x0423e622, sceNpTusGetMultiSlotVariable); - sceNpTus->AddFunc(0x2357ba9e, sceNpTusGetMultiSlotVariableVUser); - sceNpTus->AddFunc(0xbb2877f2, sceNpTusGetMultiSlotVariableAsync); - sceNpTus->AddFunc(0xfc7d346e, sceNpTusGetMultiSlotVariableVUserAsync); - sceNpTus->AddFunc(0x0d15043b, sceNpTusGetMultiUserVariable); - sceNpTus->AddFunc(0x6c511024, sceNpTusGetMultiUserVariableVUser); - sceNpTus->AddFunc(0xcc7a31cd, sceNpTusGetMultiUserVariableAsync); - sceNpTus->AddFunc(0x9549d22c, sceNpTusGetMultiUserVariableVUserAsync); - sceNpTus->AddFunc(0x94989003, sceNpTusAddAndGetVariable); - sceNpTus->AddFunc(0xf60be06f, sceNpTusAddAndGetVariableVUser); - sceNpTus->AddFunc(0x1fa5c87d, sceNpTusAddAndGetVariableAsync); - sceNpTus->AddFunc(0xa7993bf3, sceNpTusAddAndGetVariableVUserAsync); - sceNpTus->AddFunc(0x47e9424a, sceNpTusTryAndSetVariable); - sceNpTus->AddFunc(0x3602bc80, sceNpTusTryAndSetVariableVUser); - sceNpTus->AddFunc(0xbbb244b7, sceNpTusTryAndSetVariableAsync); - sceNpTus->AddFunc(0x17db7aa7, sceNpTusTryAndSetVariableVUserAsync); - sceNpTus->AddFunc(0xaf985783, sceNpTusDeleteMultiSlotVariable); - sceNpTus->AddFunc(0xc4e51fbf, sceNpTusDeleteMultiSlotVariableVUser); - sceNpTus->AddFunc(0xf5363608, sceNpTusDeleteMultiSlotVariableAsync); - sceNpTus->AddFunc(0xc2e18da8, sceNpTusDeleteMultiSlotVariableVUserAsync); - sceNpTus->AddFunc(0x7d5f0f0e, sceNpTusSetData); - sceNpTus->AddFunc(0x0835deb2, sceNpTusSetDataVUser); - sceNpTus->AddFunc(0xe847341f, sceNpTusSetDataAsync); - sceNpTus->AddFunc(0x9cc0cf44, sceNpTusSetDataVUserAsync); - sceNpTus->AddFunc(0x8ddd0d85, sceNpTusGetData); - sceNpTus->AddFunc(0xae4e590e, sceNpTusGetDataVUser); - sceNpTus->AddFunc(0x5175abb9, sceNpTusGetDataAsync); - sceNpTus->AddFunc(0x38f364b0, sceNpTusGetDataVUserAsync); - sceNpTus->AddFunc(0xc848d425, sceNpTusGetMultiSlotDataStatus); - sceNpTus->AddFunc(0xa3abfadb, sceNpTusGetMultiSlotDataStatusVUser); - sceNpTus->AddFunc(0x651fd79f, sceNpTusGetMultiSlotDataStatusAsync); - sceNpTus->AddFunc(0x2ab21ea9, sceNpTusGetMultiSlotDataStatusVUserAsync); - sceNpTus->AddFunc(0x348dbcb4, sceNpTusGetMultiUserDataStatus); - sceNpTus->AddFunc(0x2d1b9f1a, sceNpTusGetMultiUserDataStatusVUser); - sceNpTus->AddFunc(0xc66ba67e, sceNpTusGetMultiUserDataStatusAsync); - sceNpTus->AddFunc(0x368fec59, sceNpTusGetMultiUserDataStatusVUserAsync); - sceNpTus->AddFunc(0xe0719847, sceNpTusDeleteMultiSlotData); - sceNpTus->AddFunc(0x01711e81, sceNpTusDeleteMultiSlotDataVUser); - sceNpTus->AddFunc(0x3175af23, sceNpTusDeleteMultiSlotDataAsync); - sceNpTus->AddFunc(0xc815b219, sceNpTusDeleteMultiSlotDataVUserAsync); -} \ No newline at end of file + sceNpTus.AddFunc(0x8f87a06b, sceNpTusInit); + sceNpTus.AddFunc(0x225aed26, sceNpTusTerm); + sceNpTus.AddFunc(0x7caf58ee, sceNpTusCreateTitleCtx); + sceNpTus.AddFunc(0x2e162a62, sceNpTusDestroyTitleCtx); + sceNpTus.AddFunc(0x1904435e, sceNpTusCreateTransactionCtx); + sceNpTus.AddFunc(0x44eca8b4, sceNpTusDestroyTransactionCtx); + sceNpTus.AddFunc(0x59432970, sceNpTusSetTimeout); + sceNpTus.AddFunc(0x325c6284, sceNpTusAbortTransaction); + sceNpTus.AddFunc(0xb8e8ff22, sceNpTusWaitAsync); + sceNpTus.AddFunc(0x19bce18c, sceNpTusPollAsync); + sceNpTus.AddFunc(0xcc86a8f6, sceNpTusSetMultiSlotVariable); + sceNpTus.AddFunc(0xf819be91, sceNpTusSetMultiSlotVariableVUser); + sceNpTus.AddFunc(0x065b610d, sceNpTusSetMultiSlotVariableAsync); + sceNpTus.AddFunc(0x96a06212, sceNpTusSetMultiSlotVariableVUserAsync); + sceNpTus.AddFunc(0x0423e622, sceNpTusGetMultiSlotVariable); + sceNpTus.AddFunc(0x2357ba9e, sceNpTusGetMultiSlotVariableVUser); + sceNpTus.AddFunc(0xbb2877f2, sceNpTusGetMultiSlotVariableAsync); + sceNpTus.AddFunc(0xfc7d346e, sceNpTusGetMultiSlotVariableVUserAsync); + sceNpTus.AddFunc(0x0d15043b, sceNpTusGetMultiUserVariable); + sceNpTus.AddFunc(0x6c511024, sceNpTusGetMultiUserVariableVUser); + sceNpTus.AddFunc(0xcc7a31cd, sceNpTusGetMultiUserVariableAsync); + sceNpTus.AddFunc(0x9549d22c, sceNpTusGetMultiUserVariableVUserAsync); + sceNpTus.AddFunc(0x94989003, sceNpTusAddAndGetVariable); + sceNpTus.AddFunc(0xf60be06f, sceNpTusAddAndGetVariableVUser); + sceNpTus.AddFunc(0x1fa5c87d, sceNpTusAddAndGetVariableAsync); + sceNpTus.AddFunc(0xa7993bf3, sceNpTusAddAndGetVariableVUserAsync); + sceNpTus.AddFunc(0x47e9424a, sceNpTusTryAndSetVariable); + sceNpTus.AddFunc(0x3602bc80, sceNpTusTryAndSetVariableVUser); + sceNpTus.AddFunc(0xbbb244b7, sceNpTusTryAndSetVariableAsync); + sceNpTus.AddFunc(0x17db7aa7, sceNpTusTryAndSetVariableVUserAsync); + sceNpTus.AddFunc(0xaf985783, sceNpTusDeleteMultiSlotVariable); + sceNpTus.AddFunc(0xc4e51fbf, sceNpTusDeleteMultiSlotVariableVUser); + sceNpTus.AddFunc(0xf5363608, sceNpTusDeleteMultiSlotVariableAsync); + sceNpTus.AddFunc(0xc2e18da8, sceNpTusDeleteMultiSlotVariableVUserAsync); + sceNpTus.AddFunc(0x7d5f0f0e, sceNpTusSetData); + sceNpTus.AddFunc(0x0835deb2, sceNpTusSetDataVUser); + sceNpTus.AddFunc(0xe847341f, sceNpTusSetDataAsync); + sceNpTus.AddFunc(0x9cc0cf44, sceNpTusSetDataVUserAsync); + sceNpTus.AddFunc(0x8ddd0d85, sceNpTusGetData); + sceNpTus.AddFunc(0xae4e590e, sceNpTusGetDataVUser); + sceNpTus.AddFunc(0x5175abb9, sceNpTusGetDataAsync); + sceNpTus.AddFunc(0x38f364b0, sceNpTusGetDataVUserAsync); + sceNpTus.AddFunc(0xc848d425, sceNpTusGetMultiSlotDataStatus); + sceNpTus.AddFunc(0xa3abfadb, sceNpTusGetMultiSlotDataStatusVUser); + sceNpTus.AddFunc(0x651fd79f, sceNpTusGetMultiSlotDataStatusAsync); + sceNpTus.AddFunc(0x2ab21ea9, sceNpTusGetMultiSlotDataStatusVUserAsync); + sceNpTus.AddFunc(0x348dbcb4, sceNpTusGetMultiUserDataStatus); + sceNpTus.AddFunc(0x2d1b9f1a, sceNpTusGetMultiUserDataStatusVUser); + sceNpTus.AddFunc(0xc66ba67e, sceNpTusGetMultiUserDataStatusAsync); + sceNpTus.AddFunc(0x368fec59, sceNpTusGetMultiUserDataStatusVUserAsync); + sceNpTus.AddFunc(0xe0719847, sceNpTusDeleteMultiSlotData); + sceNpTus.AddFunc(0x01711e81, sceNpTusDeleteMultiSlotDataVUser); + sceNpTus.AddFunc(0x3175af23, sceNpTusDeleteMultiSlotDataAsync); + sceNpTus.AddFunc(0xc815b219, sceNpTusDeleteMultiSlotDataVUserAsync); +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index 37ae8f610c..a28e2b804e 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -21,7 +21,7 @@ #include "Emu/Cell/RawSPUThread.h" #include "sysPrxForUser.h" -Module *sysPrxForUser = nullptr; +extern Module sysPrxForUser; #define TLS_MAX 128 #define TLS_SYS 0x30 @@ -33,7 +33,7 @@ std::array, TLS_MAX> g_tls_owners; void sys_initialize_tls() { - sysPrxForUser->Log("sys_initialize_tls()"); + sysPrxForUser.Log("sys_initialize_tls()"); } u32 ppu_get_tls(u32 thread) @@ -42,7 +42,7 @@ u32 ppu_get_tls(u32 thread) { g_tls_size = Emu.GetTLSMemsz() + TLS_SYS; g_tls_start = Memory.MainMem.AllocAlign(g_tls_size * TLS_MAX, 4096); // memory for up to TLS_MAX threads - sysPrxForUser->Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", + sysPrxForUser.Notice("Thread Local Storage initialized (g_tls_start=0x%x, user_size=0x%x)\n*** TLS segment addr: 0x%08x\n*** TLS segment size: 0x%08x", g_tls_start, Emu.GetTLSMemsz(), Emu.GetTLSAddr(), Emu.GetTLSFilesz()); } @@ -89,49 +89,49 @@ void ppu_free_tls(u32 thread) int _sys_heap_create_heap(const u32 heap_addr, const u32 align, const u32 size) { - sysPrxForUser->Warning("_sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); + sysPrxForUser.Warning("_sys_heap_create_heap(heap_addr=0x%x, align=0x%x, size=0x%x)", heap_addr, align, size); std::shared_ptr heap(new HeapInfo(heap_addr, align, size)); - u32 heap_id = sysPrxForUser->GetNewId(heap); - sysPrxForUser->Warning("*** sys_heap created: id = %d", heap_id); + u32 heap_id = sysPrxForUser.GetNewId(heap); + sysPrxForUser.Warning("*** sys_heap created: id = %d", heap_id); return heap_id; } u32 _sys_heap_malloc(const u32 heap_id, const u32 size) { - sysPrxForUser->Warning("_sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); + sysPrxForUser.Warning("_sys_heap_malloc(heap_id=%d, size=0x%x)", heap_id, size); std::shared_ptr heap; - if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH; + if(!sysPrxForUser.CheckId(heap_id, heap)) return CELL_ESRCH; return (u32)Memory.Alloc(size, 1); } u32 _sys_heap_memalign(u32 heap_id, u32 align, u32 size) { - sysPrxForUser->Warning("_sys_heap_memalign(heap_id=%d, align=0x%x, size=0x%x)", heap_id, align, size); + sysPrxForUser.Warning("_sys_heap_memalign(heap_id=%d, align=0x%x, size=0x%x)", heap_id, align, size); std::shared_ptr heap; - if(!sysPrxForUser->CheckId(heap_id, heap)) return CELL_ESRCH; + if(!sysPrxForUser.CheckId(heap_id, heap)) return CELL_ESRCH; return (u32)Memory.Alloc(size, align); } s64 _sys_process_atexitspawn() { - sysPrxForUser->Log("_sys_process_atexitspawn()"); + sysPrxForUser.Log("_sys_process_atexitspawn()"); return CELL_OK; } s64 _sys_process_at_Exitspawn() { - sysPrxForUser->Log("_sys_process_at_Exitspawn"); + sysPrxForUser.Log("_sys_process_at_Exitspawn"); return CELL_OK; } int sys_process_is_stack(u32 p) { - sysPrxForUser->Log("sys_process_is_stack(p=0x%x)", p); + sysPrxForUser.Log("sys_process_is_stack(p=0x%x)", p); // prx: compare high 4 bits with "0xD" return (p >= Memory.StackMem.GetStartAddr() && p <= Memory.StackMem.GetEndAddr()) ? 1 : 0; @@ -139,44 +139,44 @@ int sys_process_is_stack(u32 p) s64 sys_prx_exitspawn_with_level() { - sysPrxForUser->Log("sys_prx_exitspawn_with_level()"); + sysPrxForUser.Log("sys_prx_exitspawn_with_level()"); return CELL_OK; } int sys_spu_elf_get_information(u32 elf_img, vm::ptr entry, vm::ptr nseg) { - sysPrxForUser->Todo("sys_spu_elf_get_information(elf_img=0x%x, entry_addr=0x%x, nseg_addr=0x%x)", elf_img, entry.addr(), nseg.addr()); + sysPrxForUser.Todo("sys_spu_elf_get_information(elf_img=0x%x, entry_addr=0x%x, nseg_addr=0x%x)", elf_img, entry.addr(), nseg.addr()); return CELL_OK; } int sys_spu_elf_get_segments(u32 elf_img, vm::ptr segments, int nseg) { - sysPrxForUser->Todo("sys_spu_elf_get_segments(elf_img=0x%x, segments_addr=0x%x, nseg=0x%x)", elf_img, segments.addr(), nseg); + sysPrxForUser.Todo("sys_spu_elf_get_segments(elf_img=0x%x, segments_addr=0x%x, nseg=0x%x)", elf_img, segments.addr(), nseg); return CELL_OK; } int sys_spu_image_import(vm::ptr img, u32 src, u32 type) { - sysPrxForUser->Warning("sys_spu_image_import(img=0x%x, src=0x%x, type=%d)", img.addr(), src, type); + sysPrxForUser.Warning("sys_spu_image_import(img=0x%x, src=0x%x, type=%d)", img.addr(), src, type); return spu_image_import(*img, src, type); } int sys_spu_image_close(vm::ptr img) { - sysPrxForUser->Warning("sys_spu_image_close(img=0x%x)", img.addr()); + sysPrxForUser.Warning("sys_spu_image_close(img=0x%x)", img.addr()); return CELL_OK; } int sys_raw_spu_load(s32 id, vm::ptr path, vm::ptr entry) { - sysPrxForUser->Warning("sys_raw_spu_load(id=0x%x, path_addr=0x%x('%s'), entry_addr=0x%x)", + sysPrxForUser.Warning("sys_raw_spu_load(id=0x%x, path_addr=0x%x('%s'), entry_addr=0x%x)", id, path.addr(), path.get_ptr(), entry.addr()); vfsFile f(path.get_ptr()); if(!f.IsOpened()) { - sysPrxForUser->Error("sys_raw_spu_load error: '%s' not found!", path.get_ptr()); + sysPrxForUser.Error("sys_raw_spu_load error: '%s' not found!", path.get_ptr()); return CELL_ENOENT; } @@ -185,7 +185,7 @@ int sys_raw_spu_load(s32 id, vm::ptr path, vm::ptr entry) if (hdr.CheckMagic()) { - sysPrxForUser->Error("sys_raw_spu_load error: '%s' is encrypted! Decrypt SELF and try again.", path.get_ptr()); + sysPrxForUser.Error("sys_raw_spu_load error: '%s' is encrypted! Decrypt SELF and try again.", path.get_ptr()); Emu.Pause(); return CELL_ENOENT; } @@ -202,7 +202,7 @@ int sys_raw_spu_load(s32 id, vm::ptr path, vm::ptr entry) int sys_raw_spu_image_load(int id, vm::ptr img) { - sysPrxForUser->Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.addr()); + sysPrxForUser.Warning("sys_raw_spu_image_load(id=0x%x, img_addr=0x%x)", id, img.addr()); // TODO: use segment info memcpy(vm::get_ptr(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id), vm::get_ptr(img->addr), 256 * 1024); @@ -213,7 +213,7 @@ int sys_raw_spu_image_load(int id, vm::ptr img) int sys_get_random_number(vm::ptr addr, u64 size) { - sysPrxForUser->Warning("sys_get_random_number(addr=0x%x, size=%d)", addr.addr(), size); + sysPrxForUser.Warning("sys_get_random_number(addr=0x%x, size=%d)", addr.addr(), size); if (size > 4096) size = 4096; @@ -228,7 +228,7 @@ int sys_get_random_number(vm::ptr addr, u64 size) vm::ptr _sys_memset(vm::ptr dst, s32 value, u32 size) { - sysPrxForUser->Log("_sys_memset(dst_addr=0x%x, value=%d, size=%d)", dst.addr(), value, size); + sysPrxForUser.Log("_sys_memset(dst_addr=0x%x, value=%d, size=%d)", dst.addr(), value, size); memset(dst.get_ptr(), value, size); return dst; @@ -236,7 +236,7 @@ vm::ptr _sys_memset(vm::ptr dst, s32 value, u32 size) vm::ptr _sys_memcpy(vm::ptr dst, vm::ptr src, u32 size) { - sysPrxForUser->Log("_sys_memcpy(dst_addr=0x%x, src_addr=0x%x, size=%d)", dst.addr(), src.addr(), size); + sysPrxForUser.Log("_sys_memcpy(dst_addr=0x%x, src_addr=0x%x, size=%d)", dst.addr(), src.addr(), size); memcpy(dst.get_ptr(), src.get_ptr(), size); return dst; @@ -244,28 +244,28 @@ vm::ptr _sys_memcpy(vm::ptr dst, vm::ptr src, u32 size) s32 _sys_memcmp(vm::ptr buf1, vm::ptr buf2, u32 size) { - sysPrxForUser->Log("_sys_memcmp(buf1_addr=0x%x, buf2_addr=0x%x, size=%d)", buf1.addr(), buf2.addr(), size); + sysPrxForUser.Log("_sys_memcmp(buf1_addr=0x%x, buf2_addr=0x%x, size=%d)", buf1.addr(), buf2.addr(), size); return memcmp(buf1.get_ptr(), buf2.get_ptr(), size); } s64 _sys_strlen(vm::ptr str) { - sysPrxForUser->Log("_sys_strlen(str_addr=0x%x)", str.addr()); + sysPrxForUser.Log("_sys_strlen(str_addr=0x%x)", str.addr()); return strlen(str.get_ptr()); } s32 _sys_strncmp(vm::ptr str1, vm::ptr str2, s32 max) { - sysPrxForUser->Log("_sys_strncmp(str1_addr=0x%x, str2_addr=0x%x, max=%d)", str1.addr(), str2.addr(), max); + sysPrxForUser.Log("_sys_strncmp(str1_addr=0x%x, str2_addr=0x%x, max=%d)", str1.addr(), str2.addr(), max); return strncmp(str1.get_ptr(), str2.get_ptr(), max); } vm::ptr _sys_strcat(vm::ptr dest, vm::ptr source) { - sysPrxForUser->Log("_sys_strcat(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); + sysPrxForUser.Log("_sys_strcat(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); if (strcat(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) { @@ -276,7 +276,7 @@ vm::ptr _sys_strcat(vm::ptr dest, vm::ptr source) vm::ptr _sys_strncat(vm::ptr dest, vm::ptr source, u32 len) { - sysPrxForUser->Log("_sys_strncat(dest_addr=0x%x, source_addr=0x%x, len=%d)", dest.addr(), source.addr(), len); + sysPrxForUser.Log("_sys_strncat(dest_addr=0x%x, source_addr=0x%x, len=%d)", dest.addr(), source.addr(), len); if (strncat(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) { @@ -287,7 +287,7 @@ vm::ptr _sys_strncat(vm::ptr dest, vm::ptr source, u32 l vm::ptr _sys_strcpy(vm::ptr dest, vm::ptr source) { - sysPrxForUser->Log("_sys_strcpy(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); + sysPrxForUser.Log("_sys_strcpy(dest_addr=0x%x, source_addr=0x%x)", dest.addr(), source.addr()); if (strcpy(dest.get_ptr(), source.get_ptr()) != dest.get_ptr()) { @@ -298,7 +298,7 @@ vm::ptr _sys_strcpy(vm::ptr dest, vm::ptr source) vm::ptr _sys_strncpy(vm::ptr dest, vm::ptr source, u32 len) { - sysPrxForUser->Log("_sys_strncpy(dest_addr=0x%x, source_addr=0x%x, len=%d)", dest.addr(), source.addr(), len); + sysPrxForUser.Log("_sys_strncpy(dest_addr=0x%x, source_addr=0x%x, len=%d)", dest.addr(), source.addr(), len); if (!dest || !source) { @@ -323,7 +323,7 @@ s32 _sys_spu_printf_initialize( vm::ptr atcb, vm::ptr dtcb) { - sysPrxForUser->Warning("_sys_spu_printf_initialize(agcb_addr=0x%x, dgcb_addr=0x%x, atcb_addr=0x%x, dtcb_addr=0x%x)", + sysPrxForUser.Warning("_sys_spu_printf_initialize(agcb_addr=0x%x, dgcb_addr=0x%x, atcb_addr=0x%x, dtcb_addr=0x%x)", agcb.addr(), dgcb.addr(), atcb.addr(), dtcb.addr()); // prx: register some callbacks @@ -336,7 +336,7 @@ s32 _sys_spu_printf_initialize( s32 _sys_spu_printf_finalize() { - sysPrxForUser->Warning("_sys_spu_printf_finalize()"); + sysPrxForUser.Warning("_sys_spu_printf_finalize()"); spu_printf_agcb.set(0); spu_printf_dgcb.set(0); @@ -347,7 +347,7 @@ s32 _sys_spu_printf_finalize() s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) { - sysPrxForUser->Warning("_sys_spu_printf_attach_group(group=%d)", group); + sysPrxForUser.Warning("_sys_spu_printf_attach_group(group=%d)", group); if (!spu_printf_agcb) { @@ -359,7 +359,7 @@ s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) { - sysPrxForUser->Warning("_sys_spu_printf_detach_group(group=%d)", group); + sysPrxForUser.Warning("_sys_spu_printf_detach_group(group=%d)", group); if (!spu_printf_dgcb) { @@ -371,7 +371,7 @@ s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) { - sysPrxForUser->Warning("_sys_spu_printf_attach_thread(thread=%d)", thread); + sysPrxForUser.Warning("_sys_spu_printf_attach_thread(thread=%d)", thread); if (!spu_printf_atcb) { @@ -383,7 +383,7 @@ s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) { - sysPrxForUser->Warning("_sys_spu_printf_detach_thread(thread=%d)", thread); + sysPrxForUser.Warning("_sys_spu_printf_detach_thread(thread=%d)", thread); if (!spu_printf_dtcb) { @@ -395,7 +395,7 @@ s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) s32 _sys_snprintf(vm::ptr dst, u32 count, vm::ptr fmt) // va_args... { - sysPrxForUser->Todo("_sys_snprintf(dst_addr=0x%x, count=%d, fmt_addr=0x%x['%s'], ...)", dst.addr(), count, fmt.addr(), fmt.get_ptr()); + sysPrxForUser.Todo("_sys_snprintf(dst_addr=0x%x, count=%d, fmt_addr=0x%x['%s'], ...)", dst.addr(), count, fmt.addr(), fmt.get_ptr()); Emu.Pause(); return 0; @@ -403,33 +403,36 @@ s32 _sys_snprintf(vm::ptr dst, u32 count, vm::ptr fmt) // va_a s32 _sys_printf(vm::ptr fmt) // va_args... { - sysPrxForUser->Todo("_sys_printf(fmt_addr=0x%x, ...)", fmt.addr()); + sysPrxForUser.Todo("_sys_printf(fmt_addr=0x%x, ...)", fmt.addr()); // probably, assertion failed - sysPrxForUser->Warning("_sys_printf: \n%s", fmt.get_ptr()); + sysPrxForUser.Warning("_sys_printf: \n%s", fmt.get_ptr()); Emu.Pause(); return CELL_OK; } s32 _unnamed_E75C40F2(u32 dest) { - sysPrxForUser->Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest); + sysPrxForUser.Todo("Unnamed function 0xE75C40F2 (dest=0x%x) -> CELL_ENOENT", dest); // prx: load some data (0x40 bytes) previously set by sys_process_get_paramsfo //memset(Memory + dest, 0, 0x40); return CELL_ENOENT; } -void sysPrxForUser_init(Module *pxThis) +Module sysPrxForUser("sysPrxForUser", []() { - sysPrxForUser = pxThis; - g_tls_start = 0; for (auto& v : g_tls_owners) { v.store(0, std::memory_order_relaxed); } + spu_printf_agcb.set(0); + spu_printf_dgcb.set(0); + spu_printf_atcb.set(0); + spu_printf_dtcb.set(0); + // Setup random number generator srand(time(NULL)); @@ -441,66 +444,66 @@ void sysPrxForUser_init(Module *pxThis) REG_FUNC(sysPrxForUser, sys_lwmutex_trylock); REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); - sysPrxForUser->AddFunc(0x8461e528, sys_time_get_system_time); + sysPrxForUser.AddFunc(0x8461e528, sys_time_get_system_time); - sysPrxForUser->AddFunc(0xe6f2c1e7, sys_process_exit); - sysPrxForUser->AddFunc(0x2c847572, _sys_process_atexitspawn); - sysPrxForUser->AddFunc(0x96328741, _sys_process_at_Exitspawn); - sysPrxForUser->AddFunc(0x4f7172c9, sys_process_is_stack); + sysPrxForUser.AddFunc(0xe6f2c1e7, sys_process_exit); + sysPrxForUser.AddFunc(0x2c847572, _sys_process_atexitspawn); + sysPrxForUser.AddFunc(0x96328741, _sys_process_at_Exitspawn); + sysPrxForUser.AddFunc(0x4f7172c9, sys_process_is_stack); - sysPrxForUser->AddFunc(0x24a1ea07, sys_ppu_thread_create); - sysPrxForUser->AddFunc(0x350d454e, sys_ppu_thread_get_id); - sysPrxForUser->AddFunc(0xaff080a4, sys_ppu_thread_exit); - sysPrxForUser->AddFunc(0xa3e3be68, sys_ppu_thread_once); + sysPrxForUser.AddFunc(0x24a1ea07, sys_ppu_thread_create); + sysPrxForUser.AddFunc(0x350d454e, sys_ppu_thread_get_id); + sysPrxForUser.AddFunc(0xaff080a4, sys_ppu_thread_exit); + sysPrxForUser.AddFunc(0xa3e3be68, sys_ppu_thread_once); - sysPrxForUser->AddFunc(0x26090058, sys_prx_load_module); - sysPrxForUser->AddFunc(0x9f18429d, sys_prx_start_module); - sysPrxForUser->AddFunc(0x80fb0c19, sys_prx_stop_module); - sysPrxForUser->AddFunc(0xf0aece0d, sys_prx_unload_module); - sysPrxForUser->AddFunc(0x42b23552, sys_prx_register_library); - sysPrxForUser->AddFunc(0xd0ea47a7, sys_prx_unregister_library); - sysPrxForUser->AddFunc(0xa5d06bf0, sys_prx_get_module_list); - sysPrxForUser->AddFunc(0x84bb6774, sys_prx_get_module_info); - sysPrxForUser->AddFunc(0xe0998dbf, sys_prx_get_module_id_by_name); - sysPrxForUser->AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); - sysPrxForUser->AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); + sysPrxForUser.AddFunc(0x26090058, sys_prx_load_module); + sysPrxForUser.AddFunc(0x9f18429d, sys_prx_start_module); + sysPrxForUser.AddFunc(0x80fb0c19, sys_prx_stop_module); + sysPrxForUser.AddFunc(0xf0aece0d, sys_prx_unload_module); + sysPrxForUser.AddFunc(0x42b23552, sys_prx_register_library); + sysPrxForUser.AddFunc(0xd0ea47a7, sys_prx_unregister_library); + sysPrxForUser.AddFunc(0xa5d06bf0, sys_prx_get_module_list); + sysPrxForUser.AddFunc(0x84bb6774, sys_prx_get_module_info); + sysPrxForUser.AddFunc(0xe0998dbf, sys_prx_get_module_id_by_name); + sysPrxForUser.AddFunc(0xaa6d9bff, sys_prx_load_module_on_memcontainer); + sysPrxForUser.AddFunc(0xa2c7ba64, sys_prx_exitspawn_with_level); - sysPrxForUser->AddFunc(0x35168520, _sys_heap_malloc); - //sysPrxForUser->AddFunc(0xaede4b03, _sys_heap_free); - //sysPrxForUser->AddFunc(0x8a561d92, _sys_heap_delete_heap); - sysPrxForUser->AddFunc(0xb2fcf2c8, _sys_heap_create_heap); - sysPrxForUser->AddFunc(0x44265c08, _sys_heap_memalign); + sysPrxForUser.AddFunc(0x35168520, _sys_heap_malloc); + //sysPrxForUser.AddFunc(0xaede4b03, _sys_heap_free); + //sysPrxForUser.AddFunc(0x8a561d92, _sys_heap_delete_heap); + sysPrxForUser.AddFunc(0xb2fcf2c8, _sys_heap_create_heap); + sysPrxForUser.AddFunc(0x44265c08, _sys_heap_memalign); - sysPrxForUser->AddFunc(0xb257540b, sys_mmapper_allocate_memory); - sysPrxForUser->AddFunc(0x70258515, sys_mmapper_allocate_memory_from_container); - sysPrxForUser->AddFunc(0xdc578057, sys_mmapper_map_memory); - sysPrxForUser->AddFunc(0x4643ba6e, sys_mmapper_unmap_memory); - sysPrxForUser->AddFunc(0x409ad939, sys_mmapper_free_memory); + sysPrxForUser.AddFunc(0xb257540b, sys_mmapper_allocate_memory); + sysPrxForUser.AddFunc(0x70258515, sys_mmapper_allocate_memory_from_container); + sysPrxForUser.AddFunc(0xdc578057, sys_mmapper_map_memory); + sysPrxForUser.AddFunc(0x4643ba6e, sys_mmapper_unmap_memory); + sysPrxForUser.AddFunc(0x409ad939, sys_mmapper_free_memory); - sysPrxForUser->AddFunc(0x1ed454ce, sys_spu_elf_get_information); - sysPrxForUser->AddFunc(0xdb6b3250, sys_spu_elf_get_segments); - sysPrxForUser->AddFunc(0xebe5f72f, sys_spu_image_import); - sysPrxForUser->AddFunc(0xe0da8efd, sys_spu_image_close); + sysPrxForUser.AddFunc(0x1ed454ce, sys_spu_elf_get_information); + sysPrxForUser.AddFunc(0xdb6b3250, sys_spu_elf_get_segments); + sysPrxForUser.AddFunc(0xebe5f72f, sys_spu_image_import); + sysPrxForUser.AddFunc(0xe0da8efd, sys_spu_image_close); - sysPrxForUser->AddFunc(0x893305fa, sys_raw_spu_load); - sysPrxForUser->AddFunc(0xb995662e, sys_raw_spu_image_load); + sysPrxForUser.AddFunc(0x893305fa, sys_raw_spu_load); + sysPrxForUser.AddFunc(0xb995662e, sys_raw_spu_image_load); - sysPrxForUser->AddFunc(0xda0eb71a, sys_lwcond_create); - sysPrxForUser->AddFunc(0x1c9a942c, sys_lwcond_destroy); - sysPrxForUser->AddFunc(0xef87a695, sys_lwcond_signal); - sysPrxForUser->AddFunc(0xe9a1bd84, sys_lwcond_signal_all); - sysPrxForUser->AddFunc(0x52aadadf, sys_lwcond_signal_to); - sysPrxForUser->AddFunc(0x2a6d9d51, sys_lwcond_wait); + sysPrxForUser.AddFunc(0xda0eb71a, sys_lwcond_create); + sysPrxForUser.AddFunc(0x1c9a942c, sys_lwcond_destroy); + sysPrxForUser.AddFunc(0xef87a695, sys_lwcond_signal); + sysPrxForUser.AddFunc(0xe9a1bd84, sys_lwcond_signal_all); + sysPrxForUser.AddFunc(0x52aadadf, sys_lwcond_signal_to); + sysPrxForUser.AddFunc(0x2a6d9d51, sys_lwcond_wait); - sysPrxForUser->AddFunc(0x71a8472a, sys_get_random_number); + sysPrxForUser.AddFunc(0x71a8472a, sys_get_random_number); - sysPrxForUser->AddFunc(0x8c2bb498, sys_spinlock_initialize); - sysPrxForUser->AddFunc(0xa285139d, sys_spinlock_lock); - sysPrxForUser->AddFunc(0x722a0254, sys_spinlock_trylock); - sysPrxForUser->AddFunc(0x5267cb35, sys_spinlock_unlock); + sysPrxForUser.AddFunc(0x8c2bb498, sys_spinlock_initialize); + sysPrxForUser.AddFunc(0xa285139d, sys_spinlock_lock); + sysPrxForUser.AddFunc(0x722a0254, sys_spinlock_trylock); + sysPrxForUser.AddFunc(0x5267cb35, sys_spinlock_unlock); - sysPrxForUser->AddFunc(0x67f9fedb, sys_game_process_exitspawn2); - sysPrxForUser->AddFunc(0xfc52a7a9, sys_game_process_exitspawn); + sysPrxForUser.AddFunc(0x67f9fedb, sys_game_process_exitspawn2); + sysPrxForUser.AddFunc(0xfc52a7a9, sys_game_process_exitspawn); REG_FUNC(sysPrxForUser, _sys_memset); REG_FUNC(sysPrxForUser, _sys_memcpy); @@ -522,13 +525,5 @@ void sysPrxForUser_init(Module *pxThis) REG_FUNC(sysPrxForUser, _sys_snprintf); REG_FUNC(sysPrxForUser, _sys_printf); - sysPrxForUser->AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown -} - -void sysPrxForUser_load() -{ - spu_printf_agcb.set(0); - spu_printf_dgcb.set(0); - spu_printf_atcb.set(0); - spu_printf_dtcb.set(0); -} \ No newline at end of file + sysPrxForUser.AddFunc(0xe75c40f2, _unnamed_E75C40F2); // real name is unknown +}); \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp index e6b87792ca..35f019dd52 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_io.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_io.cpp @@ -1,17 +1,15 @@ #include "stdafx.h" #include "Emu/SysCalls/Modules.h" -Module *sys_io = nullptr; +extern Module sys_io; extern void cellPad_init(); extern void cellKb_init(); extern void cellMouse_init(); -void sys_io_init(Module *pxThis) +Module sys_io("sys_io", []() { - sys_io = pxThis; - cellPad_init(); cellKb_init(); cellMouse_init(); -} +}); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 3307007470..be4a8701a8 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -17,7 +17,7 @@ extern "C" #include "sys_net.h" -Module *sys_net = nullptr; +extern Module sys_net; vm::ptr g_lastError = vm::ptr::make(0); @@ -94,7 +94,7 @@ using pck_len_t = u32; // Functions int sys_net_accept(s32 s, vm::ptr addr, vm::ptr paddrlen) { - sys_net->Warning("accept(s=%d, family_addr=0x%x, paddrlen=0x%x)", s, addr.addr(), paddrlen.addr()); + sys_net.Warning("accept(s=%d, family_addr=0x%x, paddrlen=0x%x)", s, addr.addr(), paddrlen.addr()); if (!addr) { int ret = accept(s, nullptr, nullptr); *g_lastError = getLastError(); @@ -114,12 +114,12 @@ int sys_net_accept(s32 s, vm::ptr addr, vm::ptr pad int sys_net_bind(s32 s, vm::ptr addr, u32 addrlen) { - sys_net->Warning("bind(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); + sys_net.Warning("bind(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); sockaddr_in saddr; memcpy(&saddr, addr.get_ptr(), sizeof(sockaddr_in)); saddr.sin_family = addr->sin_family; const char *ipaddr = inet_ntoa(saddr.sin_addr); - sys_net->Warning("binding on %s to port %d", ipaddr, ntohs(saddr.sin_port)); + sys_net.Warning("binding on %s to port %d", ipaddr, ntohs(saddr.sin_port)); int ret = bind(s, (const sockaddr *)&saddr, addrlen); *g_lastError = getLastError(); return ret; @@ -127,12 +127,12 @@ int sys_net_bind(s32 s, vm::ptr addr, u32 addrlen) int sys_net_connect(s32 s, vm::ptr addr, u32 addrlen) { - sys_net->Warning("connect(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); + sys_net.Warning("connect(s=%d, family_addr=0x%x, addrlen=%d)", s, addr.addr(), addrlen); sockaddr_in saddr; memcpy(&saddr, addr.get_ptr(), sizeof(sockaddr_in)); saddr.sin_family = addr->sin_family; const char *ipaddr = inet_ntoa(saddr.sin_addr); - sys_net->Warning("connecting on %s to port %d", ipaddr, ntohs(saddr.sin_port)); + sys_net.Warning("connecting on %s to port %d", ipaddr, ntohs(saddr.sin_port)); int ret = connect(s, (const sockaddr *) &saddr, addrlen); *g_lastError = getLastError(); return ret; @@ -170,7 +170,7 @@ int getsockopt() int sys_net_inet_addr(vm::ptr cp) { - sys_net->Warning("inet_addr(cp_addr=0x%x['%s'])", cp.addr(), cp.get_ptr()); + sys_net.Warning("inet_addr(cp_addr=0x%x['%s'])", cp.addr(), cp.get_ptr()); return htonl(inet_addr(cp.get_ptr())); // return a big-endian IP address } @@ -218,14 +218,14 @@ int inet_ntop() int sys_net_inet_pton(s32 af, vm::ptr src, vm::ptr dst) { - sys_net->Warning("inet_pton(af=%d, src_addr=0x%x, dst_addr=0x%x)", af, src.addr(), dst.addr()); + sys_net.Warning("inet_pton(af=%d, src_addr=0x%x, dst_addr=0x%x)", af, src.addr(), dst.addr()); return inet_pton(af, src.get_ptr(), dst.get_ptr()); } int sys_net_listen(s32 s, s32 backlog) { - sys_net->Warning("listen(s=%d, backlog=%d)", s, backlog); + sys_net.Warning("listen(s=%d, backlog=%d)", s, backlog); int ret = listen(s, backlog); *g_lastError = getLastError(); return ret; @@ -233,7 +233,7 @@ int sys_net_listen(s32 s, s32 backlog) int sys_net_recv(s32 s, vm::ptr buf, u32 len, s32 flags) { - sys_net->Warning("recv(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); + sys_net.Warning("recv(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); int ret = recv(s, buf.get_ptr(), len, flags); *g_lastError = getLastError(); @@ -242,7 +242,7 @@ int sys_net_recv(s32 s, vm::ptr buf, u32 len, s32 flags) int sys_net_recvfrom(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr addr, vm::ptr paddrlen) { - sys_net->Warning("recvfrom(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr_addr=0x%x, paddrlen=0x%x)", + sys_net.Warning("recvfrom(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr_addr=0x%x, paddrlen=0x%x)", s, buf.addr(), len, flags, addr.addr(), paddrlen.addr()); sockaddr _addr; @@ -263,7 +263,7 @@ int recvmsg() int sys_net_send(s32 s, vm::ptr buf, u32 len, s32 flags) { - sys_net->Warning("send(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); + sys_net.Warning("send(s=%d, buf_addr=0x%x, len=%d, flags=0x%x)", s, buf.addr(), len, flags); int ret = send(s, buf.get_ptr(), len, flags); *g_lastError = getLastError(); @@ -278,7 +278,7 @@ int sendmsg() int sys_net_sendto(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr addr, u32 addrlen) { - sys_net->Warning("sendto(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr=0x%x, addrlen=%d)", + sys_net.Warning("sendto(s=%d, buf_addr=0x%x, len=%d, flags=0x%x, addr=0x%x, addrlen=%d)", s, buf.addr(), len, flags, addr.addr(), addrlen); sockaddr _addr; @@ -291,7 +291,7 @@ int sys_net_sendto(s32 s, vm::ptr buf, u32 len, s32 flags, vm::ptr optval, u32 optlen) { - sys_net->Warning("socket(s=%d, level=%d, optname=%d, optval_addr=0x%x, optlen=%d)", s, level, optname, optval.addr(), optlen); + sys_net.Warning("socket(s=%d, level=%d, optname=%d, optval_addr=0x%x, optlen=%d)", s, level, optname, optval.addr(), optlen); int ret = setsockopt(s, level, optname, optval.get_ptr(), optlen); *g_lastError = getLastError(); @@ -300,7 +300,7 @@ int sys_net_setsockopt(s32 s, s32 level, s32 optname, vm::ptr optval int sys_net_shutdown(s32 s, s32 how) { - sys_net->Warning("shutdown(s=%d, how=%d)", s, how); + sys_net.Warning("shutdown(s=%d, how=%d)", s, how); int ret = shutdown(s, how); *g_lastError = getLastError(); return ret; @@ -308,7 +308,7 @@ int sys_net_shutdown(s32 s, s32 how) int sys_net_socket(s32 family, s32 type, s32 protocol) { - sys_net->Warning("socket(family=%d, type=%d, protocol=%d)", family, type, protocol); + sys_net.Warning("socket(family=%d, type=%d, protocol=%d)", family, type, protocol); int ret = socket(family, type, protocol); *g_lastError = getLastError(); return ret; @@ -316,7 +316,7 @@ int sys_net_socket(s32 family, s32 type, s32 protocol) int sys_net_socketclose(s32 s) { - sys_net->Warning("socket(s=%d)", s); + sys_net.Warning("socket(s=%d)", s); #ifdef _WIN32 int ret = closesocket(s); #else @@ -340,7 +340,7 @@ int socketselect() int sys_net_initialize_network_ex(vm::ptr param) { - sys_net->Warning("sys_net_initialize_network_ex(param_addr=0x%x)", param.addr()); + sys_net.Warning("sys_net_initialize_network_ex(param_addr=0x%x)", param.addr()); g_lastError = vm::ptr::make((u32)Memory.Alloc(4, 1)); #ifdef _WIN32 WSADATA wsaData; @@ -406,7 +406,7 @@ int sys_net_show_nameserver() u32 _sys_net_errno_loc() { - sys_net->Warning("_sys_net_errno_loc()"); + sys_net.Warning("_sys_net_errno_loc()"); return g_lastError.addr(); } @@ -472,7 +472,7 @@ int sys_net_show_ifconfig() int sys_net_finalize_network() { - sys_net->Warning("sys_net_initialize_network_ex()"); + sys_net.Warning("sys_net_initialize_network_ex()"); Memory.Free(g_lastError.addr()); g_lastError = vm::ptr::make(0); #ifdef _WIN32 @@ -499,67 +499,65 @@ int sys_net_free_thread_context() return CELL_OK; } -void sys_net_init(Module *pxThis) +Module sys_net("sys_net", []() { - sys_net = pxThis; - // The names of the following functions are modified to avoid overloading problems - sys_net->AddFunc(0xc94f6939, sys_net_accept); - sys_net->AddFunc(0xb0a59804, sys_net_bind); - sys_net->AddFunc(0x64f66d35, sys_net_connect); - //sys_net->AddFunc(0xf7ac8941, sys_net_gethostbyaddr); - //sys_net->AddFunc(0x71f4c717, sys_net_gethostbyname); - //sys_net->AddFunc(0xf9ec2db6, sys_net_getpeername); - //sys_net->AddFunc(0x13efe7f5, sys_net_getsockname); - //sys_net->AddFunc(0x5a045bd1, sys_net_getsockopt); - sys_net->AddFunc(0xdabbc2c0, sys_net_inet_addr); - //sys_net->AddFunc(0xa9a079e0, sys_net_inet_aton); - //sys_net->AddFunc(0x566893ce, sys_net_inet_lnaof); - //sys_net->AddFunc(0xb4152c74, sys_net_inet_makeaddr); - //sys_net->AddFunc(0xe39a62a7, sys_net_inet_netof); - //sys_net->AddFunc(0x506ad863, sys_net_inet_network); - //sys_net->AddFunc(0x858a930b, sys_net_inet_ntoa); - //sys_net->AddFunc(0xc98a3146, sys_net_inet_ntop); - sys_net->AddFunc(0x8af3825e, sys_net_inet_pton); - sys_net->AddFunc(0x28e208bb, sys_net_listen); - //sys_net->AddFunc(, sys_net_ntohl); - //sys_net->AddFunc(, sys_net_ntohs); - sys_net->AddFunc(0xfba04f37, sys_net_recv); - sys_net->AddFunc(0x1f953b9f, sys_net_recvfrom); - //sys_net->AddFunc(0xc9d09c34, sys_net_recvmsg); - sys_net->AddFunc(0xdc751b40, sys_net_send); - //sys_net->AddFunc(0xad09481b, sys_net_sendmsg); - sys_net->AddFunc(0x9647570b, sys_net_sendto); - sys_net->AddFunc(0x88f03575, sys_net_setsockopt); - sys_net->AddFunc(0xa50777c6, sys_net_shutdown); - sys_net->AddFunc(0x9c056962, sys_net_socket); - sys_net->AddFunc(0x6db6e8cd, sys_net_socketclose); - //sys_net->AddFunc(0x051ee3ee, sys_net_socketpoll); - //sys_net->AddFunc(0x3f09e20a, sys_net_socketselect); + sys_net.AddFunc(0xc94f6939, sys_net_accept); + sys_net.AddFunc(0xb0a59804, sys_net_bind); + sys_net.AddFunc(0x64f66d35, sys_net_connect); + //sys_net.AddFunc(0xf7ac8941, sys_net_gethostbyaddr); + //sys_net.AddFunc(0x71f4c717, sys_net_gethostbyname); + //sys_net.AddFunc(0xf9ec2db6, sys_net_getpeername); + //sys_net.AddFunc(0x13efe7f5, sys_net_getsockname); + //sys_net.AddFunc(0x5a045bd1, sys_net_getsockopt); + sys_net.AddFunc(0xdabbc2c0, sys_net_inet_addr); + //sys_net.AddFunc(0xa9a079e0, sys_net_inet_aton); + //sys_net.AddFunc(0x566893ce, sys_net_inet_lnaof); + //sys_net.AddFunc(0xb4152c74, sys_net_inet_makeaddr); + //sys_net.AddFunc(0xe39a62a7, sys_net_inet_netof); + //sys_net.AddFunc(0x506ad863, sys_net_inet_network); + //sys_net.AddFunc(0x858a930b, sys_net_inet_ntoa); + //sys_net.AddFunc(0xc98a3146, sys_net_inet_ntop); + sys_net.AddFunc(0x8af3825e, sys_net_inet_pton); + sys_net.AddFunc(0x28e208bb, sys_net_listen); + //sys_net.AddFunc(, sys_net_ntohl); + //sys_net.AddFunc(, sys_net_ntohs); + sys_net.AddFunc(0xfba04f37, sys_net_recv); + sys_net.AddFunc(0x1f953b9f, sys_net_recvfrom); + //sys_net.AddFunc(0xc9d09c34, sys_net_recvmsg); + sys_net.AddFunc(0xdc751b40, sys_net_send); + //sys_net.AddFunc(0xad09481b, sys_net_sendmsg); + sys_net.AddFunc(0x9647570b, sys_net_sendto); + sys_net.AddFunc(0x88f03575, sys_net_setsockopt); + sys_net.AddFunc(0xa50777c6, sys_net_shutdown); + sys_net.AddFunc(0x9c056962, sys_net_socket); + sys_net.AddFunc(0x6db6e8cd, sys_net_socketclose); + //sys_net.AddFunc(0x051ee3ee, sys_net_socketpoll); + //sys_net.AddFunc(0x3f09e20a, sys_net_socketselect); - sys_net->AddFunc(0x139a9e9b, sys_net_initialize_network_ex); - sys_net->AddFunc(0x05bd4438, sys_net_get_udpp2p_test_param); - sys_net->AddFunc(0x10b81ed6, sys_net_set_udpp2p_test_param); - sys_net->AddFunc(0x1d14d6e4, sys_net_get_lib_name_server); - sys_net->AddFunc(0x27fb339d, sys_net_if_ctl); - sys_net->AddFunc(0x368823c0, sys_net_get_netemu_test_param); - sys_net->AddFunc(0x3b27c780, sys_net_get_sockinfo); - sys_net->AddFunc(0x44328aa2, sys_net_close_dump); - sys_net->AddFunc(0x4ab0b9b9, sys_net_set_test_param); - sys_net->AddFunc(0x5420e419, sys_net_show_nameserver); - sys_net->AddFunc(0x6005cde1, _sys_net_errno_loc); - sys_net->AddFunc(0x7687d48c, sys_net_set_resolver_configurations); - sys_net->AddFunc(0x79b61646, sys_net_show_route); - sys_net->AddFunc(0x89c9917c, sys_net_read_dump); - sys_net->AddFunc(0x8ccf05ed, sys_net_abort_resolver); - sys_net->AddFunc(0x8d1b77fb, sys_net_abort_socket); - sys_net->AddFunc(0x9a318259, sys_net_set_lib_name_server); - sys_net->AddFunc(0xa5a86557, sys_net_get_test_param); - sys_net->AddFunc(0xa765d029, sys_net_get_sockinfo_ex); - sys_net->AddFunc(0xab447704, sys_net_open_dump); - sys_net->AddFunc(0xb48636c4, sys_net_show_ifconfig); - sys_net->AddFunc(0xb68d5625, sys_net_finalize_network); - sys_net->AddFunc(0xc9157d30, _sys_net_h_errno_loc); - sys_net->AddFunc(0xe2434507, sys_net_set_netemu_test_param); - sys_net->AddFunc(0xfdb8f926, sys_net_free_thread_context); -} + sys_net.AddFunc(0x139a9e9b, sys_net_initialize_network_ex); + sys_net.AddFunc(0x05bd4438, sys_net_get_udpp2p_test_param); + sys_net.AddFunc(0x10b81ed6, sys_net_set_udpp2p_test_param); + sys_net.AddFunc(0x1d14d6e4, sys_net_get_lib_name_server); + sys_net.AddFunc(0x27fb339d, sys_net_if_ctl); + sys_net.AddFunc(0x368823c0, sys_net_get_netemu_test_param); + sys_net.AddFunc(0x3b27c780, sys_net_get_sockinfo); + sys_net.AddFunc(0x44328aa2, sys_net_close_dump); + sys_net.AddFunc(0x4ab0b9b9, sys_net_set_test_param); + sys_net.AddFunc(0x5420e419, sys_net_show_nameserver); + sys_net.AddFunc(0x6005cde1, _sys_net_errno_loc); + sys_net.AddFunc(0x7687d48c, sys_net_set_resolver_configurations); + sys_net.AddFunc(0x79b61646, sys_net_show_route); + sys_net.AddFunc(0x89c9917c, sys_net_read_dump); + sys_net.AddFunc(0x8ccf05ed, sys_net_abort_resolver); + sys_net.AddFunc(0x8d1b77fb, sys_net_abort_socket); + sys_net.AddFunc(0x9a318259, sys_net_set_lib_name_server); + sys_net.AddFunc(0xa5a86557, sys_net_get_test_param); + sys_net.AddFunc(0xa765d029, sys_net_get_sockinfo_ex); + sys_net.AddFunc(0xab447704, sys_net_open_dump); + sys_net.AddFunc(0xb48636c4, sys_net_show_ifconfig); + sys_net.AddFunc(0xb68d5625, sys_net_finalize_network); + sys_net.AddFunc(0xc9157d30, _sys_net_h_errno_loc); + sys_net.AddFunc(0xe2434507, sys_net_set_netemu_test_param); + sys_net.AddFunc(0xfdb8f926, sys_net_free_thread_context); +}); diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index 3a76026cf7..53612a418c 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -955,15 +955,8 @@ void SysCalls::DoSyscall(PPUThread& CPU, u32 code) (*sc_table[code])(CPU); return; } - - if(Emu.GetModuleManager().CallFunc(CPU, code)) - { - return; - } - - LOG_ERROR(HLE, "TODO: %s", GetHLEFuncName(code).c_str()); - CPU.GPR[3] = 0; + throw "Invalid syscall number"; } IdManager& SysCallBase::GetIdManager() const diff --git a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp index 9a77ad0c51..ddf9448482 100644 --- a/rpcs3/Emu/SysCalls/lv2/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/cellFs.cpp @@ -18,7 +18,7 @@ #include "Emu/FS/vfsDir.h" #include "cellFs.h" -Module *sys_fs = nullptr; +extern Module sys_fs; struct FsRingBufferConfig { @@ -41,8 +41,8 @@ struct FsRingBufferConfig s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs->Log("cellFsOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path.addr(), flags, fd, arg, size); - sys_fs->Log("cellFsOpen(path='%s')", path.get_ptr()); + sys_fs.Log("cellFsOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx)", path.addr(), flags, fd, arg, size); + sys_fs.Log("cellFsOpen(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -97,13 +97,13 @@ s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::p if (_oflags != 0) { - sys_fs->Error("cellFsOpen(): '%s' has unknown flags! flags: 0x%08x", path.get_ptr(), flags); + sys_fs.Error("cellFsOpen(): '%s' has unknown flags! flags: 0x%08x", path.get_ptr(), flags); return CELL_EINVAL; } if (!Emu.GetVFS().ExistsFile(_path)) { - sys_fs->Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags); + sys_fs.Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags); return CELL_ENOENT; } @@ -111,23 +111,23 @@ s32 cellFsOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::p if (!stream || !stream->IsOpened()) { - sys_fs->Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags); + sys_fs.Error("cellFsOpen(): '%s' not found! flags: 0x%08x", path.get_ptr(), flags); return CELL_ENOENT; } - u32 id = sys_fs->GetNewId(stream, TYPE_FS_FILE); + u32 id = sys_fs.GetNewId(stream, TYPE_FS_FILE); *fd = id; - sys_fs->Notice("cellFsOpen(): '%s' opened, id -> 0x%x", path.get_ptr(), id); + sys_fs.Notice("cellFsOpen(): '%s' opened, id -> 0x%x", path.get_ptr(), id); return CELL_OK; } s32 cellFsRead(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr> nread) { - sys_fs->Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); + sys_fs.Log("cellFsRead(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (nbytes != (u32)nbytes) @@ -144,10 +144,10 @@ s32 cellFsRead(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr> nread) s32 cellFsWrite(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite) { - sys_fs->Log("cellFsWrite(fd=0x%x, buf=0x%x, nbytes=0x%llx, nwrite=0x%x)", fd, buf, nbytes, nwrite); + sys_fs.Log("cellFsWrite(fd=0x%x, buf=0x%x, nbytes=0x%llx, nwrite=0x%x)", fd, buf, nbytes, nwrite); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) return CELL_ESRCH; + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; if (nbytes != (u32)nbytes) return CELL_ENOMEM; @@ -162,7 +162,7 @@ s32 cellFsWrite(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrite s32 cellFsClose(u32 fd) { - sys_fs->Warning("cellFsClose(fd=0x%x)", fd); + sys_fs.Warning("cellFsClose(fd=0x%x)", fd); if (!Emu.GetIdManager().RemoveID(fd)) return CELL_ESRCH; @@ -172,8 +172,8 @@ s32 cellFsClose(u32 fd) s32 cellFsOpendir(vm::ptr path, vm::ptr fd) { - sys_fs->Warning("cellFsOpendir(path_addr=0x%x, fd=0x%x)", path.addr(), fd); - sys_fs->Warning("cellFsOpendir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsOpendir(path_addr=0x%x, fd=0x%x)", path.addr(), fd); + sys_fs.Warning("cellFsOpendir(path='%s')", path.get_ptr()); std::shared_ptr dir(Emu.GetVFS().OpenDir(path.get_ptr())); if (!dir || !dir->IsOpened()) @@ -181,16 +181,16 @@ s32 cellFsOpendir(vm::ptr path, vm::ptr fd) return CELL_ENOENT; } - *fd = sys_fs->GetNewId(dir, TYPE_FS_DIR); + *fd = sys_fs.GetNewId(dir, TYPE_FS_DIR); return CELL_OK; } s32 cellFsReaddir(u32 fd, vm::ptr dir, vm::ptr nread) { - sys_fs->Warning("cellFsReaddir(fd=0x%x, dir=0x%x, nread=0x%x)", fd, dir, nread); + sys_fs.Warning("cellFsReaddir(fd=0x%x, dir=0x%x, nread=0x%x)", fd, dir, nread); std::shared_ptr directory; - if (!sys_fs->CheckId(fd, directory)) + if (!sys_fs.CheckId(fd, directory)) return CELL_ESRCH; const DirEntryInfo* info = directory->Read(); @@ -211,7 +211,7 @@ s32 cellFsReaddir(u32 fd, vm::ptr dir, vm::ptr nread) s32 cellFsClosedir(u32 fd) { - sys_fs->Warning("cellFsClosedir(fd=0x%x)", fd); + sys_fs.Warning("cellFsClosedir(fd=0x%x)", fd); if (!Emu.GetIdManager().RemoveID(fd)) return CELL_ESRCH; @@ -221,8 +221,8 @@ s32 cellFsClosedir(u32 fd) s32 cellFsStat(vm::ptr path, vm::ptr sb) { - sys_fs->Warning("cellFsStat(path_addr=0x%x, sb=0x%x)", path.addr(), sb); - sys_fs->Warning("cellFsStat(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsStat(path_addr=0x%x, sb=0x%x)", path.addr(), sb); + sys_fs.Warning("cellFsStat(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -248,7 +248,7 @@ s32 cellFsStat(vm::ptr path, vm::ptr sb) #endif if (stat_result) { - sys_fs->Error("cellFsStat(): stat('%s') failed -> 0x%x", real_path.c_str(), stat_result); + sys_fs.Error("cellFsStat(): stat('%s') failed -> 0x%x", real_path.c_str(), stat_result); } else { @@ -267,7 +267,7 @@ s32 cellFsStat(vm::ptr path, vm::ptr sb) CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; if (sb->st_mode == mode) - sys_fs->Error("cellFsStat(): mode is the same (0x%x)", mode); + sys_fs.Error("cellFsStat(): mode is the same (0x%x)", mode); sb->st_uid = uid; sb->st_gid = gid; @@ -296,19 +296,19 @@ s32 cellFsStat(vm::ptr path, vm::ptr sb) } if (sb->st_size == size && size != 0) - sys_fs->Error("cellFsStat(): size is the same (0x%x)", size); + sys_fs.Error("cellFsStat(): size is the same (0x%x)", size); - sys_fs->Warning("cellFsStat(): '%s' not found", path.get_ptr()); + sys_fs.Warning("cellFsStat(): '%s' not found", path.get_ptr()); return CELL_ENOENT; } s32 cellFsFstat(u32 fd, vm::ptr sb) { - sys_fs->Warning("cellFsFstat(fd=0x%x, sb=0x%x)", fd, sb); + sys_fs.Warning("cellFsFstat(fd=0x%x, sb=0x%x)", fd, sb); IDType type; std::shared_ptr file; - if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) + if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; sb->st_mode = @@ -330,8 +330,8 @@ s32 cellFsFstat(u32 fd, vm::ptr sb) s32 cellFsMkdir(vm::ptr path, u32 mode) { - sys_fs->Warning("cellFsMkdir(path_addr=0x%x, mode=0x%x)", path.addr(), mode); - sys_fs->Warning("cellFsMkdir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsMkdir(path_addr=0x%x, mode=0x%x)", path.addr(), mode); + sys_fs.Warning("cellFsMkdir(path='%s')", path.get_ptr()); const std::string _path = path.get_ptr(); @@ -341,14 +341,14 @@ s32 cellFsMkdir(vm::ptr path, u32 mode) if (!Emu.GetVFS().CreateDir(_path)) return CELL_EBUSY; - sys_fs->Notice("cellFsMkdir(): directory '%s' created", path.get_ptr()); + sys_fs.Notice("cellFsMkdir(): directory '%s' created", path.get_ptr()); return CELL_OK; } s32 cellFsRename(vm::ptr from, vm::ptr to) { - sys_fs->Warning("cellFsRename(from_addr=0x%x, to_addr=0x%x)", from.addr(), to.addr()); - sys_fs->Warning("cellFsRename(from='%s', to='%s')", from.get_ptr(), to.get_ptr()); + sys_fs.Warning("cellFsRename(from_addr=0x%x, to_addr=0x%x)", from.addr(), to.addr()); + sys_fs.Warning("cellFsRename(from='%s', to='%s')", from.get_ptr(), to.get_ptr()); std::string _from = from.get_ptr(); std::string _to = to.get_ptr(); @@ -360,7 +360,7 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) if(!dir.Rename(_from, _to)) return CELL_EBUSY; - sys_fs->Notice("cellFsRename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); + sys_fs.Notice("cellFsRename(): directory '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); return CELL_OK; } } @@ -373,7 +373,7 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) if(!f.Rename(_from, _to)) return CELL_EBUSY; - sys_fs->Notice("cellFsRename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); + sys_fs.Notice("cellFsRename(): file '%s' renamed to '%s'", from.get_ptr(), to.get_ptr()); return CELL_OK; } } @@ -382,8 +382,8 @@ s32 cellFsRename(vm::ptr from, vm::ptr to) } s32 cellFsChmod(vm::ptr path, u32 mode) { - sys_fs->Todo("cellFsChmod(path_addr=0x%x, mode=0x%x)", path.addr(), mode); - sys_fs->Todo("cellFsChmod(path='%s')", path.get_ptr()); + sys_fs.Todo("cellFsChmod(path_addr=0x%x, mode=0x%x)", path.addr(), mode); + sys_fs.Todo("cellFsChmod(path='%s')", path.get_ptr()); // TODO: @@ -392,7 +392,7 @@ s32 cellFsChmod(vm::ptr path, u32 mode) s32 cellFsFsync(u32 fd) { - sys_fs->Todo("cellFsFsync(fd=0x%x)", fd); + sys_fs.Todo("cellFsFsync(fd=0x%x)", fd); // TODO: @@ -401,8 +401,8 @@ s32 cellFsFsync(u32 fd) s32 cellFsRmdir(vm::ptr path) { - sys_fs->Warning("cellFsRmdir(path_addr=0x%x)", path.addr()); - sys_fs->Warning("cellFsRmdir(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsRmdir(path_addr=0x%x)", path.addr()); + sys_fs.Warning("cellFsRmdir(path='%s')", path.get_ptr()); std::string _path = path.get_ptr(); @@ -413,14 +413,14 @@ s32 cellFsRmdir(vm::ptr path) if (!d.Remove(_path)) return CELL_EBUSY; - sys_fs->Notice("cellFsRmdir(): directory '%s' removed", path.get_ptr()); + sys_fs.Notice("cellFsRmdir(): directory '%s' removed", path.get_ptr()); return CELL_OK; } s32 cellFsUnlink(vm::ptr path) { - sys_fs->Warning("cellFsUnlink(path_addr=0x%x)", path.addr()); - sys_fs->Warning("cellFsUnlink(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsUnlink(path_addr=0x%x)", path.addr()); + sys_fs.Warning("cellFsUnlink(path='%s')", path.get_ptr()); std::string _path = path.get_ptr(); @@ -433,13 +433,13 @@ s32 cellFsUnlink(vm::ptr path) if (!Emu.GetVFS().RemoveFile(_path)) return CELL_EACCES; - sys_fs->Notice("cellFsUnlink(): file '%s' removed", path.get_ptr()); + sys_fs.Notice("cellFsUnlink(): file '%s' removed", path.get_ptr()); return CELL_OK; } s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr> pos) { - sys_fs->Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=0x%x)", fd, offset, whence, pos); + sys_fs.Log("cellFsLseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=0x%x)", fd, offset, whence, pos); vfsSeekMode seek_mode; switch(whence) @@ -448,13 +448,13 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr> pos) case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break; case CELL_SEEK_END: seek_mode = vfsSeekEnd; break; default: - sys_fs->Error("cellFsLseek(fd=0x%x): Unknown seek whence! (0x%x)", fd, whence); + sys_fs.Error("cellFsLseek(fd=0x%x): Unknown seek whence! (0x%x)", fd, whence); return CELL_EINVAL; } IDType type; std::shared_ptr file; - if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) + if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; *pos = file->Seek(offset, seek_mode); @@ -463,11 +463,11 @@ s32 cellFsLseek(u32 fd, s64 offset, u32 whence, vm::ptr> pos) s32 cellFsFtruncate(u32 fd, u64 size) { - sys_fs->Warning("cellFsFtruncate(fd=0x%x, size=0x%llx)", fd, size); + sys_fs.Warning("cellFsFtruncate(fd=0x%x, size=0x%llx)", fd, size); IDType type; std::shared_ptr file; - if (!sys_fs->CheckId(fd, file, type) || type != TYPE_FS_FILE) + if (!sys_fs.CheckId(fd, file, type) || type != TYPE_FS_FILE) return CELL_ESRCH; u64 initialSize = file->GetSize(); @@ -492,13 +492,13 @@ s32 cellFsFtruncate(u32 fd, u64 size) s32 cellFsTruncate(vm::ptr path, u64 size) { - sys_fs->Warning("cellFsTruncate(path_addr=0x%x, size=0x%llx)", path.addr(), size); - sys_fs->Warning("cellFsTruncate(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsTruncate(path_addr=0x%x, size=0x%llx)", path.addr(), size); + sys_fs.Warning("cellFsTruncate(path='%s')", path.get_ptr()); vfsFile f(path.get_ptr(), vfsReadWrite); if (!f.IsOpened()) { - sys_fs->Warning("cellFsTruncate(): '%s' not found", path.get_ptr()); + sys_fs.Warning("cellFsTruncate(): '%s' not found", path.get_ptr()); return CELL_ENOENT; } u64 initialSize = f.GetSize(); @@ -523,12 +523,12 @@ s32 cellFsTruncate(vm::ptr path, u64 size) s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_size) { - sys_fs->Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=0x%x, block_size=0x%x)", fd, sector_size, block_size); + sys_fs.Warning("cellFsFGetBlockSize(fd=0x%x, sector_size=0x%x, block_size=0x%x)", fd, sector_size, block_size); LV2_LOCK(0); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; *sector_size = 4096; // ? @@ -539,8 +539,8 @@ s32 cellFsFGetBlockSize(u32 fd, vm::ptr sector_size, vm::ptr block_siz s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::ptr block_size) { - sys_fs->Warning("cellFsGetBlockSize(path_addr=0x%x, sector_size=0x%x, block_size=0x%x)", path.addr(), sector_size, block_size); - sys_fs->Warning("cellFsGetBlockSize(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsGetBlockSize(path_addr=0x%x, sector_size=0x%x, block_size=0x%x)", path.addr(), sector_size, block_size); + sys_fs.Warning("cellFsGetBlockSize(path='%s')", path.get_ptr()); *sector_size = 4096; // ? *block_size = 4096; // ? @@ -550,8 +550,8 @@ s32 cellFsGetBlockSize(vm::ptr path, vm::ptr sector_size, vm::p s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr block_count) { - sys_fs->Warning("cellFsGetFreeSize(path_addr=0x%x, block_size=0x%x, block_count=0x%x)", path.addr(), block_size, block_count); - sys_fs->Warning("cellFsGetFreeSize(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsGetFreeSize(path_addr=0x%x, block_size=0x%x, block_count=0x%x)", path.addr(), block_size, block_count); + sys_fs.Warning("cellFsGetFreeSize(path='%s')", path.get_ptr()); // TODO: Get real values. Currently, it always returns 40 GB of free space divided in 4 KB blocks *block_size = 4096; // ? @@ -562,10 +562,10 @@ s32 cellFsGetFreeSize(vm::ptr path, vm::ptr block_size, vm::ptr s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 entries_size, vm::ptr data_count) { - sys_fs->Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=0x%x, entries_size=0x%x, data_count=0x%x)", fd, entries, entries_size, data_count); + sys_fs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=0x%x, entries_size=0x%x, data_count=0x%x)", fd, entries, entries_size, data_count); std::shared_ptr directory; - if (!sys_fs->CheckId(fd, directory)) + if (!sys_fs.CheckId(fd, directory)) return CELL_ESRCH; const DirEntryInfo* info = directory->Read(); @@ -598,10 +598,10 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) { - sys_fs->Warning("cellFsStReadInit(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); + sys_fs.Warning("cellFsStReadInit(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; fs_config.m_ring_buffer = *ringbuf; @@ -623,10 +623,10 @@ s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) s32 cellFsStReadFinish(u32 fd) { - sys_fs->Warning("cellFsStReadFinish(fd=0x%x)", fd); + sys_fs.Warning("cellFsStReadFinish(fd=0x%x)", fd); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; Memory.Free(fs_config.m_buffer); @@ -637,25 +637,25 @@ s32 cellFsStReadFinish(u32 fd) s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { - sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=0x%x)", fd, ringbuf); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; *ringbuf = fs_config.m_ring_buffer; - sys_fs->Warning("*** fs stream config: block_size=0x%llx, copy=0x%x, ringbuf_size=0x%llx, transfer_rate=0x%llx", + sys_fs.Warning("*** fs stream config: block_size=0x%llx, copy=0x%x, ringbuf_size=0x%llx, transfer_rate=0x%llx", ringbuf->block_size, ringbuf->copy, ringbuf->ringbuf_size, ringbuf->transfer_rate); return CELL_OK; } s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { - sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, status=0x%x)", fd, status); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=0x%x)", fd, status); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; *status = fs_config.m_fs_status; @@ -665,10 +665,10 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { - sys_fs->Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=0x%x)", fd, regid); + sys_fs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=0x%x)", fd, regid); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; *regid = fs_config.m_regid; @@ -678,10 +678,10 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { - sys_fs->Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); + sys_fs.Todo("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; fs_config.m_current_addr = fs_config.m_buffer + (u32)offset; @@ -692,10 +692,10 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) s32 cellFsStReadStop(u32 fd) { - sys_fs->Warning("cellFsStReadStop(fd=0x%x)", fd); + sys_fs.Warning("cellFsStReadStop(fd=0x%x)", fd); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; fs_config.m_fs_status = CELL_FS_ST_STOP; @@ -705,10 +705,10 @@ s32 cellFsStReadStop(u32 fd) s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { - sys_fs->Warning("cellFsStRead(fd=0x%x, buf=0x%x, size=0x%llx, rsize=0x%x)", fd, buf, size, rsize); + sys_fs.Warning("cellFsStRead(fd=0x%x, buf=0x%x, size=0x%llx, rsize=0x%x)", fd, buf, size, rsize); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; // TODO: use ringbuffer (fs_config) @@ -724,10 +724,10 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr size) { - sys_fs->Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=0x%x, size=0x%x)", fd, addr, size); + sys_fs.Todo("cellFsStReadGetCurrentAddr(fd=0x%x, addr=0x%x, size=0x%x)", fd, addr, size); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; @@ -735,10 +735,10 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr> addr, vm::ptr s s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { - sys_fs->Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=0x%x, size=0x%llx)", fd, addr, size); + sys_fs.Todo("cellFsStReadPutCurrentAddr(fd=0x%x, addr=0x%x, size=0x%llx)", fd, addr, size); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; @@ -746,10 +746,10 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) s32 cellFsStReadWait(u32 fd, u64 size) { - sys_fs->Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); + sys_fs.Todo("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; @@ -757,10 +757,10 @@ s32 cellFsStReadWait(u32 fd, u64 size) s32 cellFsStReadWaitCallback(u32 fd, u64 size, vm::ptr func) { - sys_fs->Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=0x%x)", fd, size, func); + sys_fs.Todo("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=0x%x)", fd, size, func); std::shared_ptr file; - if (!sys_fs->CheckId(fd, file)) + if (!sys_fs.CheckId(fd, file)) return CELL_ESRCH; return CELL_OK; @@ -799,13 +799,13 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil if (!packed_stream || !packed_stream->IsOpened()) { - sys_fs->Error("'%s' not found! flags: 0x%02x", packed_file.c_str(), vfsRead); + sys_fs.Error("'%s' not found! flags: 0x%02x", packed_file.c_str(), vfsRead); return CELL_ENOENT; } if (!unpacked_stream || !unpacked_stream->IsOpened()) { - sys_fs->Error("'%s' couldn't be created! flags: 0x%02x", unpacked_file.c_str(), vfsWrite); + sys_fs.Error("'%s' couldn't be created! flags: 0x%02x", unpacked_file.c_str(), vfsWrite); return CELL_ENOENT; } @@ -814,7 +814,7 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil u32 format = re32(*(u32*)&buffer[0]); if (format != 0x4E504400) // "NPD\x00" { - sys_fs->Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format); + sys_fs.Error("Illegal format. Expected 0x4E504400, but got 0x%08x", format); return CELL_EFSSPECIFIC; } @@ -828,7 +828,7 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil // SDATA file is compressed if (flags & 0x1) { - sys_fs->Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet."); + sys_fs.Warning("cellFsSdataOpen: Compressed SDATA files are not supported yet."); return CELL_EFSSPECIFIC; } @@ -841,7 +841,7 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil if (!sdata_check(version, flags, filesizeInput, filesizeTmp)) { - sys_fs->Error("cellFsSdataOpen: Wrong header information."); + sys_fs.Error("cellFsSdataOpen: Wrong header information."); return CELL_EFSSPECIFIC; } @@ -868,8 +868,8 @@ int sdata_unpack(const std::string& packed_file, const std::string& unpacked_fil s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, vm::ptr arg, u64 size) { - sys_fs->Warning("cellFsSdataOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path.addr(), flags, fd, arg, size); - sys_fs->Warning("cellFsSdataOpen(path='%s')", path.get_ptr()); + sys_fs.Warning("cellFsSdataOpen(path_addr=0x%x, flags=0x%x, fd=0x%x, arg=0x%x, size=0x%llx) -> cellFsOpen()", path.addr(), flags, fd, arg, size); + sys_fs.Warning("cellFsSdataOpen(path='%s')", path.get_ptr()); /*if (flags != CELL_O_RDONLY) return CELL_EINVAL; @@ -884,7 +884,7 @@ s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, int ret = sdata_unpack(path, unpacked_path); if (ret) return ret; - fd = sys_fs->GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE); + fd = sys_fs.GetNewId(Emu.GetVFS().OpenFile(unpacked_path, vfsRead), TYPE_FS_FILE); return CELL_OK;*/ @@ -893,7 +893,7 @@ s32 cellFsSdataOpen(vm::ptr path, s32 flags, vm::ptr> fd, s32 cellFsSdataOpenByFd(u32 mself_fd, s32 flags, vm::ptr sdata_fd, u64 offset, vm::ptr arg, u64 size) { - sys_fs->Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd=0x%x, offset=0x%llx, arg=0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size); + sys_fs.Todo("cellFsSdataOpenByFd(mself_fd=0x%x, flags=0x%x, sdata_fd=0x%x, offset=0x%llx, arg=0x%x, size=0x%llx)", mself_fd, flags, sdata_fd, offset, arg, size); // TODO: @@ -911,7 +911,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptrWarning("fsAioRead() aborted"); + sys_fs.Warning("fsAioRead() aborted"); return; } } @@ -920,9 +920,9 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr orig_file; - if (!sys_fs->CheckId(fd, orig_file)) + if (!sys_fs.CheckId(fd, orig_file)) { - sys_fs->Error("Wrong fd (%s)", fd); + sys_fs.Error("Wrong fd (%s)", fd); Emu.Pause(); return; } @@ -944,7 +944,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptrLog("*** fsAioRead(fd=%d, offset=0x%llx, buf=0x%x, size=0x%llx, error=0x%x, res=0x%llx, xid=0x%x)", + sys_fs.Log("*** fsAioRead(fd=%d, offset=0x%llx, buf=0x%x, size=0x%llx, error=0x%x, res=0x%llx, xid=0x%x)", fd, aio->offset, aio->buf, aio->size, error, res, xid); } @@ -961,7 +961,7 @@ void fsAioRead(u32 fd, vm::ptr aio, int xid, vm::ptr aio, vm::ptr id, vm::ptr xaio, s32 error, s32 xid, u64 size)> func) { - sys_fs->Warning("cellFsAioRead(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); + sys_fs.Warning("cellFsAioRead(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); if (!aio_init) { @@ -971,7 +971,7 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, vm::ptr orig_file; u32 fd = aio->fd; - if (!sys_fs->CheckId(fd, orig_file)) + if (!sys_fs.CheckId(fd, orig_file)) { return CELL_EBADF; } @@ -986,7 +986,7 @@ s32 cellFsAioRead(vm::ptr aio, vm::ptr id, vm::ptr aio, vm::ptr id, vm::ptr xaio, s32 error, s32 xid, u64 size)> func) { - sys_fs->Todo("cellFsAioWrite(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); + sys_fs.Todo("cellFsAioWrite(aio=0x%x, id=0x%x, func=0x%x)", aio, id, func); // TODO: @@ -995,8 +995,8 @@ s32 cellFsAioWrite(vm::ptr aio, vm::ptr id, vm::ptr mount_point) { - sys_fs->Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.addr()); - sys_fs->Warning("cellFsAioInit(mount_point='%s')", mount_point.get_ptr()); + sys_fs.Warning("cellFsAioInit(mount_point_addr=0x%x)", mount_point.addr()); + sys_fs.Warning("cellFsAioInit(mount_point='%s')", mount_point.get_ptr()); aio_init = true; return CELL_OK; @@ -1004,8 +1004,8 @@ s32 cellFsAioInit(vm::ptr mount_point) s32 cellFsAioFinish(vm::ptr mount_point) { - sys_fs->Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.addr()); - sys_fs->Warning("cellFsAioFinish(mount_point='%s')", mount_point.get_ptr()); + sys_fs.Warning("cellFsAioFinish(mount_point_addr=0x%x)", mount_point.addr()); + sys_fs.Warning("cellFsAioFinish(mount_point='%s')", mount_point.get_ptr()); //aio_init = false; return CELL_OK; @@ -1013,7 +1013,7 @@ s32 cellFsAioFinish(vm::ptr mount_point) s32 cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, vm::ptr> nread) { - sys_fs->Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=0x%x, buffer_size=%lld, nread=0x%llx)", fd, offset, buf, buffer_size, nread); + sys_fs.Warning("cellFsReadWithOffset(fd=%d, offset=0x%llx, buf=0x%x, buffer_size=%lld, nread=0x%llx)", fd, offset, buf, buffer_size, nread); int ret; vm::stackvar> oldPos(CPU), newPos(CPU); @@ -1029,56 +1029,51 @@ s32 cellFsReadWithOffset(PPUThread& CPU, u32 fd, u64 offset, vm::ptr buf, return CELL_OK; } -void sys_fs_init(Module *pxThis) -{ - sys_fs = pxThis; - - sys_fs->AddFunc(0x718bf5f8, cellFsOpen); - sys_fs->AddFunc(0xb1840b53, cellFsSdataOpen); - sys_fs->AddFunc(0x6d3bb15b, cellFsSdataOpenByFd); - sys_fs->AddFunc(0x4d5ff8e2, cellFsRead); - sys_fs->AddFunc(0xecdcf2ab, cellFsWrite); - sys_fs->AddFunc(0x2cb51f0d, cellFsClose); - sys_fs->AddFunc(0x3f61245c, cellFsOpendir); - sys_fs->AddFunc(0x5c74903d, cellFsReaddir); - sys_fs->AddFunc(0xff42dcc3, cellFsClosedir); - sys_fs->AddFunc(0x7de6dced, cellFsStat); - sys_fs->AddFunc(0xef3efa34, cellFsFstat); - sys_fs->AddFunc(0xba901fe6, cellFsMkdir); - sys_fs->AddFunc(0xf12eecc8, cellFsRename); - sys_fs->AddFunc(0x99406d0b, cellFsChmod); - sys_fs->AddFunc(0x967a162b, cellFsFsync); - sys_fs->AddFunc(0x2796fdf3, cellFsRmdir); - sys_fs->AddFunc(0x7f4677a8, cellFsUnlink); - sys_fs->AddFunc(0xa397d042, cellFsLseek); - sys_fs->AddFunc(0x0e2939e5, cellFsFtruncate); - sys_fs->AddFunc(0xc9dc3ac5, cellFsTruncate); - sys_fs->AddFunc(0xcb588dba, cellFsFGetBlockSize); - sys_fs->AddFunc(0xc1c507e7, cellFsAioRead); - sys_fs->AddFunc(0x4cef342e, cellFsAioWrite); - sys_fs->AddFunc(0xdb869f20, cellFsAioInit); - sys_fs->AddFunc(0x9f951810, cellFsAioFinish); - sys_fs->AddFunc(0x1a108ab7, cellFsGetBlockSize); - sys_fs->AddFunc(0xaa3b4bcd, cellFsGetFreeSize); - sys_fs->AddFunc(0x0d5b4a14, cellFsReadWithOffset); - sys_fs->AddFunc(0x9b882495, cellFsGetDirectoryEntries); - sys_fs->AddFunc(0x2664c8ae, cellFsStReadInit); - sys_fs->AddFunc(0xd73938df, cellFsStReadFinish); - sys_fs->AddFunc(0xb3afee8b, cellFsStReadGetRingBuf); - sys_fs->AddFunc(0xcf34969c, cellFsStReadGetStatus); - sys_fs->AddFunc(0xbd273a88, cellFsStReadGetRegid); - sys_fs->AddFunc(0x8df28ff9, cellFsStReadStart); - sys_fs->AddFunc(0xf8e5d9a0, cellFsStReadStop); - sys_fs->AddFunc(0x27800c6b, cellFsStRead); - sys_fs->AddFunc(0x190912f6, cellFsStReadGetCurrentAddr); - sys_fs->AddFunc(0x81f33783, cellFsStReadPutCurrentAddr); - sys_fs->AddFunc(0x8f71c5b2, cellFsStReadWait); - sys_fs->AddFunc(0x866f6aec, cellFsStReadWaitCallback); -} - -void sys_fs_load() +Module sys_fs("sys_fs", []() { g_FsAioReadID = 0; g_FsAioReadCur = 0; aio_init = false; -} + + sys_fs.AddFunc(0x718bf5f8, cellFsOpen); + sys_fs.AddFunc(0xb1840b53, cellFsSdataOpen); + sys_fs.AddFunc(0x6d3bb15b, cellFsSdataOpenByFd); + sys_fs.AddFunc(0x4d5ff8e2, cellFsRead); + sys_fs.AddFunc(0xecdcf2ab, cellFsWrite); + sys_fs.AddFunc(0x2cb51f0d, cellFsClose); + sys_fs.AddFunc(0x3f61245c, cellFsOpendir); + sys_fs.AddFunc(0x5c74903d, cellFsReaddir); + sys_fs.AddFunc(0xff42dcc3, cellFsClosedir); + sys_fs.AddFunc(0x7de6dced, cellFsStat); + sys_fs.AddFunc(0xef3efa34, cellFsFstat); + sys_fs.AddFunc(0xba901fe6, cellFsMkdir); + sys_fs.AddFunc(0xf12eecc8, cellFsRename); + sys_fs.AddFunc(0x99406d0b, cellFsChmod); + sys_fs.AddFunc(0x967a162b, cellFsFsync); + sys_fs.AddFunc(0x2796fdf3, cellFsRmdir); + sys_fs.AddFunc(0x7f4677a8, cellFsUnlink); + sys_fs.AddFunc(0xa397d042, cellFsLseek); + sys_fs.AddFunc(0x0e2939e5, cellFsFtruncate); + sys_fs.AddFunc(0xc9dc3ac5, cellFsTruncate); + sys_fs.AddFunc(0xcb588dba, cellFsFGetBlockSize); + sys_fs.AddFunc(0xc1c507e7, cellFsAioRead); + sys_fs.AddFunc(0x4cef342e, cellFsAioWrite); + sys_fs.AddFunc(0xdb869f20, cellFsAioInit); + sys_fs.AddFunc(0x9f951810, cellFsAioFinish); + sys_fs.AddFunc(0x1a108ab7, cellFsGetBlockSize); + sys_fs.AddFunc(0xaa3b4bcd, cellFsGetFreeSize); + sys_fs.AddFunc(0x0d5b4a14, cellFsReadWithOffset); + sys_fs.AddFunc(0x9b882495, cellFsGetDirectoryEntries); + sys_fs.AddFunc(0x2664c8ae, cellFsStReadInit); + sys_fs.AddFunc(0xd73938df, cellFsStReadFinish); + sys_fs.AddFunc(0xb3afee8b, cellFsStReadGetRingBuf); + sys_fs.AddFunc(0xcf34969c, cellFsStReadGetStatus); + sys_fs.AddFunc(0xbd273a88, cellFsStReadGetRegid); + sys_fs.AddFunc(0x8df28ff9, cellFsStReadStart); + sys_fs.AddFunc(0xf8e5d9a0, cellFsStReadStop); + sys_fs.AddFunc(0x27800c6b, cellFsStRead); + sys_fs.AddFunc(0x190912f6, cellFsStReadGetCurrentAddr); + sys_fs.AddFunc(0x81f33783, cellFsStReadPutCurrentAddr); + sys_fs.AddFunc(0x8f71c5b2, cellFsStReadWait); + sys_fs.AddFunc(0x866f6aec, cellFsStReadWaitCallback); +}); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index db61eac0ea..4927d38377 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -189,7 +189,7 @@ bool Emulator::BootGame(const std::string& path, bool direct) void Emulator::Load() { - GetModuleManager().init(); + GetModuleManager().Init(); if (!rExists(m_path)) return; @@ -379,6 +379,8 @@ void Emulator::Stop() // TODO: check finalization order + clear_ps3_functions(); + SavePoints(BreakPointsDBName); m_break_points.clear(); m_marked_points.clear(); @@ -394,7 +396,7 @@ void Emulator::Stop() GetKeyboardManager().Close(); GetMouseManager().Close(); GetCallbackManager().Clear(); - GetModuleManager().UnloadModules(); + GetModuleManager().Close(); GetSFuncManager().StaticFinalize(); GetSyncPrimManager().Close(); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index c4076fca07..e3de0bb9fd 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -110,13 +110,13 @@ namespace loader if (!segment.begin) { - LOG_ERROR(LOADER, "%s() sprx: AllocFixed(0x%llx, 0x%x) failed", __FUNCTION__, phdr.p_vaddr.addr(), (u32)phdr.p_memsz); + LOG_ERROR(LOADER, "%s() sprx: vm::alloc(0x%x) failed", __FUNCTION__, segment.size); return loading_error; } segment.initial_addr.set(phdr.p_vaddr.addr()); - LOG_ERROR(LOADER, "segment addr=0x%x, initial addr = 0x%x", segment.begin.addr(), segment.initial_addr.addr()); + LOG_WARNING(LOADER, "segment addr=0x%x, initial addr = 0x%x", segment.begin.addr(), segment.initial_addr.addr()); if (phdr.p_filesz) { @@ -129,16 +129,11 @@ namespace loader sys_prx_module_info_t module_info; m_stream->Seek(handler::get_stream_offset() + phdr.p_paddr.addr()); m_stream->Read(&module_info, sizeof(module_info)); - LOG_ERROR(LOADER, "%s (%x):", module_info.name, (u32)module_info.toc); + info.name = std::string(module_info.name, 28); - info.rtoc = module_info.toc; + info.rtoc = module_info.toc + segment.begin.addr(); - int import_count = (module_info.imports_end - module_info.imports_start) / sizeof(sys_prx_library_info_t); - - if (import_count) - { - LOG_ERROR(LOADER, "**** Lib '%s' has %d imports!", module_info.name, import_count); - } + LOG_WARNING(LOADER, "%s (rtoc=%x):", info.name, info.rtoc); sys_prx_library_info_t lib; for (u32 e = module_info.exports_start.addr(); @@ -155,12 +150,12 @@ namespace loader m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr); m_stream->Read(name, sizeof(name)); modulename = std::string(name); - LOG_ERROR(LOADER, "**** %s", name); + LOG_WARNING(LOADER, "**** Exported: %s", name); } auto &module = info.modules[modulename]; - LOG_ERROR(LOADER, "**** 0x%x - 0x%x - 0x%x", (u32)lib.unk4, (u32)lib.unk5, (u32)lib.unk6); + LOG_WARNING(LOADER, "**** 0x%x - 0x%x - 0x%x", (u32)lib.unk4, (u32)lib.unk5, (u32)lib.unk6); for (u16 i = 0, end = lib.num_func; i < end; ++i) { @@ -174,7 +169,7 @@ namespace loader module.exports[fnid] = fstub; //LOG_NOTICE(LOADER, "Exported function '%s' in '%s' module (LLE)", SysCalls::GetHLEFuncName(fnid).c_str(), module_name.c_str()); - LOG_ERROR(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub); + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub); } } @@ -184,6 +179,34 @@ namespace loader { m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + i); m_stream->Read(&lib, sizeof(lib)); + + std::string modulename; + if (lib.name_addr) + { + char name[27]; + m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.name_addr); + m_stream->Read(name, sizeof(name)); + modulename = std::string(name); + LOG_WARNING(LOADER, "**** Imported: %s", name); + } + + auto &module = info.modules[modulename]; + + LOG_WARNING(LOADER, "**** 0x%x - 0x%x - 0x%x", (u32)lib.unk4, (u32)lib.unk5, (u32)lib.unk6); + + for (u16 i = 0, end = lib.num_func; i < end; ++i) + { + be_t fnid, fstub; + m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.fnid_addr + i * sizeof(fnid)); + m_stream->Read(&fnid, sizeof(fnid)); + + m_stream->Seek(handler::get_stream_offset() + phdr.p_offset + lib.fstub_addr + i * sizeof(fstub)); + m_stream->Read(&fstub, sizeof(fstub)); + + module.imports[fnid] = fstub; + + LOG_WARNING(LOADER, "**** %s: [%s] -> 0x%x", modulename.c_str(), SysCalls::GetHLEFuncName(fnid).c_str(), (u32)fstub); + } } } @@ -207,22 +230,22 @@ namespace loader switch ((u32)rel.type) { case 1: - LOG_WARNING(LOADER, "**** RELOCATION(1): 0x%x <- 0x%x", ADDR, (u32)(info.segments[rel.index_value].begin.addr() + rel.ptr.addr())); + LOG_NOTICE(LOADER, "**** RELOCATION(1): 0x%x <- 0x%x", ADDR, (u32)(info.segments[rel.index_value].begin.addr() + rel.ptr.addr())); *vm::ptr::make(ADDR) = info.segments[rel.index_value].begin.addr() + rel.ptr.addr(); break; case 4: - LOG_WARNING(LOADER, "**** RELOCATION(4): 0x%x <- 0x%x", ADDR, (u16)(rel.ptr.addr())); + LOG_NOTICE(LOADER, "**** RELOCATION(4): 0x%x <- 0x%x", ADDR, (u16)(rel.ptr.addr())); *vm::ptr::make(ADDR) = (u16)(u64)rel.ptr.addr(); break; case 5: - LOG_WARNING(LOADER, "**** RELOCATION(5): 0x%x <- 0x%x", ADDR, (u16)(info.segments[rel.index_value].begin.addr() >> 16)); + LOG_NOTICE(LOADER, "**** RELOCATION(5): 0x%x <- 0x%x", ADDR, (u16)(info.segments[rel.index_value].begin.addr() >> 16)); *vm::ptr::make(ADDR) = info.segments[rel.index_value].begin.addr() >> 16; break; case 6: - LOG_ERROR(LOADER, "**** RELOCATION(6): 0x%x <- 0x%x", ADDR, (u16)(info.segments[1].begin.addr() >> 16)); + LOG_WARNING(LOADER, "**** RELOCATION(6): 0x%x <- 0x%x", ADDR, (u16)(info.segments[1].begin.addr() >> 16)); *vm::ptr::make(ADDR) = info.segments[1].begin.addr() >> 16; break; @@ -330,17 +353,40 @@ namespace loader continue; } - Module* module = Emu.GetModuleManager().GetModuleByName(m.first); + Module* module = Emu.GetModuleManager().GetModuleByName(m.first.c_str()); if (!module) { - LOG_ERROR(LOADER, "unknown module '%s' in '%s' library", m.first.c_str(), info.name.c_str()); - module = new Module(-1, m.first.c_str()); + LOG_WARNING(LOADER, "Unknown module '%s' in '%s' library", m.first.c_str(), info.name.c_str()); } - for (auto &e : m.second.exports) + for (auto& f : m.second.exports) { - module->RegisterLLEFunc(e.first, vm::ptr::make(e.second)); + add_ps3_func(ModuleFunc(f.first, module, nullptr, vm::ptr::make(f.second))); + } + + for (auto& f : m.second.imports) + { + const u32 nid = f.first; + const u32 addr = f.second + info.segments[0].begin.addr(); + + u32 index; + + auto func = get_ps3_func_by_nid(nid, &index); + + if (!func) + { + LOG_ERROR(LOADER, "Unimplemented function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + + index = add_ps3_func(ModuleFunc(nid, module, nullptr)); + } + else + { + LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + } + + vm::write32(addr + 0, HACK(index)); + vm::write32(addr + 4, BLR()); } } } @@ -505,65 +551,81 @@ namespace loader for (auto stub = proc_prx_param.libstubstart; stub < proc_prx_param.libstubend; ++stub) { const std::string module_name = stub->s_modulename.get_ptr(); - Module* module = Emu.GetModuleManager().GetModuleByName(module_name); - if (module) - { - //module->SetLoaded(); - } - else + + Module* module = Emu.GetModuleManager().GetModuleByName(module_name.c_str()); + + if (!module) { LOG_WARNING(LOADER, "Unknown module '%s'", module_name.c_str()); } - struct tbl_item - { - be_t stub; - be_t rtoc; - }; + //struct tbl_item + //{ + // be_t stub; + // be_t rtoc; + //}; - struct stub_data_t - { - be_t data[3]; - } - static const stub_data = - { - be_t::make(MR(11, 2)), - be_t::make(SC(0)), - be_t::make(BLR()) - }; + //struct stub_data_t + //{ + // be_t data[3]; + //} + //static const stub_data = + //{ + // be_t::make(MR(11, 2)), + // be_t::make(SC(0)), + // be_t::make(BLR()) + //}; - const auto& tbl = vm::get().alloc(stub->s_imports); - const auto& dst = vm::get().alloc(stub->s_imports); + //const auto& tbl = vm::get().alloc(stub->s_imports); + //const auto& dst = vm::get().alloc(stub->s_imports); for (u32 i = 0; i < stub->s_imports; ++i) { const u32 nid = stub->s_nid[i]; - auto func = module ? module->GetFunc(nid) : nullptr; + const u32 addr = stub->s_text[i]; - if (!func || !func->lle_func) + u32 index; + + auto func = get_ps3_func_by_nid(nid, &index); + + if (!func) { - dst[i] = stub_data; + LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (0x%x)", SysCalls::GetHLEFuncName(nid), module_name, addr); - tbl[i].stub = (dst + i).addr(); - tbl[i].rtoc = stub->s_nid[i]; - - stub->s_text[i] = (tbl + i).addr(); - - if (module && !module->Load(nid)) - { - LOG_ERROR(LOADER, "Unimplemented function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str()); - } - else //if (Ini.HLELogging.GetValue()) - { - LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str()); - } + index = add_ps3_func(ModuleFunc(nid, module, nullptr)); } else { - stub->s_text[i] = func->lle_func.addr(); - //Is function auto exported, than we can use it - LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (LLE: 0x%x)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str(), (u32)stub->s_text[i]); + LOG_NOTICE(LOADER, "Imported %sfunction '%s' in '%s' module (0x%x)", func->lle_func ? "LLE " : "", SysCalls::GetHLEFuncName(nid), module_name, addr); } + + vm::write32(addr + 0, HACK(index)); + vm::write32(addr + 4, BLR()); + + //if (!func || !func->lle_func) + //{ + // dst[i] = stub_data; + + // tbl[i].stub = (dst + i).addr(); + // tbl[i].rtoc = stub->s_nid[i]; + + // stub->s_text[i] = (tbl + i).addr(); + + // if (!func) + // { + // + // } + // else //if (Ini.HLELogging.GetValue()) + // { + // LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (HLE)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str()); + // } + //} + //else + //{ + // stub->s_text[i] = func->lle_func.addr(); + // //Is function auto exported, than we can use it + // LOG_NOTICE(LOADER, "Imported function '%s' in '%s' module (LLE: 0x%x)", SysCalls::GetHLEFuncName(nid).c_str(), module_name.c_str(), (u32)stub->s_text[i]); + //} } } } From 1589b7269952956f85e59c72a60c2bd676281bb8 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 18 Feb 2015 19:28:09 +0300 Subject: [PATCH 18/25] Compilation fix --- rpcs3/Emu/SysCalls/Modules.cpp | 2 +- rpcs3/Emu/SysCalls/Modules.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 9e10944726..183c4271f9 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -9,7 +9,7 @@ std::vector g_ps3_func_list; -u32 add_ps3_func(ModuleFunc& func) +u32 add_ps3_func(ModuleFunc func) { for (auto& f : g_ps3_func_list) { diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index f52049a426..a2f803a95c 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -122,7 +122,7 @@ public: template __forceinline void AddFuncSub(const char group[8], const u64 ops[], const char* name, T func); }; -u32 add_ps3_func(ModuleFunc& func); +u32 add_ps3_func(ModuleFunc func); ModuleFunc* get_ps3_func_by_nid(u32 nid, u32* out_index = nullptr); ModuleFunc* get_ps3_func_by_index(u32 index); void execute_ps3_func_by_index(PPUThread& CPU, u32 id); @@ -138,7 +138,7 @@ __forceinline void Module::AddFunc(u32 id, T func) template __forceinline void Module::AddFunc(const char* name, T func) { - AddFunc(getFunctionId(name), func); + AddFunc(get_function_id(name), func); } template @@ -169,7 +169,7 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], cons void fix_import(Module* module, u32 nid, u32 addr); -#define FIX_IMPORT(module, func, addr) fix_import(module, getFunctionId(#func), addr) +#define FIX_IMPORT(module, func, addr) fix_import(module, get_function_id(#func), addr) void fix_relocs(Module* module, u32 lib, u32 start, u32 end, u32 seg2); From 91c9fd3c3cb64d38de56a755d2e9c240a5d20c90 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 18 Feb 2015 19:37:12 +0300 Subject: [PATCH 19/25] Compilation fix --- rpcs3/Emu/SysCalls/Modules.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 183c4271f9..7c038025ca 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -3,6 +3,7 @@ #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/Static.h" +#include "Emu/SysCalls/CB_FUNC.h" #include "Crypto/sha1.h" #include "ModuleManager.h" #include "Emu/Cell/PPUInstrTable.h" From 681fb1eeaaaca8ec0795f763410649c9aa734bfd Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Wed, 18 Feb 2015 23:40:04 +0530 Subject: [PATCH 20/25] PPUJIT: Support stopping/pausing threads (does not always work) --- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 63 ++++++++++++++++++++-------- rpcs3/Emu/Cell/PPULLVMRecompiler.h | 9 +++- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 7bcb074901..2d45881eaf 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -26,8 +26,10 @@ using namespace ppu_recompiler_llvm; u64 Compiler::s_rotate_mask[64][64]; bool Compiler::s_rotate_mask_inited = false; -Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block) - : m_recompilation_engine(recompilation_engine) { +Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, + const Executable execute_unknown_block, bool (*poll_status_function)(PPUThread * ppu_state)) + : m_recompilation_engine(recompilation_engine) + , m_poll_status_function(poll_status_function) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetDisassembler(); @@ -157,20 +159,21 @@ Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & } // Found an empty block + m_state.current_instruction_address = GetAddressFromBasicBlockName(block_i->getName()); + m_ir_builder->SetInsertPoint(block_i); auto exit_instr_i32 = m_ir_builder->CreatePHI(m_ir_builder->getInt32Ty(), 0); exit_instr_list.push_back(exit_instr_i32); - auto instr_address = GetAddressFromBasicBlockName(block_i->getName()); - SetPc(m_ir_builder->getInt32(instr_address)); + SetPc(m_ir_builder->getInt32(m_state.current_instruction_address)); if (generate_linkable_exits) { auto context_i64 = m_ir_builder->CreateZExt(exit_instr_i32, m_ir_builder->getInt64Ty()); context_i64 = m_ir_builder->CreateOr(context_i64, (u64)cfg.function_address << 32); - auto ret_i32 = IndirectCall(instr_address, context_i64, false); + auto ret_i32 = IndirectCall(m_state.current_instruction_address, context_i64, false); auto cmp_i1 = m_ir_builder->CreateICmpNE(ret_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(instr_address, "then"); - auto merge_bb = GetBasicBlockFromAddress(instr_address, "merge"); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_0"); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_0"); m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); m_ir_builder->SetInsertPoint(then_bb); @@ -195,8 +198,8 @@ Executable Compiler::Compile(const std::string & name, const ControlFlowGraph & if (generate_linkable_exits) { auto cmp_i1 = m_ir_builder->CreateICmpNE(exit_instr_i32, m_ir_builder->getInt32(0)); - auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then"); - auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge"); + auto then_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "then_0"); + auto merge_bb = GetBasicBlockFromAddress(0xFFFFFFFF, "merge_0"); m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); m_ir_builder->SetInsertPoint(then_bb); @@ -2011,6 +2014,15 @@ void Compiler::SC(u32 lev) { CompilationError(fmt::Format("SC %u", lev)); break; } + + auto ret_i1 = Call("PollStatus", m_poll_status_function, m_state.args[CompileTaskState::Args::State]); + auto cmp_i1 = m_ir_builder->CreateICmpEQ(ret_i1, m_ir_builder->getInt1(true)); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_true"); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_true"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + m_ir_builder->SetInsertPoint(then_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0xFFFFFFFF)); + m_ir_builder->SetInsertPoint(merge_bb); } void Compiler::B(s32 ll, u32 aa, u32 lk) { @@ -5535,7 +5547,17 @@ llvm::Value * Compiler::IndirectCall(u32 address, Value * context_i64, bool is_f auto location_i64_ptr = m_ir_builder->CreateIntToPtr(location_i64, m_ir_builder->getInt64Ty()->getPointerTo()); auto executable_i64 = m_ir_builder->CreateLoad(location_i64_ptr); auto executable_ptr = m_ir_builder->CreateIntToPtr(executable_i64, m_compiled_function_type->getPointerTo()); - return m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); + auto ret_i32 = m_ir_builder->CreateCall2(executable_ptr, m_state.args[CompileTaskState::Args::State], context_i64); + + auto cmp_i1 = m_ir_builder->CreateICmpEQ(ret_i32, m_ir_builder->getInt32(0xFFFFFFFF)); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then_all_fs"); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge_all_fs"); + m_ir_builder->CreateCondBr(cmp_i1, then_bb, merge_bb); + + m_ir_builder->SetInsertPoint(then_bb); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); + m_ir_builder->SetInsertPoint(merge_bb); + return ret_i32; } void Compiler::CompilationError(const std::string & error) { @@ -5559,7 +5581,7 @@ RecompilationEngine::RecompilationEngine() : ThreadBase("PPU Recompilation Engine") , m_log(nullptr) , m_next_ordinal(0) - , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn) { + , m_compiler(*this, ExecutionEngine::ExecuteFunction, ExecutionEngine::ExecuteTillReturn, ExecutionEngine::PollStatus) { m_compiler.RunAllTests(); } @@ -5972,12 +5994,7 @@ u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_stat execution_engine->m_tracer.Trace(Tracer::TraceType::ExitFromCompiledFunction, context >> 32, context & 0xFFFFFFFF); } - while (!terminate && !Emu.IsStopped()) { - if (Emu.IsPaused()) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - continue; - } - + while (terminate == false && PollStatus(ppu_state) == false) { auto executable = execution_engine->GetExecutable(ppu_state->PC, ExecuteTillReturn); if (executable != ExecuteTillReturn && executable != ExecuteFunction) { auto entry = ppu_state->PC; @@ -6017,6 +6034,18 @@ u32 ppu_recompiler_llvm::ExecutionEngine::ExecuteTillReturn(PPUThread * ppu_stat return 0; } +bool ppu_recompiler_llvm::ExecutionEngine::PollStatus(PPUThread * ppu_state) { + while (Emu.IsPaused() || ppu_state->IsPaused()) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + if (Emu.IsStopped() || ppu_state->IsStopped()) { + return true; + } + + return false; +} + BranchType ppu_recompiler_llvm::GetBranchTypeFromInstruction(u32 instruction) { auto type = BranchType::NonBranch; auto field1 = instruction >> 26; diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 588d9a1c47..64de33049f 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -272,7 +272,8 @@ namespace ppu_recompiler_llvm { std::chrono::nanoseconds total_time; }; - Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, const Executable execute_unknown_block); + Compiler(RecompilationEngine & recompilation_engine, const Executable execute_unknown_function, + const Executable execute_unknown_block, bool (*poll_status_function)(PPUThread * ppu_state)); Compiler(const Compiler & other) = delete; Compiler(Compiler && other) = delete; @@ -734,6 +735,9 @@ namespace ppu_recompiler_llvm { /// Recompilation engine RecompilationEngine & m_recompilation_engine; + /// The function that should be called to check the status of the thread + bool (*m_poll_status_function)(PPUThread * ppu_state); + /// The function that will be called to execute unknown functions llvm::Function * m_execute_unknown_function; @@ -1163,6 +1167,9 @@ namespace ppu_recompiler_llvm { /// Execute till the current function returns static u32 ExecuteTillReturn(PPUThread * ppu_state, u64 context); + + /// Check thread status. Returns true if the thread must exit. + static bool PollStatus(PPUThread * ppu_state); }; /// Get the branch type from a branch instruction From 4272ec7a8204c11120337f8d614eff1666ec4f03 Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Thu, 19 Feb 2015 00:37:09 +0530 Subject: [PATCH 21/25] PPUJIT: Convert tabs to spaces --- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 2 +- rpcs3/Emu/Cell/PPULLVMRecompiler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 14444eb684..621270b58a 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1999,7 +1999,7 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { } void Compiler::HACK(u32 index) { - Call("execute_ps3_func_by_index", &execute_ps3_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index)); + Call("execute_ps3_func_by_index", &execute_ps3_func_by_index, m_state.args[CompileTaskState::Args::State], m_ir_builder->getInt32(index)); } void Compiler::SC(u32 lev) { diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 18e731be13..81e28f66b6 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -470,7 +470,7 @@ namespace ppu_recompiler_llvm { void ADDI(u32 rd, u32 ra, s32 simm16) override; void ADDIS(u32 rd, u32 ra, s32 simm16) override; void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) override; - void HACK(u32 id) override; + void HACK(u32 id) override; void SC(u32 sc_code) override; void B(s32 ll, u32 aa, u32 lk) override; void MCRF(u32 crfd, u32 crfs) override; From d177b1adea075123f9f8e8c2d5435689433d3265 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Feb 2015 00:23:31 +0300 Subject: [PATCH 22/25] ARMv7: loader fixed --- Utilities/Timer.h | 8 ++-- rpcs3/Emu/ARMv7/ARMv7Decoder.cpp | 15 ++----- rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp | 27 ++++++++++--- rpcs3/Emu/ARMv7/PSVFuncList.cpp | 59 ++++++++++++++-------------- rpcs3/Emu/ARMv7/PSVFuncList.h | 17 +++++--- rpcs3/Loader/ELF32.cpp | 24 ++++++----- 6 files changed, 85 insertions(+), 65 deletions(-) diff --git a/Utilities/Timer.h b/Utilities/Timer.h index 6be99c9e52..39ccfc0104 100644 --- a/Utilities/Timer.h +++ b/Utilities/Timer.h @@ -28,22 +28,22 @@ public: double GetElapsedTimeInSec() const { - return GetElapsedTimeInMicroSec() / 1000000.0; + return double(GetElapsedTimeInMicroSec()) / 1000000.0; } double GetElapsedTimeInMilliSec() const { - return GetElapsedTimeInMicroSec() / 1000.0; + return double(GetElapsedTimeInMicroSec()) / 1000.0; } - double GetElapsedTimeInMicroSec() const + u64 GetElapsedTimeInMicroSec() const { std::chrono::high_resolution_clock::time_point now = m_stopped ? m_end : std::chrono::high_resolution_clock::now(); return std::chrono::duration_cast(now - m_start).count(); } - double GetElapsedTimeInNanoSec() const + u64 GetElapsedTimeInNanoSec() const { std::chrono::high_resolution_clock::time_point now = m_stopped ? m_end : std::chrono::high_resolution_clock::now(); diff --git a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp index 0b62114b2b..00bffb74c4 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Decoder.cpp @@ -1286,17 +1286,10 @@ void armv7_decoder_initialize(u32 addr, u32 end_addr, bool dump) // possibly a call to imported function: if (target >= end_addr && ((target - end_addr) % 16) == 0 && (instr & 0xfff000f0) == 0xe0700090) { - // check if implemented - if (const u32 func = (instr & 0xfff00) >> 4 | (instr & 0xf)) - { - // replace BLX with "HACK" instruction directly (in Thumb form), it can help to see where it was called from - vm::psv::write32(addr, 0xf870 | func << 16); - g_opct[0xf8700000 | func] = g_op4t.HACK(); - } - else - { - // leave as is if unimplemented - } + // replace BLX with "HACK" instruction directly (in Thumb form), it can help to see where it was called from + const u32 index = (instr & 0xfff00) >> 4 | (instr & 0xf); + vm::psv::write32(addr, 0xf870 | index << 16); + g_opct[0xf8700000 | index] = g_op4t.HACK(); } else { diff --git a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp index e07bbaa00b..452da44c12 100644 --- a/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp +++ b/rpcs3/Emu/ARMv7/ARMv7Interpreter.cpp @@ -503,20 +503,20 @@ void ARMv7_instrs::UNK(ARMv7Context& context, const ARMv7Code code) void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7_encoding type) { - u32 cond, func; + u32 cond, index; switch (type) { case T1: { cond = context.ITSTATE.advance(); - func = code.data & 0xffff; + index = code.data & 0xffff; break; } case A1: { cond = code.data >> 28; - func = (code.data & 0xfff00) >> 4 | (code.data & 0xf); + index = (code.data & 0xfff00) >> 4 | (code.data & 0xf); break; } default: throw __FUNCTION__; @@ -524,13 +524,30 @@ void ARMv7_instrs::HACK(ARMv7Context& context, const ARMv7Code code, const ARMv7 if (context.debug) { - if (context.debug & DF_DISASM) context.debug_str = fmt::format("hack%s %s", fmt_cond(cond), get_psv_func_by_index(func)->name); + if (context.debug & DF_DISASM) + { + if (auto func = get_psv_func_by_index(index)) + { + if (func->func) + { + context.debug_str = fmt::format("hack%s %s", fmt_cond(cond), func->name); + } + else + { + context.debug_str = fmt::format("hack%s UNIMPLEMENTED:0x%08X (%s)", fmt_cond(cond), func->nid, func->name); + } + } + else + { + context.debug_str = fmt::format("hack%s %d", fmt_cond(cond), index); + } + } if (process_debug(context)) return; } if (ConditionPassed(context, cond)) { - execute_psv_func_by_index(context, func); + execute_psv_func_by_index(context, index); } } diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.cpp b/rpcs3/Emu/ARMv7/PSVFuncList.cpp index 763b36d4af..fdbad45cad 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.cpp +++ b/rpcs3/Emu/ARMv7/PSVFuncList.cpp @@ -5,30 +5,50 @@ std::vector g_psv_func_list; std::vector g_psv_modules; -void add_psv_func(psv_func& data) +u32 add_psv_func(psv_func data) { for (auto& f : g_psv_func_list) { - if (f.nid == data.nid && &f - g_psv_func_list.data() >= 2 /* special functions count */) + if (f.nid == data.nid) { + const u32 index = (u32)(&f - g_psv_func_list.data()); + + if (index < SFI_MAX) + { + continue; + } + if (data.func) { f.func = data.func; } - return; + return index; } } g_psv_func_list.push_back(data); + return (u32)(g_psv_func_list.size() - 1); } -const psv_func* get_psv_func_by_nid(u32 nid) +psv_func* get_psv_func_by_nid(u32 nid, u32* out_index) { for (auto& f : g_psv_func_list) { - if (f.nid == nid && &f - g_psv_func_list.data() >= 2 /* special functions count */) + if (f.nid == nid && &f - g_psv_func_list.data()) { + const u32 index = (u32)(&f - g_psv_func_list.data()); + + if (index < SFI_MAX) + { + continue; + } + + if (out_index) + { + *out_index = index; + } + return &f; } } @@ -36,19 +56,7 @@ const psv_func* get_psv_func_by_nid(u32 nid) return nullptr; } -u32 get_psv_func_index(const psv_func* func) -{ - auto res = func - g_psv_func_list.data(); - - if ((size_t)res >= g_psv_func_list.size()) - { - throw __FUNCTION__; - } - - return (u32)res; -} - -const psv_func* get_psv_func_by_index(u32 index) +psv_func* get_psv_func_by_index(u32 index) { if (index >= g_psv_func_list.size()) { @@ -210,24 +218,15 @@ void initialize_psv_modules() g_psv_modules.push_back(&sceXml); // setup special functions (without NIDs) - psv_func unimplemented; - unimplemented.nid = 0; - unimplemented.name = "UNIMPLEMENTED"; - unimplemented.func.reset(new psv_func_detail::func_binder([](ARMv7Context& context) - { - context.thread.m_last_syscall = vm::psv::read32(context.thread.PC + 4); - throw "Unimplemented function"; - })); - g_psv_func_list.push_back(unimplemented); + g_psv_func_list.resize(SFI_MAX); - psv_func hle_return; - hle_return.nid = 1; + psv_func& hle_return = g_psv_func_list[SFI_HLE_RETURN]; + hle_return.nid = 0; hle_return.name = "HLE_RETURN"; hle_return.func.reset(new psv_func_detail::func_binder([](ARMv7Context& context) { context.thread.FastStop(); })); - g_psv_func_list.push_back(hle_return); // load functions for (auto module : g_psv_modules) diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 34cd990c93..ed2d9217a8 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -478,8 +478,15 @@ struct psv_func psv_log_base* module; // Module for information }; +enum psv_special_function_index : u16 +{ + SFI_HLE_RETURN, + + SFI_MAX +}; + // Do not call directly -void add_psv_func(psv_func& data); +u32 add_psv_func(psv_func data); // Do not call directly template void reg_psv_func(u32 nid, psv_log_base* module, const char* name, RT(*func)(T...)) { @@ -491,12 +498,10 @@ template void reg_psv_func(u32 nid, psv_log_base* mo add_psv_func(f); } -// Find registered HLE function by its ID -const psv_func* get_psv_func_by_nid(u32 nid); -// Get index of registered HLE function -u32 get_psv_func_index(const psv_func* func); +// Find registered HLE function by NID +psv_func* get_psv_func_by_nid(u32 nid, u32* out_index = nullptr); // Find registered HLE function by its index -const psv_func* get_psv_func_by_index(u32 index); +psv_func* get_psv_func_by_index(u32 index); // Execute registered HLE function by its index void execute_psv_func_by_index(ARMv7Context& context, u32 index); // Register all HLE functions diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index a118451126..42de280949 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -134,7 +134,7 @@ namespace loader auto armv7_thr_stop_data = vm::psv::ptr::make(Memory.PSV.RAM.AllocAlign(3 * 4)); armv7_thr_stop_data[0] = 0xf870; // HACK instruction (Thumb) - armv7_thr_stop_data[1] = 0x0001; // index 1 + armv7_thr_stop_data[1] = SFI_HLE_RETURN; Emu.SetCPUThreadStop(armv7_thr_stop_data.addr()); u32 entry = 0; // actual entry point (ELFs entry point is ignored) @@ -228,28 +228,34 @@ namespace loader const u32 nid = fnid[j]; const u32 addr = fstub[j]; - if (auto func = get_psv_func_by_nid(nid)) + u32 index; + + if (auto func = get_psv_func_by_nid(nid, &index)) { if (func->module) { - func->module->Notice("Imported function %s (nid=0x%08x, addr=0x%x)", func->name, nid, addr); + LOG_NOTICE(LOADER, "Imported function '%s' in module '%s' (nid=0x%08x, addr=0x%x)", func->name, func->module->GetName(), nid, addr); } else { - LOG_NOTICE(LOADER, "Imported function %s (nid=0x%08x, addr=0x%x)", func->name, nid, addr); + LOG_NOTICE(LOADER, "Imported function '%s' (nid=0x%08x, addr=0x%x)", func->name, nid, addr); } - - const u32 code = get_psv_func_index(func); - vm::psv::write32(addr + 0, 0xe0700090 | (code & 0xfff0) << 4 | (code & 0xf)); // HACK instruction (ARM) } else { LOG_ERROR(LOADER, "Unknown function 0x%08x (addr=0x%x)", nid, addr); - vm::psv::write32(addr + 0, 0xe0700090); // HACK instruction (ARM), unimplemented stub (code 0) - vm::psv::write32(addr + 4, nid); // nid + psv_func unimplemented; + unimplemented.nid = nid; + unimplemented.module = nullptr; + unimplemented.name = "UNKNOWN"; // TODO: set correct name if possible + unimplemented.func = nullptr; + + index = add_psv_func(unimplemented); } + vm::psv::write32(addr + 0, 0xe0700090 | (index & 0xfff0) << 4 | (index & 0xf)); // HACK instruction (ARM) + code_end = std::min(addr, code_end); } } From e84fc6426cad7c273e03f5f27c5102fbf142fa40 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Feb 2015 01:54:31 +0300 Subject: [PATCH 23/25] PRX_DEBUG removed --- rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp | 144 +-- rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp | 273 +----- rpcs3/Emu/SysCalls/Modules/cellPngDec.h | 58 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp | 1003 ++++---------------- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 4 +- rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp | 479 ++-------- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 152 +-- rpcs3/Emu/SysCalls/Modules/cellSync2.cpp | 263 +---- 8 files changed, 361 insertions(+), 2015 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp index ed3c645231..0427de1bc3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp @@ -7,65 +7,44 @@ extern Module cellAtrac; #include "cellAtrac.h" -#ifdef PRX_DEBUG -#include "prx_libatrac3plus.h" -u32 libatrac3plus; -u32 libatrac3plus_rtoc; -#endif - -s64 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) +s32 cellAtracSetDataAndGetMemSize(vm::ptr pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr puiWorkMemByte) { cellAtrac.Warning("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)", pHandle.addr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x11F4, libatrac3plus_rtoc); -#endif *puiWorkMemByte = 0x1000; // unproved return CELL_OK; } -s64 cellAtracCreateDecoder(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) +s32 cellAtracCreateDecoder(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) { cellAtrac.Warning("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0FF0, libatrac3plus_rtoc); -#endif pHandle->data.pucWorkMem_addr = pucWorkMem_addr; return CELL_OK; } -s64 cellAtracCreateDecoderExt(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr pExtRes) +s32 cellAtracCreateDecoderExt(vm::ptr pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, vm::ptr pExtRes) { cellAtrac.Warning("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)", pHandle.addr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0DB0, libatrac3plus_rtoc); -#endif pHandle->data.pucWorkMem_addr = pucWorkMem_addr; return CELL_OK; } -s64 cellAtracDeleteDecoder(vm::ptr pHandle) +s32 cellAtracDeleteDecoder(vm::ptr pHandle) { cellAtrac.Warning("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0D08, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr puiSamples, vm::ptr puiFinishflag, vm::ptr piRemainFrame) +s32 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr puiSamples, vm::ptr puiFinishflag, vm::ptr piRemainFrame) { cellAtrac.Warning("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), pfOutAddr, puiSamples.addr(), puiFinishflag.addr(), piRemainFrame.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x09A8, libatrac3plus_rtoc); -#endif *puiSamples = 0; *puiFinishflag = 1; @@ -73,13 +52,10 @@ s64 cellAtracDecode(vm::ptr pHandle, u32 pfOutAddr, vm::ptr pHandle, vm::ptr ppucWritePointer, vm::ptr puiWritableByte, vm::ptr puiReadPosition) +s32 cellAtracGetStreamDataInfo(vm::ptr pHandle, vm::ptr ppucWritePointer, vm::ptr puiWritableByte, vm::ptr puiReadPosition) { cellAtrac.Warning("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)", pHandle.addr(), ppucWritePointer.addr(), puiWritableByte.addr(), puiReadPosition.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0BE8, libatrac3plus_rtoc); -#endif *ppucWritePointer = pHandle->data.pucWorkMem_addr; *puiWritableByte = 0x1000; @@ -87,112 +63,82 @@ s64 cellAtracGetStreamDataInfo(vm::ptr pHandle, vm::ptr pp return CELL_OK; } -s64 cellAtracAddStreamData(vm::ptr pHandle, u32 uiAddByte) +s32 cellAtracAddStreamData(vm::ptr pHandle, u32 uiAddByte) { cellAtrac.Warning("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.addr(), uiAddByte); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0AFC, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRemainFrame) +s32 cellAtracGetRemainFrame(vm::ptr pHandle, vm::ptr piRemainFrame) { cellAtrac.Warning("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.addr(), piRemainFrame.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x092C, libatrac3plus_rtoc); -#endif *piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY; return CELL_OK; } -s64 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVacantSize) +s32 cellAtracGetVacantSize(vm::ptr pHandle, vm::ptr puiVacantSize) { cellAtrac.Warning("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.addr(), puiVacantSize.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x08B0, libatrac3plus_rtoc); -#endif *puiVacantSize = 0x1000; return CELL_OK; } -s64 cellAtracIsSecondBufferNeeded(vm::ptr pHandle) +s32 cellAtracIsSecondBufferNeeded(vm::ptr pHandle) { cellAtrac.Warning("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0010, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracGetSecondBufferInfo(vm::ptr pHandle, vm::ptr puiReadPosition, vm::ptr puiDataByte) +s32 cellAtracGetSecondBufferInfo(vm::ptr pHandle, vm::ptr puiReadPosition, vm::ptr puiDataByte) { cellAtrac.Warning("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)", pHandle.addr(), puiReadPosition.addr(), puiDataByte.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x07E8, libatrac3plus_rtoc); -#endif *puiReadPosition = 0; *puiDataByte = 0; // write to null block will occur return CELL_OK; } -s64 cellAtracSetSecondBuffer(vm::ptr pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte) +s32 cellAtracSetSecondBuffer(vm::ptr pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte) { cellAtrac.Warning("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)", pHandle.addr(), pucSecondBufferAddr, uiSecondBufferByte); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0704, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChannel) +s32 cellAtracGetChannel(vm::ptr pHandle, vm::ptr puiChannel) { cellAtrac.Warning("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.addr(), puiChannel.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0060, libatrac3plus_rtoc); -#endif *puiChannel = 2; return CELL_OK; } -s64 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxSample) +s32 cellAtracGetMaxSample(vm::ptr pHandle, vm::ptr puiMaxSample) { cellAtrac.Warning("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.addr(), puiMaxSample.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x00AC, libatrac3plus_rtoc); -#endif *puiMaxSample = 512; return CELL_OK; } -s64 cellAtracGetNextSample(vm::ptr pHandle, vm::ptr puiNextSample) +s32 cellAtracGetNextSample(vm::ptr pHandle, vm::ptr puiNextSample) { cellAtrac.Warning("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.addr(), puiNextSample.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0688, libatrac3plus_rtoc); -#endif *puiNextSample = 0; return CELL_OK; } -s64 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSample, vm::ptr piLoopStartSample, vm::ptr piLoopEndSample) +s32 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSample, vm::ptr piLoopStartSample, vm::ptr piLoopEndSample) { cellAtrac.Warning("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)", pHandle.addr(), piEndSample.addr(), piLoopStartSample.addr(), piLoopEndSample.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0104, libatrac3plus_rtoc); -#endif *piEndSample = 0; *piLoopStartSample = 0; @@ -200,60 +146,45 @@ s64 cellAtracGetSoundInfo(vm::ptr pHandle, vm::ptr piEndSa return CELL_OK; } -s64 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr puiSamplePosition) +s32 cellAtracGetNextDecodePosition(vm::ptr pHandle, vm::ptr puiSamplePosition) { cellAtrac.Warning("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)", pHandle.addr(), puiSamplePosition.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0190, libatrac3plus_rtoc); -#endif *puiSamplePosition = 0; return CELL_ATRAC_ERROR_ALLDATA_WAS_DECODED; } -s64 cellAtracGetBitrate(vm::ptr pHandle, vm::ptr puiBitrate) +s32 cellAtracGetBitrate(vm::ptr pHandle, vm::ptr puiBitrate) { cellAtrac.Warning("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)", pHandle.addr(), puiBitrate.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x0374, libatrac3plus_rtoc); -#endif *puiBitrate = 128; return CELL_OK; } -s64 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNum, vm::ptr puiLoopStatus) +s32 cellAtracGetLoopInfo(vm::ptr pHandle, vm::ptr piLoopNum, vm::ptr puiLoopStatus) { cellAtrac.Warning("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)", pHandle.addr(), piLoopNum.addr(), puiLoopStatus.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x025C, libatrac3plus_rtoc); -#endif *piLoopNum = 0; *puiLoopStatus = 0; return CELL_OK; } -s64 cellAtracSetLoopNum(vm::ptr pHandle, int iLoopNum) +s32 cellAtracSetLoopNum(vm::ptr pHandle, int iLoopNum) { cellAtrac.Warning("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.addr(), iLoopNum); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x1538, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiSample, vm::ptr pBufferInfo) +s32 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiSample, vm::ptr pBufferInfo) { cellAtrac.Warning("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)", pHandle.addr(), uiSample, pBufferInfo.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x05BC, libatrac3plus_rtoc); -#endif pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr; pBufferInfo->uiWritableByte = 0x1000; @@ -262,24 +193,18 @@ s64 cellAtracGetBufferInfoForResetting(vm::ptr pHandle, u32 uiS return CELL_OK; } -s64 cellAtracResetPlayPosition(vm::ptr pHandle, u32 uiSample, u32 uiWriteByte) +s32 cellAtracResetPlayPosition(vm::ptr pHandle, u32 uiSample, u32 uiWriteByte) { cellAtrac.Warning("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)", pHandle.addr(), uiSample, uiWriteByte); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x04E4, libatrac3plus_rtoc); -#endif return CELL_OK; } -s64 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr piResult) +s32 cellAtracGetInternalErrorInfo(vm::ptr pHandle, vm::ptr piResult) { cellAtrac.Warning("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)", pHandle.addr(), piResult.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libatrac3plus + 0x02E4, libatrac3plus_rtoc); -#endif *piResult = 0; return CELL_OK; @@ -317,27 +242,4 @@ Module cellAtrac("cellAtrac", []() cellAtrac.AddFunc(0x7772eb2b, cellAtracResetPlayPosition); cellAtrac.AddFunc(0xb5c11938, cellAtracGetInternalErrorInfo); - -#ifdef PRX_DEBUG - CallAfter([]() - { - if (!Memory.MainMem.GetStartAddr()) return; - - libatrac3plus = (u32)Memory.MainMem.AllocAlign(sizeof(libatrac3plus_data), 0x100000); - memcpy(vm::get_ptr(libatrac3plus), libatrac3plus_data, sizeof(libatrac3plus_data)); - libatrac3plus_rtoc = libatrac3plus + 0xBED0; - - extern Module* cellAdec; - - FIX_IMPORT(cellAdec, cellAdecDecodeAu, libatrac3plus + 0x399C); - FIX_IMPORT(cellAdec, cellAdecStartSeq, libatrac3plus + 0x39BC); - FIX_IMPORT(cellAdec, cellAdecQueryAttr, libatrac3plus + 0x39DC); - FIX_IMPORT(cellAdec, cellAdecClose, libatrac3plus + 0x39FC); - FIX_IMPORT(cellAdec, cellAdecGetPcm, libatrac3plus + 0x3A1C); - FIX_IMPORT(cellAdec, cellAdecOpen, libatrac3plus + 0x3A3C); - fix_import(cellAdec, 0xDF982D2C, libatrac3plus + 0x3A5C); - - fix_relocs(cellAtrac, libatrac3plus, 0x3EF0, 0x5048, 0x3CE0); - }); -#endif }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 7607bf0236..539161c412 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -10,15 +10,7 @@ extern Module cellPngDec; -#undef PRX_DEBUG - -#ifdef PRX_DEBUG -#include "prx_libpngdec.h" -u32 libpngdec; -u32 libpngdec_rtoc; -#endif - -s64 pngDecCreate( +s32 pngDecCreate( vm::ptr mainHandle, vm::ptr param, vm::ptr ext = vm::ptr::make(0)) @@ -47,7 +39,7 @@ s64 pngDecCreate( return CELL_OK; } -s64 pngDecDestroy(CellPngDecMainHandle dec) +s32 pngDecDestroy(CellPngDecMainHandle dec) { if (!Memory.Free(dec.addr())) { @@ -57,7 +49,7 @@ s64 pngDecDestroy(CellPngDecMainHandle dec) return CELL_OK; } -s64 pngDecOpen( +s32 pngDecOpen( CellPngDecMainHandle dec, vm::ptr subHandle, vm::ptr src, @@ -117,7 +109,7 @@ s64 pngDecOpen( return CELL_OK; } -s64 pngDecClose(CellPngDecSubHandle stream) +s32 pngDecClose(CellPngDecSubHandle stream) { cellFsClose(stream->fd); if (!Memory.Free(stream.addr())) @@ -128,7 +120,7 @@ s64 pngDecClose(CellPngDecSubHandle stream) return CELL_OK; } -s64 pngReadHeader( +s32 pngReadHeader( CellPngDecSubHandle stream, vm::ptr info, vm::ptr extInfo = vm::ptr::make(0)) @@ -191,7 +183,7 @@ s64 pngReadHeader( return CELL_OK; } -s64 pngDecSetParameter( +s32 pngDecSetParameter( CellPngDecSubHandle stream, vm::ptr inParam, vm::ptr outParam, @@ -236,7 +228,7 @@ s64 pngDecSetParameter( return CELL_OK; } -s64 pngDecodeData( +s32 pngDecodeData( CellPngDecSubHandle stream, vm::ptr data, vm::ptr dataCtrlParam, @@ -365,13 +357,8 @@ s64 pngDecodeData( return CELL_OK; } -s64 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam) +s32 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - const_cast(*threadInParam).spuThreadEnable = CELL_PNGDEC_SPU_THREAD_DISABLE; // hack - return GetCurrentPPUThread().FastCall2(libpngdec + 0x295C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", mainHandle.addr(), threadInParam.addr(), threadOutParam.addr()); @@ -382,20 +369,15 @@ s64 cellPngDecCreate(vm::ptr mainHandle, vm::ptrpngCodecVersion = PNGDEC_CODEC_VERSION; return CELL_OK; -#endif } -s64 cellPngDecExtCreate( +s32 cellPngDecExtCreate( vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam, vm::ptr extThreadInParam, vm::ptr extThreadOutParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x296C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)", mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr()); @@ -408,41 +390,30 @@ s64 cellPngDecExtCreate( extThreadOutParam->reserved = 0; return CELL_OK; -#endif } -s64 cellPngDecDestroy(CellPngDecMainHandle mainHandle) +s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x1E6C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr()); // destroy decoder return pngDecDestroy(mainHandle); -#endif } -s64 cellPngDecOpen( +s32 cellPngDecOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F3C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr()); // create stream handle return pngDecOpen(mainHandle, subHandle, src, openInfo); -#endif } -s64 cellPngDecExtOpen( +s32 cellPngDecExtOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, vm::ptr src, @@ -450,78 +421,53 @@ s64 cellPngDecExtOpen( vm::ptr cbCtrlStrm, vm::ptr opnParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x3F34, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr(), cbCtrlStrm.addr(), opnParam.addr()); // create stream handle return pngDecOpen(mainHandle, subHandle, src, openInfo, cbCtrlStrm, opnParam); -#endif } -s64 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle) +s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x066C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr()); return pngDecClose(subHandle); -#endif } -s64 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info) +s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A3C, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle.addr(), subHandle.addr(), info.addr()); return pngReadHeader(subHandle, info); -#endif } -s64 cellPngDecExtReadHeader( +s32 cellPngDecExtReadHeader( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info, vm::ptr extInfo) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x3A34, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), info.addr(), extInfo.addr()); return pngReadHeader(subHandle, info, extInfo); -#endif } -s64 cellPngDecSetParameter( +s32 cellPngDecSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr inParam, vm::ptr outParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x33F4, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr()); return pngDecSetParameter(subHandle, inParam, outParam); -#endif } -s64 cellPngDecExtSetParameter( +s32 cellPngDecExtSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr inParam, @@ -529,36 +475,26 @@ s64 cellPngDecExtSetParameter( vm::ptr extInParam, vm::ptr extOutParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x33EC, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x", mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr(), extInParam.addr(), extOutParam.addr()); return pngDecSetParameter(subHandle, inParam, outParam, extInParam, extOutParam); -#endif } -s64 cellPngDecDecodeData( +s32 cellPngDecDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D40, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo); -#endif } -s64 cellPngDecExtDecodeData( +s32 cellPngDecExtDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, @@ -567,210 +503,120 @@ s64 cellPngDecExtDecodeData( vm::ptr cbCtrlDisp, vm::ptr dispParam) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x5D38, libpngdec_rtoc); -#else cellPngDec.Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam_addr=0x%x)", mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr(), cbCtrlDisp.addr(), dispParam.addr()); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo, cbCtrlDisp, dispParam); -#endif } -s64 cellPngDecGetUnknownChunks( +s32 cellPngDecGetUnknownChunks( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr> unknownChunk, vm::ptr unknownChunkNumber) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x03EC, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal) +s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0730, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm) +s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0894, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal) +s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x09EC, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys) +s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0B14, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs) +s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0C58, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt) +s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0D9C, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd) +s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x0ED0, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time) +s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x1024, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist) +s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x116C, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns) +s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x12A4, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit) +s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x1420, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp) +s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x1574, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb) +s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x16B4, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama) +s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x17CC, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte) +s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x18E4, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } -s64 cellPngDecGetTextChunk( +s32 cellPngDecGetTextChunk( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr textInfoNum, vm::ptr> textInfo) { -#ifdef PRX_DEBUG - cellPngDec.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libpngdec + 0x19FC, libpngdec_rtoc); -#else UNIMPLEMENTED_FUNC(cellPngDec); return CELL_OK; -#endif } Module cellPngDec("cellPngDec", []() @@ -804,51 +650,4 @@ Module cellPngDec("cellPngDec", []() REG_FUNC(cellPngDec, cellPngDecOpen); REG_FUNC(cellPngDec, cellPngDecExtDecodeData); REG_FUNC(cellPngDec, cellPngDecDecodeData); - -#ifdef PRX_DEBUG - CallAfter([]() - { - if (!Memory.MainMem.GetStartAddr()) return; - - libpngdec = (u32)Memory.MainMem.AllocAlign(sizeof(libpngdec_data), 0x100000); - memcpy(vm::get_ptr(libpngdec), libpngdec_data, sizeof(libpngdec_data)); - libpngdec_rtoc = libpngdec + 0x49710; - - extern Module* sysPrxForUser; - extern Module* cellSpurs; - extern Module* sys_fs; - - FIX_IMPORT(sysPrxForUser, _sys_snprintf , libpngdec + 0x1E6D0); - FIX_IMPORT(sysPrxForUser, _sys_strlen , libpngdec + 0x1E6F0); - fix_import(sysPrxForUser, 0x3EF17F8C , libpngdec + 0x1E710); - FIX_IMPORT(sysPrxForUser, _sys_memset , libpngdec + 0x1E730); - FIX_IMPORT(sysPrxForUser, _sys_memcpy , libpngdec + 0x1E750); - FIX_IMPORT(sysPrxForUser, _sys_strcpy , libpngdec + 0x1E770); - FIX_IMPORT(sysPrxForUser, _sys_strncpy , libpngdec + 0x1E790); - FIX_IMPORT(sysPrxForUser, _sys_memcmp , libpngdec + 0x1E7B0); - FIX_IMPORT(cellSpurs, cellSpursQueueDetachLv2EventQueue , libpngdec + 0x1E7D0); - FIX_IMPORT(cellSpurs, cellSpursAttributeSetNamePrefix , libpngdec + 0x1E7F0); - FIX_IMPORT(cellSpurs, _cellSpursQueueInitialize , libpngdec + 0x1E810); - FIX_IMPORT(cellSpurs, _cellSpursTasksetAttributeInitialize, libpngdec + 0x1E830); - FIX_IMPORT(cellSpurs, cellSpursTasksetAttributeSetName , libpngdec + 0x1E850); - FIX_IMPORT(cellSpurs, cellSpursTaskGetReadOnlyAreaPattern , libpngdec + 0x1E870); - FIX_IMPORT(cellSpurs, cellSpursTaskGetContextSaveAreaSize , libpngdec + 0x1E890); - FIX_IMPORT(cellSpurs, cellSpursQueuePopBody , libpngdec + 0x1E8B0); - FIX_IMPORT(cellSpurs, cellSpursQueuePushBody , libpngdec + 0x1E8D0); - FIX_IMPORT(cellSpurs, _cellSpursAttributeInitialize , libpngdec + 0x1E8F0); - FIX_IMPORT(cellSpurs, cellSpursJoinTaskset , libpngdec + 0x1E910); - FIX_IMPORT(cellSpurs, cellSpursShutdownTaskset , libpngdec + 0x1E930); - FIX_IMPORT(cellSpurs, cellSpursInitializeWithAttribute , libpngdec + 0x1E950); - FIX_IMPORT(cellSpurs, cellSpursCreateTask , libpngdec + 0x1E970); - FIX_IMPORT(cellSpurs, cellSpursCreateTasksetWithAttribute , libpngdec + 0x1E990); - FIX_IMPORT(cellSpurs, cellSpursFinalize , libpngdec + 0x1E9B0); - FIX_IMPORT(cellSpurs, cellSpursQueueAttachLv2EventQueue , libpngdec + 0x1E9D0); - FIX_IMPORT(sys_fs, cellFsClose , libpngdec + 0x1E9F0); - FIX_IMPORT(sys_fs, cellFsRead , libpngdec + 0x1EA10); - FIX_IMPORT(sys_fs, cellFsOpen , libpngdec + 0x1EA30); - FIX_IMPORT(sys_fs, cellFsLseek , libpngdec + 0x1EA50); - - fix_relocs(cellPngDec, libpngdec, 0x41C30, 0x47AB0, 0x40A00); - }); -#endif }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h index 86170f7508..361d83fe07 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.h @@ -183,77 +183,77 @@ struct CellPngDecDataOutInfo }; // Functions -s64 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam); +s32 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam); -s64 cellPngDecExtCreate( +s32 cellPngDecExtCreate( vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam, vm::ptr extThreadInParam, vm::ptr extThreadOutParam); -s64 cellPngDecOpen( +s32 cellPngDecOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo); -s64 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info); +s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info); -s64 cellPngDecSetParameter( +s32 cellPngDecSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr inParam, vm::ptr outParam); -s64 cellPngDecDecodeData( +s32 cellPngDecDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo); -s64 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle); +s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle); -s64 cellPngDecDestroy(CellPngDecMainHandle mainHandle); +s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle); -s64 cellPngDecGetTextChunk( +s32 cellPngDecGetTextChunk( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr textInfoNum, vm::ptr> textInfo); -s64 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte); +s32 cellPngDecGetPLTE(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr plte); -s64 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama); +s32 cellPngDecGetgAMA(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr gama); -s64 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb); +s32 cellPngDecGetsRGB(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr srgb); -s64 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp); +s32 cellPngDecGetiCCP(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr iccp); -s64 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit); +s32 cellPngDecGetsBIT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr sbit); -s64 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns); +s32 cellPngDecGettRNS(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr trns); -s64 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist); +s32 cellPngDecGethIST(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr hist); -s64 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time); +s32 cellPngDecGettIME(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr time); -s64 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd); +s32 cellPngDecGetbKGD(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr bkgd); -s64 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt); +s32 cellPngDecGetsPLT(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr splt); -s64 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs); +s32 cellPngDecGetoFFs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr offs); -s64 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys); +s32 cellPngDecGetpHYs(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr phys); -s64 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal); +s32 cellPngDecGetsCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr scal); -s64 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm); +s32 cellPngDecGetcHRM(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr chrm); -s64 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal); +s32 cellPngDecGetpCAL(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr pcal); -s64 cellPngDecGetUnknownChunks( +s32 cellPngDecGetUnknownChunks( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr> unknownChunk, @@ -345,7 +345,7 @@ struct CellPngDecCbCtrlDisp }; // Functions -s64 cellPngDecExtOpen( +s32 cellPngDecExtOpen( CellPngDecMainHandle mainHandle, vm::ptr subHandle, vm::ptr src, @@ -353,13 +353,13 @@ s64 cellPngDecExtOpen( vm::ptr cbCtrlStrm, vm::ptr opnParam); -s64 cellPngDecExtReadHeader( +s32 cellPngDecExtReadHeader( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info, vm::ptr extInfo); -s64 cellPngDecExtSetParameter( +s32 cellPngDecExtSetParameter( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr inParam, @@ -367,7 +367,7 @@ s64 cellPngDecExtSetParameter( vm::ptr extInParam, vm::ptr extOutParam); -s64 cellPngDecExtDecodeData( +s32 cellPngDecExtDecodeData( CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr data, diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index 54422a30a4..86f2d01add 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -21,39 +21,26 @@ extern Module cellSpurs; -#ifdef PRX_DEBUG -extern u32 libsre; -extern u32 libsre_rtoc; -#endif - bool spursKernelEntry(SPUThread & spu); -s64 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id); -s64 _cellSpursSendSignal(vm::ptr taskset, u32 taskID); +s32 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id); +s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskID); -s64 spursCreateLv2EventQueue(vm::ptr spurs, u32& queue_id, vm::ptr port, s32 size, u64 name_u64) +s32 spursCreateLv2EventQueue(vm::ptr spurs, u32& queue_id, vm::ptr port, s32 size, u64 name_u64) { -#ifdef PRX_DEBUG_XXX - vm::var> queue; - s32 res = cb_call, vm::ptr>, vm::ptr, s32, u32>(GetCurrentPPUThread(), libsre + 0xB14C, libsre_rtoc, - spurs, queue, port, size, vm::read32(libsre_rtoc - 0x7E2C)); - queue_id = queue.value(); - return res; -#endif - queue_id = event_queue_create(SYS_SYNC_FIFO, SYS_PPU_QUEUE, name_u64, 0, size); if (!queue_id) { return CELL_EAGAIN; // rough } - if (s32 res = (s32)spursAttachLv2EventQueue(spurs, queue_id, port, 1, true)) + if (s32 res = spursAttachLv2EventQueue(spurs, queue_id, port, 1, true)) { assert(!"spursAttachLv2EventQueue() failed"); } return CELL_OK; } -s64 spursInit( +s32 spursInit( vm::ptr spurs, const u32 revision, const u32 sdkVersion, @@ -68,11 +55,6 @@ s64 spursInit( const u32 swlMaxSpu, const u32 swlIsPreem) { -#ifdef PRX_DEBUG_XXX - return cb_call, u32, u32, s32, s32, s32, u32, u32, u32, u32, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x74E4, libsre_rtoc, - spurs, revision, sdkVersion, nSpus, spuPriority, ppuPriority, flags, vm::get_addr(prefix), prefixSize, container, vm::get_addr(swlPriority), swlMaxSpu, swlIsPreem); -#endif - // SPURS initialization (asserts should actually rollback and return the error instead) if (!spurs) @@ -117,12 +99,7 @@ s64 spursInit( } // default or system workload: -#ifdef PRX_DEBUG - spurs->m.wklInfoSysSrv.addr.set(be_t::make(vm::read32(libsre_rtoc - 0x7EA4))); - spurs->m.wklInfoSysSrv.size = 0x2200; -#else spurs->m.wklInfoSysSrv.addr.set(be_t::make(SPURS_IMG_ADDR_SYS_SRV_WORKLOAD)); -#endif spurs->m.wklInfoSysSrv.arg = 0; spurs->m.wklInfoSysSrv.uniqueId.write_relaxed(0xff); u32 sem; @@ -149,15 +126,9 @@ s64 spursInit( spurs->m.unk13 = 0; spurs->m.nSpus = nSpus; spurs->m.spuPriority = spuPriority; -#ifdef PRX_DEBUG - if (s32 res = spu_image_import(spurs->m.spuImg, vm::read32(libsre_rtoc - (isSecond ? 0x7E94 : 0x7E98)), 1)) - { - assert(!"spu_image_import() failed"); - } -#else - spurs->m.spuImg.addr = (u32)Memory.Alloc(0x40000, 4096); + + spurs->m.spuImg.addr = Memory.MainMem.AllocAlign(0x40000, 4096); spurs->m.spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; -#endif s32 tgt = SYS_SPU_THREAD_GROUP_TYPE_NORMAL; if (flags & SAF_SPU_TGT_EXCLUSIVE_NON_CONTEXT) @@ -181,9 +152,9 @@ s64 spursInit( for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++) { auto spu = spu_thread_initialize(tg, num, spurs->m.spuImg, name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0); -#ifndef PRX_DEBUG_XXX + spu->RegisterHleFunction(spurs->m.spuImg.entry_point, spursKernelEntry); -#endif + spurs->m.spus[num] = spu->GetId(); } @@ -215,7 +186,7 @@ s64 spursInit( spurs->m.ppuPriority = ppuPriority; u32 queue; - if (s32 res = (s32)spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv")) + if (s32 res = spursCreateLv2EventQueue(spurs, queue, vm::ptr::make(spurs.addr() + 0xc9), 0x2a, *(u64*)"_spuPrv")) { assert(!"spursCreateLv2EventQueue() failed"); } @@ -234,10 +205,6 @@ s64 spursInit( spurs->m.ppu0 = ppu_thread_create(0, 0, ppuPriority, 0x4000, true, false, name + "SpursHdlr0", [spurs](PPUThread& CPU) { -#ifdef PRX_DEBUG_XXX - return cb_call>(CPU, libsre + 0x9214, libsre_rtoc, spurs); -#endif - if (spurs->m.flags & SAF_UNKNOWN_FLAG_30) { return; @@ -366,9 +333,7 @@ s64 spursInit( spurs->m.ppu1 = ppu_thread_create(0, 0, ppuPriority, 0x8000, true, false, name + "SpursHdlr1", [spurs](PPUThread& CPU) { -#ifdef PRX_DEBUG - return cb_call>(CPU, libsre + 0xB40C, libsre_rtoc, spurs); -#endif + // TODO })->GetId(); @@ -392,10 +357,7 @@ s64 spursInit( if (flags & SAF_SYSTEM_WORKLOAD_ENABLED) // initialize system workload (disabled) { s32 res = CELL_OK; -#ifdef PRX_DEBUG_XXX - res = cb_call, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x10428, libsre_rtoc, - spurs, vm::get_addr(swlPriority), swlMaxSpu, swlIsPreem); -#endif + // TODO assert(res == CELL_OK); } else if (flags & SAF_EXIT_IF_NO_WORK) // wakeup @@ -406,13 +368,10 @@ s64 spursInit( return CELL_OK; } -s64 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) +s32 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { cellSpurs.Warning("cellSpursInitialize(spurs_addr=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", spurs.addr(), nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x8480, libsre_rtoc); -#endif return spursInit( spurs, @@ -430,12 +389,9 @@ s64 cellSpursInitialize(vm::ptr spurs, s32 nSpus, s32 spuPriority, s3 0); } -s64 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptr attr) +s32 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptr attr) { cellSpurs.Warning("cellSpursInitializeWithAttribute(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x839C, libsre_rtoc); -#endif if (!attr) { @@ -466,12 +422,9 @@ s64 cellSpursInitializeWithAttribute(vm::ptr spurs, vm::ptrm.swlIsPreem); } -s64 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptr attr) +s32 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptr attr) { cellSpurs.Warning("cellSpursInitializeWithAttribute2(spurs_addr=0x%x, attr_addr=0x%x)", spurs.addr(), attr.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x82B4, libsre_rtoc); -#endif if (!attr) { @@ -502,13 +455,10 @@ s64 cellSpursInitializeWithAttribute2(vm::ptr spurs, vm::ptrm.swlIsPreem); } -s64 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) +s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision, u32 sdkVersion, u32 nSpus, s32 spuPriority, s32 ppuPriority, bool exitIfNoWork) { cellSpurs.Warning("_cellSpursAttributeInitialize(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, nSpus=%d, spuPriority=%d, ppuPriority=%d, exitIfNoWork=%d)", attr.addr(), revision, sdkVersion, nSpus, spuPriority, ppuPriority, exitIfNoWork ? 1 : 0); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x72CC, libsre_rtoc); -#endif if (!attr) { @@ -529,12 +479,9 @@ s64 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision return CELL_OK; } -s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container) +s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container) { cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=%d)", attr.addr(), container); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x6FF8, libsre_rtoc); -#endif if (!attr) { @@ -555,12 +502,9 @@ s64 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr return CELL_OK; } -s64 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr prefix, u32 size) +s32 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr prefix, u32 size) { cellSpurs.Warning("cellSpursAttributeSetNamePrefix(attr_addr=0x%x, prefix_addr=0x%x, size=%d)", attr.addr(), prefix.addr(), size); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x7234, libsre_rtoc); -#endif if (!attr || !prefix) { @@ -581,12 +525,9 @@ s64 cellSpursAttributeSetNamePrefix(vm::ptr attr, vm::ptr attr) +s32 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr attr) { cellSpurs.Warning("cellSpursAttributeEnableSpuPrintfIfAvailable(attr_addr=0x%x)", attr.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x7150, libsre_rtoc); -#endif if (!attr) { @@ -601,12 +542,9 @@ s64 cellSpursAttributeEnableSpuPrintfIfAvailable(vm::ptr att return CELL_OK; } -s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s32 type) +s32 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s32 type) { cellSpurs.Warning("cellSpursAttributeSetSpuThreadGroupType(attr_addr=0x%x, type=%d)", attr.addr(), type); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x70C8, libsre_rtoc); -#endif if (!attr) { @@ -636,13 +574,10 @@ s64 cellSpursAttributeSetSpuThreadGroupType(vm::ptr attr, s3 return CELL_OK; } -s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) +s32 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm::ptr priority, u32 maxSpu, vm::ptr isPreemptible) { cellSpurs.Warning("cellSpursAttributeEnableSystemWorkload(attr_addr=0x%x, priority_addr=0x%x, maxSpu=%d, isPreemptible_addr=0x%x)", attr.addr(), priority.addr(), maxSpu, isPreemptible.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0xF410, libsre_rtoc); -#endif if (!attr) { @@ -694,12 +629,9 @@ s64 cellSpursAttributeEnableSystemWorkload(vm::ptr attr, vm: return CELL_SPURS_CORE_ERROR_INVAL; } -s64 cellSpursFinalize(vm::ptr spurs) +s32 cellSpursFinalize(vm::ptr spurs) { cellSpurs.Todo("cellSpursFinalize(spurs_addr=0x%x)", spurs.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x8568, libsre_rtoc); -#endif if (!spurs) { @@ -714,18 +646,13 @@ s64 cellSpursFinalize(vm::ptr spurs) return CELL_SPURS_CORE_ERROR_STAT; } - + // TODO return CELL_OK; } -s64 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated) +s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated) { -#ifdef PRX_DEBUG_XXX - return cb_call, u32, vm::ptr, s32, bool>(GetCurrentPPUThread(), libsre + 0xAE34, libsre_rtoc, - spurs, queue, port, isDynamic, wasCreated); -#endif - if (!spurs || !port) { return CELL_SPURS_CORE_ERROR_NULL_POINTER; @@ -784,45 +711,29 @@ s64 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po return CELL_OK; } -s64 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) +s32 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) { cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=%d, port_addr=0x%x, isDynamic=%d)", spurs.addr(), queue, port.addr(), isDynamic); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0xAFE0, libsre_rtoc); -#endif return spursAttachLv2EventQueue(spurs, queue, port, isDynamic, false); } -s64 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port) +s32 cellSpursDetachLv2EventQueue(vm::ptr spurs, u8 port) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursDetachLv2EventQueue(spurs_addr=0x%x, port=%d)", spurs.addr(), port); - return GetCurrentPPUThread().FastCall2(libsre + 0xB144, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetSpuGuid() +s32 cellSpursGetSpuGuid() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xEFB0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) +s32 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) { cellSpurs.Warning("cellSpursGetSpuThreadGroupId(spurs_addr=0x%x, group_addr=0x%x)", spurs.addr(), group.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x8B30, libsre_rtoc); -#endif if (!spurs || !group) { @@ -837,12 +748,9 @@ s64 cellSpursGetSpuThreadGroupId(vm::ptr spurs, vm::ptr group) return CELL_OK; } -s64 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) +s32 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) { cellSpurs.Warning("cellSpursGetNumSpuThread(spurs_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), nThreads.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x8B78, libsre_rtoc); -#endif if (!spurs || !nThreads) { @@ -857,12 +765,9 @@ s64 cellSpursGetNumSpuThread(vm::ptr spurs, vm::ptr nThreads) return CELL_OK; } -s64 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::ptr nThreads) +s32 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::ptr nThreads) { cellSpurs.Warning("cellSpursGetSpuThreadId(spurs_addr=0x%x, thread_addr=0x%x, nThreads_addr=0x%x)", spurs.addr(), thread.addr(), nThreads.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x8A98, libsre_rtoc); -#endif if (!spurs || !thread || !nThreads) { @@ -882,90 +787,50 @@ s64 cellSpursGetSpuThreadId(vm::ptr spurs, vm::ptr thread, vm::p return CELL_OK; } -s64 cellSpursSetMaxContention(vm::ptr spurs, u32 workloadId, u32 maxContention) +s32 cellSpursSetMaxContention(vm::ptr spurs, u32 workloadId, u32 maxContention) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursSetMaxContention(spurs_addr=0x%x, workloadId=%d, maxContention=%d)", spurs.addr(), workloadId, maxContention); - return GetCurrentPPUThread().FastCall2(libsre + 0x8E90, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursSetPriorities(vm::ptr spurs, u32 workloadId, vm::ptr priorities) +s32 cellSpursSetPriorities(vm::ptr spurs, u32 workloadId, vm::ptr priorities) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursSetPriorities(spurs_addr=0x%x, workloadId=%d, priorities_addr=0x%x)", spurs.addr(), workloadId, priorities.addr()); - return GetCurrentPPUThread().FastCall2(libsre + 0x8BC0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::ptr isPreemptible) +s32 cellSpursSetPreemptionVictimHints(vm::ptr spurs, vm::ptr isPreemptible) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursSetPreemptionVictimHints(spurs_addr=0x%x, isPreemptible_addr=0x%x)", spurs.addr(), isPreemptible.addr()); - return GetCurrentPPUThread().FastCall2(libsre + 0xF5A4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag) +s32 cellSpursEnableExceptionEventHandler(vm::ptr spurs, bool flag) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursEnableExceptionEventHandler(spurs_addr=0x%x, flag=%d)", spurs.addr(), flag); - return GetCurrentPPUThread().FastCall2(libsre + 0xDCC0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, u32 eaHandler_addr, u32 arg_addr) +s32 cellSpursSetGlobalExceptionEventHandler(vm::ptr spurs, u32 eaHandler_addr, u32 arg_addr) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursSetGlobalExceptionEventHandler(spurs_addr=0x%x, eaHandler_addr=0x%x, arg_addr=0x%x)", - spurs.addr(), eaHandler_addr, arg_addr); - return GetCurrentPPUThread().FastCall2(libsre + 0xD6D0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs) +s32 cellSpursUnsetGlobalExceptionEventHandler(vm::ptr spurs) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursUnsetGlobalExceptionEventHandler(spurs_addr=0x%x)", spurs.addr()); - return GetCurrentPPUThread().FastCall2(libsre + 0xD674, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetInfo(vm::ptr spurs, vm::ptr info) +s32 cellSpursGetInfo(vm::ptr spurs, vm::ptr info) { -#ifdef PRX_DEBUG - cellSpurs.Warning("cellSpursGetInfo(spurs_addr=0x%x, info_addr=0x%x)", spurs.addr(), info.addr()); - return GetCurrentPPUThread().FastCall2(libsre + 0xE540, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 spursWakeUp(PPUThread& CPU, vm::ptr spurs) +s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs) { -#ifdef PRX_DEBUG_XXX - return cb_call>(GetCurrentPPUThread(), libsre + 0x84D8, libsre_rtoc, spurs); -#endif - if (!spurs) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; @@ -998,7 +863,7 @@ s64 spursWakeUp(PPUThread& CPU, vm::ptr spurs) return CELL_OK; } -s64 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) +s32 cellSpursWakeUp(PPUThread& CPU, vm::ptr spurs) { cellSpurs.Warning("%s(spurs_addr=0x%x)", __FUNCTION__, spurs.addr()); @@ -1019,12 +884,6 @@ s32 spursAddWorkload( vm::ptr hook, vm::ptr hookArg) { -#ifdef PRX_DEBUG_XXX - return cb_call, vm::ptr, vm::ptr, u32, u64, u32, u32, u32, u32, u32, u32, u32>(GetCurrentPPUThread(), libsre + 0x96EC, libsre_rtoc, - spurs, wid, pm, size, data, vm::get_addr(priorityTable), minContention, maxContention, - nameClass.addr(), nameInstance.addr(), hook.addr(), hookArg.addr()); -#endif - if (!spurs || !wid || !pm) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; @@ -1176,7 +1035,7 @@ s32 spursAddWorkload( return CELL_OK; } -s64 cellSpursAddWorkload( +s32 cellSpursAddWorkload( vm::ptr spurs, vm::ptr wid, vm::ptr pm, @@ -1188,9 +1047,6 @@ s64 cellSpursAddWorkload( { cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x9ED0, libsre_rtoc); -#endif return spursAddWorkload( spurs, @@ -1207,7 +1063,7 @@ s64 cellSpursAddWorkload( vm::ptr::make(0)); } -s64 _cellSpursWorkloadAttributeInitialize( +s32 _cellSpursWorkloadAttributeInitialize( vm::ptr attr, u32 revision, u32 sdkVersion, @@ -1220,9 +1076,6 @@ s64 _cellSpursWorkloadAttributeInitialize( { cellSpurs.Warning("%s(attr_addr=0x%x, revision=%d, sdkVersion=0x%x, pm_addr=0x%x, size=0x%x, data=0x%llx, priorityTable_addr=0x%x, minContention=0x%x, maxContention=0x%x)", __FUNCTION__, attr.addr(), revision, sdkVersion, pm.addr(), size, data, priorityTable.addr(), minContention, maxContention); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x9F08, libsre_rtoc); -#endif if (!attr) { @@ -1257,12 +1110,9 @@ s64 _cellSpursWorkloadAttributeInitialize( return CELL_OK; } -s64 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::ptr nameClass, vm::ptr nameInstance) +s32 cellSpursWorkloadAttributeSetName(vm::ptr attr, vm::ptr nameClass, vm::ptr nameInstance) { cellSpurs.Warning("%s(attr_addr=0x%x, nameClass_addr=0x%x, nameInstance_addr=0x%x)", __FUNCTION__, attr.addr(), nameClass.addr(), nameInstance.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x9664, libsre_rtoc); -#endif if (!attr) { @@ -1278,12 +1128,9 @@ s64 cellSpursWorkloadAttributeSetName(vm::ptr attr, return CELL_OK; } -s64 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg) +s32 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr attr, vm::ptr hook, vm::ptr arg) { cellSpurs.Warning("%s(attr_addr=0x%x, hook_addr=0x%x, arg=0x%x)", __FUNCTION__, attr.addr(), hook.addr(), arg.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x96A4, libsre_rtoc); -#endif if (!attr || !hook) { @@ -1299,12 +1146,9 @@ s64 cellSpursWorkloadAttributeSetShutdownCompletionEventHook(vm::ptr spurs, const vm::ptr wid, vm::ptr attr) +s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptr wid, vm::ptr attr) { cellSpurs.Warning("%s(spurs_addr=0x%x, wid_addr=0x%x, attr_addr=0x%x)", __FUNCTION__, spurs.addr(), wid.addr(), attr.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0x9E14, libsre_rtoc); -#endif if (!attr) { @@ -1334,45 +1178,27 @@ s64 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptr::make(attr->m.hookArg.addr())); } -s64 cellSpursRemoveWorkload() +s32 cellSpursRemoveWorkload() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xA414, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursWaitForWorkloadShutdown() +s32 cellSpursWaitForWorkloadShutdown() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xA20C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursShutdownWorkload() +s32 cellSpursShutdownWorkload() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xA060, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set) +s32 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set) { cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, is_set=%d)", __FUNCTION__, spurs.addr(), wid, is_set); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0xF158, libsre_rtoc); -#endif if (!spurs) { @@ -1437,12 +1263,9 @@ s64 _cellSpursWorkloadFlagReceiver(vm::ptr spurs, u32 wid, u32 is_set return CELL_OK; } -s64 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::ptr> flag) +s32 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::ptr> flag) { cellSpurs.Warning("%s(spurs_addr=0x%x, flag_addr=0x%x)", __FUNCTION__, spurs.addr(), flag.addr()); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0xEC00, libsre_rtoc); -#endif if (!spurs || !flag) { @@ -1457,13 +1280,10 @@ s64 cellSpursGetWorkloadFlag(vm::ptr spurs, vm::ptr spurs, u32 workloadId) +s32 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) { cellSpurs.Warning("%s(spurs=0x%x, workloadId=0x%x)", __FUNCTION__, spurs.addr(), workloadId); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0xA658, libsre_rtoc); -#else if (spurs.addr() == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; @@ -1514,16 +1334,12 @@ s64 cellSpursSendWorkloadSignal(vm::ptr spurs, u32 workloadId) } return CELL_OK; -#endif } -s64 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 workloadId) +s32 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 workloadId) { cellSpurs.Warning("%s(spurs_addr=0x%x, data=0x%x, workloadId=%d)", __FUNCTION__, spurs.addr(), data.addr(), workloadId); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0xA78C, libsre_rtoc); -#else if (spurs.addr() == 0 || data.addr() == 0) { return CELL_SPURS_POLICY_MODULE_ERROR_NULL_POINTER; @@ -1559,15 +1375,11 @@ s64 cellSpursGetWorkloadData(vm::ptr spurs, vm::ptr data, u32 wo } return CELL_OK; -#endif } -s64 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) +s32 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) { cellSpurs.Warning("%s(spurs_addr=0x%x, wid=%d, value=0x%x)", __FUNCTION__, spurs.addr(), wid, value); -#ifdef PRX_DEBUG_XXX - return GetCurrentPPUThread().FastCall2(libsre + 0xAB2C, libsre_rtoc); -#endif if (!spurs) { @@ -1601,102 +1413,59 @@ s64 cellSpursReadyCountStore(vm::ptr spurs, u32 wid, u32 value) return CELL_OK; } -s64 cellSpursReadyCountAdd() +s32 cellSpursReadyCountAdd() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xA868, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursReadyCountCompareAndSwap() +s32 cellSpursReadyCountCompareAndSwap() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xA9CC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursReadyCountSwap() +s32 cellSpursReadyCountSwap() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xAC34, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursRequestIdleSpu() +s32 cellSpursRequestIdleSpu() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xAD88, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetWorkloadInfo() +s32 cellSpursGetWorkloadInfo() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xE70C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursWorkloadFlagReceiver2() +s32 _cellSpursWorkloadFlagReceiver2() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xF298, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursSetExceptionEventHandler() +s32 cellSpursSetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xDB54, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursUnsetExceptionEventHandler() +s32 cellSpursUnsetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0xD77C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection) +s32 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr taskset, vm::ptr eventFlag, u32 flagClearMode, u32 flagDirection) { cellSpurs.Warning("_cellSpursEventFlagInitialize(spurs_addr=0x%x, taskset_addr=0x%x, eventFlag_addr=0x%x, flagClearMode=%d, flagDirection=%d)", spurs.addr(), taskset.addr(), eventFlag.addr(), flagClearMode, flagDirection); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1564C, libsre_rtoc); -#else if (taskset.addr() == 0 && spurs.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -1738,16 +1507,12 @@ s64 _cellSpursEventFlagInitialize(vm::ptr spurs, vm::ptr eventFlag) +s32 cellSpursEventFlagAttachLv2EventQueue(vm::ptr eventFlag) { cellSpurs.Warning("cellSpursEventFlagAttachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x157B8, libsre_rtoc); -#else if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -1818,16 +1583,12 @@ success: eventFlag->m.eventQueueId = eventQueueId; eventFlag->m.spuPort = port; return CELL_OK; -#endif } -s64 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) +s32 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) { cellSpurs.Warning("cellSpursEventFlagDetachLv2EventQueue(eventFlag_addr=0x%x)", eventFlag.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15998, libsre_rtoc); -#else if (!eventFlag) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -1873,7 +1634,7 @@ s64 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) sys_event_port_destroy(eventFlag->m.eventPortId); } - s64 rc = CELL_OK; + s32 rc = CELL_OK; // TODO: Implement the following // auto rc = spursDetachLv2EventQueue(spurs, port, 1); // if (rc == CELL_OK) @@ -1888,10 +1649,9 @@ s64 cellSpursEventFlagDetachLv2EventQueue(vm::ptr eventFlag) } return CELL_OK; -#endif } -s64 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) +s32 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode, u32 block) { if (eventFlag.addr() == 0 || mask.addr() == 0) { @@ -2032,24 +1792,17 @@ s64 _cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr return CELL_OK; } -s64 cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) +s32 cellSpursEventFlagWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) { cellSpurs.Warning("cellSpursEventFlagWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=%d)", eventFlag.addr(), mask.addr(), mode); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15E68, libsre_rtoc); -#else return _cellSpursEventFlagWait(eventFlag, mask, mode, 1/*block*/); -#endif } -s64 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) +s32 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) { cellSpurs.Warning("cellSpursEventFlagClear(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15E9C, libsre_rtoc); -#else if (eventFlag.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2062,16 +1815,12 @@ s64 cellSpursEventFlagClear(vm::ptr eventFlag, u16 bits) eventFlag->m.events &= ~bits; return CELL_OK; -#endif } -s64 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) +s32 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) { cellSpurs.Warning("cellSpursEventFlagSet(eventFlag_addr=0x%x, bits=0x%x)", eventFlag.addr(), bits); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15F04, libsre_rtoc); -#else if (eventFlag.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2190,27 +1939,19 @@ s64 cellSpursEventFlagSet(vm::ptr eventFlag, u16 bits) } return CELL_OK; -#endif } -s64 cellSpursEventFlagTryWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) +s32 cellSpursEventFlagTryWait(vm::ptr eventFlag, vm::ptr mask, u32 mode) { cellSpurs.Warning("cellSpursEventFlagTryWait(eventFlag_addr=0x%x, mask_addr=0x%x, mode=0x%x)", eventFlag.addr(), mask.addr(), mode); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15E70, libsre_rtoc); -#else return _cellSpursEventFlagWait(eventFlag, mask, mode, 0/*block*/); -#endif } -s64 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::ptr direction) +s32 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::ptr direction) { cellSpurs.Warning("cellSpursEventFlagGetDirection(eventFlag_addr=0x%x, direction_addr=0x%x)", eventFlag.addr(), direction.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x162C4, libsre_rtoc); -#else if (eventFlag.addr() == 0 || direction.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2223,16 +1964,12 @@ s64 cellSpursEventFlagGetDirection(vm::ptr eventFlag, vm::pt *direction = eventFlag->m.direction; return CELL_OK; -#endif } -s64 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode) +s32 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::ptr clear_mode) { cellSpurs.Warning("cellSpursEventFlagGetClearMode(eventFlag_addr=0x%x, clear_mode_addr=0x%x)", eventFlag.addr(), clear_mode.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x16310, libsre_rtoc); -#else if (eventFlag.addr() == 0 || clear_mode.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2245,16 +1982,12 @@ s64 cellSpursEventFlagGetClearMode(vm::ptr eventFlag, vm::pt *clear_mode = eventFlag->m.clearMode; return CELL_OK; -#endif } -s64 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::ptr taskset) +s32 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, vm::ptr taskset) { cellSpurs.Warning("cellSpursEventFlagGetTasksetAddress(eventFlag_addr=0x%x, taskset_addr=0x%x)", eventFlag.addr(), taskset.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1635C, libsre_rtoc); -#else if (eventFlag.addr() == 0 || taskset.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2267,307 +2000,171 @@ s64 cellSpursEventFlagGetTasksetAddress(vm::ptr eventFlag, v taskset.set(eventFlag->m.isIwl ? 0 : eventFlag->m.addr); return CELL_OK; -#endif } -s64 _cellSpursLFQueueInitialize() +s32 _cellSpursLFQueueInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17028, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursLFQueuePushBody() +s32 _cellSpursLFQueuePushBody() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x170AC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursLFQueueDetachLv2EventQueue() +s32 cellSpursLFQueueDetachLv2EventQueue() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x177CC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursLFQueueAttachLv2EventQueue() +s32 cellSpursLFQueueAttachLv2EventQueue() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x173EC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursLFQueuePopBody() +s32 _cellSpursLFQueuePopBody() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17238, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursLFQueueGetTasksetAddress() +s32 cellSpursLFQueueGetTasksetAddress() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17C34, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursQueueInitialize() +s32 _cellSpursQueueInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x163B4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueuePopBody() +s32 cellSpursQueuePopBody() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x16BF0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueuePushBody() +s32 cellSpursQueuePushBody() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x168C4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueAttachLv2EventQueue() +s32 cellSpursQueueAttachLv2EventQueue() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1666C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueDetachLv2EventQueue() +s32 cellSpursQueueDetachLv2EventQueue() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x16524, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueGetTasksetAddress() +s32 cellSpursQueueGetTasksetAddress() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x16F50, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueClear() +s32 cellSpursQueueClear() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1675C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueDepth() +s32 cellSpursQueueDepth() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1687C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueGetEntrySize() +s32 cellSpursQueueGetEntrySize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x16FE0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueSize() +s32 cellSpursQueueSize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x167F0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursQueueGetDirection() +s32 cellSpursQueueGetDirection() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x16F98, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursCreateJobChainWithAttribute() +s32 cellSpursCreateJobChainWithAttribute() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1898C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursCreateJobChain() +s32 cellSpursCreateJobChain() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18B84, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJoinJobChain() +s32 cellSpursJoinJobChain() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18DB0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursKickJobChain() +s32 cellSpursKickJobChain() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18E8C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursJobChainAttributeInitialize() +s32 _cellSpursJobChainAttributeInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1845C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetJobChainId() +s32 cellSpursGetJobChainId() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x19064, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainSetExceptionEventHandler() +s32 cellSpursJobChainSetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1A5A0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainUnsetExceptionEventHandler() +s32 cellSpursJobChainUnsetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1A614, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetJobChainInfo() +s32 cellSpursGetJobChainInfo() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1A7A0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainGetSpursAddress() +s32 cellSpursJobChainGetSpursAddress() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1A900, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 spursCreateTaskset(vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, +s32 spursCreateTaskset(vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, u32 max_contention, vm::ptr name, u32 size, s32 enable_clear_ls) { if (!spurs || !taskset) @@ -2610,14 +2207,10 @@ s64 spursCreateTaskset(vm::ptr spurs, vm::ptr tasks return CELL_OK; } -s64 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +s32 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14BEC, libsre_rtoc); -#endif - if (!attr) { CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2644,44 +2237,26 @@ s64 cellSpursCreateTasksetWithAttribute(vm::ptr spurs, vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, u32 maxContention) +s32 cellSpursCreateTaskset(vm::ptr spurs, vm::ptr taskset, u64 args, vm::ptr priority, u32 maxContention) { cellSpurs.Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", spurs.addr(), taskset.addr(), args, priority.addr(), maxContention); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14CB8, libsre_rtoc); -#endif - -#if 0 - SPURSManagerTasksetAttribute *tattr = new SPURSManagerTasksetAttribute(args, priority, maxContention); - taskset->taskset = new SPURSManagerTaskset(taskset.addr(), tattr); - - return CELL_OK; -#endif - return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::ptr::make(0), 6400/*CellSpursTaskset::size*/, 0); } -s64 cellSpursJoinTaskset(vm::ptr taskset) +s32 cellSpursJoinTaskset(vm::ptr taskset) { cellSpurs.Warning("cellSpursJoinTaskset(taskset_addr=0x%x)", taskset.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x152F8, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) +s32 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) { cellSpurs.Warning("cellSpursGetTasksetId(taskset_addr=0x%x, wid=0x%x)", taskset.addr(), wid.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14EA0, libsre_rtoc); -#else if (!taskset || !wid) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2699,36 +2274,27 @@ s64 cellSpursGetTasksetId(vm::ptr taskset, vm::ptr wid) *wid = taskset->m.wid; return CELL_OK; -#endif } -s64 cellSpursShutdownTaskset(vm::ptr taskset) +s32 cellSpursShutdownTaskset(vm::ptr taskset) { - cellSpurs.Warning("cellSpursShutdownTaskset(taskset_addr=0x%x)", taskset.addr()); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14868, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } u32 _cellSpursGetSdkVersion() { - static s32 sdk_version = -2; + s32 sdk_version; - if (sdk_version == -2) + if (process_get_sdk_version(process_getpid(), sdk_version) != CELL_OK) { - vm::var> version; - sys_process_get_sdk_version(sys_process_getpid(), vm::ptr::make(version.addr())); - sdk_version = version.value(); + throw __FUNCTION__; } return sdk_version; } -s64 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::ptr elf_addr, vm::ptr context_addr, u32 context_size, vm::ptr ls_pattern, vm::ptr arg) +s32 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm::ptr elf_addr, vm::ptr context_addr, u32 context_size, vm::ptr ls_pattern, vm::ptr arg) { if (!taskset || !elf_addr) { @@ -2825,7 +2391,7 @@ s64 spursCreateTask(vm::ptr taskset, vm::ptr task_id, vm: return CELL_OK; } -s64 spursTaskStart(vm::ptr taskset, u32 taskId) +s32 spursTaskStart(vm::ptr taskset, u32 taskId) { auto pendingReady = taskset->m.pending_ready.value(); pendingReady._bit[taskId] = true; @@ -2848,15 +2414,12 @@ s64 spursTaskStart(vm::ptr taskset, u32 taskId) return rc; } -s64 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, u32 elf_addr, u32 context_addr, u32 context_size, vm::ptr lsPattern, +s32 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, u32 elf_addr, u32 context_addr, u32 context_size, vm::ptr lsPattern, vm::ptr argument) { cellSpurs.Warning("cellSpursCreateTask(taskset_addr=0x%x, taskID_addr=0x%x, elf_addr_addr=0x%x, context_addr_addr=0x%x, context_size=%d, lsPattern_addr=0x%x, argument_addr=0x%x)", taskset.addr(), taskId.addr(), elf_addr, context_addr, context_size, lsPattern.addr(), argument.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x12414, libsre_rtoc); -#else if (!taskset) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2882,15 +2445,10 @@ s64 cellSpursCreateTask(vm::ptr taskset, vm::ptr taskId, *taskId = tmpTaskId; return CELL_OK; -#endif } -s64 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) +s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) { -#ifdef PRX_DEBUG - cellSpurs.Warning("_cellSpursSendSignal(taskset_addr=0x%x, taskId=%d)", taskset.addr(), taskId); - return GetCurrentPPUThread().FastCall2(libsre + 0x124CC, libsre_rtoc); -#else if (!taskset) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2936,28 +2494,18 @@ s64 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) } return CELL_OK; -#endif } -s64 cellSpursCreateTaskWithAttribute() +s32 cellSpursCreateTaskWithAttribute() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x12204, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::ptr name) +s32 cellSpursTasksetAttributeSetName(vm::ptr attr, vm::ptr name) { cellSpurs.Warning("%s(attr=0x%x, name=0x%x)", __FUNCTION__, attr.addr(), name.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14210, libsre_rtoc); -#else if (!attr || !name) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2970,16 +2518,12 @@ s64 cellSpursTasksetAttributeSetName(vm::ptr attr, vm attr->m.name = name; return CELL_OK; -#endif } -s64 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size) +s32 cellSpursTasksetAttributeSetTasksetSize(vm::ptr attr, u32 size) { cellSpurs.Warning("%s(attr=0x%x, size=0x%x)", __FUNCTION__, attr.addr(), size); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14254, libsre_rtoc); -#else if (!attr) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -2997,16 +2541,12 @@ s64 cellSpursTasksetAttributeSetTasksetSize(vm::ptr a attr->m.taskset_size = size; return CELL_OK; -#endif } -s64 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable) +s32 cellSpursTasksetAttributeEnableClearLS(vm::ptr attr, s32 enable) { cellSpurs.Warning("%s(attr=0x%x, enable=%d)", __FUNCTION__, attr.addr(), enable); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x142AC, libsre_rtoc); -#else if (!attr) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3019,16 +2559,12 @@ s64 cellSpursTasksetAttributeEnableClearLS(vm::ptr at attr->m.enable_clear_ls = enable ? 1 : 0; return CELL_OK; -#endif } -s64 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision) +s32 _cellSpursTasksetAttribute2Initialize(vm::ptr attribute, u32 revision) { cellSpurs.Warning("_cellSpursTasksetAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1474C, libsre_rtoc); -#else + memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute2::size); attribute->m.revision = revision; attribute->m.name.set(0); @@ -3043,112 +2579,60 @@ s64 _cellSpursTasksetAttribute2Initialize(vm::ptr at attribute->m.enable_clear_ls = 0; attribute->m.task_name_buffer.set(0); return CELL_OK; -#endif } -s64 cellSpursTaskExitCodeGet() +s32 cellSpursTaskExitCodeGet() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1397C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskExitCodeInitialize() +s32 cellSpursTaskExitCodeInitialize() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1352C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskExitCodeTryGet() +s32 cellSpursTaskExitCodeTryGet() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13974, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskGetLoadableSegmentPattern() +s32 cellSpursTaskGetLoadableSegmentPattern() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13ED4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskGetReadOnlyAreaPattern() +s32 cellSpursTaskGetReadOnlyAreaPattern() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13CFC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskGenerateLsPattern() +s32 cellSpursTaskGenerateLsPattern() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13B78, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursTaskAttributeInitialize() +s32 _cellSpursTaskAttributeInitialize() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x10C30, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTaskAttributeSetExitCodeContainer() +s32 cellSpursTaskAttributeSetExitCodeContainer() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x10A98, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision) +s32 _cellSpursTaskAttribute2Initialize(vm::ptr attribute, u32 revision) { cellSpurs.Warning("_cellSpursTaskAttribute2Initialize(attribute_addr=0x%x, revision=%d)", attribute.addr(), revision); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x10B00, libsre_rtoc); -#else attribute->revision = revision; attribute->sizeContext = 0; attribute->eaContext = 0; @@ -3161,28 +2645,18 @@ s64 _cellSpursTaskAttribute2Initialize(vm::ptr attribut attribute->name_addr = 0; return CELL_OK; -#endif } -s64 cellSpursTaskGetContextSaveAreaSize() +s32 cellSpursTaskGetContextSaveAreaSize() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1409C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) +s32 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr taskset, vm::ptr attr) { cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, attr=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), attr.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x15108, libsre_rtoc); -#else vm::ptr tmp_attr; if (!attr) @@ -3206,76 +2680,42 @@ s64 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr // TODO: Implement rest of the function return CELL_OK; -#endif } -s64 cellSpursCreateTask2() +s32 cellSpursCreateTask2() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x11E54, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJoinTask2() +s32 cellSpursJoinTask2() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x11378, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTryJoinTask2() +s32 cellSpursTryJoinTask2() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x11748, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursDestroyTaskset2() +s32 cellSpursDestroyTaskset2() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14EE8, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursCreateTask2WithBinInfo() +s32 cellSpursCreateTask2WithBinInfo() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x120E0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg) +s32 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, vm::ptr handler, vm::ptr arg) { cellSpurs.Warning("%s(taskset=0x5x, handler=0x%x, arg=0x%x)", __FUNCTION__, taskset.addr(), handler.addr(), arg.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13124, libsre_rtoc); -#else if (!taskset || !handler) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3299,16 +2739,12 @@ s64 cellSpursTasksetSetExceptionEventHandler(vm::ptr taskset, taskset->m.exception_handler = handler; taskset->m.exception_handler_arg = arg; return CELL_OK; -#endif } -s64 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset) +s32 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset) { cellSpurs.Warning("%s(taskset=0x%x)", __FUNCTION__, taskset.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x13194, libsre_rtoc); -#else if (!taskset) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3327,16 +2763,12 @@ s64 cellSpursTasksetUnsetExceptionEventHandler(vm::ptr taskset taskset->m.exception_handler.set(0); taskset->m.exception_handler_arg.set(0); return CELL_OK; -#endif } -s64 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id) +s32 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, u32 id) { cellSpurs.Warning("%s(spurs=0x%x, taskset=0x%x, id=0x%x)", __FUNCTION__, spurs.addr(), taskset.addr(), id); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x133AC, libsre_rtoc); -#else if (taskset.addr() == 0) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3352,16 +2784,12 @@ s64 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr taskset, vm::ptr spurs) +s32 cellSpursTasksetGetSpursAddress(vm::ptr taskset, vm::ptr spurs) { cellSpurs.Warning("%s(taskset=0x%x, spurs=0x%x)", __FUNCTION__, taskset.addr(), spurs.addr()); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x14408, libsre_rtoc); -#else if (!taskset || !spurs) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3379,29 +2807,19 @@ s64 cellSpursTasksetGetSpursAddress(vm::ptr taskset, vm: *spurs = (u32)taskset->m.spurs.addr(); return CELL_OK; -#endif } -s64 cellSpursGetTasksetInfo() +s32 cellSpursGetTasksetInfo() { - cellSpurs.Warning("%s()", __FUNCTION__); - -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x1445C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::ptr priority, u32 max_contention) +s32 _cellSpursTasksetAttributeInitialize(vm::ptr attribute, u32 revision, u32 sdk_version, u64 args, vm::ptr priority, u32 max_contention) { cellSpurs.Warning("%s(attribute=0x%x, revision=%d, skd_version=%d, args=0x%llx, priority=0x%x, max_contention=%d)", __FUNCTION__, attribute.addr(), revision, sdk_version, args, priority.addr(), max_contention); -#ifdef PRX_DEBUG - return GetCurrentPPUThread().FastCall2(libsre + 0x142FC, libsre_rtoc); -#else if (!attribute) { return CELL_SPURS_TASK_ERROR_NULL_POINTER; @@ -3428,205 +2846,114 @@ s64 _cellSpursTasksetAttributeInitialize(vm::ptr attr attribute->m.taskset_size = 6400/*CellSpursTaskset::size*/; attribute->m.max_contention = max_contention; return CELL_OK; -#endif } -s64 cellSpursJobGuardInitialize() +s32 cellSpursJobGuardInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1807C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainAttributeSetName() +s32 cellSpursJobChainAttributeSetName() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1861C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursShutdownJobChain() +s32 cellSpursShutdownJobChain() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18D2C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainAttributeSetHaltOnError() +s32 cellSpursJobChainAttributeSetHaltOnError() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18660, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainAttributeSetJobTypeMemoryCheck() +s32 cellSpursJobChainAttributeSetJobTypeMemoryCheck() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x186A4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobGuardNotify() +s32 cellSpursJobGuardNotify() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17FA4, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobGuardReset() +s32 cellSpursJobGuardReset() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17F60, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursRunJobChain() +s32 cellSpursRunJobChain() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18F94, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobChainGetError() +s32 cellSpursJobChainGetError() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x190AC, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursGetJobPipelineInfo() +s32 cellSpursGetJobPipelineInfo() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1A954, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobSetMaxGrab() +s32 cellSpursJobSetMaxGrab() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1AC88, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursJobHeaderSetJobbin2Param() +s32 cellSpursJobHeaderSetJobbin2Param() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1AD58, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursAddUrgentCommand() +s32 cellSpursAddUrgentCommand() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x18160, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursAddUrgentCall() +s32 cellSpursAddUrgentCall() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x1823C, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursBarrierInitialize() +s32 cellSpursBarrierInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17CD8, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursBarrierGetTasksetAddress() +s32 cellSpursBarrierGetTasksetAddress() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17DB0, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 _cellSpursSemaphoreInitialize() +s32 _cellSpursSemaphoreInitialize() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17DF8, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } -s64 cellSpursSemaphoreGetTasksetAddress() +s32 cellSpursSemaphoreGetTasksetAddress() { -#ifdef PRX_DEBUG - cellSpurs.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsre + 0x17F18, libsre_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpurs); return CELL_OK; -#endif } bool spursIsLibProfLoaded() @@ -3647,7 +2974,7 @@ void spursTraceStatusUpdate(vm::ptr spurs) } } -s64 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) +s32 spursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode, u32 updateStatus) { if (!spurs || !buffer) { @@ -3697,7 +3024,7 @@ s64 spursTraceInitialize(vm::ptr spurs, vm::ptr b return CELL_OK; } -s64 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) +s32 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr buffer, u32 size, u32 mode) { if (spursIsLibProfLoaded()) { @@ -3707,7 +3034,7 @@ s64 cellSpursTraceInitialize(vm::ptr spurs, vm::ptr spurs, u32 updateStatus) +s32 spursTraceStart(vm::ptr spurs, u32 updateStatus) { if (!spurs) { @@ -3733,7 +3060,7 @@ s64 spursTraceStart(vm::ptr spurs, u32 updateStatus) return CELL_OK; } -s64 cellSpursTraceStart(vm::ptr spurs) +s32 cellSpursTraceStart(vm::ptr spurs) { if (!spurs) { @@ -3748,7 +3075,7 @@ s64 cellSpursTraceStart(vm::ptr spurs) return spursTraceStart(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } -s64 spursTraceStop(vm::ptr spurs, u32 updateStatus) +s32 spursTraceStop(vm::ptr spurs, u32 updateStatus) { if (!spurs) { @@ -3774,7 +3101,7 @@ s64 spursTraceStop(vm::ptr spurs, u32 updateStatus) return CELL_OK; } -s64 cellSpursTraceStop(vm::ptr spurs) +s32 cellSpursTraceStop(vm::ptr spurs) { if (!spurs) { @@ -3789,7 +3116,7 @@ s64 cellSpursTraceStop(vm::ptr spurs) return spursTraceStop(spurs, spurs->m.traceMode & CELL_SPURS_TRACE_MODE_FLAG_SYNCHRONOUS_START_STOP); } -s64 cellSpursTraceFinalize(vm::ptr spurs) +s32 cellSpursTraceFinalize(vm::ptr spurs) { if (!spurs) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index f6e96733c3..f474da8893 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -957,5 +957,5 @@ struct SpursTasksetContext static_assert(sizeof(SpursTasksetContext) == 0x900, "Incorrect size for SpursTasksetContext"); -s64 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated); -s64 spursWakeUp(PPUThread& CPU, vm::ptr spurs); +s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic, bool wasCreated); +s32 spursWakeUp(PPUThread& CPU, vm::ptr spurs); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp index 8878858ea5..8b4c3b4f14 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpursJq.cpp @@ -13,692 +13,376 @@ extern Module cellSpursJq; -#ifdef PRX_DEBUG -#include "prx_libspurs_jq.h" -u32 libspurs_jq; -u32 libspurs_jq_rtoc; -#endif - -s64 cellSpursJobQueueAttributeInitialize() +s32 cellSpursJobQueueAttributeInitialize() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000010, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetMaxGrab() +s32 cellSpursJobQueueAttributeSetMaxGrab() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000058, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetSubmitWithEntryLock() +s32 cellSpursJobQueueAttributeSetSubmitWithEntryLock() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000098, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetDoBusyWaiting() +s32 cellSpursJobQueueAttributeSetDoBusyWaiting() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0000BC, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetIsHaltOnError() +s32 cellSpursJobQueueAttributeSetIsHaltOnError() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0000E0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetIsJobTypeMemoryCheck() +s32 cellSpursJobQueueAttributeSetIsJobTypeMemoryCheck() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000104, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetMaxSizeJobDescriptor() +s32 cellSpursJobQueueAttributeSetMaxSizeJobDescriptor() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000128, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueAttributeSetGrabParameters() +s32 cellSpursJobQueueAttributeSetGrabParameters() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000178, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSetWaitingMode() +s32 cellSpursJobQueueSetWaitingMode() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0001C8, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursShutdownJobQueue() +s32 cellSpursShutdownJobQueue() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0002F0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursCreateJobQueueWithJobDescriptorPool() +s32 _cellSpursCreateJobQueueWithJobDescriptorPool() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0003CC, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursCreateJobQueue() +s32 _cellSpursCreateJobQueue() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000CA8, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJoinJobQueue() +s32 cellSpursJoinJobQueue() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x000CF0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushJobListBody() +s32 _cellSpursJobQueuePushJobListBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001B24, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushJobBody2() +s32 _cellSpursJobQueuePushJobBody2() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001BF0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushJob2Body() +s32 _cellSpursJobQueuePushJob2Body() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001CD0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushAndReleaseJobBody() +s32 _cellSpursJobQueuePushAndReleaseJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001DC8, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushJobBody() +s32 _cellSpursJobQueuePushJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001EC8, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushBody() +s32 _cellSpursJobQueuePushBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x001F90, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueueAllocateJobDescriptorBody() +s32 _cellSpursJobQueueAllocateJobDescriptorBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002434, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushSync() +s32 _cellSpursJobQueuePushSync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002498, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePushFlush() +s32 _cellSpursJobQueuePushFlush() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002528, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueGetSpurs() +s32 cellSpursJobQueueGetSpurs() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002598, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueGetHandleCount() +s32 cellSpursJobQueueGetHandleCount() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0025C4, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueGetError() +s32 cellSpursJobQueueGetError() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002600, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueGetMaxSizeJobDescriptor() +s32 cellSpursJobQueueGetMaxSizeJobDescriptor() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002668, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursGetJobQueueId() +s32 cellSpursGetJobQueueId() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0026A4, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueGetSuspendedJobSize() +s32 cellSpursJobQueueGetSuspendedJobSize() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002700, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueClose() +s32 cellSpursJobQueueClose() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002D70, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueOpen() +s32 cellSpursJobQueueOpen() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x002E50, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSemaphoreTryAcquire() +s32 cellSpursJobQueueSemaphoreTryAcquire() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003370, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSemaphoreAcquire() +s32 cellSpursJobQueueSemaphoreAcquire() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003378, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSemaphoreInitialize() +s32 cellSpursJobQueueSemaphoreInitialize() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003380, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSendSignal() +s32 cellSpursJobQueueSendSignal() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0033E0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortGetJobQueue() +s32 cellSpursJobQueuePortGetJobQueue() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x00354C, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushSync() +s32 _cellSpursJobQueuePortPushSync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003554, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushFlush() +s32 _cellSpursJobQueuePortPushFlush() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0035C0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushJobListBody() +s32 _cellSpursJobQueuePortPushJobListBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003624, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushJobBody() +s32 _cellSpursJobQueuePortPushJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A88, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushJobBody2() +s32 _cellSpursJobQueuePortPushJobBody2() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A94, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortPushBody() +s32 _cellSpursJobQueuePortPushBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003A98, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortTrySync() +s32 cellSpursJobQueuePortTrySync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C38, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortSync() +s32 cellSpursJobQueuePortSync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C40, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortInitialize() +s32 cellSpursJobQueuePortInitialize() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003C48, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortInitializeWithDescriptorBuffer() +s32 cellSpursJobQueuePortInitializeWithDescriptorBuffer() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003D78, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePortFinalize() +s32 cellSpursJobQueuePortFinalize() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x003E40, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortCopyPushJobBody() +s32 _cellSpursJobQueuePortCopyPushJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004280, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortCopyPushJobBody2() +s32 _cellSpursJobQueuePortCopyPushJobBody2() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x00428C, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePortCopyPushBody() +s32 _cellSpursJobQueuePortCopyPushBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004290, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2GetJobQueue() +s32 cellSpursJobQueuePort2GetJobQueue() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0042A4, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2PushSync() +s32 cellSpursJobQueuePort2PushSync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0042AC, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2PushFlush() +s32 cellSpursJobQueuePort2PushFlush() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004330, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePort2PushJobListBody() +s32 _cellSpursJobQueuePort2PushJobListBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0043B0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2Sync() +s32 cellSpursJobQueuePort2Sync() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0045AC, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2Create() +s32 cellSpursJobQueuePort2Create() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0046C4, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2Destroy() +s32 cellSpursJobQueuePort2Destroy() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x0047E4, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueuePort2AllocateJobDescriptor() +s32 cellSpursJobQueuePort2AllocateJobDescriptor() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004928, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePort2PushAndReleaseJobBody() +s32 _cellSpursJobQueuePort2PushAndReleaseJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004D94, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePort2CopyPushJobBody() +s32 _cellSpursJobQueuePort2CopyPushJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004DD0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 _cellSpursJobQueuePort2PushJobBody() +s32 _cellSpursJobQueuePort2PushJobBody() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004E0C, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueSetExceptionEventHandler() +s32 cellSpursJobQueueSetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004E48, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } -s64 cellSpursJobQueueUnsetExceptionEventHandler() +s32 cellSpursJobQueueUnsetExceptionEventHandler() { -#ifdef PRX_DEBUG - cellSpursJq.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libspurs_jq + 0x004EC0, libspurs_jq_rtoc); -#else UNIMPLEMENTED_FUNC(cellSpursJq); return CELL_OK; -#endif } Module cellSpursJq("cellSpursJq", []() @@ -765,43 +449,4 @@ Module cellSpursJq("cellSpursJq", []() REG_FUNC(cellSpursJq, _cellSpursJobQueuePort2PushJobBody); REG_FUNC(cellSpursJq, cellSpursJobQueueSetExceptionEventHandler); REG_FUNC(cellSpursJq, cellSpursJobQueueUnsetExceptionEventHandler); - -#ifdef PRX_DEBUG - CallAfter([]() - { - if (!Memory.MainMem.GetStartAddr()) return; - - libspurs_jq = (u32)Memory.MainMem.AllocAlign(sizeof(libspurs_jq_data), 0x100000); - memcpy(vm::get_ptr(libspurs_jq), libspurs_jq_data, sizeof(libspurs_jq_data)); - libspurs_jq_rtoc = libspurs_jq + 0x17E80; - - extern Module* sysPrxForUser; - extern Module* cellSpurs; - extern Module* cellFiber; - - FIX_IMPORT(cellSpurs, cellSpursSendWorkloadSignal , libspurs_jq + 0x6728); - FIX_IMPORT(cellSpurs, cellSpursWorkloadAttributeSetName , libspurs_jq + 0x6748); - FIX_IMPORT(cellSpurs, cellSpursRemoveWorkload , libspurs_jq + 0x6768); - FIX_IMPORT(cellSpurs, cellSpursWaitForWorkloadShutdown , libspurs_jq + 0x6788); - FIX_IMPORT(cellSpurs, cellSpursWakeUp , libspurs_jq + 0x67A8); - FIX_IMPORT(cellSpurs, cellSpursShutdownWorkload , libspurs_jq + 0x67C8); - FIX_IMPORT(cellSpurs, cellSpursAddWorkloadWithAttribute , libspurs_jq + 0x67E8); - FIX_IMPORT(cellSpurs, cellSpursSetExceptionEventHandler , libspurs_jq + 0x6808); - FIX_IMPORT(cellSpurs, _cellSpursWorkloadAttributeInitialize , libspurs_jq + 0x6828); - FIX_IMPORT(cellFiber, cellFiberPpuSelf , libspurs_jq + 0x6848); - FIX_IMPORT(cellFiber, cellFiberPpuWaitSignal , libspurs_jq + 0x6868); - FIX_IMPORT(sysPrxForUser, _sys_strncmp , libspurs_jq + 0x6888); - FIX_IMPORT(sysPrxForUser, _sys_snprintf , libspurs_jq + 0x68A8); - FIX_IMPORT(sysPrxForUser, sys_lwcond_destroy , libspurs_jq + 0x68C8); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_create , libspurs_jq + 0x68E8); - FIX_IMPORT(sysPrxForUser, _sys_memset , libspurs_jq + 0x6908); - FIX_IMPORT(sysPrxForUser, _sys_printf , libspurs_jq + 0x6928); - fix_import(sysPrxForUser, 0x9FB6228E , libspurs_jq + 0x6948); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_destroy , libspurs_jq + 0x6968); - FIX_IMPORT(sysPrxForUser, sys_lwcond_create , libspurs_jq + 0x6988); - fix_import(sysPrxForUser, 0xE75C40F2 , libspurs_jq + 0x69A8); - - fix_relocs(cellSpursJq, libspurs_jq, 0xFF70, 0x12370, 0xED00); - }); -#endif }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 502b51c1eb..eb9d622c8d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -13,12 +13,6 @@ extern Module cellSync; -#ifdef PRX_DEBUG -#include "prx_libsre.h" -u32 libsre; -u32 libsre_rtoc; -#endif - waiter_map_t g_sync_mutex_wm("sync_mutex_wm"); waiter_map_t g_sync_barrier_wait_wm("sync_barrier_wait_wm"); waiter_map_t g_sync_barrier_notify_wm("sync_barrier_notify_wm"); @@ -886,11 +880,6 @@ void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 siz s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { -#ifdef PRX_DEBUG_XXX - return cb_caller, vm::ptr, u32, u32, CellSyncQueueDirection, vm::ptr>::call(GetCurrentPPUThread(), libsre + 0x205C, libsre_rtoc, - queue, buffer, size, depth, direction, eaSignal); -#endif - if (!queue) { return CELL_SYNC_ERROR_NULL_POINTER; @@ -1112,10 +1101,7 @@ s32 _cellSyncLFQueueGetPushPointer(vm::ptr queue, vm::ptr s32 syncLFQueueGetPushPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue) { - // TODO - //pointer = 0; - assert(!"syncLFQueueGetPushPointer2()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueGetPushPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) @@ -1274,10 +1260,7 @@ s32 _cellSyncLFQueueCompletePushPointer(vm::ptr queue, s32 poin s32 syncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal) { - // TODO - //if (fpSendSignal) return fpSendSignal(0, 0); - assert(!"syncLFQueueCompletePushPointer2()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueCompletePushPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal) @@ -1304,32 +1287,18 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: } s32 position; -#ifdef PRX_DEBUG - vm::stackvar> position_v(CPU); -#endif + while (true) { s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { -#ifdef PRX_DEBUG_XXX - res = cb_call, u32, u32, u64>(CPU, libsre + 0x24B0, libsre_rtoc, - queue, position_v.addr(), isBlocking, 0); - position = position_v.value(); -#else res = syncLFQueueGetPushPointer(queue, position, isBlocking, 0); -#endif } else { -#ifdef PRX_DEBUG - res = cb_call, u32, u32, u64>(CPU, libsre + 0x3050, libsre_rtoc, - queue, position_v.addr(), isBlocking, 0); - position = position_v.value(); -#else res = syncLFQueueGetPushPointer2(queue, position, isBlocking, 0); -#endif } if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) @@ -1342,6 +1311,7 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + if (Emu.IsStopped()) { cellSync.Warning("_cellSyncLFQueuePushBody(queue_addr=0x%x) aborted", queue.addr()); @@ -1355,23 +1325,14 @@ s32 _cellSyncLFQueuePushBody(PPUThread& CPU, vm::ptr queue, vm: memcpy(vm::get_ptr(addr), buffer.get_ptr(), size); s32 res; + if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { -#ifdef PRX_DEBUG_XXX - res = cb_call, s32, u64>(CPU, libsre + 0x26C0, libsre_rtoc, - queue, position, 0); -#else res = syncLFQueueCompletePushPointer(queue, position, nullptr); -#endif } else { -#ifdef PRX_DEBUG - res = cb_call, s32, u64>(CPU, libsre + 0x355C, libsre_rtoc, - queue, position, 0); -#else res = syncLFQueueCompletePushPointer2(queue, position, nullptr); -#endif } return res; @@ -1491,10 +1452,7 @@ s32 _cellSyncLFQueueGetPopPointer(vm::ptr queue, vm::ptr p s32 syncLFQueueGetPopPointer2(vm::ptr queue, s32& pointer, u32 isBlocking, u32 useEventQueue) { - // TODO - //pointer = 0; - assert(!"syncLFQueueGetPopPointer2()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueGetPopPointer2(vm::ptr queue, vm::ptr pointer, u32 isBlocking, u32 useEventQueue) @@ -1653,10 +1611,7 @@ s32 _cellSyncLFQueueCompletePopPointer(vm::ptr queue, s32 point s32 syncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, const std::function fpSendSignal, u32 noQueueFull) { - // TODO - //if (fpSendSignal) fpSendSignal(0, 0); - assert(!"syncLFQueueCompletePopPointer2()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueCompletePopPointer2(vm::ptr queue, s32 pointer, vm::ptr fpSendSignal, u32 noQueueFull) @@ -1683,31 +1638,17 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: } s32 position; -#ifdef PRX_DEBUG - vm::stackvar> position_v(CPU); -#endif + while (true) { s32 res; if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { -#ifdef PRX_DEBUG_XXX - res = cb_call, u32, u32, u64, u64>(CPU, libsre + 0x2A90, libsre_rtoc, - queue, position_v.addr(), isBlocking, 0, 0); - position = position_v.value(); -#else res = syncLFQueueGetPopPointer(queue, position, isBlocking, 0, 0); -#endif } else { -#ifdef PRX_DEBUG - res = cb_call, u32, u32, u64>(CPU, libsre + 0x39AC, libsre_rtoc, - queue, position_v.addr(), isBlocking, 0); - position = position_v.value(); -#else res = syncLFQueueGetPopPointer2(queue, position, isBlocking, 0); -#endif } if (!isBlocking || res != CELL_SYNC_ERROR_AGAIN) @@ -1720,6 +1661,7 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + if (Emu.IsStopped()) { cellSync.Warning("_cellSyncLFQueuePopBody(queue_addr=0x%x) aborted", queue.addr()); @@ -1733,23 +1675,14 @@ s32 _cellSyncLFQueuePopBody(PPUThread& CPU, vm::ptr queue, vm:: memcpy(buffer.get_ptr(), vm::get_ptr(addr), size); s32 res; + if (queue->m_direction != CELL_SYNC_QUEUE_ANY2ANY) { -#ifdef PRX_DEBUG_XXX - res = cb_call, s32, u64, u64>(CPU, libsre + 0x2CA8, libsre_rtoc, - queue, position, 0, 0); -#else res = syncLFQueueCompletePopPointer(queue, position, nullptr, 0); -#endif } else { -#ifdef PRX_DEBUG - res = cb_call, s32, u64, u64>(CPU, libsre + 0x3EB8, libsre_rtoc, - queue, position, 0, 0); -#else res = syncLFQueueCompletePopPointer2(queue, position, nullptr, 0); -#endif } return res; @@ -1910,13 +1843,7 @@ s32 cellSyncLFQueueGetEntrySize(vm::ptr queue, vm::ptr spus, u32 num, vm::ptr queue) { -#ifdef PRX_DEBUG - return cb_call, u32, vm::ptr>(GetCurrentPPUThread(), libsre + 0x19A8, libsre_rtoc, - spus, num, queue); -#endif - - assert(!"syncLFQueueAttachLv2EventQueue()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) @@ -1928,13 +1855,7 @@ s32 _cellSyncLFQueueAttachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr spus, u32 num, vm::ptr queue) { -#ifdef PRX_DEBUG - return cb_call, u32, vm::ptr>(GetCurrentPPUThread(), libsre + 0x1DA0, libsre_rtoc, - spus, num, queue); -#endif - - assert(!"syncLFQueueDetachLv2EventQueue()"); - return CELL_OK; + throw __FUNCTION__; } s32 _cellSyncLFQueueDetachLv2EventQueue(vm::ptr spus, u32 num, vm::ptr queue) @@ -1992,53 +1913,4 @@ Module cellSync("cellSync", []() cellSync.AddFunc(0xe1bc7add, _cellSyncLFQueuePopBody); cellSync.AddFunc(0xe9bf2110, _cellSyncLFQueueGetPushPointer); cellSync.AddFunc(0xfe74e8e7, _cellSyncLFQueueCompletePopPointer); - -#ifdef PRX_DEBUG - CallAfter([]() - { - if (!Memory.MainMem.GetStartAddr()) return; - - libsre = (u32)Memory.MainMem.AllocAlign(sizeof(libsre_data), 0x100000); - memcpy(vm::get_ptr(libsre), libsre_data, sizeof(libsre_data)); - libsre_rtoc = libsre + 0x399B0; - - extern Module* sysPrxForUser; - - FIX_IMPORT(sysPrxForUser, cellUserTraceRegister , libsre + 0x1D5BC); // ??? - FIX_IMPORT(sysPrxForUser, cellUserTraceUnregister , libsre + 0x1D5DC); // ??? - - FIX_IMPORT(sysPrxForUser, _sys_strncmp , libsre + 0x1D5FC); - FIX_IMPORT(sysPrxForUser, _sys_strcat , libsre + 0x1D61C); - FIX_IMPORT(sysPrxForUser, _sys_vsnprintf , libsre + 0x1D63C); - FIX_IMPORT(sysPrxForUser, _sys_snprintf , libsre + 0x1D65C); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_lock , libsre + 0x1D67C); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_unlock , libsre + 0x1D69C); - FIX_IMPORT(sysPrxForUser, sys_lwcond_destroy , libsre + 0x1D6BC); - FIX_IMPORT(sysPrxForUser, sys_ppu_thread_create , libsre + 0x1D6DC); - FIX_IMPORT(sysPrxForUser, sys_lwcond_wait , libsre + 0x1D6FC); - FIX_IMPORT(sysPrxForUser, _sys_strlen , libsre + 0x1D71C); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_create , libsre + 0x1D73C); - FIX_IMPORT(sysPrxForUser, _sys_spu_printf_detach_group , libsre + 0x1D75C); - FIX_IMPORT(sysPrxForUser, _sys_memset , libsre + 0x1D77C); - FIX_IMPORT(sysPrxForUser, _sys_memcpy , libsre + 0x1D79C); - FIX_IMPORT(sysPrxForUser, _sys_strncat , libsre + 0x1D7BC); - FIX_IMPORT(sysPrxForUser, _sys_strcpy , libsre + 0x1D7DC); - FIX_IMPORT(sysPrxForUser, _sys_printf , libsre + 0x1D7FC); - fix_import(sysPrxForUser, 0x9FB6228E , libsre + 0x1D81C); - FIX_IMPORT(sysPrxForUser, sys_ppu_thread_exit , libsre + 0x1D83C); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_destroy , libsre + 0x1D85C); - FIX_IMPORT(sysPrxForUser, _sys_strncpy , libsre + 0x1D87C); - FIX_IMPORT(sysPrxForUser, sys_lwcond_create , libsre + 0x1D89C); - FIX_IMPORT(sysPrxForUser, _sys_spu_printf_attach_group , libsre + 0x1D8BC); - FIX_IMPORT(sysPrxForUser, sys_prx_get_module_id_by_name , libsre + 0x1D8DC); - FIX_IMPORT(sysPrxForUser, sys_spu_image_close , libsre + 0x1D8FC); - fix_import(sysPrxForUser, 0xE75C40F2 , libsre + 0x1D91C); - FIX_IMPORT(sysPrxForUser, sys_spu_image_import , libsre + 0x1D93C); - FIX_IMPORT(sysPrxForUser, sys_lwcond_signal , libsre + 0x1D95C); - FIX_IMPORT(sysPrxForUser, _sys_vprintf , libsre + 0x1D97C); - FIX_IMPORT(sysPrxForUser, _sys_memcmp , libsre + 0x1D99C); - - fix_relocs(cellSync, libsre, 0x31EE0, 0x3A4F0, 0x2DF00); - }); -#endif }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp index 0f229cf3fa..8875129728 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync2.cpp @@ -7,18 +7,8 @@ extern Module cellSync2; -#ifdef PRX_DEBUG -#include "prx_libsync2.h" -u32 libsync2; -u32 libsync2_rtoc; -#endif - -s64 _cellSync2MutexAttributeInitialize(vm::ptr attr, u32 sdkVersion) +s32 _cellSync2MutexAttributeInitialize(vm::ptr attr, u32 sdkVersion) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x16A0, libsync2_rtoc); -#else cellSync2.Warning("_cellSync2MutexAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; @@ -30,85 +20,50 @@ s64 _cellSync2MutexAttributeInitialize(vm::ptr attr, u3 strcpy_trunc(attr->name, "CellSync2Mutex"); return CELL_OK; -#endif } -s64 cellSync2MutexEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2MutexEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0xC3C, libsync2_rtoc); -#else cellSync2.Todo("cellSync2MutexEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; return CELL_OK; -#endif } -s64 cellSync2MutexInitialize() +s32 cellSync2MutexInitialize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x1584, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2MutexFinalize() +s32 cellSync2MutexFinalize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x142C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2MutexLock() +s32 cellSync2MutexLock() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x1734, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2MutexTryLock() +s32 cellSync2MutexTryLock() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x1A2C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2MutexUnlock() +s32 cellSync2MutexUnlock() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x186C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 sdkVersion) +s32 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 sdkVersion) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x26DC, libsync2_rtoc); -#else cellSync2.Warning("_cellSync2CondAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; @@ -116,85 +71,50 @@ s64 _cellSync2CondAttributeInitialize(vm::ptr attr, u32 strcpy_trunc(attr->name, "CellSync2Cond"); return CELL_OK; -#endif } -s64 cellSync2CondEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2CondEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x1B90, libsync2_rtoc); -#else cellSync2.Todo("cellSync2CondEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; return CELL_OK; -#endif } -s64 cellSync2CondInitialize() +s32 cellSync2CondInitialize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x25DC, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2CondFinalize() +s32 cellSync2CondFinalize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x23E0, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2CondWait() +s32 cellSync2CondWait() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x283C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2CondSignal() +s32 cellSync2CondSignal() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x2768, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2CondSignalAll() +s32 cellSync2CondSignalAll() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x2910, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 _cellSync2SemaphoreAttributeInitialize(vm::ptr attr, u32 sdkVersion) +s32 _cellSync2SemaphoreAttributeInitialize(vm::ptr attr, u32 sdkVersion) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x5644, libsync2_rtoc); -#else cellSync2.Warning("_cellSync2SemaphoreAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; @@ -205,96 +125,56 @@ s64 _cellSync2SemaphoreAttributeInitialize(vm::ptr strcpy_trunc(attr->name, "CellSync2Semaphore"); return CELL_OK; -#endif } -s64 cellSync2SemaphoreEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2SemaphoreEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x4AC4, libsync2_rtoc); -#else cellSync2.Todo("cellSync2SemaphoreEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->maxWaiters == 0 || attr->maxWaiters > 32768) return CELL_SYNC2_ERROR_INVAL; return CELL_OK; -#endif } -s64 cellSync2SemaphoreInitialize() +s32 cellSync2SemaphoreInitialize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x54E0, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2SemaphoreFinalize() +s32 cellSync2SemaphoreFinalize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x52F0, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2SemaphoreAcquire() +s32 cellSync2SemaphoreAcquire() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x57A4, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2SemaphoreTryAcquire() +s32 cellSync2SemaphoreTryAcquire() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x56D8, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2SemaphoreRelease() +s32 cellSync2SemaphoreRelease() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x5870, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2SemaphoreGetCount() +s32 cellSync2SemaphoreGetCount() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x4B4C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 _cellSync2QueueAttributeInitialize(vm::ptr attr, u32 sdkVersion) +s32 _cellSync2QueueAttributeInitialize(vm::ptr attr, u32 sdkVersion) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x3C5C, libsync2_rtoc); -#else cellSync2.Warning("_cellSync2QueueAttributeInitialize(attr_addr=0x%x, sdkVersion=0x%x)", attr.addr(), sdkVersion); attr->sdkVersion = sdkVersion; @@ -308,15 +188,10 @@ s64 _cellSync2QueueAttributeInitialize(vm::ptr attr, u3 strcpy_trunc(attr->name, "CellSync2Queue"); return CELL_OK; -#endif } -s64 cellSync2QueueEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) +s32 cellSync2QueueEstimateBufferSize(vm::ptr attr, vm::ptr bufferSize) { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x2A98, libsync2_rtoc); -#else cellSync2.Todo("cellSync2QueueEstimateBufferSize(attr_addr=0x%x, bufferSize_addr=0x%x)", attr.addr(), bufferSize.addr()); if (attr->elementSize == 0 || attr->elementSize > 16384 || attr->elementSize % 16 || attr->depth == 0 || attr->depth > 4294967292 || @@ -324,95 +199,54 @@ s64 cellSync2QueueEstimateBufferSize(vm::ptr attr return CELL_SYNC2_ERROR_INVAL; return CELL_OK; -#endif } -s64 cellSync2QueueInitialize() +s32 cellSync2QueueInitialize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x3F98, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueueFinalize() +s32 cellSync2QueueFinalize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x3C28, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueuePush() +s32 cellSync2QueuePush() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x478C, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueueTryPush() +s32 cellSync2QueueTryPush() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x4680, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueuePop() +s32 cellSync2QueuePop() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x4974, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueueTryPop() +s32 cellSync2QueueTryPop() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x4880, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueueGetSize() +s32 cellSync2QueueGetSize() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x2C00, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } -s64 cellSync2QueueGetDepth() +s32 cellSync2QueueGetDepth() { -#ifdef PRX_DEBUG - cellSync2.Warning("%s()", __FUNCTION__); - return GetCurrentPPUThread().FastCall2(libsync2 + 0x2B90, libsync2_rtoc); -#else UNIMPLEMENTED_FUNC(cellSync2); return CELL_OK; -#endif } Module cellSync2("cellSync2", []() @@ -452,37 +286,4 @@ Module cellSync2("cellSync2", []() cellSync2.AddFunc(0x0c9a0ea9, cellSync2QueueTryPop); cellSync2.AddFunc(0x12f0a27d, cellSync2QueueGetSize); cellSync2.AddFunc(0xf0e1471c, cellSync2QueueGetDepth); - -#ifdef PRX_DEBUG - CallAfter([]() - { - if (!Memory.MainMem.GetStartAddr()) return; - - libsync2 = (u32)Memory.MainMem.AllocAlign(sizeof(libsync2_data), 0x100000); - memcpy(vm::get_ptr(libsync2), libsync2_data, sizeof(libsync2_data)); - libsync2_rtoc = libsync2 + 0xF280; - - extern Module* sysPrxForUser; - extern Module* cellSpurs; - extern Module* cellSpursJq; - extern Module* cellFiber; - - FIX_IMPORT(cellSpurs, _cellSpursSendSignal , libsync2 + 0x61F0); - FIX_IMPORT(cellSpursJq, cellSpursJobQueueSendSignal , libsync2 + 0x6210); - FIX_IMPORT(cellFiber, cellFiberPpuUtilWorkerControlSendSignal , libsync2 + 0x6230); - FIX_IMPORT(cellFiber, cellFiberPpuSelf , libsync2 + 0x6250); - FIX_IMPORT(cellFiber, cellFiberPpuWaitSignal , libsync2 + 0x6270); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_lock , libsync2 + 0x6290); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_unlock , libsync2 + 0x62B0); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_create , libsync2 + 0x62D0); - FIX_IMPORT(sysPrxForUser, sys_ppu_thread_get_id , libsync2 + 0x62F0); - FIX_IMPORT(sysPrxForUser, _sys_memset , libsync2 + 0x6310); - FIX_IMPORT(sysPrxForUser, _sys_printf , libsync2 + 0x6330); - fix_import(sysPrxForUser, 0x9FB6228E , libsync2 + 0x6350); - FIX_IMPORT(sysPrxForUser, sys_lwmutex_destroy , libsync2 + 0x6370); - FIX_IMPORT(sysPrxForUser, _sys_strncpy , libsync2 + 0x6390); - - fix_relocs(cellSync2, libsync2, 0x73A0, 0x95A0, 0x6B90); - }); -#endif }); From 2d1d996c508d79b0f5ddffe3b6e99910997b5658 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Feb 2015 14:18:28 +0300 Subject: [PATCH 24/25] Small fix --- Utilities/Thread.cpp | 2 +- rpcs3/Emu/Cell/PPUThread.cpp | 4 +--- rpcs3/Emu/Cell/PPUThread.h | 16 +++++++++++++++- rpcs3/Emu/SysCalls/Modules.h | 2 +- rpcs3/Emu/SysCalls/lv2/sys_prx.cpp | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index a47f656695..d379528d5e 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -270,7 +270,7 @@ void decode_x64_reg_op(const u8* code, x64_op_t& out_op, x64_reg_t& out_reg, siz { case 0x7f: { - if (repe && !oso) // MOVDQU xmm/m, xmm + if ((repe && !oso) || (!repe && oso)) // MOVDQU/MOVDQA xmm/m, xmm { out_op = X64OP_STORE; out_reg = get_modRM_reg_xmm(code, rex); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 08d0f15815..01b3a94b9e 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -189,7 +189,7 @@ u64 PPUThread::GetStackArg(s32 i) return vm::read64(vm::cast(GPR[1] + 0x70 + 0x8 * (i - 9))); } -u64 PPUThread::FastCall2(u32 addr, u32 rtoc) +void PPUThread::FastCall2(u32 addr, u32 rtoc) { auto old_status = m_status; auto old_PC = PC; @@ -212,8 +212,6 @@ u64 PPUThread::FastCall2(u32 addr, u32 rtoc) GPR[2] = old_rtoc; LR = old_LR; SetCurrentNamedThread(old_thread); - - return GPR[3]; } void PPUThread::FastStop() diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 88f1cb392c..64c11c7563 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -793,13 +793,27 @@ public: return false; } + u64 get_next_gpr_arg(u32& g_count, u32& f_count, u32& v_count) + { + assert(!f_count && !v_count); // not supported + + if (g_count < 8) + { + return GPR[g_count++ + 3]; + } + else + { + return GetStackArg(++g_count); + } + } + public: virtual void InitRegs() override; virtual void InitStack() override; virtual void CloseStack() override; virtual void Task() override; u64 GetStackArg(s32 i); - u64 FastCall2(u32 addr, u32 rtoc); + void FastCall2(u32 addr, u32 rtoc); void FastStop(); virtual void DoRun() override; diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index a2f803a95c..856430a235 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -179,4 +179,4 @@ void fix_relocs(Module* module, u32 lib, u32 start, u32 end, u32 seg2); #define REG_FUNC(module, name) module.AddFunc(get_function_id(#name), name) -#define UNIMPLEMENTED_FUNC(module) module.Fatal("%s", __FUNCTION__) +#define UNIMPLEMENTED_FUNC(module) module.Error("%s", __FUNCTION__) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index cf3cc9f17e..70def9c4a3 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -126,7 +126,7 @@ s32 sys_prx_get_module_id_by_address() s32 sys_prx_get_module_id_by_name() { sys_prx.Todo("sys_prx_get_module_id_by_name()"); - return CELL_OK; + return CELL_PRX_ERROR_UNKNOWN_MODULE; } s32 sys_prx_get_module_info() From fed1418c0eb921a0f6f7359c6bb468aba3f31bcb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 19 Feb 2015 16:47:53 +0300 Subject: [PATCH 25/25] Loader fix --- rpcs3/Emu/SysCalls/Modules.cpp | 5 ++- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 9 ----- rpcs3/Emu/SysCalls/Modules/cellSync.h | 27 +++++++++++-- rpcs3/Loader/ELF64.cpp | 54 ++++++++++++++++++++++--- 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 7c038025ca..523f572c59 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -1,7 +1,9 @@ #include "stdafx.h" +#include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/SysCalls/Modules.h" +#include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/Static.h" #include "Emu/SysCalls/CB_FUNC.h" #include "Crypto/sha1.h" @@ -84,7 +86,8 @@ void execute_ps3_func_by_index(PPUThread& CPU, u32 index) } else { - throw "Unimplemented function"; + LOG_ERROR(HLE, "Unimplemented function %s", SysCalls::GetHLEFuncName(func->id)); + CPU.GPR[3] = 0; } CPU.m_last_syscall = old_last_syscall; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index eb9d622c8d..0894a4e53b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -829,15 +829,6 @@ s32 cellSyncQueueClear(vm::ptr queue) // LFQueue functions -void syncLFQueueDump(vm::ptr queue) -{ - cellSync.Notice("CellSyncLFQueue dump: addr = 0x%x", queue.addr()); - for (u32 i = 0; i < sizeof(CellSyncLFQueue) / 16; i++) - { - cellSync.Notice("*** 0x%.16llx 0x%.16llx", vm::read64(queue.addr() + i * 16), vm::read64(queue.addr() + i * 16 + 8)); - } -} - void syncLFQueueInit(vm::ptr queue, vm::ptr buffer, u32 size, u32 depth, CellSyncQueueDirection direction, vm::ptr eaSignal) { queue->m_size = size; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.h b/rpcs3/Emu/SysCalls/Modules/cellSync.h index 998418615a..ba7ab97781 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.h @@ -135,16 +135,18 @@ struct CellSyncLFQueue be_t m_h6; }; - union + union // 0x0 { - atomic_t pop1; // 0x0 + atomic_t pop1; atomic_t pop3; }; - union + + union // 0x8 { - atomic_t push1; // 0x8 + atomic_t push1; atomic_t push3; }; + be_t m_size; // 0x10 be_t m_depth; // 0x14 vm::bptr m_buffer; // 0x18 @@ -159,6 +161,23 @@ struct CellSyncLFQueue vm::bptr m_eaSignal; // 0x70 be_t m_v2; // 0x78 be_t m_eq_id; // 0x7C + + std::string dump() + { + std::string res = "CellSyncLFQueue dump:"; + + auto data = (be_t*)this; + + for (u32 i = 0; i < sizeof(CellSyncLFQueue) / sizeof(u64); i += 2) + { + res += "\n*** 0x"; + res += fmt::to_hex(data[i + 0], 16); + res += " 0x"; + res += fmt::to_hex(data[i + 1], 16); + } + + return res; + } }; static_assert(sizeof(CellSyncLFQueue) == 128, "CellSyncLFQueue: wrong size"); diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index e3de0bb9fd..dfb12aee06 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -303,6 +303,7 @@ namespace loader std::vector start_funcs; std::vector stop_funcs; + std::vector exit_funcs; //load modules vfsDir lle_dir("/dev_flash/sys/external"); @@ -341,12 +342,48 @@ namespace loader { for (auto &e : m.second.exports) { + auto code = vm::ptr::make(vm::check_addr(e.second, 8) ? vm::read32(e.second) : 0); + + bool is_empty = !code || (code[0] == 0x38600000 && code[1] == BLR()); + + if (!code) + { + LOG_ERROR(LOADER, "bad OPD of special function 0x%08x in '%s' library (0x%x)", e.first, info.name.c_str(), code); + } + switch (e.first) { - case 0xbc9a0086: start_funcs.push_back(e.second); break; - case 0xab779874: stop_funcs.push_back(e.second); break; + case 0xbc9a0086: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "start func found in '%s' library (0x%x)", info.name.c_str(), code); + start_funcs.push_back(e.second); + } + break; + } - default: LOG_ERROR(LOADER, "unknown special func 0x%08x in '%s' library", e.first, info.name.c_str()); break; + case 0xab779874: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "stop func found in '%s' library (0x%x)", info.name.c_str(), code); + stop_funcs.push_back(e.second); + } + break; + } + + case 0x3ab9a95e: + { + if (!is_empty) + { + LOG_ERROR(LOADER, "exit func found in '%s' library (0x%x)", info.name.c_str(), code); + exit_funcs.push_back(e.second); + } + break; + } + + default: LOG_ERROR(LOADER, "unknown special func 0x%08x in '%s' library (0x%x)", e.first, info.name.c_str(), code); break; } } @@ -385,8 +422,15 @@ namespace loader LOG_NOTICE(LOADER, "Imported function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); } - vm::write32(addr + 0, HACK(index)); - vm::write32(addr + 4, BLR()); + if (!vm::check_addr(addr, 8)) + { + LOG_ERROR(LOADER, "Failed to inject code for function '%s' (0x%x)", SysCalls::GetHLEFuncName(nid), addr); + } + else + { + vm::write32(addr + 0, HACK(index)); + vm::write32(addr + 4, BLR()); + } } } }