diff --git a/rpcs3/Emu/Cell/ErrorCodes.h b/rpcs3/Emu/Cell/ErrorCodes.h index 05445a6aa0..15c0698bb8 100644 --- a/rpcs3/Emu/Cell/ErrorCodes.h +++ b/rpcs3/Emu/Cell/ErrorCodes.h @@ -110,9 +110,12 @@ struct ppu_error_code { } + // Helper + enum class not_an_error : s32 {}; + // Silence any error - constexpr ppu_error_code(s32 value, const std::nothrow_t&) - : value(value) + constexpr ppu_error_code(not_an_error value) + : value(static_cast<s32>(value)) { } @@ -124,7 +127,7 @@ struct ppu_error_code }; // Helper macro for silencing possible error checks on returning ppu_error_code values -#define NOT_AN_ERROR(value) { static_cast<s32>(value), std::nothrow } +#define NOT_AN_ERROR(...) static_cast<ppu_error_code::not_an_error>(__VA_ARGS__) template<typename T, typename> struct ppu_gpr_cast_impl; diff --git a/rpcs3/Emu/Cell/Modules/cellAdec.cpp b/rpcs3/Emu/Cell/Modules/cellAdec.cpp index b6acc1f23c..6214c8fb41 100644 --- a/rpcs3/Emu/Cell/Modules/cellAdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAdec.cpp @@ -15,7 +15,9 @@ extern "C" #include "cellPamf.h" #include "cellAdec.h" -LOG_CHANNEL(cellAdec); +#include <thread> + +logs::channel cellAdec("cellAdec", logs::level::notice); AudioDecoder::AudioDecoder(s32 type, u32 addr, u32 size, vm::ptr<CellAdecCbMsg> func, u32 arg) : type(type) @@ -468,7 +470,7 @@ void adecOpen(u32 adec_id) // TODO: call from the constructor adec.adecCb->cpu_init(); adec.adecCb->state -= cpu_state::stop; - adec.adecCb->lock_notify(); + (*adec.adecCb)->lock_notify(); } bool adecCheckType(s32 type) @@ -569,7 +571,7 @@ s32 cellAdecClose(u32 handle) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove<PPUThread>(adec->adecCb->id); @@ -682,7 +684,7 @@ s32 cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer) AdecFrame af; if (!adec->frames.try_pop(af)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_ADEC_ERROR_EMPTY; } @@ -798,7 +800,7 @@ s32 cellAdecGetPcmItem(u32 handle, vm::pptr<CellAdecPcmItem> pcmItem) AdecFrame af; if (!adec->frames.try_peek(af)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_ADEC_ERROR_EMPTY; } diff --git a/rpcs3/Emu/Cell/Modules/cellAtrac.cpp b/rpcs3/Emu/Cell/Modules/cellAtrac.cpp index d251fe9bcb..0a6fb4360e 100644 --- a/rpcs3/Emu/Cell/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAtrac.cpp @@ -4,7 +4,7 @@ #include "cellAtrac.h" -LOG_CHANNEL(cellAtrac); +logs::channel cellAtrac("cellAtrac", logs::level::notice); s32 cellAtracSetDataAndGetMemSize(vm::ptr<CellAtracHandle> pHandle, vm::ptr<u8> pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, vm::ptr<u32> puiWorkMemByte) { diff --git a/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp b/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp index 75e1263f62..c7dac5b60b 100644 --- a/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAtracMulti.cpp @@ -4,7 +4,7 @@ #include "cellAtracMulti.h" -LOG_CHANNEL(cellAtracMulti); +logs::channel cellAtracMulti("cellAtracMulti", logs::level::notice); s32 cellAtracMultiSetDataAndGetMemSize(vm::ptr<CellAtracMultiHandle> pHandle, vm::ptr<u8> pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, u32 uiOutputChNum, vm::ptr<s32> piTrackArray, vm::ptr<u32> puiWorkMemByte) { diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index 9a119a0865..a6364a6ed0 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" @@ -8,7 +9,9 @@ #include "Emu/Audio/AudioThread.h" #include "cellAudio.h" -LOG_CHANNEL(cellAudio); +#include <thread> + +logs::channel cellAudio("cellAudio", logs::level::notice); cfg::bool_entry g_cfg_audio_dump_to_file(cfg::root.audio, "Dump to file"); cfg::bool_entry g_cfg_audio_convert_to_u16(cfg::root.audio, "Convert to 16 bit"); diff --git a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp index 8383a7657f..0472272b0a 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudioOut.cpp @@ -3,7 +3,7 @@ #include "cellAudioOut.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) { diff --git a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp index 7a005dc34a..fc7bb16c26 100644 --- a/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAvconfExt.cpp @@ -6,7 +6,7 @@ #include "cellAudioOut.h" #include "cellVideoOut.h" -LOG_CHANNEL(cellAvconfExt); +logs::channel cellAvconfExt("cellAvconfExt", logs::level::notice); vm::gvar<f32> g_gamma; // TODO diff --git a/rpcs3/Emu/Cell/Modules/cellBgdl.cpp b/rpcs3/Emu/Cell/Modules/cellBgdl.cpp index b83c0fa791..8847bafebd 100644 --- a/rpcs3/Emu/Cell/Modules/cellBgdl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellBgdl.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellBGDL); +logs::channel cellBGDL("cellBGDL", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.cpp b/rpcs3/Emu/Cell/Modules/cellCamera.cpp index 6a2c491a43..9c445f1a65 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCamera.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/IdManager.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" #include "cellCamera.h" -LOG_CHANNEL(cellCamera); +logs::channel cellCamera("cellCamera", logs::level::notice); cfg::map_entry<bool> g_cfg_camera(cfg::root.io, "Camera", { diff --git a/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp b/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp index bb0b24b9ef..b834d9b57d 100644 --- a/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCelp8Enc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellCelp8Enc); +logs::channel cellCelp8Enc("cellCelp8Enc", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp b/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp index bb551877bb..0cd61d2504 100644 --- a/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCelpEnc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellCelpEnc); +logs::channel cellCelpEnc("cellCelpEnc", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellDaisy.cpp b/rpcs3/Emu/Cell/Modules/cellDaisy.cpp index bd82c4d31b..4f37bc46e7 100644 --- a/rpcs3/Emu/Cell/Modules/cellDaisy.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDaisy.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellDaisy); +logs::channel cellDaisy("cellDaisy", logs::level::notice); s32 _ZN4cell5Daisy17LFQueue2PushCloseEPNS0_8LFQueue2EPFiPvjE() { diff --git a/rpcs3/Emu/Cell/Modules/cellDmux.cpp b/rpcs3/Emu/Cell/Modules/cellDmux.cpp index cb86cb76bb..7ea8c97263 100644 --- a/rpcs3/Emu/Cell/Modules/cellDmux.cpp +++ b/rpcs3/Emu/Cell/Modules/cellDmux.cpp @@ -6,7 +6,9 @@ #include "cellPamf.h" #include "cellDmux.h" -LOG_CHANNEL(cellDmux); +#include <thread> + +logs::channel cellDmux("cellDmux", logs::level::notice); PesHeader::PesHeader(DemuxerStream& stream) : pts(CODEC_TS_INVALID) @@ -142,7 +144,7 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra u32 addr; { std::lock_guard<std::mutex> lock(m_mutex); - ASSERT(!is_full(size)); + VERIFY(!is_full(size)); if (put + size + 128 > memAddr + memSize) { @@ -183,7 +185,7 @@ void ElementaryStream::push_au(u32 size, u64 dts, u64 pts, u64 userdata, bool ra put_count++; } - ASSERT(entries.push(addr, &dmux->is_closed)); + VERIFY(entries.push(addr, &dmux->is_closed)); } void ElementaryStream::push(DemuxerStream& stream, u32 size) @@ -447,7 +449,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor if (es.raw_data.size() > 1024 * 1024) { stream = backup; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -543,7 +545,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor if (es.isfull(old_size)) { stream = backup; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -711,7 +713,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor { if (Emu.IsStopped() || dmux.is_closed) break; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } es.push_au(old_size, es.last_dts, es.last_pts, stream.userdata, false, 0); @@ -759,7 +761,7 @@ void dmuxOpen(u32 dmux_id) // TODO: call from the constructor dmux.dmuxCb->cpu_init(); dmux.dmuxCb->state -= cpu_state::stop; - dmux.dmuxCb->lock_notify(); + (*dmux.dmuxCb)->lock_notify(); } s32 cellDmuxQueryAttr(vm::cptr<CellDmuxType> type, vm::ptr<CellDmuxAttr> attr) @@ -865,7 +867,7 @@ s32 cellDmuxClose(u32 handle) return CELL_OK; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove<PPUThread>(dmux->dmuxCb->id); @@ -886,7 +888,7 @@ s32 cellDmuxSetStream(u32 handle, u32 streamAddress, u32 streamSize, b8 disconti if (dmux->is_running.exchange(true)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_DMUX_ERROR_BUSY; } @@ -943,7 +945,7 @@ s32 cellDmuxResetStreamAndWaitDone(u32 handle) cellDmux.warning("cellDmuxResetStreamAndWaitDone(%d) aborted", handle); return CELL_OK; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellFiber.cpp b/rpcs3/Emu/Cell/Modules/cellFiber.cpp index ba744dc37a..8229bb859d 100644 --- a/rpcs3/Emu/Cell/Modules/cellFiber.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFiber.cpp @@ -4,7 +4,7 @@ #include "cellFiber.h" -LOG_CHANNEL(cellFiber); +logs::channel cellFiber("cellFiber", logs::level::notice); s32 _cellFiberPpuInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellFont.cpp b/rpcs3/Emu/Cell/Modules/cellFont.cpp index 0d3f10c2a5..cc3df1b933 100644 --- a/rpcs3/Emu/Cell/Modules/cellFont.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFont.cpp @@ -8,7 +8,7 @@ #include "cellFont.h" -LOG_CHANNEL(cellFont); +logs::channel cellFont("cellFont", logs::level::notice); // Functions s32 cellFontInitializeWithRevision(u64 revisionFlags, vm::ptr<CellFontConfig> config) diff --git a/rpcs3/Emu/Cell/Modules/cellFontFT.cpp b/rpcs3/Emu/Cell/Modules/cellFontFT.cpp index 5821d440c6..20b3167a9f 100644 --- a/rpcs3/Emu/Cell/Modules/cellFontFT.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFontFT.cpp @@ -3,7 +3,7 @@ #include "cellFontFT.h" -LOG_CHANNEL(cellFontFT); +logs::channel cellFontFT("cellFontFT", logs::level::notice); s32 cellFontInitLibraryFreeTypeWithRevision(u64 revisionFlags, vm::ptr<CellFontLibraryConfigFT> config, vm::pptr<CellFontLibrary> lib) { diff --git a/rpcs3/Emu/Cell/Modules/cellFs.cpp b/rpcs3/Emu/Cell/Modules/cellFs.cpp index 220df6262a..1ac9a05dfe 100644 --- a/rpcs3/Emu/Cell/Modules/cellFs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellFs.cpp @@ -8,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellFs); +logs::channel cellFs("cellFs", logs::level::notice); s32 cellFsOpen(vm::cptr<char> path, s32 flags, vm::ptr<u32> fd, vm::cptr<void> arg, u64 size) { @@ -527,7 +527,7 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) } } - file->cv.wait_for(lock, std::chrono::milliseconds(1)); + file->cv.wait_for(lock, 1ms); } file->st_status.compare_and_swap(SSS_STOPPED, SSS_INITIALIZED); @@ -688,7 +688,7 @@ s32 cellFsStReadWait(u32 fd, u64 size) { CHECK_EMU_STATUS; - file->cv.wait_for(lock, std::chrono::milliseconds(1)); + file->cv.wait_for(lock, 1ms); } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellGame.cpp b/rpcs3/Emu/Cell/Modules/cellGame.cpp index 632d72000b..32bace6827 100644 --- a/rpcs3/Emu/Cell/Modules/cellGame.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGame.cpp @@ -10,7 +10,9 @@ #include "Loader/PSF.h" #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellGame); +#include <thread> + +logs::channel cellGame("cellGame", logs::level::notice); // Normal content directory (if is_temporary is not involved): // contentInfo = dir @@ -308,7 +310,7 @@ ppu_error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentIn } // Create PARAM.SFO - fs::file(dir + "/PARAM.SFO", fs::rewrite).write(psf::save_object(prm->sfo)); + psf::save_object(fs::file(dir + "/PARAM.SFO", fs::rewrite), prm->sfo); // Disable deletion prm->is_temporary = false; @@ -555,7 +557,7 @@ ppu_error_code cellGameGetParamString(s32 id, vm::ptr<char> buf, u32 bufsize) std::string&& value = psf::get_string(prm->sfo, key); value.resize(bufsize - 1); - std::copy_n(value.c_str(), value.size() + 1, buf.get_ptr()); + std::memcpy(buf.get_ptr(), value.c_str(), bufsize); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp index 9367db8796..411f51043a 100644 --- a/rpcs3/Emu/Cell/Modules/cellGameExec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGameExec.cpp @@ -3,7 +3,7 @@ #include "cellGame.h" -LOG_CHANNEL(cellGameExec); +logs::channel cellGameExec("cellGameExec", logs::level::notice); s32 cellGameSetExitParam() { diff --git a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp index cb290a71a1..962218925c 100644 --- a/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGcmSys.cpp @@ -8,7 +8,9 @@ #include "Emu/RSX/GSRender.h" #include "cellGcmSys.h" -LOG_CHANNEL(cellGcmSys); +#include <thread> + +logs::channel cellGcmSys("cellGcmSys", logs::level::notice); extern s32 cellGcmCallback(vm::ptr<CellGcmContextData> context, u32 count); @@ -933,7 +935,7 @@ 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); - ASSERT(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/); + VERIFY(flags == 2 /*CELL_GCM_IOMAP_FLAG_STRICT_ORDERING*/); return gcmMapEaIoAddress(ea, io, size, true); } @@ -1257,7 +1259,7 @@ static std::pair<u32, u32> getNextCommandBufferBeginEnd(u32 current) static u32 getOffsetFromAddress(u32 address) { const u32 upper = offsetTable.ioAddress[address >> 20]; // 12 bits - Expects(upper != 0xFFFF); + EXPECTS(upper != 0xFFFF); return (upper << 20) | (address & 0xFFFFF); } diff --git a/rpcs3/Emu/Cell/Modules/cellGem.cpp b/rpcs3/Emu/Cell/Modules/cellGem.cpp index f10e41ea58..a33cd86879 100644 --- a/rpcs3/Emu/Cell/Modules/cellGem.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGem.cpp @@ -4,7 +4,7 @@ #include "cellGem.h" -LOG_CHANNEL(cellGem); +logs::channel cellGem("cellGem", logs::level::notice); struct gem_t { diff --git a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp index 64c10ca7cf..f5420ed299 100644 --- a/rpcs3/Emu/Cell/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellGifDec.cpp @@ -9,7 +9,7 @@ #include "Emu/Cell/lv2/sys_fs.h" #include "cellGifDec.h" -LOG_CHANNEL(cellGifDec); +logs::channel cellGifDec("cellGifDec", logs::level::notice); // cellGifDec aliases (only for cellGifDec.cpp) using PPMainHandle = vm::pptr<GifDecoder>; diff --git a/rpcs3/Emu/Cell/Modules/cellHttp.cpp b/rpcs3/Emu/Cell/Modules/cellHttp.cpp index 46328b1cf7..e8036bdc30 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellHttp); +logs::channel cellHttp("cellHttp", logs::level::notice); s32 cellHttpInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp index 35c7c5328c..c68c4344ce 100644 --- a/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellHttpUtil.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellHttpUtil); +logs::channel cellHttpUtil("cellHttpUtil", logs::level::notice); s32 cellHttpUtilParseUri() { diff --git a/rpcs3/Emu/Cell/Modules/cellImejp.cpp b/rpcs3/Emu/Cell/Modules/cellImejp.cpp index 278103fd3f..4a56d547de 100644 --- a/rpcs3/Emu/Cell/Modules/cellImejp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellImejp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellImeJp); +logs::channel cellImeJp("cellImeJp", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp index 3fcb2a967e..2cfc9f5efc 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellJpgDec.cpp @@ -9,7 +9,7 @@ #include "Emu/Cell/lv2/sys_fs.h" #include "cellJpgDec.h" -LOG_CHANNEL(cellJpgDec); +logs::channel cellJpgDec("cellJpgDec", logs::level::notice); s32 cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { diff --git a/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp b/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp index 605a04e930..96a46b3900 100644 --- a/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellJpgEnc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellJpgEnc); +logs::channel cellJpgEnc("cellJpgEnc", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellKb.cpp b/rpcs3/Emu/Cell/Modules/cellKb.cpp index a4647993b1..08d69ae94d 100644 --- a/rpcs3/Emu/Cell/Modules/cellKb.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKb.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/KeyboardHandler.h" #include "cellKb.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellKbInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp index 3a51a3c347..9ca2554aea 100644 --- a/rpcs3/Emu/Cell/Modules/cellKey2char.cpp +++ b/rpcs3/Emu/Cell/Modules/cellKey2char.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellKey2char); +logs::channel cellKey2char("cellKey2char", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellL10n.cpp b/rpcs3/Emu/Cell/Modules/cellL10n.cpp index 73ec6cad6c..7dbc9c3da5 100644 --- a/rpcs3/Emu/Cell/Modules/cellL10n.cpp +++ b/rpcs3/Emu/Cell/Modules/cellL10n.cpp @@ -14,7 +14,7 @@ typedef const char *HostCode; #include "cellL10n.h" -LOG_CHANNEL(cellL10n); +logs::channel cellL10n("cellL10n", logs::level::notice); // Translate code id to code name. some codepage may has another name. // If this makes your compilation fail, try replace the string code with one in "iconv -l" diff --git a/rpcs3/Emu/Cell/Modules/cellMic.cpp b/rpcs3/Emu/Cell/Modules/cellMic.cpp index b0cd2b8ba7..059d508642 100644 --- a/rpcs3/Emu/Cell/Modules/cellMic.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMic.cpp @@ -4,7 +4,7 @@ #include "cellMic.h" -LOG_CHANNEL(cellMic); +logs::channel cellMic("cellMic", logs::level::notice); s32 cellMicInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellMouse.cpp b/rpcs3/Emu/Cell/Modules/cellMouse.cpp index e9cea73dc8..fd91435ed9 100644 --- a/rpcs3/Emu/Cell/Modules/cellMouse.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMouse.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/MouseHandler.h" #include "cellMouse.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellMouseInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp index 880a126d1c..e4c7fe221c 100644 --- a/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMsgDialog.cpp @@ -6,7 +6,9 @@ #include "cellSysutil.h" #include "cellMsgDialog.h" -extern _log::channel cellSysutil; +#include <thread> + +extern logs::channel cellSysutil; s32 cellMsgDialogOpen() { diff --git a/rpcs3/Emu/Cell/Modules/cellMusic.cpp b/rpcs3/Emu/Cell/Modules/cellMusic.cpp index 6fe8cd4146..7cd839bfdd 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusic.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusic.cpp @@ -5,7 +5,7 @@ #include "cellMusic.h" -LOG_CHANNEL(cellMusic); +logs::channel cellMusic("cellMusic", logs::level::notice); struct music2_t { diff --git a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp index dcb43e75a8..f850afa90d 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicDecode.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellMusicDecode); +logs::channel cellMusicDecode("cellMusicDecode", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp b/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp index 0c614e907e..924306c3b3 100644 --- a/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellMusicExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellMusicExport); +logs::channel cellMusicExport("cellMusicExport", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp index 65ceda8e18..4114c89444 100644 --- a/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellNetCtl.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" @@ -7,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellNetCtl); +logs::channel cellNetCtl("cellNetCtl", logs::level::notice); cfg::map_entry<s32> g_cfg_net_status(cfg::root.net, "Connection status", { diff --git a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp index ccc0c51f7f..605d59578a 100644 --- a/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOskDialog.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellOskDialog); +logs::channel cellOskDialog("cellOskDialog", logs::level::notice); s32 cellOskDialogLoadAsync() { diff --git a/rpcs3/Emu/Cell/Modules/cellOvis.cpp b/rpcs3/Emu/Cell/Modules/cellOvis.cpp index 49e22da87f..2b4716f959 100644 --- a/rpcs3/Emu/Cell/Modules/cellOvis.cpp +++ b/rpcs3/Emu/Cell/Modules/cellOvis.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellOvis); +logs::channel cellOvis("cellOvis", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPad.cpp b/rpcs3/Emu/Cell/Modules/cellPad.cpp index f0441cc739..bed38f18de 100644 --- a/rpcs3/Emu/Cell/Modules/cellPad.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPad.cpp @@ -6,7 +6,7 @@ #include "Emu/Io/PadHandler.h" #include "cellPad.h" -extern _log::channel sys_io; +extern logs::channel sys_io; s32 cellPadInit(u32 max_connect) { diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.cpp b/rpcs3/Emu/Cell/Modules/cellPamf.cpp index fcd64720b6..a4a05d92f7 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPamf.cpp @@ -12,12 +12,12 @@ bool squeue_test_exit() return Emu.IsStopped(); } -LOG_CHANNEL(cellPamf); +logs::channel cellPamf("cellPamf", logs::level::notice); s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) { // convert type and ch to EsFilterId - Expects(ch < 16); + EXPECTS(ch < 16); pEsFilterId.supplementalInfo1 = type == CELL_PAMF_STREAM_TYPE_AVC; pEsFilterId.supplementalInfo2 = 0; @@ -117,7 +117,7 @@ s32 pamfStreamTypeToEsFilterId(u8 type, u8 ch, CellCodecEsFilterId& pEsFilterId) u8 pamfGetStreamType(vm::ptr<CellPamfReader> pSelf, u32 stream) { // TODO: get stream type correctly - Expects(stream < (u32)pSelf->pAddr->stream_count); + EXPECTS(stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[stream]; switch (header.type) @@ -138,7 +138,7 @@ u8 pamfGetStreamType(vm::ptr<CellPamfReader> pSelf, u32 stream) u8 pamfGetStreamChannel(vm::ptr<CellPamfReader> pSelf, u32 stream) { // TODO: get stream channel correctly - Expects(stream < (u32)pSelf->pAddr->stream_count); + EXPECTS(stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[stream]; switch (header.type) @@ -146,29 +146,29 @@ u8 pamfGetStreamChannel(vm::ptr<CellPamfReader> pSelf, u32 stream) case 0x1b: // AVC case 0x02: // M2V { - Expects((header.fid_major & 0xf0) == 0xe0 && header.fid_minor == 0); + EXPECTS((header.fid_major & 0xf0) == 0xe0 && header.fid_minor == 0); return header.fid_major % 16; } case 0xdc: // ATRAC3PLUS { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0); return header.fid_minor % 16; } case 0x80: // LPCM { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x40); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x40); return header.fid_minor % 16; } case 0x81: // AC3 { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x30); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x30); return header.fid_minor % 16; } case 0xdd: { - Expects(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x20); + EXPECTS(header.fid_major == 0xbd && (header.fid_minor & 0xf0) == 0x20); return header.fid_minor % 16; } } @@ -454,7 +454,7 @@ s32 cellPamfReaderGetEsFilterId(vm::ptr<CellPamfReader> pSelf, vm::ptr<CellCodec // always returns CELL_OK - Expects((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); + EXPECTS((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; pEsFilterId->filterIdMajor = header.fid_major; pEsFilterId->filterIdMinor = header.fid_minor; @@ -467,7 +467,7 @@ s32 cellPamfReaderGetStreamInfo(vm::ptr<CellPamfReader> pSelf, vm::ptr<void> pIn { cellPamf.warning("cellPamfReaderGetStreamInfo(pSelf=*0x%x, pInfo=*0x%x, size=%d)", pSelf, pInfo, size); - Expects((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); + EXPECTS((u32)pSelf->stream < (u32)pSelf->pAddr->stream_count); auto& header = pSelf->pAddr->stream_headers[pSelf->stream]; const u8 type = pamfGetStreamType(pSelf, pSelf->stream); const u8 ch = pamfGetStreamChannel(pSelf, pSelf->stream); diff --git a/rpcs3/Emu/Cell/Modules/cellPamf.h b/rpcs3/Emu/Cell/Modules/cellPamf.h index 4dd45b3256..60d042e77e 100644 --- a/rpcs3/Emu/Cell/Modules/cellPamf.h +++ b/rpcs3/Emu/Cell/Modules/cellPamf.h @@ -400,6 +400,8 @@ CHECK_SIZE(CellPamfReader, 128); s32 cellPamfReaderInitialize(vm::ptr<CellPamfReader> pSelf, vm::cptr<PamfHeader> pAddr, u64 fileSize, u32 attribute); +#include <mutex> +#include <condition_variable> extern const std::function<bool()> SQUEUE_ALWAYS_EXIT; extern const std::function<bool()> SQUEUE_NEVER_EXIT; @@ -462,8 +464,8 @@ public: while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.push_lock) { @@ -492,9 +494,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.push_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.push_lock); sync.push_lock = 0; sync.count++; }); @@ -525,8 +527,8 @@ public: while (u32 res = m_sync.atomic_op([&pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (!sync.count) { @@ -555,9 +557,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock); sync.pop_lock = 0; sync.position++; sync.count--; @@ -589,13 +591,13 @@ public: bool peek(T& data, u32 start_pos, const std::function<bool()>& test_exit) { - Expects(start_pos < sq_size); + EXPECTS(start_pos < sq_size); u32 pos = 0; while (u32 res = m_sync.atomic_op([&pos, start_pos](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.count <= start_pos) { @@ -624,9 +626,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock); sync.pop_lock = 0; }); @@ -665,7 +667,7 @@ public: public: T& operator [] (u32 index) { - Expects(index < m_count); + EXPECTS(index < m_count); index += m_pos; index = index < sq_size ? index : index - sq_size; return m_data[index]; @@ -678,8 +680,8 @@ public: while (m_sync.atomic_op([&pos, &count](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.pop_lock || sync.push_lock) { @@ -701,9 +703,9 @@ public: m_sync.atomic_op([](squeue_sync_var_t& sync) { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); - Expects(sync.pop_lock && sync.push_lock); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); + EXPECTS(sync.pop_lock && sync.push_lock); sync.pop_lock = 0; sync.push_lock = 0; }); @@ -716,8 +718,8 @@ public: { while (m_sync.atomic_op([](squeue_sync_var_t& sync) -> u32 { - Expects(sync.count <= sq_size); - Expects(sync.position < sq_size); + EXPECTS(sync.count <= sq_size); + EXPECTS(sync.position < sq_size); if (sync.pop_lock || sync.push_lock) { diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp index 90f759f1e4..6d971b8b1c 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoDecode.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoDecode); +logs::channel cellPhotoDecode("cellPhotoDecode", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp index 3b9f4a6381..dd1d76396d 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoExport); +logs::channel cellPhotoExport("cellPhotoExport", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp b/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp index 4bb17ce497..5813848716 100644 --- a/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPhotoImport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPhotoImportUtil); +logs::channel cellPhotoImportUtil("cellPhotoImportUtil", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp index 431170548e..82b8038ee5 100644 --- a/rpcs3/Emu/Cell/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPngDec.cpp @@ -7,7 +7,7 @@ #include "png.h" #include "cellPngDec.h" -LOG_CHANNEL(cellPngDec); +logs::channel cellPngDec("cellPngDec", logs::level::notice); // cellPngDec aliases to improve readability using PPHandle = vm::pptr<PngHandle>; diff --git a/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp b/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp index a1efb70795..5ccf49dadb 100644 --- a/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPngEnc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPngEnc); +logs::channel cellPngEnc("cellPngEnc", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellPrint.cpp b/rpcs3/Emu/Cell/Modules/cellPrint.cpp index b0a37969cd..648237c75f 100644 --- a/rpcs3/Emu/Cell/Modules/cellPrint.cpp +++ b/rpcs3/Emu/Cell/Modules/cellPrint.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellPrint); +logs::channel cellPrint("cellPrint", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellRec.cpp b/rpcs3/Emu/Cell/Modules/cellRec.cpp index ce3aa50e99..5d61b2d8c8 100644 --- a/rpcs3/Emu/Cell/Modules/cellRec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRec.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellRec); +logs::channel cellRec("cellRec", logs::level::notice); s32 cellRecOpen() { diff --git a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp index 0c7983bb12..fdd9c072cb 100644 --- a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellRemotePlay); +logs::channel cellRemotePlay("cellRemotePlay", logs::level::notice); s32 cellRemotePlayGetStatus() { diff --git a/rpcs3/Emu/Cell/Modules/cellResc.cpp b/rpcs3/Emu/Cell/Modules/cellResc.cpp index 00e1a5f8f9..182bfd0e14 100644 --- a/rpcs3/Emu/Cell/Modules/cellResc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellResc.cpp @@ -6,7 +6,7 @@ #include "Emu/RSX/GCM.h" #include "cellResc.h" -LOG_CHANNEL(cellResc); +logs::channel cellResc("cellResc", logs::level::notice); s32 cellRescInit(vm::ptr<CellRescInitConfig> initConfig) { diff --git a/rpcs3/Emu/Cell/Modules/cellRtc.cpp b/rpcs3/Emu/Cell/Modules/cellRtc.cpp index 8648da34ee..0c53abf9f4 100644 --- a/rpcs3/Emu/Cell/Modules/cellRtc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRtc.cpp @@ -3,7 +3,7 @@ #include "cellRtc.h" -LOG_CHANNEL(cellRtc); +logs::channel cellRtc("cellRtc", logs::level::notice); s64 convertToUNIXTime(u16 seconds, u16 minutes, u16 hours, u16 days, s32 years) { diff --git a/rpcs3/Emu/Cell/Modules/cellRudp.cpp b/rpcs3/Emu/Cell/Modules/cellRudp.cpp index f72f07fa01..c7ae11dfda 100644 --- a/rpcs3/Emu/Cell/Modules/cellRudp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRudp.cpp @@ -5,7 +5,7 @@ #include "cellRudp.h" -LOG_CHANNEL(cellRudp); +logs::channel cellRudp("cellRudp", logs::level::notice); struct rudp_t { diff --git a/rpcs3/Emu/Cell/Modules/cellSail.cpp b/rpcs3/Emu/Cell/Modules/cellSail.cpp index 8193c663ff..970bd2a324 100644 --- a/rpcs3/Emu/Cell/Modules/cellSail.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSail.cpp @@ -5,7 +5,7 @@ #include "cellSail.h" #include "cellPamf.h" -LOG_CHANNEL(cellSail); +logs::channel cellSail("cellSail", logs::level::notice); void playerBoot(vm::ptr<CellSailPlayer> pSelf, u64 userParam) { @@ -818,7 +818,7 @@ s32 cellSailPlayerCreateDescriptor(vm::ptr<CellSailPlayer> pSelf, s32 streamType u32 buffer = vm::alloc(size, vm::main); auto bufPtr = vm::cptr<PamfHeader>::make(buffer); PamfHeader *buf = const_cast<PamfHeader*>(bufPtr.get_ptr()); - ASSERT(f.read(buf, size) == size); + VERIFY(f.read(buf, size) == size); u32 sp_ = vm::alloc(sizeof(CellPamfReader), vm::main); auto sp = vm::ptr<CellPamfReader>::make(sp_); u32 reader = cellPamfReaderInitialize(sp, bufPtr, size, 0); diff --git a/rpcs3/Emu/Cell/Modules/cellSailRec.cpp b/rpcs3/Emu/Cell/Modules/cellSailRec.cpp index 7840bc8461..e7c7b7b306 100644 --- a/rpcs3/Emu/Cell/Modules/cellSailRec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSailRec.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSailRec); +logs::channel cellSailRec("cellSailRec", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp index 97389a9a41..b55023b667 100644 --- a/rpcs3/Emu/Cell/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSaveData.cpp @@ -7,7 +7,9 @@ #include "Loader/PSF.h" #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSaveData); +#include <algorithm> + +logs::channel cellSaveData("cellSaveData", logs::level::notice); // cellSaveData aliases (only for cellSaveData.cpp) using PSetList = vm::ptr<CellSaveDataSetList>; @@ -609,7 +611,7 @@ static never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, // Write PARAM.SFO if (psf.size()) { - fs::file(sfo_path, fs::rewrite).write(psf::save_object(psf)); + psf::save_object(fs::file(sfo_path, fs::rewrite), psf); } return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp index b062a1d5e8..613fa93f11 100644 --- a/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp +++ b/rpcs3/Emu/Cell/Modules/cellScreenshot.cpp @@ -4,7 +4,7 @@ #include "cellScreenshot.h" -LOG_CHANNEL(cellScreenshot); +logs::channel cellScreenshot("cellScreenshot", logs::level::notice); s32 cellScreenShotSetParameter() //const CellScreenShotSetParam *param { diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index 6c9e43fc6c..e1e199f450 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -4,7 +4,7 @@ #include "cellSearch.h" -LOG_CHANNEL(cellSearch); +logs::channel cellSearch("cellSearch", logs::level::notice); s32 cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr<CellSearchSystemCallback> func, vm::ptr<u32> userData) { diff --git a/rpcs3/Emu/Cell/Modules/cellSheap.cpp b/rpcs3/Emu/Cell/Modules/cellSheap.cpp index fe8ac83558..314178e1eb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSheap.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSheap.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSheap); +logs::channel cellSheap("cellSheap", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSpudll.cpp b/rpcs3/Emu/Cell/Modules/cellSpudll.cpp index 5aeaa9ae77..9d7b095223 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpudll.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpudll.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSpudll); +logs::channel cellSpudll("cellSpudll", logs::level::notice); s32 cellSpudllGetImageSize(vm::ptr<u32> psize, vm::cptr<void> so_elf, vm::cptr<struct CellSpudllHandleConfig> config) { diff --git a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp index d20b448ce4..db522166bb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpurs.cpp @@ -15,7 +15,7 @@ #include "sysPrxForUser.h" #include "cellSpurs.h" -LOG_CHANNEL(cellSpurs); +logs::channel cellSpurs("cellSpurs", logs::level::notice); // TODO struct cell_error_t @@ -30,6 +30,28 @@ struct cell_error_t #define CHECK_SUCCESS(expr) if (cell_error_t error{expr}) throw fmt::exception("Failure: %s -> 0x%x" HERE, #expr, error.value) +static u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function<void(PPUThread&)> task) +{ + const auto ppu = idm::make_ptr<PPUThread>(name); + + ppu->prio = prio; + ppu->stack_size = stacksize; + ppu->custom_task = std::move(task); + ppu->cpu_init(); + + if (entry) + { + ppu->pc = vm::read32(entry); + ppu->GPR[2] = vm::read32(entry + 4); // rtoc + } + + ppu->GPR[3] = arg; + ppu->state -= cpu_state::stop; + (*ppu)->lock_notify(); + + return ppu->id; +} + //---------------------------------------------------------------------------- // Function prototypes //---------------------------------------------------------------------------- @@ -588,7 +610,7 @@ void _spurs::handler_entry(PPUThread& ppu, vm::ptr<CellSpurs> spurs) if ((spurs->flags1 & SF1_EXIT_IF_NO_WORK) == 0) { - ASSERT(spurs->handlerExiting == 1); + VERIFY(spurs->handlerExiting == 1); return sys_ppu_thread_exit(ppu, 0); } @@ -651,16 +673,16 @@ s32 _spurs::wakeup_shutdown_completion_waiter(PPUThread& ppu, vm::ptr<CellSpurs> { wklF->hook(ppu, spurs, wid, wklF->hookArg); - ASSERT(wklEvent->load() & 0x01); - ASSERT(wklEvent->load() & 0x02); - ASSERT((wklEvent->load() & 0x20) == 0); + VERIFY(wklEvent->load() & 0x01); + VERIFY(wklEvent->load() & 0x02); + VERIFY((wklEvent->load() & 0x20) == 0); wklEvent->fetch_or(0x20); } s32 rc = CELL_OK; if (!wklF->hook || wklEvent->load() & 0x10) { - ASSERT(wklF->x28 == 2); + VERIFY(wklF->x28 == 2); rc = sys_semaphore_post((u32)wklF->sem, 1); } @@ -1027,7 +1049,7 @@ s32 _spurs::initialize(PPUThread& ppu, vm::ptr<CellSpurs> spurs, u32 revision, u // Import SPURS kernel spurs->spuImg.type = SYS_SPU_IMAGE_TYPE_USER; - spurs->spuImg.segs = { vm::alloc(0x40000, vm::main), vm::addr }; + spurs->spuImg.segs = vm::cast(vm::alloc(0x40000, vm::main)); spurs->spuImg.entry_point = isSecond ? CELL_SPURS_KERNEL2_ENTRY_ADDR : CELL_SPURS_KERNEL1_ENTRY_ADDR; spurs->spuImg.nsegs = 1; @@ -2117,8 +2139,8 @@ s32 _spurs::add_workload(vm::ptr<CellSpurs> spurs, vm::ptr<u32> wid, vm::cptr<vo u32 index = wnum & 0xf; if (wnum <= 15) { - ASSERT((spurs->wklCurrentContention[wnum] & 0xf) == 0); - ASSERT((spurs->wklPendingContention[wnum] & 0xf) == 0); + VERIFY((spurs->wklCurrentContention[wnum] & 0xf) == 0); + VERIFY((spurs->wklPendingContention[wnum] & 0xf) == 0); spurs->wklState1[wnum] = 1; spurs->wklStatus1[wnum] = 0; spurs->wklEvent1[wnum] = 0; @@ -2153,8 +2175,8 @@ s32 _spurs::add_workload(vm::ptr<CellSpurs> spurs, vm::ptr<u32> wid, vm::cptr<vo } else { - ASSERT((spurs->wklCurrentContention[index] & 0xf0) == 0); - ASSERT((spurs->wklPendingContention[index] & 0xf0) == 0); + VERIFY((spurs->wklCurrentContention[index] & 0xf0) == 0); + VERIFY((spurs->wklPendingContention[index] & 0xf0) == 0); spurs->wklState2[index] = 1; spurs->wklStatus2[index] = 0; spurs->wklEvent2[index] = 0; @@ -2233,7 +2255,7 @@ s32 _spurs::add_workload(vm::ptr<CellSpurs> spurs, vm::ptr<u32> wid, vm::cptr<vo v = mask | (0x80000000u >> wnum); }); - ASSERT(res_wkl <= 31); + VERIFY(res_wkl <= 31); spurs->wklState(wnum).exchange(2); spurs->sysSrvMsgUpdateWorkload.exchange(0xff); spurs->sysSrvMessage.exchange(0xff); diff --git a/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp b/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp index b5d85f2d5c..5be8826002 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursJq.cpp @@ -8,7 +8,7 @@ #include "cellSpurs.h" #include "cellSpursJq.h" -LOG_CHANNEL(cellSpursJq); +logs::channel cellSpursJq("cellSpursJq", logs::level::notice); s32 cellSpursJobQueueAttributeInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp index 7739b1efc3..26ef8ba13c 100644 --- a/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSpursSpu.cpp @@ -9,11 +9,15 @@ #include "Emu/Cell/lv2/sys_spu.h" #include "cellSpurs.h" +#include <thread> + //---------------------------------------------------------------------------- // Externs //---------------------------------------------------------------------------- -extern _log::channel cellSpurs; +extern logs::channel cellSpurs; + +extern std::mutex& get_current_thread_mutex(); //---------------------------------------------------------------------------- // Function prototypes @@ -685,7 +689,7 @@ bool spursKernelEntry(SPUThread& spu) { while (true) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::this_thread::sleep_for(100ms); CHECK_EMU_STATUS; } @@ -861,7 +865,7 @@ void spursSysServiceIdleHandler(SPUThread& spu, SpursKernelContext* ctxt) // The system service blocks by making a reservation and waiting on the lock line reservation lost event. CHECK_EMU_STATUS; if (!lock) lock.lock(); - get_current_thread_cv().wait_for(lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lock, 1ms); continue; } diff --git a/rpcs3/Emu/Cell/Modules/cellSsl.cpp b/rpcs3/Emu/Cell/Modules/cellSsl.cpp index ab14c7fedd..daa0707378 100644 --- a/rpcs3/Emu/Cell/Modules/cellSsl.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSsl.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSsl); +logs::channel cellSsl("cellSsl", logs::level::notice); s32 cellSslInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellStorage.cpp b/rpcs3/Emu/Cell/Modules/cellStorage.cpp index 894f33cf4a..cc498d6471 100644 --- a/rpcs3/Emu/Cell/Modules/cellStorage.cpp +++ b/rpcs3/Emu/Cell/Modules/cellStorage.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellStorageDataImportMove() { diff --git a/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp b/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp index 6f971a4923..3e978e0dcc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSubdisplay.cpp @@ -3,7 +3,7 @@ #include "cellSubdisplay.h" -LOG_CHANNEL(cellSubdisplay); +logs::channel cellSubdisplay("cellSubdisplay", logs::level::notice); s32 cellSubDisplayInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellSync.cpp b/rpcs3/Emu/Cell/Modules/cellSync.cpp index eb1f4fc716..1dc29dfb85 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSync.cpp @@ -8,7 +8,9 @@ #include "Emu/Memory/wait_engine.h" -LOG_CHANNEL(cellSync); +#include <thread> + +logs::channel cellSync("cellSync", logs::level::notice); namespace _sync { @@ -32,12 +34,12 @@ ppu_error_code cellSyncMutexInitialize(vm::ptr<CellSyncMutex> mutex) { cellSync.trace("cellSyncMutexInitialize(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -51,12 +53,12 @@ ppu_error_code cellSyncMutexLock(vm::ptr<CellSyncMutex> mutex) { cellSync.trace("cellSyncMutexLock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -76,12 +78,12 @@ ppu_error_code cellSyncMutexTryLock(vm::ptr<CellSyncMutex> mutex) { cellSync.trace("cellSyncMutexTryLock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -98,12 +100,12 @@ ppu_error_code cellSyncMutexUnlock(vm::ptr<CellSyncMutex> mutex) { cellSync.trace("cellSyncMutexUnlock(mutex=*0x%x)", mutex); - if (!mutex) + if (UNLIKELY(!mutex)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!mutex.aligned()) + if (UNLIKELY(!mutex.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -119,17 +121,17 @@ ppu_error_code cellSyncBarrierInitialize(vm::ptr<CellSyncBarrier> barrier, u16 t { cellSync.trace("cellSyncBarrierInitialize(barrier=*0x%x, total_count=%d)", barrier, total_count); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } - if (!total_count || total_count > 32767) + if (UNLIKELY(!total_count || total_count > 32767)) { return CELL_SYNC_ERROR_INVAL; } @@ -144,12 +146,12 @@ ppu_error_code cellSyncBarrierNotify(vm::ptr<CellSyncBarrier> barrier) { cellSync.trace("cellSyncBarrierNotify(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -165,12 +167,12 @@ ppu_error_code cellSyncBarrierTryNotify(vm::ptr<CellSyncBarrier> barrier) { cellSync.trace("cellSyncBarrierTryNotify(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -191,12 +193,12 @@ ppu_error_code cellSyncBarrierWait(vm::ptr<CellSyncBarrier> barrier) { cellSync.trace("cellSyncBarrierWait(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -214,12 +216,12 @@ ppu_error_code cellSyncBarrierTryWait(vm::ptr<CellSyncBarrier> barrier) { cellSync.trace("cellSyncBarrierTryWait(barrier=*0x%x)", barrier); - if (!barrier) + if (UNLIKELY(!barrier)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!barrier.aligned()) + if (UNLIKELY(!barrier.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -240,17 +242,17 @@ ppu_error_code cellSyncRwmInitialize(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buf { cellSync.trace("cellSyncRwmInitialize(rwm=*0x%x, buffer=*0x%x, buffer_size=0x%x)", rwm, buffer, buffer_size); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned() || buffer % 128) + if (UNLIKELY(!rwm.aligned() || buffer % 128)) { return CELL_SYNC_ERROR_ALIGN; } - if (buffer_size % 128 || buffer_size > 0x4000) + if (UNLIKELY(buffer_size % 128 || buffer_size > 0x4000)) { return CELL_SYNC_ERROR_INVAL; } @@ -269,12 +271,12 @@ ppu_error_code cellSyncRwmRead(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer) { cellSync.trace("cellSyncRwmRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -300,12 +302,12 @@ ppu_error_code cellSyncRwmTryRead(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> buffer { cellSync.trace("cellSyncRwmTryRead(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -334,12 +336,12 @@ ppu_error_code cellSyncRwmWrite(vm::ptr<CellSyncRwm> rwm, vm::cptr<void> buffer) { cellSync.trace("cellSyncRwmWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -365,12 +367,12 @@ ppu_error_code cellSyncRwmTryWrite(vm::ptr<CellSyncRwm> rwm, vm::cptr<void> buff { cellSync.trace("cellSyncRwmTryWrite(rwm=*0x%x, buffer=*0x%x)", rwm, buffer); - if (!rwm || !buffer) + if (UNLIKELY(!rwm || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!rwm.aligned()) + if (UNLIKELY(!rwm.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -396,22 +398,22 @@ ppu_error_code cellSyncQueueInitialize(vm::ptr<CellSyncQueue> queue, vm::ptr<u8> { cellSync.trace("cellSyncQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x)", queue, buffer, size, depth); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (size && !buffer) + if (UNLIKELY(size && !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } - if (!depth || size % 16) + if (UNLIKELY(!depth || size % 16)) { return CELL_SYNC_ERROR_INVAL; } @@ -431,12 +433,12 @@ ppu_error_code cellSyncQueuePush(vm::ptr<CellSyncQueue> queue, vm::cptr<void> bu { cellSync.trace("cellSyncQueuePush(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -462,12 +464,12 @@ ppu_error_code cellSyncQueueTryPush(vm::ptr<CellSyncQueue> queue, vm::cptr<void> { cellSync.trace("cellSyncQueueTryPush(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -496,12 +498,12 @@ ppu_error_code cellSyncQueuePop(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buff { cellSync.trace("cellSyncQueuePop(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -527,12 +529,12 @@ ppu_error_code cellSyncQueueTryPop(vm::ptr<CellSyncQueue> queue, vm::ptr<void> b { cellSync.trace("cellSyncQueueTryPop(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -561,12 +563,12 @@ ppu_error_code cellSyncQueuePeek(vm::ptr<CellSyncQueue> queue, vm::ptr<void> buf { cellSync.trace("cellSyncQueuePeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -592,12 +594,12 @@ ppu_error_code cellSyncQueueTryPeek(vm::ptr<CellSyncQueue> queue, vm::ptr<void> { cellSync.trace("cellSyncQueueTryPeek(queue=*0x%x, buffer=*0x%x)", queue, buffer); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -626,12 +628,12 @@ ppu_error_code cellSyncQueueSize(vm::ptr<CellSyncQueue> queue) { cellSync.trace("cellSyncQueueSize(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -645,12 +647,12 @@ ppu_error_code cellSyncQueueClear(vm::ptr<CellSyncQueue> queue) { cellSync.trace("cellSyncQueueClear(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -713,30 +715,30 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::cpt { cellSync.warning("cellSyncLFQueueInitialize(queue=*0x%x, buffer=*0x%x, size=0x%x, depth=0x%x, direction=%d, eaSignal=*0x%x)", queue, buffer, size, depth, direction, eaSignal); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } if (size) { - if (!buffer) + if (UNLIKELY(!buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (size > 0x4000 || size % 16) + if (UNLIKELY(size > 0x4000 || size % 16)) { return CELL_SYNC_ERROR_INVAL; } } - if (!depth || depth > 0x7fff || direction > 3) + if (UNLIKELY(!depth || depth > 0x7fff || direction > 3)) { return CELL_SYNC_ERROR_INVAL; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -764,7 +766,7 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::cpt if (old) { - if (sdk_ver > 0x17ffff && old != 2) + if (UNLIKELY(sdk_ver > 0x17ffff && old != 2)) { return CELL_SYNC_ERROR_STAT; } @@ -777,7 +779,7 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::cpt { for (const auto& data : vm::_ref<u64[16]>(queue.addr())) { - if (data) + if (UNLIKELY(data)) { return CELL_SYNC_ERROR_STAT; } @@ -793,14 +795,14 @@ ppu_error_code cellSyncLFQueueInitialize(vm::ptr<CellSyncLFQueue> queue, vm::cpt if (old_value == 2) { - if (queue->m_size != size || queue->m_depth != depth || queue->m_buffer != buffer) + if (UNLIKELY(queue->m_size != size || queue->m_depth != depth || queue->m_buffer != buffer)) { return CELL_SYNC_ERROR_INVAL; } if (sdk_ver > 0x17ffff) { - if (queue->m_eaSignal != eaSignal || queue->m_direction != direction) + if (UNLIKELY(queue->m_eaSignal != eaSignal || queue->m_direction != direction)) { return CELL_SYNC_ERROR_INVAL; } @@ -822,7 +824,7 @@ ppu_error_code _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptr<CellSyncLF { cellSync.warning("_cellSyncLFQueueGetPushPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, useEventQueue=%d)", queue, pointer, isBlocking, useEventQueue); - if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)) { return CELL_SYNC_ERROR_PERM; } @@ -906,7 +908,7 @@ ppu_error_code _cellSyncLFQueueGetPushPointer(PPUThread& ppu, vm::ptr<CellSyncLF } } - ASSERT(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); + VERIFY(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); var1 = 1; } } @@ -923,7 +925,7 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptr<CellS { cellSync.warning("_cellSyncLFQueueCompletePushPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x)", queue, pointer, fpSendSignal); - if (queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_PPU2SPU)) { return CELL_SYNC_ERROR_PERM; } @@ -997,7 +999,7 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptr<CellS if (var9 > 1 && (u32)var8 > 1) { - ASSERT(16 - var2 <= 1); + VERIFY(16 - var2 <= 1); } s32 var11 = (pack >> 10) & 0x1f; @@ -1029,11 +1031,11 @@ ppu_error_code _cellSyncLFQueueCompletePushPointer(PPUThread& ppu, vm::ptr<CellS if (queue->push2.compare_and_swap_test(old, push2)) { - ASSERT(var2 + var4 < 16); + VERIFY(var2 + var4 < 16); if (var6 != -1) { - ASSERT(queue->push3.compare_and_swap_test(old2, push3)); - ASSERT(fpSendSignal); + VERIFY(queue->push3.compare_and_swap_test(old2, push3)); + VERIFY(fpSendSignal); return NOT_AN_ERROR(fpSendSignal(ppu, (u32)queue->m_eaSignal.addr(), var6)); } else @@ -1064,12 +1066,12 @@ ppu_error_code _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> // cellSyncLFQueuePush has 1 in isBlocking param, cellSyncLFQueueTryPush has 0 cellSync.warning("_cellSyncLFQueuePushBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -1098,7 +1100,7 @@ ppu_error_code _cellSyncLFQueuePushBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> break; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } const s32 depth = queue->m_depth; @@ -1121,7 +1123,7 @@ ppu_error_code _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptr<CellSyncLFQ { cellSync.warning("_cellSyncLFQueueGetPopPointer(queue=*0x%x, pointer=*0x%x, isBlocking=%d, arg4=%d, useEventQueue=%d)", queue, pointer, isBlocking, arg4, useEventQueue); - if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)) { return CELL_SYNC_ERROR_PERM; } @@ -1205,7 +1207,7 @@ ppu_error_code _cellSyncLFQueueGetPopPointer(PPUThread& ppu, vm::ptr<CellSyncLFQ } } - ASSERT(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); + VERIFY(sys_event_queue_receive(ppu, queue->m_eq_id, vm::null, 0) == CELL_OK); var1 = 1; } } @@ -1223,7 +1225,7 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptr<CellSy // arguments copied from _cellSyncLFQueueCompletePushPointer + unknown argument (noQueueFull taken from LFQueue2CompletePopPointer) cellSync.warning("_cellSyncLFQueueCompletePopPointer(queue=*0x%x, pointer=%d, fpSendSignal=*0x%x, noQueueFull=%d)", queue, pointer, fpSendSignal, noQueueFull); - if (queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU) + if (UNLIKELY(queue->m_direction != CELL_SYNC_QUEUE_SPU2PPU)) { return CELL_SYNC_ERROR_PERM; } @@ -1301,7 +1303,7 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptr<CellSy if (var9 > 1 && (u32)var8 > 1) { - ASSERT(16 - var2 <= 1); + VERIFY(16 - var2 <= 1); } s32 var11 = (pack >> 10) & 0x1f; @@ -1331,8 +1333,8 @@ ppu_error_code _cellSyncLFQueueCompletePopPointer(PPUThread& ppu, vm::ptr<CellSy { if (var6 != -1) { - ASSERT(queue->pop3.compare_and_swap_test(old2, pop3)); - ASSERT(fpSendSignal); + VERIFY(queue->pop3.compare_and_swap_test(old2, pop3)); + VERIFY(fpSendSignal); return NOT_AN_ERROR(fpSendSignal(ppu, (u32)queue->m_eaSignal.addr(), var6)); } else @@ -1363,12 +1365,12 @@ ppu_error_code _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> // cellSyncLFQueuePop has 1 in isBlocking param, cellSyncLFQueueTryPop has 0 cellSync.warning("_cellSyncLFQueuePopBody(queue=*0x%x, buffer=*0x%x, isBlocking=%d)", queue, buffer, isBlocking); - if (!queue || !buffer) + if (UNLIKELY(!queue || !buffer)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned() || buffer % 16) + if (UNLIKELY(!queue.aligned() || buffer % 16)) { return CELL_SYNC_ERROR_ALIGN; } @@ -1397,7 +1399,7 @@ ppu_error_code _cellSyncLFQueuePopBody(PPUThread& ppu, vm::ptr<CellSyncLFQueue> break; } - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } const s32 depth = queue->m_depth; @@ -1420,12 +1422,12 @@ ppu_error_code cellSyncLFQueueClear(vm::ptr<CellSyncLFQueue> queue) { cellSync.warning("cellSyncLFQueueClear(queue=*0x%x)", queue); - if (!queue) + if (UNLIKELY(!queue)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1471,12 +1473,12 @@ ppu_error_code cellSyncLFQueueSize(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> { cellSync.warning("cellSyncLFQueueSize(queue=*0x%x, size=*0x%x)", queue, size); - if (!queue || !size) + if (UNLIKELY(!queue || !size)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1508,12 +1510,12 @@ ppu_error_code cellSyncLFQueueDepth(vm::ptr<CellSyncLFQueue> queue, vm::ptr<u32> { cellSync.trace("cellSyncLFQueueDepth(queue=*0x%x, depth=*0x%x)", queue, depth); - if (!queue || !depth) + if (UNLIKELY(!queue || !depth)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1527,12 +1529,12 @@ ppu_error_code _cellSyncLFQueueGetSignalAddress(vm::cptr<CellSyncLFQueue> queue, { cellSync.trace("_cellSyncLFQueueGetSignalAddress(queue=*0x%x, ppSignal=**0x%x)", queue, ppSignal); - if (!queue || !ppSignal) + if (UNLIKELY(!queue || !ppSignal)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1546,12 +1548,12 @@ ppu_error_code cellSyncLFQueueGetDirection(vm::cptr<CellSyncLFQueue> queue, vm:: { cellSync.trace("cellSyncLFQueueGetDirection(queue=*0x%x, direction=*0x%x)", queue, direction); - if (!queue || !direction) + if (UNLIKELY(!queue || !direction)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } @@ -1565,12 +1567,12 @@ ppu_error_code cellSyncLFQueueGetEntrySize(vm::cptr<CellSyncLFQueue> queue, vm:: { cellSync.trace("cellSyncLFQueueGetEntrySize(queue=*0x%x, entry_size=*0x%x)", queue, entry_size); - if (!queue || !entry_size) + if (UNLIKELY(!queue || !entry_size)) { return CELL_SYNC_ERROR_NULL_POINTER; } - if (!queue.aligned()) + if (UNLIKELY(!queue.aligned())) { return CELL_SYNC_ERROR_ALIGN; } diff --git a/rpcs3/Emu/Cell/Modules/cellSync2.cpp b/rpcs3/Emu/Cell/Modules/cellSync2.cpp index 21673c5012..27e28faff9 100644 --- a/rpcs3/Emu/Cell/Modules/cellSync2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSync2.cpp @@ -6,7 +6,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSync2); +logs::channel cellSync2("cellSync2", logs::level::notice); vm::gvar<CellSync2CallerThreadType> gCellSync2CallerThreadTypePpuThread; vm::gvar<CellSync2Notifier> gCellSync2NotifierPpuThread; diff --git a/rpcs3/Emu/Cell/Modules/cellSysconf.cpp b/rpcs3/Emu/Cell/Modules/cellSysconf.cpp index 3685f8f1ef..c43d66f9eb 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysconf.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysconf.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysconf); +logs::channel cellSysconf("cellSysconf", logs::level::notice); s32 cellSysconfAbort() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp index b4718e11dc..99be319178 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysmodule.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysmodule); +logs::channel cellSysmodule("cellSysmodule", logs::level::notice); enum { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp index 1e92f757ae..ce21bcb7dc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutil.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" @@ -7,7 +8,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellSysutil); +logs::channel cellSysutil("cellSysutil", logs::level::notice); // Temporarily using sys_callbacks_t = std::array<std::pair<vm::ptr<CellSysutilCallback>, vm::ptr<void>>, 4>; @@ -53,43 +54,47 @@ cfg::map_entry<s32> g_cfg_sys_language(cfg::root.sys, "Language", { "English (UK)", CELL_SYSUTIL_LANG_ENGLISH_GB }, }); -static const char* get_systemparam_id_name(s32 id) -{ - static thread_local char tls_id_name[16]; // for test - - switch (id) - { - case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: return "ID_DATE_FORMAT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: return "ID_TIME_FORMAT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: return "ID_TIMEZONE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: return "ID_SUMMERTIME"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: return "ID_GAME_PARENTAL_LEVEL"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: return "ID_GAME_PARENTAL_LEVEL0_RESTRICT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: return "ID_CURRENT_USER_HAS_NP_ACCOUNT"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: return "ID_CAMERA_PLFREQ"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: return "ID_PAD_RUMBLE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: return "ID_KEYBOARD_TYPE"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: return "ID_JAPANESE_KEYBOARD_ENTRY_METHOD"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: return "ID_CHINESE_KEYBOARD_ENTRY_METHOD"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: return "ID_PAD_AUTOOFF"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: return "ID_NICKNAME"; - case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; - } - - std::snprintf(tls_id_name, sizeof(tls_id_name), "0x%04X", id); - return tls_id_name; -} - enum class systemparam_id_name : s32 {}; template<> struct unveil<systemparam_id_name, void> { - static inline const char* get(systemparam_id_name arg) + struct temp { - return get_systemparam_id_name((s32)arg); + s32 value; + char buf[12]; + + temp(systemparam_id_name value) + : value(s32(value)) + { + } + }; + + static inline const char* get(temp&& in) + { + switch (in.value) + { + case CELL_SYSUTIL_SYSTEMPARAM_ID_LANG: return "ID_LANG"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_ENTER_BUTTON_ASSIGN: return "ID_ENTER_BUTTON_ASSIGN"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_DATE_FORMAT: return "ID_DATE_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIME_FORMAT: return "ID_TIME_FORMAT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_TIMEZONE: return "ID_TIMEZONE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_SUMMERTIME: return "ID_SUMMERTIME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL: return "ID_GAME_PARENTAL_LEVEL"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_GAME_PARENTAL_LEVEL0_RESTRICT: return "ID_GAME_PARENTAL_LEVEL0_RESTRICT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USER_HAS_NP_ACCOUNT: return "ID_CURRENT_USER_HAS_NP_ACCOUNT"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CAMERA_PLFREQ: return "ID_CAMERA_PLFREQ"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_RUMBLE: return "ID_PAD_RUMBLE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_KEYBOARD_TYPE: return "ID_KEYBOARD_TYPE"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_JAPANESE_KEYBOARD_ENTRY_METHOD: return "ID_JAPANESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CHINESE_KEYBOARD_ENTRY_METHOD: return "ID_CHINESE_KEYBOARD_ENTRY_METHOD"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_PAD_AUTOOFF: return "ID_PAD_AUTOOFF"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_NICKNAME: return "ID_NICKNAME"; + case CELL_SYSUTIL_SYSTEMPARAM_ID_CURRENT_USERNAME: return "ID_CURRENT_USERNAME"; + } + + std::snprintf(in.buf, sizeof(in.buf), "!0x%04X", in.value); + return in.buf; } }; @@ -170,7 +175,7 @@ s32 cellSysutilGetSystemParamInt(s32 id, vm::ptr<s32> value) s32 cellSysutilGetSystemParamString(s32 id, vm::ptr<char> buf, u32 bufsize) { - cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, get_systemparam_id_name(id), buf, bufsize); + cellSysutil.trace("cellSysutilGetSystemParamString(id=0x%x(%s), buf=*0x%x, bufsize=%d)", id, systemparam_id_name(id), buf, bufsize); memset(buf.get_ptr(), 0, bufsize); @@ -255,7 +260,7 @@ s32 cellSysCacheMount(vm::ptr<CellSysCacheParam> param) cellSysutil.warning("cellSysCacheMount(param=*0x%x)", param); const std::string& cache_id = param->cacheId; - ASSERT(cache_id.size() < sizeof(param->cacheId)); + VERIFY(cache_id.size() < sizeof(param->cacheId)); const std::string& cache_path = "/dev_hdd1/cache/" + cache_id + '/'; strcpy_trunc(param->getCachePath, cache_path); diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp index f8c6d1668f..d989ceb55d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAp.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilAp); +logs::channel cellSysutilAp("cellSysutilAp", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp index 24b78da7b4..fee4207eee 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilAvc); +logs::channel cellSysutilAvc("cellSysutilAvc", logs::level::notice); s32 cellSysutilAvcByeRequest() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp index c88ffd32d5..1acf10e32d 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilAvc2.cpp @@ -5,7 +5,7 @@ #include "sceNp2.h" #include "cellSysutilAvc2.h" -LOG_CHANNEL(cellSysutilAvc2); +logs::channel cellSysutilAvc2("cellSysutilAvc2", logs::level::notice); s32 cellSysutilAvc2GetPlayerInfo() { diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp index e009f8e0bc..109e7a817a 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilMisc.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellSysutilMisc); +logs::channel cellSysutilMisc("cellSysutilMisc", logs::level::notice); // License areas enum diff --git a/rpcs3/Emu/Cell/Modules/cellUsbd.cpp b/rpcs3/Emu/Cell/Modules/cellUsbd.cpp index 607277c74e..d998d9387c 100644 --- a/rpcs3/Emu/Cell/Modules/cellUsbd.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUsbd.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/PPUModule.h" #include "cellUsbd.h" -LOG_CHANNEL(cellUsbd); +logs::channel cellUsbd("cellUsbd", logs::level::notice); s32 cellUsbdInit() { diff --git a/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp b/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp index ccd4cae8bb..88267a3468 100644 --- a/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUsbpspcm.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellUsbPspcm); +logs::channel cellUsbPspcm("cellUsbPspcm", logs::level::notice); // Return Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp b/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp index 790d6b9eab..9c6e3f0d85 100644 --- a/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/Cell/Modules/cellUserInfo.cpp @@ -6,7 +6,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(cellUserInfo); +logs::channel cellUserInfo("cellUserInfo", logs::level::notice); s32 cellUserInfoGetStat(u32 id, vm::ptr<CellUserInfoUserStat> stat) { diff --git a/rpcs3/Emu/Cell/Modules/cellVdec.cpp b/rpcs3/Emu/Cell/Modules/cellVdec.cpp index 2192d6f4c9..47bc12d9ca 100644 --- a/rpcs3/Emu/Cell/Modules/cellVdec.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVdec.cpp @@ -16,7 +16,9 @@ extern "C" #include "cellPamf.h" #include "cellVdec.h" -LOG_CHANNEL(cellVdec); +#include <thread> + +logs::channel cellVdec("cellVdec", logs::level::notice); vm::gvar<s32> _cell_vdec_prx_ver; // ??? @@ -541,7 +543,7 @@ void vdecOpen(u32 vdec_id) // TODO: call from the constructor vdec.vdecCb->cpu_init(); vdec.vdecCb->state -= cpu_state::stop; - vdec.vdecCb->lock_notify(); + (*vdec.vdecCb)->lock_notify(); } s32 cellVdecQueryAttr(vm::cptr<CellVdecType> type, vm::ptr<CellVdecAttr> attr) @@ -594,7 +596,7 @@ s32 cellVdecClose(u32 handle) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack } idm::remove<PPUThread>(vdec->vdecCb->id); @@ -676,7 +678,7 @@ s32 cellVdecGetPicture(u32 handle, vm::cptr<CellVdecPicFormat> format, vm::ptr<u VdecFrame vf; if (!vdec->frames.try_pop(vf)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_VDEC_ERROR_EMPTY; } @@ -800,13 +802,13 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem) VdecFrame vf; if (!vdec->frames.try_peek(vf)) { - //std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + //std::this_thread::sleep_for(1ms); // hack return CELL_VDEC_ERROR_EMPTY; } AVFrame& frame = *vf.data; - const vm::ptr<CellVdecPicItem> info{ vdec->memAddr + vdec->memBias, vm::addr }; + const vm::ptr<CellVdecPicItem> info = vm::cast(vdec->memAddr + vdec->memBias); vdec->memBias += 512; if (vdec->memBias + 512 > vdec->memSize) @@ -834,7 +836,7 @@ s32 cellVdecGetPicItem(u32 handle, vm::pptr<CellVdecPicItem> picItem) if (vdec->type == CELL_VDEC_CODEC_TYPE_AVC) { - const vm::ptr<CellVdecAvcInfo> avc{ info.addr() + SIZE_32(CellVdecPicItem), vm::addr }; + const vm::ptr<CellVdecAvcInfo> avc = vm::cast(info.addr() + SIZE_32(CellVdecPicItem)); avc->horizontalSize = frame.width; avc->verticalSize = frame.height; diff --git a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp index 266d8abc45..90034a357f 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoExport.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVideoExport); +logs::channel cellVideoExport("cellVideoExport", logs::level::notice); s32 cellVideoExportProgress() { diff --git a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp index a3a2ba826c..27aa431d0b 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoOut.cpp @@ -1,10 +1,11 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" #include "cellVideoOut.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; cfg::map_entry<u8> g_cfg_video_out_resolution(cfg::root.video, "Resolution", "1280x720", { diff --git a/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp b/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp index f41f52a573..5ab0c7ba5c 100644 --- a/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVideoUpload.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVideoUpload); +logs::channel cellVideoUpload("cellVideoUpload", logs::level::notice); s32 cellVideoUploadInitialize() { diff --git a/rpcs3/Emu/Cell/Modules/cellVoice.cpp b/rpcs3/Emu/Cell/Modules/cellVoice.cpp index 83c227faa9..b9ae6d2331 100644 --- a/rpcs3/Emu/Cell/Modules/cellVoice.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVoice.cpp @@ -2,7 +2,7 @@ #include "Emu/System.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(cellVoice); +logs::channel cellVoice("cellVoice", logs::level::notice); // Error Codes enum diff --git a/rpcs3/Emu/Cell/Modules/cellVpost.cpp b/rpcs3/Emu/Cell/Modules/cellVpost.cpp index d42d4febbc..a8bdcbef42 100644 --- a/rpcs3/Emu/Cell/Modules/cellVpost.cpp +++ b/rpcs3/Emu/Cell/Modules/cellVpost.cpp @@ -10,7 +10,7 @@ extern "C" #include "cellVpost.h" -LOG_CHANNEL(cellVpost); +logs::channel cellVpost("cellVpost", logs::level::notice); s32 cellVpostQueryAttr(vm::cptr<CellVpostCfgParam> cfgParam, vm::ptr<CellVpostAttr> attr) { diff --git a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp index 4f0877a095..999056a52d 100644 --- a/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp +++ b/rpcs3/Emu/Cell/Modules/cellWebBrowser.cpp @@ -3,7 +3,7 @@ #include "cellWebBrowser.h" -extern _log::channel cellSysutil; +extern logs::channel cellSysutil; s32 cellWebBrowserActivate() { diff --git a/rpcs3/Emu/Cell/Modules/libmixer.cpp b/rpcs3/Emu/Cell/Modules/libmixer.cpp index 2813a039bb..932d20e67e 100644 --- a/rpcs3/Emu/Cell/Modules/libmixer.cpp +++ b/rpcs3/Emu/Cell/Modules/libmixer.cpp @@ -5,9 +5,11 @@ #include "cellAudio.h" #include "libmixer.h" -#include <cmath> -LOG_CHANNEL(libmixer); +#include <cmath> +#include <thread> + +logs::channel libmixer("libmixer", logs::level::notice); // TODO: use fxm SurMixerConfig g_surmx; @@ -332,7 +334,7 @@ s32 cellSurMixerCreate(vm::cptr<CellSurMixerConfig> config) if (g_surmx.mixcount > (port.tag + 0)) // adding positive value (1-15): preemptive buffer filling (hack) { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack continue; } @@ -448,7 +450,7 @@ s32 cellSurMixerCreate(vm::cptr<CellSurMixerConfig> config) ppu->cpu_init(); ppu->state -= cpu_state::stop; - ppu->lock_notify(); + (*ppu)->lock_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/libsnd3.cpp b/rpcs3/Emu/Cell/Modules/libsnd3.cpp index 861039754d..f76ffdc839 100644 --- a/rpcs3/Emu/Cell/Modules/libsnd3.cpp +++ b/rpcs3/Emu/Cell/Modules/libsnd3.cpp @@ -3,7 +3,7 @@ #include "libsnd3.h" -LOG_CHANNEL(libsnd3); +logs::channel libsnd3("libsnd3", logs::level::notice); s32 cellSnd3Init(u32 maxVoice, u32 samples, vm::ptr<CellSnd3RequestQueueCtx> queue) { diff --git a/rpcs3/Emu/Cell/Modules/libsynth2.cpp b/rpcs3/Emu/Cell/Modules/libsynth2.cpp index 532932a2d7..98d123487e 100644 --- a/rpcs3/Emu/Cell/Modules/libsynth2.cpp +++ b/rpcs3/Emu/Cell/Modules/libsynth2.cpp @@ -3,7 +3,7 @@ #include "libsynth2.h" -LOG_CHANNEL(libsynth2); +logs::channel libsynth2("libsynth2", logs::level::notice); s32 cellSoundSynth2Config(s16 param, s32 value) { diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 80c682eeed..a1cd7c7ede 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -6,7 +6,7 @@ #include "Crypto/unedat.h" #include "sceNp.h" -LOG_CHANNEL(sceNp); +logs::channel sceNp("sceNp", logs::level::notice); s32 sceNpInit(u32 poolsize, vm::ptr<void> poolptr) { diff --git a/rpcs3/Emu/Cell/Modules/sceNp2.cpp b/rpcs3/Emu/Cell/Modules/sceNp2.cpp index c424aaf877..653c4a5295 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp2.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNp2.h" -LOG_CHANNEL(sceNp2); +logs::channel sceNp2("sceNp2", logs::level::notice); s32 sceNp2Init(u32 poolsize, vm::ptr<void> poolptr) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpClans.cpp b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp index e3d7daca27..eb3e3bed8a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpClans.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpClans.cpp @@ -5,7 +5,7 @@ #include "sceNp.h" #include "sceNpClans.h" -LOG_CHANNEL(sceNpClans); +logs::channel sceNpClans("sceNpClans", logs::level::notice); s32 sceNpClansInit(vm::ptr<SceNpCommunicationId> commId, vm::ptr<SceNpCommunicationPassphrase> passphrase, vm::ptr<void> pool, vm::ptr<u32> poolSize, u32 flags) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp index ba8f47ce7e..5b9b9e50d0 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpCommerce2.cpp @@ -3,7 +3,7 @@ #include "sceNpCommerce2.h" -LOG_CHANNEL(sceNpCommerce2); +logs::channel sceNpCommerce2("sceNpCommerce2", logs::level::notice); s32 sceNpCommerce2ExecuteStoreBrowse() { diff --git a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp index 15dc2c7153..552b69807a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpSns.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpSns.cpp @@ -3,7 +3,7 @@ #include "sceNpSns.h" -LOG_CHANNEL(sceNpSns); +logs::channel sceNpSns("sceNpSns", logs::level::notice); s32 sceNpSnsFbInit(vm::ptr<const SceNpSnsFbInitParams> params) { diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index f81d2b535d..1f011f2b2b 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -12,7 +12,7 @@ #include "Utilities/StrUtil.h" -LOG_CHANNEL(sceNpTrophy); +logs::channel sceNpTrophy("sceNpTrophy", logs::level::notice); struct trophy_context_t { @@ -269,7 +269,7 @@ s32 sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGameDetai const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"); // TODO: rXmlDocument can open only real file - ASSERT(!fs::get_virtual_device(path)); + VERIFY(!fs::get_virtual_device(path)); rXmlDocument doc; doc.Load(path); @@ -399,7 +399,7 @@ s32 sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceN const std::string& path = vfs::get("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM"); // TODO: rXmlDocument can open only real file - ASSERT(!fs::get_virtual_device(path)); + VERIFY(!fs::get_virtual_device(path)); rXmlDocument doc; doc.Load(path); diff --git a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp index 1ee55bf9f6..932f667f51 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTus.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTus.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNpTus.h" -LOG_CHANNEL(sceNpTus); +logs::channel sceNpTus("sceNpTus", logs::level::notice); s32 sceNpTusInit() { diff --git a/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp index 0dc924f80a..0d99b7e843 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpUtil.cpp @@ -4,7 +4,7 @@ #include "sceNp.h" #include "sceNpUtil.h" -LOG_CHANNEL(sceNpUtil); +logs::channel sceNpUtil("sceNpUtil", logs::level::notice); s32 sceNpUtilBandwidthTestInitStart(u32 prio, size_t stack) { diff --git a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp index b531810687..d82f10ac30 100644 --- a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp @@ -6,7 +6,7 @@ #include "Emu/Cell/lv2/sys_process.h" #include "sysPrxForUser.h" -LOG_CHANNEL(sysPrxForUser); +logs::channel sysPrxForUser("sysPrxForUser", logs::level::notice); extern u64 get_system_time(); diff --git a/rpcs3/Emu/Cell/Modules/sys_game.cpp b/rpcs3/Emu/Cell/Modules/sys_game.cpp index 1c2d47b368..974ad7d3ee 100644 --- a/rpcs3/Emu/Cell/Modules/sys_game.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_game.cpp @@ -4,7 +4,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sys_game_process_exitspawn(vm::cptr<char> path, u32 argv_addr, u32 envp_addr, u32 data_addr, u32 data_size, u32 prio, u64 flags) { diff --git a/rpcs3/Emu/Cell/Modules/sys_heap.cpp b/rpcs3/Emu/Cell/Modules/sys_heap.cpp index 13b344fd2f..7d711f0f22 100644 --- a/rpcs3/Emu/Cell/Modules/sys_heap.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_heap.cpp @@ -5,7 +5,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; struct HeapInfo { diff --git a/rpcs3/Emu/Cell/Modules/sys_io.cpp b/rpcs3/Emu/Cell/Modules/sys_io.cpp index 11d2202e5d..7a5dad63b0 100644 --- a/rpcs3/Emu/Cell/Modules/sys_io.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_io.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -LOG_CHANNEL(sys_io); +logs::channel sys_io("sys_io", logs::level::notice); extern void cellPad_init(); extern void cellKb_init(); diff --git a/rpcs3/Emu/Cell/Modules/sys_libc.cpp b/rpcs3/Emu/Cell/Modules/sys_libc.cpp index 74fabd32b0..38195675d8 100644 --- a/rpcs3/Emu/Cell/Modules/sys_libc.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc.cpp @@ -3,7 +3,7 @@ #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/PPUOpcodes.h" -LOG_CHANNEL(sys_libc); +logs::channel sys_libc("sys_libc", logs::level::notice); namespace sys_libc_func { diff --git a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp index 15be5a9f46..97b1045823 100644 --- a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern fs::file g_tty; diff --git a/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp index 791e29ceed..eaa1c38f26 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lv2dbg.cpp @@ -5,7 +5,7 @@ #include "sys_lv2dbg.h" -LOG_CHANNEL(sys_lv2dbg); +logs::channel sys_lv2dbg("sys_lv2dbg", logs::level::notice); s32 sys_dbg_read_ppu_thread_context(u64 id, vm::ptr<sys_dbg_ppu_thread_context_t> ppu_context) { diff --git a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index 7b4b019a8d..4d3e0e5518 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -7,7 +7,7 @@ #include "Emu/Cell/lv2/sys_lwcond.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s32 sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwcond_attribute_t> attr) { diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 7cbaab6dba..7050e97aa5 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -7,7 +7,7 @@ #include "Emu/Cell/lv2/sys_lwmutex.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attribute_t> attr) { diff --git a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp index 99763b4b1f..b4f748485b 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mempool.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mempool.cpp @@ -5,7 +5,7 @@ #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; using sys_mempool_t = u32; diff --git a/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp index 37830aea71..e07618022e 100644 --- a/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_mmapper_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_mmapper.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sysPrxForUser_sys_mmapper_init() { diff --git a/rpcs3/Emu/Cell/Modules/sys_net.cpp b/rpcs3/Emu/Cell/Modules/sys_net.cpp index abe038f6c4..126dfd515c 100644 --- a/rpcs3/Emu/Cell/Modules/sys_net.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_net.cpp @@ -14,7 +14,7 @@ #include <unistd.h> #endif -LOG_CHANNEL(libnet); +logs::channel libnet("libnet", logs::level::notice); // We map host sockets to sequential IDs to return as FDs because syscalls using // socketselect(), etc. expect socket FDs to be under 1024. @@ -127,7 +127,7 @@ namespace sys_net { g_tls_net_data.set(vm::alloc(sizeof(decltype(g_tls_net_data)::type), vm::main)); - thread_ctrl::at_exit([addr = g_tls_net_data.addr()] + thread_ctrl::atexit([addr = g_tls_net_data.addr()] { vm::dealloc_verbose_nothrow(addr, vm::main); }); diff --git a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp index f339fa8407..b37289ec3f 100644 --- a/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_ppu_thread_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_ppu_thread.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern u32 ppu_alloc_tls(); extern void ppu_free_tls(u32 addr); diff --git a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp index 1b2fac8523..70ba08027c 100644 --- a/rpcs3/Emu/Cell/Modules/sys_prx_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_prx_.cpp @@ -5,7 +5,7 @@ #include "Emu/Cell/lv2/sys_prx.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; s64 sys_prx_exitspawn_with_level() { diff --git a/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp index 9ec0c65ff8..47a5986fe1 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spinlock.cpp @@ -6,7 +6,7 @@ #include "Emu/Memory/wait_engine.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; void sys_spinlock_initialize(vm::ptr<atomic_be_t<u32>> lock) { diff --git a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp index 3d2c0e6863..111ce221de 100644 --- a/rpcs3/Emu/Cell/Modules/sys_spu_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_spu_.cpp @@ -7,7 +7,7 @@ #include "Crypto/unself.h" #include "sysPrxForUser.h" -extern _log::channel sysPrxForUser; +extern logs::channel sysPrxForUser; extern u64 get_system_time(); @@ -59,7 +59,7 @@ s32 sys_spu_image_close(vm::ptr<sys_spu_image_t> img) return CELL_EINVAL; } - ASSERT(vm::dealloc(img->segs.addr(), vm::main)); // Current rough implementation + VERIFY(vm::dealloc(img->segs.addr(), vm::main)); // Current rough implementation return CELL_OK; } diff --git a/rpcs3/Emu/Cell/PPUCallback.cpp b/rpcs3/Emu/Cell/PPUCallback.cpp index f1652f4d66..3f29de1945 100644 --- a/rpcs3/Emu/Cell/PPUCallback.cpp +++ b/rpcs3/Emu/Cell/PPUCallback.cpp @@ -6,6 +6,8 @@ #include "PPUThread.h" #include "PPUCallback.h" +#include <condition_variable> + void CallbackManager::Register(check_cb_t func) { std::lock_guard<std::mutex> lock(m_mutex); @@ -24,9 +26,11 @@ void CallbackManager::Async(async_cb_t func) m_async_cb.emplace(std::move(func)); - m_cb_thread->notify(); + (*m_cb_thread)->notify(); } +extern std::condition_variable& get_current_thread_cv(); + CallbackManager::check_cb_t CallbackManager::Check() { std::lock_guard<std::mutex> lock(m_mutex); diff --git a/rpcs3/Emu/Cell/PPUCallback.h b/rpcs3/Emu/Cell/PPUCallback.h index 66b3ce2449..42fe061830 100644 --- a/rpcs3/Emu/Cell/PPUCallback.h +++ b/rpcs3/Emu/Cell/PPUCallback.h @@ -193,6 +193,7 @@ template<typename RT, typename... T> inline RT cb_call(PPUThread& CPU, u32 pc, u } #include <queue> +#include <mutex> class CallbackManager { diff --git a/rpcs3/Emu/Cell/PPUDisAsm.cpp b/rpcs3/Emu/Cell/PPUDisAsm.cpp index 31a1cfa48d..2d2f93e8d9 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.cpp +++ b/rpcs3/Emu/Cell/PPUDisAsm.cpp @@ -10,16 +10,6 @@ u32 PPUDisAsm::disasm(u32 pc) return 4; } -void PPUDisAsm::TDI(ppu_opcode_t op) -{ - DisAsm_INT1_R1_IMM("tdi", op.bo, op.ra, op.simm16); -} - -void PPUDisAsm::TWI(ppu_opcode_t op) -{ - DisAsm_INT1_R1_IMM("twi", op.bo, op.ra, op.simm16); -} - void PPUDisAsm::MFVSCR(ppu_opcode_t op) { DisAsm_V1("mfvscr", op.vd); @@ -740,6 +730,16 @@ void PPUDisAsm::VXOR(ppu_opcode_t op) DisAsm_V3("vxor", op.vd, op.va, op.vb); } +void PPUDisAsm::TDI(ppu_opcode_t op) +{ + DisAsm_INT1_R1_IMM("tdi", op.bo, op.ra, op.simm16); +} + +void PPUDisAsm::TWI(ppu_opcode_t op) +{ + DisAsm_INT1_R1_IMM("twi", op.bo, op.ra, op.simm16); +} + void PPUDisAsm::MULLI(ppu_opcode_t op) { DisAsm_R2_IMM("mulli", op.rd, op.ra, op.simm16); @@ -1949,6 +1949,16 @@ void PPUDisAsm::LWA(ppu_opcode_t op) DisAsm_R2_IMM("lwa", op.rd, op.ra, op.ds * 4); } +void PPUDisAsm::STD(ppu_opcode_t op) +{ + DisAsm_R2_IMM("std", op.rs, op.ra, op.ds * 4); +} + +void PPUDisAsm::STDU(ppu_opcode_t op) +{ + DisAsm_R2_IMM("stdu", op.rs, op.ra, op.ds * 4); +} + void PPUDisAsm::FDIVS(ppu_opcode_t op) { DisAsm_F3_RC("fdivs", op.frd, op.fra, op.frb, op.rc); @@ -1999,16 +2009,6 @@ void PPUDisAsm::FNMADDS(ppu_opcode_t op) DisAsm_F4_RC("fnmadds", op.frd, op.fra, op.frc, op.frb, op.rc); } -void PPUDisAsm::STD(ppu_opcode_t op) -{ - DisAsm_R2_IMM("std", op.rs, op.ra, op.ds * 4); -} - -void PPUDisAsm::STDU(ppu_opcode_t op) -{ - DisAsm_R2_IMM("stdu", op.rs, op.ra, op.ds * 4); -} - void PPUDisAsm::MTFSB1(ppu_opcode_t op) { Write(fmt::format("mtfsb1%s %d", op.rc ? "." : "", op.crbd)); diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 7138bfe519..37d969a728 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -243,8 +243,6 @@ private: public: u32 disasm(u32 pc) override; - void TDI(ppu_opcode_t op); - void TWI(ppu_opcode_t op); void MFVSCR(ppu_opcode_t op); void MTVSCR(ppu_opcode_t op); void VADDCUW(ppu_opcode_t op); @@ -389,6 +387,8 @@ public: void VUPKLSB(ppu_opcode_t op); void VUPKLSH(ppu_opcode_t op); void VXOR(ppu_opcode_t op); + void TDI(ppu_opcode_t op); + void TWI(ppu_opcode_t op); void MULLI(ppu_opcode_t op); void SUBFIC(ppu_opcode_t op); void CMPLI(ppu_opcode_t op); @@ -582,6 +582,8 @@ public: void LD(ppu_opcode_t op); void LDU(ppu_opcode_t op); void LWA(ppu_opcode_t op); + void STD(ppu_opcode_t op); + void STDU(ppu_opcode_t op); void FDIVS(ppu_opcode_t op); void FSUBS(ppu_opcode_t op); void FADDS(ppu_opcode_t op); @@ -592,8 +594,6 @@ public: void FMSUBS(ppu_opcode_t op); void FNMSUBS(ppu_opcode_t op); void FNMADDS(ppu_opcode_t op); - void STD(ppu_opcode_t op); - void STDU(ppu_opcode_t op); void MTFSB1(ppu_opcode_t op); void MCRFS(ppu_opcode_t op); void MTFSB0(ppu_opcode_t op); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 5601971adf..c15b27762d 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -2,6 +2,7 @@ #include "Emu/System.h" #include "PPUThread.h" #include "PPUInterpreter.h" + #include <cmath> // TODO: fix rol8 and rol16 for __GNUG__ (probably with __asm__) @@ -147,70 +148,44 @@ public: } const g_ppu_scale_table; -void ppu_interpreter::TDI(PPUThread& ppu, ppu_opcode_t op) -{ - const s64 a = ppu.GPR[op.ra], b = op.simm16; - const u64 a_ = a, b_ = b; - - if (((op.bo & 0x10) && a < b) || - ((op.bo & 0x8) && a > b) || - ((op.bo & 0x4) && a == b) || - ((op.bo & 0x2) && a_ < b_) || - ((op.bo & 0x1) && a_ > b_)) - { - throw std::runtime_error("Trap!" HERE); - } -} - -void ppu_interpreter::TWI(PPUThread& ppu, ppu_opcode_t op) -{ - const s32 a = u32(ppu.GPR[op.ra]), b = op.simm16; - const u32 a_ = a, b_ = b; - - if (((op.bo & 0x10) && a < b) || - ((op.bo & 0x8) && a > b) || - ((op.bo & 0x4) && a == b) || - ((op.bo & 0x2) && a_ < b_) || - ((op.bo & 0x1) && a_ > b_)) - { - throw std::runtime_error("Trap!" HERE); - } -} - - -void ppu_interpreter::MFVSCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFVSCR(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("MFVSCR" HERE); } -void ppu_interpreter::MTVSCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTVSCR(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTVSCR"); + return true; } -void ppu_interpreter::VADDCUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDCUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; ppu.VR[op.vd].vi = _mm_srli_epi32(_mm_cmpgt_epi32(_mm_xor_si128(b, _mm_set1_epi32(0x80000000)), _mm_xor_si128(a, _mm_set1_epi32(0x7fffffff))), 31); + return true; } -void ppu_interpreter::VADDFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::addfs(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDSBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = ppu.VR[op.vb]; @@ -219,51 +194,60 @@ void ppu_interpreter::VADDSWS(PPUThread& ppu, ppu_opcode_t op) const auto x = _mm_srai_epi32(m.vi, 31); // saturation mask const auto y = _mm_srai_epi32(_mm_and_si128(s.vi, m.vi), 31); // positive saturation mask ppu.VR[op.vd].vi = _mm_xor_si128(_mm_xor_si128(_mm_srli_epi32(x, 1), y), _mm_or_si128(s.vi, x)); + return true; } -void ppu_interpreter::VADDUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUBM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add8(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add16(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_adds_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VADDUWM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUWM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::add32(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VADDUWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VADDUWS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; ppu.VR[op.vd].vi = _mm_or_si128(_mm_add_epi32(a, b), _mm_cmpgt_epi32(_mm_xor_si128(b, _mm_set1_epi32(0x80000000)), _mm_xor_si128(a, _mm_set1_epi32(0x7fffffff)))); + return true; } -void ppu_interpreter::VAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAND(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] & ppu.VR[op.vb]; + return true; } -void ppu_interpreter::VANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::andnot(ppu.VR[op.vb], ppu.VR[op.va]); + return true; } -void ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add8(ppu.VR[op.vb], v128::from8p(1)); // add 1 @@ -271,9 +255,10 @@ void ppu_interpreter::VAVGSB(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from8p(0x80); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq8(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi64(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add16(ppu.VR[op.vb], v128::from16p(1)); // add 1 @@ -281,9 +266,10 @@ void ppu_interpreter::VAVGSH(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from16p(0x8000); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq16(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi16(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = v128::add32(ppu.VR[op.vb], v128::from32p(1)); // add 1 @@ -291,40 +277,46 @@ void ppu_interpreter::VAVGSW(PPUThread& ppu, ppu_opcode_t op) const auto sign = v128::from32p(0x80000000); const auto overflow = (((a ^ summ) & (b ^ summ)) ^ summ ^ v128::eq32(b, sign)) & sign; // calculate msb ppu.VR[op.vd].vi = _mm_or_si128(overflow.vi, _mm_srli_epi32(summ.vi, 1)); + return true; } -void ppu_interpreter::VAVGUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_avg_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VAVGUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_avg_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VAVGUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VAVGUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va]; const auto b = ppu.VR[op.vb]; const auto summ = v128::add32(v128::add32(a, b), v128::from32p(1)); const auto carry = _mm_xor_si128(_mm_slli_epi32(sse_cmpgt_epu32(summ.vi, a.vi), 31), _mm_set1_epi32(0x80000000)); ppu.VR[op.vd].vi = _mm_or_si128(carry, _mm_srli_epi32(summ.vi, 1)); + return true; } -void ppu_interpreter::VCFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCFSX(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_mul_ps(_mm_cvtepi32_ps(ppu.VR[op.vb].vi), g_ppu_scale_table[0 - op.vuimm]); + return true; } -void ppu_interpreter::VCFUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCFUX(PPUThread& ppu, ppu_opcode_t op) { const auto b = ppu.VR[op.vb].vi; const auto fix = _mm_and_ps(_mm_castsi128_ps(_mm_srai_epi32(b, 31)), _mm_set1_ps(0x80000000)); ppu.VR[op.vd].vf = _mm_mul_ps(_mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(b, _mm_set1_epi32(0x7fffffff))), fix), g_ppu_scale_table[0 - op.vuimm]); + return true; } -void ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vf; const auto b = ppu.VR[op.vb].vf; @@ -333,154 +325,179 @@ void ppu_interpreter::VCMPBFP(PPUThread& ppu, ppu_opcode_t op) const auto cmp2 = _mm_cmpnge_ps(a, _mm_xor_ps(b, sign)); ppu.VR[op.vd].vf = _mm_or_ps(_mm_and_ps(cmp1, sign), _mm_and_ps(cmp2, _mm_castsi128_ps(_mm_set1_epi32(0x40000000)))); if (UNLIKELY(op.oe)) ppu.SetCR(6, false, false, _mm_movemask_ps(_mm_or_ps(cmp1, cmp2)) == 0, false); + return true; } -void ppu_interpreter::VCMPEQFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpeq_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq8(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq16(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPEQUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPEQUW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8((ppu.VR[op.vd] = v128::eq32(ppu.VR[op.va], ppu.VR[op.vb])).vi); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGEFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpge_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTFP(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_ps(ppu.VR[op.vd].vf = _mm_cmpgt_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xf, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTSW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = _mm_cmpgt_epi32(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUB(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUH(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCMPGTUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCMPGTUW(PPUThread& ppu, ppu_opcode_t op) { const auto rmask = _mm_movemask_epi8(ppu.VR[op.vd].vi = sse_cmpgt_epu32(ppu.VR[op.va].vi, ppu.VR[op.vb].vi)); if (UNLIKELY(op.oe)) ppu.SetCR(6, rmask == 0xffff, false, rmask == 0, false); + return true; } -void ppu_interpreter::VCTSXS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCTSXS(PPUThread& ppu, ppu_opcode_t op) { const auto scaled = _mm_mul_ps(ppu.VR[op.vb].vf, g_ppu_scale_table[op.vuimm]); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_cvttps_epi32(scaled), _mm_castps_si128(_mm_cmpge_ps(scaled, _mm_set1_ps(0x80000000)))); + return true; } -void ppu_interpreter::VCTUXS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VCTUXS(PPUThread& ppu, ppu_opcode_t op) { const auto scaled1 = _mm_max_ps(_mm_mul_ps(ppu.VR[op.vb].vf, g_ppu_scale_table[op.vuimm]), _mm_set1_ps(0.0f)); const auto scaled2 = _mm_and_ps(_mm_sub_ps(scaled1, _mm_set1_ps(0x80000000)), _mm_cmpge_ps(scaled1, _mm_set1_ps(0x80000000))); ppu.VR[op.vd].vi = _mm_or_si128(_mm_or_si128(_mm_cvttps_epi32(scaled1), _mm_cvttps_epi32(scaled2)), _mm_castps_si128(_mm_cmpge_ps(scaled1, _mm_set1_ps(0x100000000)))); + return true; } -void ppu_interpreter::VEXPTEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VEXPTEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = sse_exp2_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VLOGEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VLOGEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = sse_log2_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMADDFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMADDFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_add_ps(_mm_mul_ps(ppu.VR[op.va].vf, ppu.VR[op.vc].vf), ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMAXFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_max_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMAXSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi8(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMAXSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_max_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMAXSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMAXUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_max_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMAXUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x80008000); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_max_epi16(_mm_xor_si128(ppu.VR[op.va].vi, mask), _mm_xor_si128(ppu.VR[op.vb].vi, mask)), mask); + return true; } -void ppu_interpreter::VMAXUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMAXUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = sse_cmpgt_epu32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(m, a), _mm_andnot_si128(m, b)); + return true; } -void ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -488,9 +505,10 @@ void ppu_interpreter::VMHADDSHS(PPUThread& ppu, ppu_opcode_t op) const auto m = _mm_or_si128(_mm_srli_epi16(_mm_mullo_epi16(a, b), 15), _mm_slli_epi16(_mm_mulhi_epi16(a, b), 1)); const auto s = _mm_cmpeq_epi16(m, _mm_set1_epi16(-0x8000)); // detect special case (positive 0x8000) ppu.VR[op.vd].vi = _mm_adds_epi16(_mm_adds_epi16(_mm_xor_si128(m, s), c), _mm_srli_epi16(s, 15)); + return true; } -void ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -498,89 +516,104 @@ void ppu_interpreter::VMHRADDSHS(PPUThread& ppu, ppu_opcode_t op) const auto m = _mm_mulhrs_epi16(a, b); const auto s = _mm_cmpeq_epi16(m, _mm_set1_epi16(-0x8000)); // detect special case (positive 0x8000) ppu.VR[op.vd].vi = _mm_adds_epi16(_mm_adds_epi16(_mm_xor_si128(m, s), c), _mm_srli_epi16(s, 15)); + return true; } -void ppu_interpreter::VMINFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_min_ps(ppu.VR[op.va].vf, ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VMINSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSB(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi8(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMINSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_min_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMINSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINSW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = _mm_cmpgt_epi32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMINUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_min_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VMINUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x80008000); ppu.VR[op.vd].vi = _mm_xor_si128(_mm_min_epi16(_mm_xor_si128(ppu.VR[op.va].vi, mask), _mm_xor_si128(ppu.VR[op.vb].vi, mask)), mask); + return true; } -void ppu_interpreter::VMINUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMINUW(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto m = sse_cmpgt_epu32(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_andnot_si128(m, a), _mm_and_si128(m, b)); + return true; } -void ppu_interpreter::VMLADDUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMLADDUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_add_epi16(_mm_mullo_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi), ppu.VR[op.vc].vi); + return true; } -void ppu_interpreter::VMRGHB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi8(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGHH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGHW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGHW(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpackhi_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi8(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMRGLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMRGLW(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_unpacklo_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; // signed bytes const auto b = ppu.VR[op.vb].vi; // unsigned bytes @@ -592,14 +625,16 @@ void ppu_interpreter::VMSUMMBM(PPUThread& ppu, ppu_opcode_t op) const auto sh = _mm_madd_epi16(ah, bh); const auto sl = _mm_madd_epi16(al, bl); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, sh), sl); + return true; } -void ppu_interpreter::VMSUMSHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMSHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_add_epi32(_mm_madd_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi), ppu.VR[op.vc].vi); + return true; } -void ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -631,9 +666,10 @@ void ppu_interpreter::VMSUMSHS(PPUThread& ppu, ppu_opcode_t op) d._s32[w] = saturated; } + return true; } -void ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -646,9 +682,10 @@ void ppu_interpreter::VMSUMUBM(PPUThread& ppu, ppu_opcode_t op) const auto sh = _mm_madd_epi16(ah, bh); const auto sl = _mm_madd_epi16(al, bl); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, sh), sl); + return true; } -void ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; @@ -658,9 +695,10 @@ void ppu_interpreter::VMSUMUHM(PPUThread& ppu, ppu_opcode_t op) const auto ls = _mm_add_epi32(_mm_srli_epi32(ml, 16), _mm_and_si128(ml, _mm_set1_epi32(0x0000ffff))); const auto hs = _mm_add_epi32(_mm_slli_epi32(mh, 16), _mm_and_si128(mh, _mm_set1_epi32(0xffff0000))); ppu.VR[op.vd].vi = _mm_add_epi32(_mm_add_epi32(c, ls), hs); + return true; } -void ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -688,83 +726,96 @@ void ppu_interpreter::VMSUMUHS(PPUThread& ppu, ppu_opcode_t op) d._u32[w] = saturated; } + return true; } -void ppu_interpreter::VMULESB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULESB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srai_epi16(ppu.VR[op.va].vi, 8), _mm_srai_epi16(ppu.VR[op.vb].vi, 8)); + return true; } -void ppu_interpreter::VMULESH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULESH(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_madd_epi16(_mm_srli_epi32(ppu.VR[op.va].vi, 16), _mm_srli_epi32(ppu.VR[op.vb].vi, 16)); + return true; } -void ppu_interpreter::VMULEUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULEUB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srli_epi16(ppu.VR[op.va].vi, 8), _mm_srli_epi16(ppu.VR[op.vb].vi, 8)); + return true; } -void ppu_interpreter::VMULEUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULEUH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto ml = _mm_mullo_epi16(a, b); const auto mh = _mm_mulhi_epu16(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_srli_epi32(ml, 16), _mm_and_si128(mh, _mm_set1_epi32(0xffff0000))); + return true; } -void ppu_interpreter::VMULOSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOSB(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_srai_epi16(_mm_slli_epi16(ppu.VR[op.va].vi, 8), 8), _mm_srai_epi16(_mm_slli_epi16(ppu.VR[op.vb].vi, 8), 8)); + return true; } -void ppu_interpreter::VMULOSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOSH(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi32(0x0000ffff); ppu.VR[op.vd].vi = _mm_madd_epi16(_mm_and_si128(ppu.VR[op.va].vi, mask), _mm_and_si128(ppu.VR[op.vb].vi, mask)); + return true; } -void ppu_interpreter::VMULOUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOUB(PPUThread& ppu, ppu_opcode_t op) { const auto mask = _mm_set1_epi16(0x00ff); ppu.VR[op.vd].vi = _mm_mullo_epi16(_mm_and_si128(ppu.VR[op.va].vi, mask), _mm_and_si128(ppu.VR[op.vb].vi, mask)); + return true; } -void ppu_interpreter::VMULOUH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VMULOUH(PPUThread& ppu, ppu_opcode_t op) { const auto a = ppu.VR[op.va].vi; const auto b = ppu.VR[op.vb].vi; const auto ml = _mm_mullo_epi16(a, b); const auto mh = _mm_mulhi_epu16(a, b); ppu.VR[op.vd].vi = _mm_or_si128(_mm_slli_epi32(mh, 16), _mm_and_si128(ml, _mm_set1_epi32(0x0000ffff))); + return true; } -void ppu_interpreter::VNMSUBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VNMSUBFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_sub_ps(ppu.VR[op.vb].vf, _mm_mul_ps(ppu.VR[op.va].vf, ppu.VR[op.vc].vf)); + return true; } -void ppu_interpreter::VNOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VNOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ~(ppu.VR[op.va] | ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] | ppu.VR[op.vb]; + return true; } -void ppu_interpreter::VPERM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPERM(PPUThread& ppu, ppu_opcode_t op) { const auto index = _mm_andnot_si128(ppu.VR[op.vc].vi, _mm_set1_epi8(0x1f)); const auto mask = _mm_cmpgt_epi8(index, _mm_set1_epi8(0xf)); const auto sa = _mm_shuffle_epi8(ppu.VR[op.va].vi, index); const auto sb = _mm_shuffle_epi8(ppu.VR[op.vb].vi, index); ppu.VR[op.vd].vi = _mm_or_si128(_mm_and_si128(mask, sa), _mm_andnot_si128(mask, sb)); + return true; } -void ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -783,24 +834,28 @@ void ppu_interpreter::VPKPX(PPUThread& ppu, ppu_opcode_t op) d._u16[3 - h] = (bb7 << 15) | (bb8 << 10) | (bb16 << 5) | bb24; d._u16[4 + (3 - h)] = (ab7 << 15) | (ab8 << 10) | (ab16 << 5) | ab24; } + return true; } -void ppu_interpreter::VPKSHSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSHSS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packs_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSHUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSHUS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packus_epi16(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSWSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSWSS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_packs_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); + return true; } -void ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) { //ppu.VR[op.vd].vi = _mm_packus_epi32(ppu.VR[op.vb].vi, ppu.VR[op.va].vi); auto& d = ppu.VR[op.vd]; @@ -834,9 +889,10 @@ void ppu_interpreter::VPKSWUS(PPUThread& ppu, ppu_opcode_t op) d._u16[h] = result; } + return true; } -void ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -846,9 +902,10 @@ void ppu_interpreter::VPKUHUM(PPUThread& ppu, ppu_opcode_t op) d._u8[b + 8] = VA._u8[b * 2]; d._u8[b] = VB._u8[b * 2]; } + return true; } -void ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -873,9 +930,10 @@ void ppu_interpreter::VPKUHUS(PPUThread& ppu, ppu_opcode_t op) d._u8[b] = (u8)result; } + return true; } -void ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -885,9 +943,10 @@ void ppu_interpreter::VPKUWUM(PPUThread& ppu, ppu_opcode_t op) d._u16[h + 4] = VA._u16[h * 2]; d._u16[h] = VB._u16[h * 2]; } + return true; } -void ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -912,58 +971,64 @@ void ppu_interpreter::VPKUWUS(PPUThread& ppu, ppu_opcode_t op) d._u16[h] = result; } + return true; } -void ppu_interpreter::VREFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VREFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_rcp_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VRFIM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIM(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = floorf(b._f[w]); + d._f[w] = std::floor(b._f[w]); } + return true; } -void ppu_interpreter::VRFIN(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIN(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = nearbyintf(b._f[w]); + d._f[w] = std::nearbyint(b._f[w]); } + return true; } -void ppu_interpreter::VRFIP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIP(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = ceilf(b._f[w]); + d._f[w] = std::ceil(b._f[w]); } + return true; } -void ppu_interpreter::VRFIZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRFIZ(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& b = ppu.VR[op.vb]; for (uint w = 0; w < 4; w++) { - d._f[w] = truncf(b._f[w]); + d._f[w] = std::truncf(b._f[w]); } + return true; } -void ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -973,9 +1038,10 @@ void ppu_interpreter::VRLB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = rol8(a._u8[i], b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -985,9 +1051,10 @@ void ppu_interpreter::VRLH(PPUThread& ppu, ppu_opcode_t op) { d._u16[i] = rol16(a._u16[i], b._u8[i * 2] & 0xf); } + return true; } -void ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -997,14 +1064,16 @@ void ppu_interpreter::VRLW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = rol32(a._u32[w], b._u8[w * 4] & 0x1f); } + return true; } -void ppu_interpreter::VRSQRTEFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VRSQRTEFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vf = _mm_rsqrt_ps(ppu.VR[op.vb].vf); + return true; } -void ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1012,9 +1081,10 @@ void ppu_interpreter::VSEL(PPUThread& ppu, ppu_opcode_t op) const auto& c = ppu.VR[op.vc]; d = (b & c) | v128::andnot(c, a); + return true; } -void ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1025,9 +1095,10 @@ void ppu_interpreter::VSL(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = (VA._u8[b] << sh) | (VA._u8[b - 1] >> (8 - sh)); } + return true; } -void ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1037,9 +1108,10 @@ void ppu_interpreter::VSLB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = a._u8[i] << (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; u8 tmpSRC[32]; @@ -1050,9 +1122,10 @@ void ppu_interpreter::VSLDOI(PPUThread& ppu, ppu_opcode_t op) { d._u8[15 - b] = tmpSRC[31 - (b + op.vsh)]; } + return true; } -void ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1062,9 +1135,10 @@ void ppu_interpreter::VSLH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = a._u16[h] << (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1076,9 +1150,10 @@ void ppu_interpreter::VSLO(PPUThread& ppu, ppu_opcode_t op) { d._u8[15 - b] = VA._u8[15 - (b + nShift)]; } + return true; } -void ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1088,9 +1163,10 @@ void ppu_interpreter::VSLW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] << (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; u8 byte = ppu.VR[op.vb]._u8[15 - op.vuimm]; @@ -1099,12 +1175,13 @@ void ppu_interpreter::VSPLTB(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = byte; } + return true; } -void ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; - Expects(op.vuimm < 8); + EXPECTS(op.vuimm < 8); u16 hword = ppu.VR[op.vb]._u16[7 - op.vuimm]; @@ -1112,9 +1189,10 @@ void ppu_interpreter::VSPLTH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = hword; } + return true; } -void ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s8 imm = op.vsimm; @@ -1123,9 +1201,10 @@ void ppu_interpreter::VSPLTISB(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = imm; } + return true; } -void ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s16 imm = op.vsimm; @@ -1134,9 +1213,10 @@ void ppu_interpreter::VSPLTISH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = imm; } + return true; } -void ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const s32 imm = op.vsimm; @@ -1145,12 +1225,13 @@ void ppu_interpreter::VSPLTISW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = imm; } + return true; } -void ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; - Expects(op.vuimm < 4); + EXPECTS(op.vuimm < 4); u32 word = ppu.VR[op.vb]._u32[3 - op.vuimm]; @@ -1158,9 +1239,10 @@ void ppu_interpreter::VSPLTW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = word; } + return true; } -void ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1171,9 +1253,10 @@ void ppu_interpreter::VSR(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = (VA._u8[b] >> sh) | (VA._u8[b + 1] << (8 - sh)); } + return true; } -void ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1183,9 +1266,10 @@ void ppu_interpreter::VSRAB(PPUThread& ppu, ppu_opcode_t op) { d._s8[i] = a._s8[i] >> (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1195,9 +1279,10 @@ void ppu_interpreter::VSRAH(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = a._s16[h] >> (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1207,9 +1292,10 @@ void ppu_interpreter::VSRAW(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = a._s32[w] >> (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1219,9 +1305,10 @@ void ppu_interpreter::VSRB(PPUThread& ppu, ppu_opcode_t op) { d._u8[i] = a._u8[i] >> (b._u8[i] & 0x7); } + return true; } -void ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1231,9 +1318,10 @@ void ppu_interpreter::VSRH(PPUThread& ppu, ppu_opcode_t op) { d._u16[h] = a._u16[h] >> (b._u16[h] & 0xf); } + return true; } -void ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VA = ppu.VR[op.va]; @@ -1245,9 +1333,10 @@ void ppu_interpreter::VSRO(PPUThread& ppu, ppu_opcode_t op) { d._u8[b] = VA._u8[b + nShift]; } + return true; } -void ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1257,9 +1346,10 @@ void ppu_interpreter::VSRW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] >> (b._u32[w] & 0x1f); } + return true; } -void ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1269,24 +1359,28 @@ void ppu_interpreter::VSUBCUW(PPUThread& ppu, ppu_opcode_t op) { d._u32[w] = a._u32[w] < b._u32[w] ? 0 : 1; } + return true; } -void ppu_interpreter::VSUBFP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBFP(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::subfs(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBSBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epi8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBSHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epi16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1307,34 +1401,40 @@ void ppu_interpreter::VSUBSWS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)result; } + return true; } -void ppu_interpreter::VSUBUBM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUBM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub8(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epu8(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBUHM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUHM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub16(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUHS(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd].vi = _mm_subs_epu16(ppu.VR[op.va].vi, ppu.VR[op.vb].vi); + return true; } -void ppu_interpreter::VSUBUWM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUWM(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = v128::sub32(ppu.VR[op.va], ppu.VR[op.vb]); + return true; } -void ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1351,9 +1451,10 @@ void ppu_interpreter::VSUBUWS(PPUThread& ppu, ppu_opcode_t op) else d._u32[w] = (u32)result; } + return true; } -void ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1377,9 +1478,10 @@ void ppu_interpreter::VSUMSWS(PPUThread& ppu, ppu_opcode_t op) } else d._s32[0] = (s32)sum; + return true; } -void ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1402,9 +1504,10 @@ void ppu_interpreter::VSUM2SWS(PPUThread& ppu, ppu_opcode_t op) } d._s32[1] = 0; d._s32[3] = 0; + return true; } -void ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1430,9 +1533,10 @@ void ppu_interpreter::VSUM4SBS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)sum; } + return true; } -void ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1458,9 +1562,10 @@ void ppu_interpreter::VSUM4SHS(PPUThread& ppu, ppu_opcode_t op) else d._s32[w] = (s32)sum; } + return true; } -void ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; const auto& a = ppu.VR[op.va]; @@ -1482,9 +1587,10 @@ void ppu_interpreter::VSUM4UBS(PPUThread& ppu, ppu_opcode_t op) else d._u32[w] = (u32)sum; } + return true; } -void ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1495,9 +1601,10 @@ void ppu_interpreter::VUPKHPX(PPUThread& ppu, ppu_opcode_t op) d._u8[w * 4 + 1] = ((VB._u8[8 + w * 2 + 1] & 0x3) << 3) | ((VB._u8[8 + w * 2 + 0] >> 5) & 0x7); d._u8[w * 4 + 0] = VB._u8[8 + w * 2 + 0] & 0x1f; } + return true; } -void ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1505,9 +1612,10 @@ void ppu_interpreter::VUPKHSB(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = VB._s8[8 + h]; } + return true; } -void ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1515,9 +1623,10 @@ void ppu_interpreter::VUPKHSH(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = VB._s16[4 + w]; } + return true; } -void ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1528,9 +1637,10 @@ void ppu_interpreter::VUPKLPX(PPUThread& ppu, ppu_opcode_t op) d._u8[w * 4 + 1] = ((VB._u8[w * 2 + 1] & 0x3) << 3) | ((VB._u8[w * 2 + 0] >> 5) & 0x7); d._u8[w * 4 + 0] = VB._u8[w * 2 + 0] & 0x1f; } + return true; } -void ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1538,9 +1648,10 @@ void ppu_interpreter::VUPKLSB(PPUThread& ppu, ppu_opcode_t op) { d._s16[h] = VB._s8[h]; } + return true; } -void ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) { auto& d = ppu.VR[op.vd]; v128 VB = ppu.VR[op.vb]; @@ -1548,28 +1659,66 @@ void ppu_interpreter::VUPKLSH(PPUThread& ppu, ppu_opcode_t op) { d._s32[w] = VB._s16[w]; } + return true; } -void ppu_interpreter::VXOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::VXOR(PPUThread& ppu, ppu_opcode_t op) { ppu.VR[op.vd] = ppu.VR[op.va] ^ ppu.VR[op.vb]; + return true; } -void ppu_interpreter::MULLI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TDI(PPUThread& ppu, ppu_opcode_t op) +{ + const s64 a = ppu.GPR[op.ra], b = op.simm16; + const u64 a_ = a, b_ = b; + + if (((op.bo & 0x10) && a < b) || + ((op.bo & 0x8) && a > b) || + ((op.bo & 0x4) && a == b) || + ((op.bo & 0x2) && a_ < b_) || + ((op.bo & 0x1) && a_ > b_)) + { + throw std::runtime_error("Trap!" HERE); + } + + return true; +} + +bool ppu_interpreter::TWI(PPUThread& ppu, ppu_opcode_t op) +{ + const s32 a = u32(ppu.GPR[op.ra]), b = op.simm16; + const u32 a_ = a, b_ = b; + + if (((op.bo & 0x10) && a < b) || + ((op.bo & 0x8) && a > b) || + ((op.bo & 0x4) && a == b) || + ((op.bo & 0x2) && a_ < b_) || + ((op.bo & 0x1) && a_ > b_)) + { + throw std::runtime_error("Trap!" HERE); + } + + return true; +} + +bool ppu_interpreter::MULLI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = (s64)ppu.GPR[op.ra] * op.simm16; + return true; } -void ppu_interpreter::SUBFIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFIC(PPUThread& ppu, ppu_opcode_t op) { const u64 a = ppu.GPR[op.ra]; const s64 i = op.simm16; const auto r = add64_flags(~a, i, 1); ppu.GPR[op.rd] = r.result; ppu.CA = r.carry; + return true; } -void ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1579,9 +1728,10 @@ void ppu_interpreter::CMPLI(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR<u32>(op.crfd, u32(ppu.GPR[op.ra]), op.uimm16); } + return true; } -void ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1591,9 +1741,10 @@ void ppu_interpreter::CMPI(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR<s32>(op.crfd, u32(ppu.GPR[op.ra]), op.simm16); } + return true; } -void ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) { const s64 a = ppu.GPR[op.ra]; const s64 i = op.simm16; @@ -1601,19 +1752,22 @@ void ppu_interpreter::ADDIC(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = r.result; ppu.CA = r.carry; if (UNLIKELY(op.main & 1)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::ADDI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = op.ra ? ((s64)ppu.GPR[op.ra] + op.simm16) : op.simm16; + return true; } -void ppu_interpreter::ADDIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = op.ra ? ((s64)ppu.GPR[op.ra] + (op.simm16 << 16)) : (op.simm16 << 16); + return true; } -void ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) { const bool bo0 = (op.bo & 0x10) != 0; const bool bo1 = (op.bo & 0x08) != 0; @@ -1627,40 +1781,50 @@ void ppu_interpreter::BC(PPUThread& ppu, ppu_opcode_t op) if (ctr_ok && cond_ok) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target((op.aa ? 0 : ppu.PC), op.simm16) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target((op.aa ? 0 : ppu.pc), op.simm16); if (op.lk) ppu.LR = nextLR; + return false; + } + else + { + return true; } } -void ppu_interpreter::HACK(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::HACK(PPUThread& ppu, ppu_opcode_t op) { ppu_execute_function(ppu, op.opcode & 0x3ffffff); + return true; } -void ppu_interpreter::SC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SC(PPUThread& ppu, ppu_opcode_t op) { switch (u32 lv = op.lev) { case 0x0: ppu_execute_syscall(ppu, ppu.GPR[11]); break; default: throw fmt::exception("SC lv%u", lv); } + + return true; } -void ppu_interpreter::B(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::B(PPUThread& ppu, ppu_opcode_t op) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(op.aa ? 0 : ppu.PC, op.ll) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(op.aa ? 0 : ppu.pc, op.ll); if (op.lk) ppu.LR = nextLR; + return false; } -void ppu_interpreter::MCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MCRF(PPUThread& ppu, ppu_opcode_t op) { CHECK_SIZE(PPUThread::CR, 32); reinterpret_cast<u32*>(ppu.CR)[op.crfd] = reinterpret_cast<u32*>(ppu.CR)[op.crfs]; + return true; } -void ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) { const bool bo0 = (op.bo & 0x10) != 0; const bool bo1 = (op.bo & 0x08) != 0; @@ -1674,156 +1838,188 @@ void ppu_interpreter::BCLR(PPUThread& ppu, ppu_opcode_t op) if (ctr_ok && cond_ok) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(0, (u32)ppu.LR) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(0, (u32)ppu.LR); if (op.lk) ppu.LR = nextLR; + return false; + } + else + { + return true; } } -void ppu_interpreter::CRNOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRNOR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] | ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] & (ppu.CR[op.crbb] ^ true); + return true; } -void ppu_interpreter::ISYNC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ISYNC(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::CRXOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRXOR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] ^ ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::CRNAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRNAND(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] & ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRAND(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] & ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::CREQV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CREQV(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = (ppu.CR[op.crba] ^ ppu.CR[op.crbb]) ^ true; + return true; } -void ppu_interpreter::CRORC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CRORC(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] | (ppu.CR[op.crbb] ^ true); + return true; } -void ppu_interpreter::CROR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CROR(PPUThread& ppu, ppu_opcode_t op) { ppu.CR[op.crbd] = ppu.CR[op.crba] | ppu.CR[op.crbb]; + return true; } -void ppu_interpreter::BCCTR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::BCCTR(PPUThread& ppu, ppu_opcode_t op) { if (op.bo & 0x10 || ppu.CR[op.bi] == ((op.bo & 0x8) != 0)) { - const u32 nextLR = ppu.PC + 4; - ppu.PC = ppu_branch_target(0, (u32)ppu.CTR) - 4; + const u32 nextLR = ppu.pc + 4; + ppu.pc = ppu_branch_target(0, (u32)ppu.CTR); if (op.lk) ppu.LR = nextLR; + return false; } + + return true; } -void ppu_interpreter::RLWIMI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWIMI(PPUThread& ppu, ppu_opcode_t op) { const u64 mask = ppu_rotate_mask(32 + op.mb32, 32 + op.me32); ppu.GPR[op.ra] = (ppu.GPR[op.ra] & ~mask) | (dup32(rol32(u32(ppu.GPR[op.rs]), op.sh32)) & mask); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLWINM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWINM(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = dup32(rol32(u32(ppu.GPR[op.rs]), op.sh32)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLWNM(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLWNM(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = dup32(rol32(u32(ppu.GPR[op.rs]), ppu.GPR[op.rb] & 0x1f)) & ppu_rotate_mask(32 + op.mb32, 32 + op.me32); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ORI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | op.uimm16; + return true; } -void ppu_interpreter::ORIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ((u64)op.uimm16 << 16); + return true; } -void ppu_interpreter::XORI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XORI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ op.uimm16; + return true; } -void ppu_interpreter::XORIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XORIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ ((u64)op.uimm16 << 16); + return true; } -void ppu_interpreter::ANDI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDI(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & op.uimm16; ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ANDIS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDIS(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ((u64)op.uimm16 << 16); ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDICL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDICL(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & (~0ull >> op.mbe64); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDICR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDICR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & (~0ull << (op.mbe64 ^ 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDIC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDIC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], op.sh64) & ppu_rotate_mask(op.mbe64, op.sh64 ^ 63); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDIMI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDIMI(PPUThread& ppu, ppu_opcode_t op) { const u64 mask = ppu_rotate_mask(op.mbe64, op.sh64 ^ 63); ppu.GPR[op.ra] = (ppu.GPR[op.ra] & ~mask) | (rol64(ppu.GPR[op.rs], op.sh64) & mask); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDCL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDCL(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], ppu.GPR[op.rb] & 0x3f) & (~0ull >> op.mbe64); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::RLDCR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::RLDCR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = rol64(ppu.GPR[op.rs], ppu.GPR[op.rb] & 0x3f) & (~0ull << (op.mbe64 ^ 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1833,9 +2029,10 @@ void ppu_interpreter::CMP(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR<s32>(op.crfd, u32(ppu.GPR[op.ra]), u32(ppu.GPR[op.rb])); } + return true; } -void ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) { s32 a = (s32)ppu.GPR[op.ra]; s32 b = (s32)ppu.GPR[op.rb]; @@ -1848,9 +2045,11 @@ void ppu_interpreter::TW(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("Trap!" HERE); } + + return true; } -void ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -1876,15 +2075,17 @@ void ppu_interpreter::LVSL(PPUThread& ppu, ppu_opcode_t op) ppu.VR[op.vd]._u64[0] = lvsl_values[addr & 0xf][0]; ppu.VR[op.vd]._u64[1] = lvsl_values[addr & 0xf][1]; + return true; } -void ppu_interpreter::LVEBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.VR[op.vd]._u8[15 - (addr & 0xf)] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -1893,15 +2094,17 @@ void ppu_interpreter::SUBFC(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::MULHDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHDU(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = UMULH64(ppu.GPR[op.ra], ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -1910,17 +2113,19 @@ void ppu_interpreter::ADDC(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::MULHWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHWU(PPUThread& ppu, ppu_opcode_t op) { u32 a = (u32)ppu.GPR[op.ra]; u32 b = (u32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = ((u64)a * (u64)b) >> 32; if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) { if (op.l11) { @@ -1940,9 +2145,10 @@ void ppu_interpreter::MFOCRF(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = (mh << 16) | ml; } + return true; } -void ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -1950,46 +2156,53 @@ void ppu_interpreter::LWARX(PPUThread& ppu, ppu_opcode_t op) vm::reservation_acquire(&value, vm::cast(addr, HERE), SIZE_32(value)); ppu.GPR[op.rd] = value; + return true; } -void ppu_interpreter::LDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LWZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SLW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = u32(ppu.GPR[op.rs] << (ppu.GPR[op.rb] & 0x3f)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CNTLZW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CNTLZW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = cntlz32(u32(ppu.GPR[op.rs])); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SLD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SLD(PPUThread& ppu, ppu_opcode_t op) { const u32 n = ppu.GPR[op.rb]; ppu.GPR[op.ra] = UNLIKELY(n & 0x40) ? 0 : ppu.GPR[op.rs] << n; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::AND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::AND(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) { if (op.l10) { @@ -1999,9 +2212,10 @@ void ppu_interpreter::CMPL(PPUThread& ppu, ppu_opcode_t op) { ppu.SetCR<u32>(op.crfd, u32(ppu.GPR[op.ra]), u32(ppu.GPR[op.rb])); } + return true; } -void ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -2027,54 +2241,62 @@ void ppu_interpreter::LVSR(PPUThread& ppu, ppu_opcode_t op) ppu.VR[op.vd]._u64[0] = lvsr_values[addr & 0xf][0]; ppu.VR[op.vd]._u64[1] = lvsr_values[addr & 0xf][1]; + return true; } -void ppu_interpreter::LVEHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~1ULL; ppu.VR[op.vd]._u16[7 - ((addr >> 1) & 0x7)] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SUBF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBF(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB - RA; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::LDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::DCBST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LWZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::CNTLZD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::CNTLZD(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = cntlz64(ppu.GPR[op.rs]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ANDC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ANDC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] & ~ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) { const s64 a = ppu.GPR[op.ra], b = ppu.GPR[op.rb]; const u64 a_ = a, b_ = b; @@ -2087,29 +2309,34 @@ void ppu_interpreter::TD(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("Trap!" HERE); } + + return true; } -void ppu_interpreter::LVEWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVEWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~3ULL; ppu.VR[op.vd]._u32[3 - ((addr >> 2) & 0x3)] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::MULHD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHD(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = MULH64(ppu.GPR[op.ra], ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::MULHW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULHW(PPUThread& ppu, ppu_opcode_t op) { s32 a = (s32)ppu.GPR[op.ra]; s32 b = (s32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = ((s64)a * (s64)b) >> 32; if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; @@ -2117,53 +2344,61 @@ void ppu_interpreter::LDARX(PPUThread& ppu, ppu_opcode_t op) vm::reservation_acquire(&value, vm::cast(addr, HERE), SIZE_32(value)); ppu.GPR[op.rd] = value; + return true; } -void ppu_interpreter::DCBF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBF(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LBZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LVX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; ppu.VR[op.vd] = vm::_ref<v128>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::NEG(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NEG(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; ppu.GPR[op.rd] = 0 - RA; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 0) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::LBZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::NOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NOR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] | ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVEBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; vm::write8(vm::cast(addr, HERE), ppu.VR[op.vs]._u8[15 - eb]); + return true; } -void ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -2172,9 +2407,10 @@ void ppu_interpreter::SUBFE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == RB >> 63) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; @@ -2183,9 +2419,10 @@ void ppu_interpreter::ADDE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) { const u64 s = ppu.GPR[op.rs]; @@ -2219,57 +2456,65 @@ void ppu_interpreter::MTOCRF(PPUThread& ppu, ppu_opcode_t op) } } } + return true; } -void ppu_interpreter::STDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STWCX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWCX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const be_t<u32> value = (u32)ppu.GPR[op.rs]; ppu.SetCR(0, false, false, vm::reservation_update(vm::cast(addr, HERE), &value, SIZE_32(value)), ppu.SO); + return true; } -void ppu_interpreter::STWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STVEHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~1ULL; const u8 eb = (addr & 0xf) >> 1; vm::write16(vm::cast(addr, HERE), ppu.VR[op.vs]._u16[7 - eb]); + return true; } -void ppu_interpreter::STDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STWUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STVEWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVEWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~3ULL; const u8 eb = (addr & 0xf) >> 2; vm::write32(vm::cast(addr, HERE), ppu.VR[op.vs]._u32[3 - eb]); + return true; } -void ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(~RA, 0, ppu.CA); @@ -2277,9 +2522,10 @@ void ppu_interpreter::SUBFZE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 0) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(RA, 0, ppu.CA); @@ -2287,29 +2533,33 @@ void ppu_interpreter::ADDZE(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == 0) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::STDCX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDCX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const be_t<u64> value = ppu.GPR[op.rs]; ppu.SetCR(0, false, false, vm::reservation_update(vm::cast(addr, HERE), &value, SIZE_32(value)), ppu.SO); + return true; } -void ppu_interpreter::STBX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STVX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; vm::_ref<v128>(vm::cast(addr, HERE)) = ppu.VR[op.vs]; + return true; } -void ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const s64 RB = ppu.GPR[op.rb]; @@ -2320,9 +2570,10 @@ void ppu_interpreter::MULLD(PPUThread& ppu, ppu_opcode_t op) ppu.SetOV(high != s64(ppu.GPR[op.rd]) >> 63); } if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(~RA, ~0ull, ppu.CA); @@ -2330,9 +2581,10 @@ void ppu_interpreter::SUBFME(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((~RA >> 63 == 1) && (~RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const auto r = add64_flags(RA, ~0ull, ppu.CA); @@ -2340,110 +2592,125 @@ void ppu_interpreter::ADDME(PPUThread& ppu, ppu_opcode_t op) ppu.CA = r.carry; if (UNLIKELY(op.oe)) ppu.SetOV((u64(RA) >> 63 == 1) && (u64(RA) >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, r.result, 0); + return true; } -void ppu_interpreter::MULLW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MULLW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.rd] = (s64)((s64)(s32)ppu.GPR[op.ra] * (s64)(s32)ppu.GPR[op.rb]); if (UNLIKELY(op.oe)) ppu.SetOV(s64(ppu.GPR[op.rd]) < s64(-1) << 31 || s64(ppu.GPR[op.rd]) >= s64(1) << 31); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::DCBTST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBTST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::STBUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::ADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ADD(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RA + RB; if (UNLIKELY(op.oe)) ppu.SetOV((RA >> 63 == RB >> 63) && (RA >> 63 != ppu.GPR[op.rd] >> 63)); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DCBT(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBT(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHZX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::EQV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EQV(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] ^ ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ECIWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ECIWX(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("ECIWX" HERE); } -void ppu_interpreter::LHZUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::XOR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::XOR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] ^ ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::MFSPR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFSPR(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); switch (n) { - case 0x001: ppu.GPR[op.rd] = u32{ ppu.SO } << 31 | ppu.OV << 30 | ppu.CA << 29 | ppu.XCNT; return; - case 0x008: ppu.GPR[op.rd] = ppu.LR; return; - case 0x009: ppu.GPR[op.rd] = ppu.CTR; return; - case 0x100: ppu.GPR[op.rd] = ppu.VRSAVE; return; + case 0x001: ppu.GPR[op.rd] = u32{ ppu.SO } << 31 | ppu.OV << 30 | ppu.CA << 29 | ppu.XCNT; break; + case 0x008: ppu.GPR[op.rd] = ppu.LR; break; + case 0x009: ppu.GPR[op.rd] = ppu.CTR; break; + case 0x100: ppu.GPR[op.rd] = ppu.VRSAVE; break; - case 0x10C: ppu.GPR[op.rd] = get_timebased_time() & 0xffffffff; return; - case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; return; + case 0x10C: ppu.GPR[op.rd] = get_timebased_time() & 0xffffffff; break; + case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; break; + default: throw fmt::exception("MFSPR 0x%x" HERE, n); } - throw fmt::exception("MFSPR 0x%x" HERE, n); + return true; } -void ppu_interpreter::LWAX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWAX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::DST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHAX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LVXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; ppu.VR[op.vd] = vm::_ref<v128>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); @@ -2453,75 +2720,86 @@ void ppu_interpreter::MFTB(PPUThread& ppu, ppu_opcode_t op) case 0x10D: ppu.GPR[op.rd] = get_timebased_time() >> 32; break; default: throw fmt::exception("MFSPR 0x%x" HERE, n); } + + return true; } -void ppu_interpreter::LWAUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWAUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::DSTST(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DSTST(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::LHAUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STHX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::ORC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ORC(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ~ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ECOWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ECOWX(PPUThread& ppu, ppu_opcode_t op) { throw std::runtime_error("ECOWX" HERE); } -void ppu_interpreter::STHUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::OR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::OR(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ppu.GPR[op.rs] | ppu.GPR[op.rb]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::DIVDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVDU(PPUThread& ppu, ppu_opcode_t op) { const u64 RA = ppu.GPR[op.ra]; const u64 RB = ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB == 0 ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(RB == 0); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DIVWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVWU(PPUThread& ppu, ppu_opcode_t op) { const u32 RA = (u32)ppu.GPR[op.ra]; const u32 RB = (u32)ppu.GPR[op.rb]; ppu.GPR[op.rd] = RB == 0 ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(RB == 0); if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) { const u32 n = (op.spr >> 5) | ((op.spr & 0x1f) << 5); @@ -2534,33 +2812,37 @@ void ppu_interpreter::MTSPR(PPUThread& ppu, ppu_opcode_t op) ppu.OV = (value & 0x40000000) != 0; ppu.CA = (value & 0x20000000) != 0; ppu.XCNT = value & 0x7f; - return; + break; } - case 0x008: ppu.LR = ppu.GPR[op.rs]; return; - case 0x009: ppu.CTR = ppu.GPR[op.rs]; return; - case 0x100: ppu.VRSAVE = (u32)ppu.GPR[op.rs]; return; + case 0x008: ppu.LR = ppu.GPR[op.rs]; break; + case 0x009: ppu.CTR = ppu.GPR[op.rs]; break; + case 0x100: ppu.VRSAVE = (u32)ppu.GPR[op.rs]; break; + default: throw fmt::exception("MTSPR 0x%x" HERE, n); } - throw fmt::exception("MTSPR 0x%x" HERE, n); + return true; } -void ppu_interpreter::DCBI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBI(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::NAND(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::NAND(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = ~(ppu.GPR[op.rs] & ppu.GPR[op.rb]); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]) & ~0xfull; vm::_ref<v128>(vm::cast(addr, HERE)) = ppu.VR[op.vs]; + return true; } -void ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) { const s64 RA = ppu.GPR[op.ra]; const s64 RB = ppu.GPR[op.rb]; @@ -2568,9 +2850,10 @@ void ppu_interpreter::DIVD(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = o ? 0 : RA / RB; if (UNLIKELY(op.oe)) ppu.SetOV(o); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.rd], 0); + return true; } -void ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) { const s32 RA = (s32)ppu.GPR[op.ra]; const s32 RB = (s32)ppu.GPR[op.rb]; @@ -2578,24 +2861,27 @@ void ppu_interpreter::DIVW(PPUThread& ppu, ppu_opcode_t op) ppu.GPR[op.rd] = o ? 0 : u32(RA / RB); if (UNLIKELY(op.oe)) ppu.SetOV(o); if (UNLIKELY(op.rc)) ppu.SetCR(0, false, false, false, ppu.SO); + return true; } -void ppu_interpreter::LVLX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVLX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 0; i < 16u - eb; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i, HERE)); + return true; } -void ppu_interpreter::LDBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref<le_t<u64>>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; u32 count = ppu.XCNT & 0x7f; @@ -2613,43 +2899,49 @@ void ppu_interpreter::LSWX(PPUThread& ppu, ppu_opcode_t op) } ppu.GPR[op.rd] = value; } + return true; } -void ppu_interpreter::LWBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref<le_t<u32>>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref<f32>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SRW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (ppu.GPR[op.rs] & 0xffffffff) >> (ppu.GPR[op.rb] & 0x3f); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRD(PPUThread& ppu, ppu_opcode_t op) { const u32 n = ppu.GPR[op.rb]; ppu.GPR[op.ra] = UNLIKELY(n & 0x40) ? 0 : ppu.GPR[op.rs] >> n; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::LVRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 16 - eb; i < 16; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16, HERE)); + return true; } -void ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] : 0; u64 N = op.rb ? op.rb : 32; @@ -2678,48 +2970,55 @@ void ppu_interpreter::LSWI(PPUThread& ppu, ppu_opcode_t op) } reg = (reg + 1) % 32; } + return true; } -void ppu_interpreter::LFSUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref<f32>(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::SYNC(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SYNC(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::LFDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref<f64>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; ppu.FPR[op.frd] = vm::_ref<f64>(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STVLX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVLX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STDBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref<le_t<u64>>(vm::cast(addr, HERE)) = ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; u32 count = ppu.XCNT & 0x7F; @@ -2736,36 +3035,41 @@ void ppu_interpreter::STSWX(PPUThread& ppu, ppu_opcode_t op) vm::write8(vm::cast(addr + byte, HERE), byte_value); } } + return true; } -void ppu_interpreter::STWBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref<le_t<u32>>(vm::cast(addr, HERE)) = (u32)ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::STFSX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref<f32>(vm::cast(addr, HERE)) = static_cast<float>(ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::STVRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STFSUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::_ref<f32>(vm::cast(addr, HERE)) = static_cast<float>(ppu.FPR[op.frs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] : 0; u64 N = op.rb ? op.rb : 32; @@ -2792,37 +3096,42 @@ void ppu_interpreter::STSWI(PPUThread& ppu, ppu_opcode_t op) } reg = (reg + 1) % 32; } + return true; } -void ppu_interpreter::STFDX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref<f64>(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; + return true; } -void ppu_interpreter::STFDUX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDUX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + ppu.GPR[op.rb]; vm::_ref<f64>(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LVLXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVLXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 0; i < 16u - eb; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i, HERE)); + return true; } -void ppu_interpreter::LHBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; ppu.GPR[op.rd] = vm::_ref<le_t<u16>>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) { s32 RS = (s32)ppu.GPR[op.rs]; u8 shift = ppu.GPR[op.rb] & 63; @@ -2838,9 +3147,10 @@ void ppu_interpreter::SRAW(PPUThread& ppu, ppu_opcode_t op) } if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) { s64 RS = ppu.GPR[op.rs]; u8 shift = ppu.GPR[op.rb] & 127; @@ -2856,31 +3166,35 @@ void ppu_interpreter::SRAD(PPUThread& ppu, ppu_opcode_t op) } if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::LVRXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LVRXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; ppu.VR[op.vd].clear(); for (u32 i = 16 - eb; i < 16; ++i) ppu.VR[op.vd]._u8[15 - i] = vm::read8(vm::cast(addr + i - 16, HERE)); + return true; } -void ppu_interpreter::DSS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DSS(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::SRAWI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRAWI(PPUThread& ppu, ppu_opcode_t op) { s32 RS = (u32)ppu.GPR[op.rs]; ppu.GPR[op.ra] = RS >> op.sh32; ppu.CA = (RS < 0) && ((u32)(ppu.GPR[op.ra] << op.sh32) != RS); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) { auto sh = op.sh64; s64 RS = ppu.GPR[op.rs]; @@ -2888,361 +3202,417 @@ void ppu_interpreter::SRADI(PPUThread& ppu, ppu_opcode_t op) ppu.CA = (RS < 0) && ((ppu.GPR[op.ra] << sh) != RS); if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::EIEIO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EIEIO(PPUThread& ppu, ppu_opcode_t op) { _mm_mfence(); + return true; } -void ppu_interpreter::STVLXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVLXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u32 eb = addr & 0xf; for (u32 i = 0; i < 16u - eb; ++i) vm::write8(vm::cast(addr + i, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::STHBRX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHBRX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::_ref<le_t<u16>>(vm::cast(addr, HERE)) = (u16)ppu.GPR[op.rs]; + return true; } -void ppu_interpreter::EXTSH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSH(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s16)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STVRXL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STVRXL(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; const u8 eb = addr & 0xf; for (u32 i = 16 - eb; i < 16; ++i) vm::write8(vm::cast(addr + i - 16, HERE), ppu.VR[op.vs]._u8[15 - i]); + return true; } -void ppu_interpreter::EXTSB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSB(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s8)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::STFIWX(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFIWX(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; vm::write32(vm::cast(addr, HERE), (u32&)ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::EXTSW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::EXTSW(PPUThread& ppu, ppu_opcode_t op) { ppu.GPR[op.ra] = (s64)(s32)ppu.GPR[op.rs]; if (UNLIKELY(op.rc)) ppu.SetCR<s64>(0, ppu.GPR[op.ra], 0); + return true; } -void ppu_interpreter::ICBI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::ICBI(PPUThread& ppu, ppu_opcode_t op) { + return true; } -void ppu_interpreter::DCBZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::DCBZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + ppu.GPR[op.rb] : ppu.GPR[op.rb]; std::memset(vm::base(vm::cast(addr, HERE) & ~127), 0, 128); + return true; } -void ppu_interpreter::LWZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LWZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read32(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LBZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LBZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LBZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read8(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STW(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STWU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STWU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STB(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STBU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STBU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write8(vm::cast(addr, HERE), (u8)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LHZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZ(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LHZU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHZU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LHA(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHA(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LHAU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LHAU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.GPR[op.rd] = (s64)(s16)vm::read16(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STH(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STH(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STHU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STHU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::write16(vm::cast(addr, HERE), (u16)ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LMW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LMW(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rd; i<32; ++i, addr += 4) { ppu.GPR[i] = vm::read32(vm::cast(addr, HERE)); } + return true; } -void ppu_interpreter::STMW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STMW(PPUThread& ppu, ppu_opcode_t op) { u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; for (u32 i = op.rs; i<32; ++i, addr += 4) { vm::write32(vm::cast(addr, HERE), (u32)ppu.GPR[i]); } + return true; } -void ppu_interpreter::LFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFS(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.FPR[op.frd] = vm::_ref<f32>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFSU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFSU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.FPR[op.frd] = vm::_ref<f32>(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LFD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; ppu.FPR[op.frd] = vm::_ref<f64>(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LFDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LFDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; ppu.FPR[op.frd] = vm::_ref<f64>(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFS(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::_ref<f32>(vm::cast(addr, HERE)) = static_cast<float>(ppu.FPR[op.frs]); + return true; } -void ppu_interpreter::STFSU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFSU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::_ref<f32>(vm::cast(addr, HERE)) = static_cast<float>(ppu.FPR[op.frs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::STFD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = op.ra ? ppu.GPR[op.ra] + op.simm16 : op.simm16; vm::_ref<f64>(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; + return true; } -void ppu_interpreter::STFDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STFDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + op.simm16; vm::_ref<f64>(vm::cast(addr, HERE)) = ppu.FPR[op.frs]; ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::LDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + (op.simm16 & ~3); ppu.GPR[op.rd] = vm::read64(vm::cast(addr, HERE)); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::LWA(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::LWA(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); ppu.GPR[op.rd] = (s64)(s32)vm::read32(vm::cast(addr, HERE)); + return true; } -void ppu_interpreter::STD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STD(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = (op.simm16 & ~3) + (op.ra ? ppu.GPR[op.ra] : 0); vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); + return true; } -void ppu_interpreter::STDU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::STDU(PPUThread& ppu, ppu_opcode_t op) { const u64 addr = ppu.GPR[op.ra] + (op.simm16 & ~3); vm::write64(vm::cast(addr, HERE), ppu.GPR[op.rs]); ppu.GPR[op.ra] = addr; + return true; } -void ppu_interpreter::FDIVS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FDIVS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] / ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSQRTS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSQRTS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = f32(sqrt(ppu.FPR[op.frb])); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = f32(std::sqrt(ppu.FPR[op.frb])); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRES(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRES(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(1.0 / ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMULS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMULS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc] + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.fra] * ppu.FPR[op.frc] - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMSUBS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMSUBS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(-(ppu.FPR[op.fra] * ppu.FPR[op.frc]) + ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMADDS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMADDS(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(-(ppu.FPR[op.fra] * ppu.FPR[op.frc]) - ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSB1(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSB1(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSB1"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MCRFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MCRFS(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MCRFS"); ppu.SetCR(op.crfd, false, false, false, false); + return true; } -void ppu_interpreter::MTFSB0(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSB0(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSB0"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSFI(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSFI(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSFI"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MFFS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MFFS(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MFFS"); ppu.FPR[op.frd] = 0.0; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::MTFSF(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::MTFSF(PPUThread& ppu, ppu_opcode_t op) { LOG_WARNING(PPU, "MTFSF"); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) { const f64 a = ppu.FPR[op.fra]; const f64 b = ppu.FPR[op.frb]; @@ -3251,141 +3621,163 @@ void ppu_interpreter::FCMPU(PPUThread& ppu, ppu_opcode_t op) ppu.FE = a == b; //ppu.FU = a != a || b != b; ppu.SetCR(op.crfd, ppu.FL, ppu.FG, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRSP(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRSP(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = f32(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIW(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIW(PPUThread& ppu, ppu_opcode_t op) { - (s32&)ppu.FPR[op.frd] = lrint(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + (s32&)ppu.FPR[op.frd] = std::lrint(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIWZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIWZ(PPUThread& ppu, ppu_opcode_t op) { (s32&)ppu.FPR[op.frd] = static_cast<s32>(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FDIV(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FDIV(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] / ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSQRT(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSQRT(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = sqrt(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = std::sqrt(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FSEL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FSEL(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] >= 0.0 ? ppu.FPR[op.frc] : ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMUL(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMUL(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FRSQRTE(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FRSQRTE(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = 1.0 / sqrt(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + ppu.FPR[op.frd] = 1.0 / std::sqrt(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc] - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.fra] * ppu.FPR[op.frc] + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMSUB(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMSUB(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -(ppu.FPR[op.fra] * ppu.FPR[op.frc]) + ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNMADD(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNMADD(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -(ppu.FPR[op.fra] * ppu.FPR[op.frc]) - ppu.FPR[op.frb]; - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCMPO(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCMPO(PPUThread& ppu, ppu_opcode_t op) { return FCMPU(ppu, op); + return true; } -void ppu_interpreter::FNEG(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNEG(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = -ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FMR(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FMR(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = ppu.FPR[op.frb]; if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FNABS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FNABS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = -fabs(ppu.FPR[op.frb]); + ppu.FPR[op.frd] = -std::fabs(ppu.FPR[op.frb]); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FABS(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FABS(PPUThread& ppu, ppu_opcode_t op) { - ppu.FPR[op.frd] = fabs(ppu.FPR[op.frb]); + ppu.FPR[op.frd] = std::fabs(ppu.FPR[op.frb]); if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTID(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTID(PPUThread& ppu, ppu_opcode_t op) { - (s64&)ppu.FPR[op.frd] = llrint(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + (s64&)ppu.FPR[op.frd] = std::llrint(ppu.FPR[op.frb]); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCTIDZ(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCTIDZ(PPUThread& ppu, ppu_opcode_t op) { (s64&)ppu.FPR[op.frd] = static_cast<s64>(ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } -void ppu_interpreter::FCFID(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::FCFID(PPUThread& ppu, ppu_opcode_t op) { ppu.FPR[op.frd] = static_cast<double>((s64&)ppu.FPR[op.frb]); - ASSERT(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + VERIFY(!op.rc); //if (UNLIKELY(op.rc)) ppu.SetCR(1, ppu.FG, ppu.FL, ppu.FE, ppu.FU); + return true; } - -void ppu_interpreter::UNK(PPUThread& ppu, ppu_opcode_t op) +bool ppu_interpreter::UNK(PPUThread& ppu, ppu_opcode_t op) { throw fmt::exception("Unknown/Illegal opcode: 0x%08x" HERE, op.opcode); } diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index ddca283103..e1c54db3cc 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -4,392 +4,390 @@ class PPUThread; -using ppu_inter_func_t = void(*)(PPUThread& ppu, ppu_opcode_t op); - struct ppu_interpreter { - static void TDI(PPUThread&, ppu_opcode_t); - static void TWI(PPUThread&, ppu_opcode_t); - static void MFVSCR(PPUThread&, ppu_opcode_t); - static void MTVSCR(PPUThread&, ppu_opcode_t); - static void VADDCUW(PPUThread&, ppu_opcode_t); - static void VADDFP(PPUThread&, ppu_opcode_t); - static void VADDSBS(PPUThread&, ppu_opcode_t); - static void VADDSHS(PPUThread&, ppu_opcode_t); - static void VADDSWS(PPUThread&, ppu_opcode_t); - static void VADDUBM(PPUThread&, ppu_opcode_t); - static void VADDUBS(PPUThread&, ppu_opcode_t); - static void VADDUHM(PPUThread&, ppu_opcode_t); - static void VADDUHS(PPUThread&, ppu_opcode_t); - static void VADDUWM(PPUThread&, ppu_opcode_t); - static void VADDUWS(PPUThread&, ppu_opcode_t); - static void VAND(PPUThread&, ppu_opcode_t); - static void VANDC(PPUThread&, ppu_opcode_t); - static void VAVGSB(PPUThread&, ppu_opcode_t); - static void VAVGSH(PPUThread&, ppu_opcode_t); - static void VAVGSW(PPUThread&, ppu_opcode_t); - static void VAVGUB(PPUThread&, ppu_opcode_t); - static void VAVGUH(PPUThread&, ppu_opcode_t); - static void VAVGUW(PPUThread&, ppu_opcode_t); - static void VCFSX(PPUThread&, ppu_opcode_t); - static void VCFUX(PPUThread&, ppu_opcode_t); - static void VCMPBFP(PPUThread&, ppu_opcode_t); - static void VCMPEQFP(PPUThread&, ppu_opcode_t); - static void VCMPEQUB(PPUThread&, ppu_opcode_t); - static void VCMPEQUH(PPUThread&, ppu_opcode_t); - static void VCMPEQUW(PPUThread&, ppu_opcode_t); - static void VCMPGEFP(PPUThread&, ppu_opcode_t); - static void VCMPGTFP(PPUThread&, ppu_opcode_t); - static void VCMPGTSB(PPUThread&, ppu_opcode_t); - static void VCMPGTSH(PPUThread&, ppu_opcode_t); - static void VCMPGTSW(PPUThread&, ppu_opcode_t); - static void VCMPGTUB(PPUThread&, ppu_opcode_t); - static void VCMPGTUH(PPUThread&, ppu_opcode_t); - static void VCMPGTUW(PPUThread&, ppu_opcode_t); - static void VCTSXS(PPUThread&, ppu_opcode_t); - static void VCTUXS(PPUThread&, ppu_opcode_t); - static void VEXPTEFP(PPUThread&, ppu_opcode_t); - static void VLOGEFP(PPUThread&, ppu_opcode_t); - static void VMADDFP(PPUThread&, ppu_opcode_t); - static void VMAXFP(PPUThread&, ppu_opcode_t); - static void VMAXSB(PPUThread&, ppu_opcode_t); - static void VMAXSH(PPUThread&, ppu_opcode_t); - static void VMAXSW(PPUThread&, ppu_opcode_t); - static void VMAXUB(PPUThread&, ppu_opcode_t); - static void VMAXUH(PPUThread&, ppu_opcode_t); - static void VMAXUW(PPUThread&, ppu_opcode_t); - static void VMHADDSHS(PPUThread&, ppu_opcode_t); - static void VMHRADDSHS(PPUThread&, ppu_opcode_t); - static void VMINFP(PPUThread&, ppu_opcode_t); - static void VMINSB(PPUThread&, ppu_opcode_t); - static void VMINSH(PPUThread&, ppu_opcode_t); - static void VMINSW(PPUThread&, ppu_opcode_t); - static void VMINUB(PPUThread&, ppu_opcode_t); - static void VMINUH(PPUThread&, ppu_opcode_t); - static void VMINUW(PPUThread&, ppu_opcode_t); - static void VMLADDUHM(PPUThread&, ppu_opcode_t); - static void VMRGHB(PPUThread&, ppu_opcode_t); - static void VMRGHH(PPUThread&, ppu_opcode_t); - static void VMRGHW(PPUThread&, ppu_opcode_t); - static void VMRGLB(PPUThread&, ppu_opcode_t); - static void VMRGLH(PPUThread&, ppu_opcode_t); - static void VMRGLW(PPUThread&, ppu_opcode_t); - static void VMSUMMBM(PPUThread&, ppu_opcode_t); - static void VMSUMSHM(PPUThread&, ppu_opcode_t); - static void VMSUMSHS(PPUThread&, ppu_opcode_t); - static void VMSUMUBM(PPUThread&, ppu_opcode_t); - static void VMSUMUHM(PPUThread&, ppu_opcode_t); - static void VMSUMUHS(PPUThread&, ppu_opcode_t); - static void VMULESB(PPUThread&, ppu_opcode_t); - static void VMULESH(PPUThread&, ppu_opcode_t); - static void VMULEUB(PPUThread&, ppu_opcode_t); - static void VMULEUH(PPUThread&, ppu_opcode_t); - static void VMULOSB(PPUThread&, ppu_opcode_t); - static void VMULOSH(PPUThread&, ppu_opcode_t); - static void VMULOUB(PPUThread&, ppu_opcode_t); - static void VMULOUH(PPUThread&, ppu_opcode_t); - static void VNMSUBFP(PPUThread&, ppu_opcode_t); - static void VNOR(PPUThread&, ppu_opcode_t); - static void VOR(PPUThread&, ppu_opcode_t); - static void VPERM(PPUThread&, ppu_opcode_t); - static void VPKPX(PPUThread&, ppu_opcode_t); - static void VPKSHSS(PPUThread&, ppu_opcode_t); - static void VPKSHUS(PPUThread&, ppu_opcode_t); - static void VPKSWSS(PPUThread&, ppu_opcode_t); - static void VPKSWUS(PPUThread&, ppu_opcode_t); - static void VPKUHUM(PPUThread&, ppu_opcode_t); - static void VPKUHUS(PPUThread&, ppu_opcode_t); - static void VPKUWUM(PPUThread&, ppu_opcode_t); - static void VPKUWUS(PPUThread&, ppu_opcode_t); - static void VREFP(PPUThread&, ppu_opcode_t); - static void VRFIM(PPUThread&, ppu_opcode_t); - static void VRFIN(PPUThread&, ppu_opcode_t); - static void VRFIP(PPUThread&, ppu_opcode_t); - static void VRFIZ(PPUThread&, ppu_opcode_t); - static void VRLB(PPUThread&, ppu_opcode_t); - static void VRLH(PPUThread&, ppu_opcode_t); - static void VRLW(PPUThread&, ppu_opcode_t); - static void VRSQRTEFP(PPUThread&, ppu_opcode_t); - static void VSEL(PPUThread&, ppu_opcode_t); - static void VSL(PPUThread&, ppu_opcode_t); - static void VSLB(PPUThread&, ppu_opcode_t); - static void VSLDOI(PPUThread&, ppu_opcode_t); - static void VSLH(PPUThread&, ppu_opcode_t); - static void VSLO(PPUThread&, ppu_opcode_t); - static void VSLW(PPUThread&, ppu_opcode_t); - static void VSPLTB(PPUThread&, ppu_opcode_t); - static void VSPLTH(PPUThread&, ppu_opcode_t); - static void VSPLTISB(PPUThread&, ppu_opcode_t); - static void VSPLTISH(PPUThread&, ppu_opcode_t); - static void VSPLTISW(PPUThread&, ppu_opcode_t); - static void VSPLTW(PPUThread&, ppu_opcode_t); - static void VSR(PPUThread&, ppu_opcode_t); - static void VSRAB(PPUThread&, ppu_opcode_t); - static void VSRAH(PPUThread&, ppu_opcode_t); - static void VSRAW(PPUThread&, ppu_opcode_t); - static void VSRB(PPUThread&, ppu_opcode_t); - static void VSRH(PPUThread&, ppu_opcode_t); - static void VSRO(PPUThread&, ppu_opcode_t); - static void VSRW(PPUThread&, ppu_opcode_t); - static void VSUBCUW(PPUThread&, ppu_opcode_t); - static void VSUBFP(PPUThread&, ppu_opcode_t); - static void VSUBSBS(PPUThread&, ppu_opcode_t); - static void VSUBSHS(PPUThread&, ppu_opcode_t); - static void VSUBSWS(PPUThread&, ppu_opcode_t); - static void VSUBUBM(PPUThread&, ppu_opcode_t); - static void VSUBUBS(PPUThread&, ppu_opcode_t); - static void VSUBUHM(PPUThread&, ppu_opcode_t); - static void VSUBUHS(PPUThread&, ppu_opcode_t); - static void VSUBUWM(PPUThread&, ppu_opcode_t); - static void VSUBUWS(PPUThread&, ppu_opcode_t); - static void VSUMSWS(PPUThread&, ppu_opcode_t); - static void VSUM2SWS(PPUThread&, ppu_opcode_t); - static void VSUM4SBS(PPUThread&, ppu_opcode_t); - static void VSUM4SHS(PPUThread&, ppu_opcode_t); - static void VSUM4UBS(PPUThread&, ppu_opcode_t); - static void VUPKHPX(PPUThread&, ppu_opcode_t); - static void VUPKHSB(PPUThread&, ppu_opcode_t); - static void VUPKHSH(PPUThread&, ppu_opcode_t); - static void VUPKLPX(PPUThread&, ppu_opcode_t); - static void VUPKLSB(PPUThread&, ppu_opcode_t); - static void VUPKLSH(PPUThread&, ppu_opcode_t); - static void VXOR(PPUThread&, ppu_opcode_t); - static void MULLI(PPUThread&, ppu_opcode_t); - static void SUBFIC(PPUThread&, ppu_opcode_t); - static void CMPLI(PPUThread&, ppu_opcode_t); - static void CMPI(PPUThread&, ppu_opcode_t); - static void ADDIC(PPUThread&, ppu_opcode_t); - static void ADDI(PPUThread&, ppu_opcode_t); - static void ADDIS(PPUThread&, ppu_opcode_t); - static void BC(PPUThread&, ppu_opcode_t); - static void HACK(PPUThread&, ppu_opcode_t); - static void SC(PPUThread&, ppu_opcode_t); - static void B(PPUThread&, ppu_opcode_t); - static void MCRF(PPUThread&, ppu_opcode_t); - static void BCLR(PPUThread&, ppu_opcode_t); - static void CRNOR(PPUThread&, ppu_opcode_t); - static void CRANDC(PPUThread&, ppu_opcode_t); - static void ISYNC(PPUThread&, ppu_opcode_t); - static void CRXOR(PPUThread&, ppu_opcode_t); - static void CRNAND(PPUThread&, ppu_opcode_t); - static void CRAND(PPUThread&, ppu_opcode_t); - static void CREQV(PPUThread&, ppu_opcode_t); - static void CRORC(PPUThread&, ppu_opcode_t); - static void CROR(PPUThread&, ppu_opcode_t); - static void BCCTR(PPUThread&, ppu_opcode_t); - static void RLWIMI(PPUThread&, ppu_opcode_t); - static void RLWINM(PPUThread&, ppu_opcode_t); - static void RLWNM(PPUThread&, ppu_opcode_t); - static void ORI(PPUThread&, ppu_opcode_t); - static void ORIS(PPUThread&, ppu_opcode_t); - static void XORI(PPUThread&, ppu_opcode_t); - static void XORIS(PPUThread&, ppu_opcode_t); - static void ANDI(PPUThread&, ppu_opcode_t); - static void ANDIS(PPUThread&, ppu_opcode_t); - static void RLDICL(PPUThread&, ppu_opcode_t); - static void RLDICR(PPUThread&, ppu_opcode_t); - static void RLDIC(PPUThread&, ppu_opcode_t); - static void RLDIMI(PPUThread&, ppu_opcode_t); - static void RLDCL(PPUThread&, ppu_opcode_t); - static void RLDCR(PPUThread&, ppu_opcode_t); - static void CMP(PPUThread&, ppu_opcode_t); - static void TW(PPUThread&, ppu_opcode_t); - static void LVSL(PPUThread&, ppu_opcode_t); - static void LVEBX(PPUThread&, ppu_opcode_t); - static void SUBFC(PPUThread&, ppu_opcode_t); - static void MULHDU(PPUThread&, ppu_opcode_t); - static void ADDC(PPUThread&, ppu_opcode_t); - static void MULHWU(PPUThread&, ppu_opcode_t); - static void MFOCRF(PPUThread&, ppu_opcode_t); - static void LWARX(PPUThread&, ppu_opcode_t); - static void LDX(PPUThread&, ppu_opcode_t); - static void LWZX(PPUThread&, ppu_opcode_t); - static void SLW(PPUThread&, ppu_opcode_t); - static void CNTLZW(PPUThread&, ppu_opcode_t); - static void SLD(PPUThread&, ppu_opcode_t); - static void AND(PPUThread&, ppu_opcode_t); - static void CMPL(PPUThread&, ppu_opcode_t); - static void LVSR(PPUThread&, ppu_opcode_t); - static void LVEHX(PPUThread&, ppu_opcode_t); - static void SUBF(PPUThread&, ppu_opcode_t); - static void LDUX(PPUThread&, ppu_opcode_t); - static void DCBST(PPUThread&, ppu_opcode_t); - static void LWZUX(PPUThread&, ppu_opcode_t); - static void CNTLZD(PPUThread&, ppu_opcode_t); - static void ANDC(PPUThread&, ppu_opcode_t); - static void TD(PPUThread&, ppu_opcode_t); - static void LVEWX(PPUThread&, ppu_opcode_t); - static void MULHD(PPUThread&, ppu_opcode_t); - static void MULHW(PPUThread&, ppu_opcode_t); - static void LDARX(PPUThread&, ppu_opcode_t); - static void DCBF(PPUThread&, ppu_opcode_t); - static void LBZX(PPUThread&, ppu_opcode_t); - static void LVX(PPUThread&, ppu_opcode_t); - static void NEG(PPUThread&, ppu_opcode_t); - static void LBZUX(PPUThread&, ppu_opcode_t); - static void NOR(PPUThread&, ppu_opcode_t); - static void STVEBX(PPUThread&, ppu_opcode_t); - static void SUBFE(PPUThread&, ppu_opcode_t); - static void ADDE(PPUThread&, ppu_opcode_t); - static void MTOCRF(PPUThread&, ppu_opcode_t); - static void STDX(PPUThread&, ppu_opcode_t); - static void STWCX(PPUThread&, ppu_opcode_t); - static void STWX(PPUThread&, ppu_opcode_t); - static void STVEHX(PPUThread&, ppu_opcode_t); - static void STDUX(PPUThread&, ppu_opcode_t); - static void STWUX(PPUThread&, ppu_opcode_t); - static void STVEWX(PPUThread&, ppu_opcode_t); - static void SUBFZE(PPUThread&, ppu_opcode_t); - static void ADDZE(PPUThread&, ppu_opcode_t); - static void STDCX(PPUThread&, ppu_opcode_t); - static void STBX(PPUThread&, ppu_opcode_t); - static void STVX(PPUThread&, ppu_opcode_t); - static void MULLD(PPUThread&, ppu_opcode_t); - static void SUBFME(PPUThread&, ppu_opcode_t); - static void ADDME(PPUThread&, ppu_opcode_t); - static void MULLW(PPUThread&, ppu_opcode_t); - static void DCBTST(PPUThread&, ppu_opcode_t); - static void STBUX(PPUThread&, ppu_opcode_t); - static void ADD(PPUThread&, ppu_opcode_t); - static void DCBT(PPUThread&, ppu_opcode_t); - static void LHZX(PPUThread&, ppu_opcode_t); - static void EQV(PPUThread&, ppu_opcode_t); - static void ECIWX(PPUThread&, ppu_opcode_t); - static void LHZUX(PPUThread&, ppu_opcode_t); - static void XOR(PPUThread&, ppu_opcode_t); - static void MFSPR(PPUThread&, ppu_opcode_t); - static void LWAX(PPUThread&, ppu_opcode_t); - static void DST(PPUThread&, ppu_opcode_t); - static void LHAX(PPUThread&, ppu_opcode_t); - static void LVXL(PPUThread&, ppu_opcode_t); - static void MFTB(PPUThread&, ppu_opcode_t); - static void LWAUX(PPUThread&, ppu_opcode_t); - static void DSTST(PPUThread&, ppu_opcode_t); - static void LHAUX(PPUThread&, ppu_opcode_t); - static void STHX(PPUThread&, ppu_opcode_t); - static void ORC(PPUThread&, ppu_opcode_t); - static void ECOWX(PPUThread&, ppu_opcode_t); - static void STHUX(PPUThread&, ppu_opcode_t); - static void OR(PPUThread&, ppu_opcode_t); - static void DIVDU(PPUThread&, ppu_opcode_t); - static void DIVWU(PPUThread&, ppu_opcode_t); - static void MTSPR(PPUThread&, ppu_opcode_t); - static void DCBI(PPUThread&, ppu_opcode_t); - static void NAND(PPUThread&, ppu_opcode_t); - static void STVXL(PPUThread&, ppu_opcode_t); - static void DIVD(PPUThread&, ppu_opcode_t); - static void DIVW(PPUThread&, ppu_opcode_t); - static void LVLX(PPUThread&, ppu_opcode_t); - static void LDBRX(PPUThread&, ppu_opcode_t); - static void LSWX(PPUThread&, ppu_opcode_t); - static void LWBRX(PPUThread&, ppu_opcode_t); - static void LFSX(PPUThread&, ppu_opcode_t); - static void SRW(PPUThread&, ppu_opcode_t); - static void SRD(PPUThread&, ppu_opcode_t); - static void LVRX(PPUThread&, ppu_opcode_t); - static void LSWI(PPUThread&, ppu_opcode_t); - static void LFSUX(PPUThread&, ppu_opcode_t); - static void SYNC(PPUThread&, ppu_opcode_t); - static void LFDX(PPUThread&, ppu_opcode_t); - static void LFDUX(PPUThread&, ppu_opcode_t); - static void STVLX(PPUThread&, ppu_opcode_t); - static void STDBRX(PPUThread&, ppu_opcode_t); - static void STSWX(PPUThread&, ppu_opcode_t); - static void STWBRX(PPUThread&, ppu_opcode_t); - static void STFSX(PPUThread&, ppu_opcode_t); - static void STVRX(PPUThread&, ppu_opcode_t); - static void STFSUX(PPUThread&, ppu_opcode_t); - static void STSWI(PPUThread&, ppu_opcode_t); - static void STFDX(PPUThread&, ppu_opcode_t); - static void STFDUX(PPUThread&, ppu_opcode_t); - static void LVLXL(PPUThread&, ppu_opcode_t); - static void LHBRX(PPUThread&, ppu_opcode_t); - static void SRAW(PPUThread&, ppu_opcode_t); - static void SRAD(PPUThread&, ppu_opcode_t); - static void LVRXL(PPUThread&, ppu_opcode_t); - static void DSS(PPUThread&, ppu_opcode_t); - static void SRAWI(PPUThread&, ppu_opcode_t); - static void SRADI(PPUThread&, ppu_opcode_t); - static void EIEIO(PPUThread&, ppu_opcode_t); - static void STVLXL(PPUThread&, ppu_opcode_t); - static void STHBRX(PPUThread&, ppu_opcode_t); - static void EXTSH(PPUThread&, ppu_opcode_t); - static void STVRXL(PPUThread&, ppu_opcode_t); - static void EXTSB(PPUThread&, ppu_opcode_t); - static void STFIWX(PPUThread&, ppu_opcode_t); - static void EXTSW(PPUThread&, ppu_opcode_t); - static void ICBI(PPUThread&, ppu_opcode_t); - static void DCBZ(PPUThread&, ppu_opcode_t); - static void LWZ(PPUThread&, ppu_opcode_t); - static void LWZU(PPUThread&, ppu_opcode_t); - static void LBZ(PPUThread&, ppu_opcode_t); - static void LBZU(PPUThread&, ppu_opcode_t); - static void STW(PPUThread&, ppu_opcode_t); - static void STWU(PPUThread&, ppu_opcode_t); - static void STB(PPUThread&, ppu_opcode_t); - static void STBU(PPUThread&, ppu_opcode_t); - static void LHZ(PPUThread&, ppu_opcode_t); - static void LHZU(PPUThread&, ppu_opcode_t); - static void LHA(PPUThread&, ppu_opcode_t); - static void LHAU(PPUThread&, ppu_opcode_t); - static void STH(PPUThread&, ppu_opcode_t); - static void STHU(PPUThread&, ppu_opcode_t); - static void LMW(PPUThread&, ppu_opcode_t); - static void STMW(PPUThread&, ppu_opcode_t); - static void LFS(PPUThread&, ppu_opcode_t); - static void LFSU(PPUThread&, ppu_opcode_t); - static void LFD(PPUThread&, ppu_opcode_t); - static void LFDU(PPUThread&, ppu_opcode_t); - static void STFS(PPUThread&, ppu_opcode_t); - static void STFSU(PPUThread&, ppu_opcode_t); - static void STFD(PPUThread&, ppu_opcode_t); - static void STFDU(PPUThread&, ppu_opcode_t); - static void LD(PPUThread&, ppu_opcode_t); - static void LDU(PPUThread&, ppu_opcode_t); - static void LWA(PPUThread&, ppu_opcode_t); - static void FDIVS(PPUThread&, ppu_opcode_t); - static void FSUBS(PPUThread&, ppu_opcode_t); - static void FADDS(PPUThread&, ppu_opcode_t); - static void FSQRTS(PPUThread&, ppu_opcode_t); - static void FRES(PPUThread&, ppu_opcode_t); - static void FMULS(PPUThread&, ppu_opcode_t); - static void FMADDS(PPUThread&, ppu_opcode_t); - static void FMSUBS(PPUThread&, ppu_opcode_t); - static void FNMSUBS(PPUThread&, ppu_opcode_t); - static void FNMADDS(PPUThread&, ppu_opcode_t); - static void STD(PPUThread&, ppu_opcode_t); - static void STDU(PPUThread&, ppu_opcode_t); - static void MTFSB1(PPUThread&, ppu_opcode_t); - static void MCRFS(PPUThread&, ppu_opcode_t); - static void MTFSB0(PPUThread&, ppu_opcode_t); - static void MTFSFI(PPUThread&, ppu_opcode_t); - static void MFFS(PPUThread&, ppu_opcode_t); - static void MTFSF(PPUThread&, ppu_opcode_t); - static void FCMPU(PPUThread&, ppu_opcode_t); - static void FRSP(PPUThread&, ppu_opcode_t); - static void FCTIW(PPUThread&, ppu_opcode_t); - static void FCTIWZ(PPUThread&, ppu_opcode_t); - static void FDIV(PPUThread&, ppu_opcode_t); - static void FSUB(PPUThread&, ppu_opcode_t); - static void FADD(PPUThread&, ppu_opcode_t); - static void FSQRT(PPUThread&, ppu_opcode_t); - static void FSEL(PPUThread&, ppu_opcode_t); - static void FMUL(PPUThread&, ppu_opcode_t); - static void FRSQRTE(PPUThread&, ppu_opcode_t); - static void FMSUB(PPUThread&, ppu_opcode_t); - static void FMADD(PPUThread&, ppu_opcode_t); - static void FNMSUB(PPUThread&, ppu_opcode_t); - static void FNMADD(PPUThread&, ppu_opcode_t); - static void FCMPO(PPUThread&, ppu_opcode_t); - static void FNEG(PPUThread&, ppu_opcode_t); - static void FMR(PPUThread&, ppu_opcode_t); - static void FNABS(PPUThread&, ppu_opcode_t); - static void FABS(PPUThread&, ppu_opcode_t); - static void FCTID(PPUThread&, ppu_opcode_t); - static void FCTIDZ(PPUThread&, ppu_opcode_t); - static void FCFID(PPUThread&, ppu_opcode_t); + static bool MFVSCR(PPUThread&, ppu_opcode_t); + static bool MTVSCR(PPUThread&, ppu_opcode_t); + static bool VADDCUW(PPUThread&, ppu_opcode_t); + static bool VADDFP(PPUThread&, ppu_opcode_t); + static bool VADDSBS(PPUThread&, ppu_opcode_t); + static bool VADDSHS(PPUThread&, ppu_opcode_t); + static bool VADDSWS(PPUThread&, ppu_opcode_t); + static bool VADDUBM(PPUThread&, ppu_opcode_t); + static bool VADDUBS(PPUThread&, ppu_opcode_t); + static bool VADDUHM(PPUThread&, ppu_opcode_t); + static bool VADDUHS(PPUThread&, ppu_opcode_t); + static bool VADDUWM(PPUThread&, ppu_opcode_t); + static bool VADDUWS(PPUThread&, ppu_opcode_t); + static bool VAND(PPUThread&, ppu_opcode_t); + static bool VANDC(PPUThread&, ppu_opcode_t); + static bool VAVGSB(PPUThread&, ppu_opcode_t); + static bool VAVGSH(PPUThread&, ppu_opcode_t); + static bool VAVGSW(PPUThread&, ppu_opcode_t); + static bool VAVGUB(PPUThread&, ppu_opcode_t); + static bool VAVGUH(PPUThread&, ppu_opcode_t); + static bool VAVGUW(PPUThread&, ppu_opcode_t); + static bool VCFSX(PPUThread&, ppu_opcode_t); + static bool VCFUX(PPUThread&, ppu_opcode_t); + static bool VCMPBFP(PPUThread&, ppu_opcode_t); + static bool VCMPEQFP(PPUThread&, ppu_opcode_t); + static bool VCMPEQUB(PPUThread&, ppu_opcode_t); + static bool VCMPEQUH(PPUThread&, ppu_opcode_t); + static bool VCMPEQUW(PPUThread&, ppu_opcode_t); + static bool VCMPGEFP(PPUThread&, ppu_opcode_t); + static bool VCMPGTFP(PPUThread&, ppu_opcode_t); + static bool VCMPGTSB(PPUThread&, ppu_opcode_t); + static bool VCMPGTSH(PPUThread&, ppu_opcode_t); + static bool VCMPGTSW(PPUThread&, ppu_opcode_t); + static bool VCMPGTUB(PPUThread&, ppu_opcode_t); + static bool VCMPGTUH(PPUThread&, ppu_opcode_t); + static bool VCMPGTUW(PPUThread&, ppu_opcode_t); + static bool VCTSXS(PPUThread&, ppu_opcode_t); + static bool VCTUXS(PPUThread&, ppu_opcode_t); + static bool VEXPTEFP(PPUThread&, ppu_opcode_t); + static bool VLOGEFP(PPUThread&, ppu_opcode_t); + static bool VMADDFP(PPUThread&, ppu_opcode_t); + static bool VMAXFP(PPUThread&, ppu_opcode_t); + static bool VMAXSB(PPUThread&, ppu_opcode_t); + static bool VMAXSH(PPUThread&, ppu_opcode_t); + static bool VMAXSW(PPUThread&, ppu_opcode_t); + static bool VMAXUB(PPUThread&, ppu_opcode_t); + static bool VMAXUH(PPUThread&, ppu_opcode_t); + static bool VMAXUW(PPUThread&, ppu_opcode_t); + static bool VMHADDSHS(PPUThread&, ppu_opcode_t); + static bool VMHRADDSHS(PPUThread&, ppu_opcode_t); + static bool VMINFP(PPUThread&, ppu_opcode_t); + static bool VMINSB(PPUThread&, ppu_opcode_t); + static bool VMINSH(PPUThread&, ppu_opcode_t); + static bool VMINSW(PPUThread&, ppu_opcode_t); + static bool VMINUB(PPUThread&, ppu_opcode_t); + static bool VMINUH(PPUThread&, ppu_opcode_t); + static bool VMINUW(PPUThread&, ppu_opcode_t); + static bool VMLADDUHM(PPUThread&, ppu_opcode_t); + static bool VMRGHB(PPUThread&, ppu_opcode_t); + static bool VMRGHH(PPUThread&, ppu_opcode_t); + static bool VMRGHW(PPUThread&, ppu_opcode_t); + static bool VMRGLB(PPUThread&, ppu_opcode_t); + static bool VMRGLH(PPUThread&, ppu_opcode_t); + static bool VMRGLW(PPUThread&, ppu_opcode_t); + static bool VMSUMMBM(PPUThread&, ppu_opcode_t); + static bool VMSUMSHM(PPUThread&, ppu_opcode_t); + static bool VMSUMSHS(PPUThread&, ppu_opcode_t); + static bool VMSUMUBM(PPUThread&, ppu_opcode_t); + static bool VMSUMUHM(PPUThread&, ppu_opcode_t); + static bool VMSUMUHS(PPUThread&, ppu_opcode_t); + static bool VMULESB(PPUThread&, ppu_opcode_t); + static bool VMULESH(PPUThread&, ppu_opcode_t); + static bool VMULEUB(PPUThread&, ppu_opcode_t); + static bool VMULEUH(PPUThread&, ppu_opcode_t); + static bool VMULOSB(PPUThread&, ppu_opcode_t); + static bool VMULOSH(PPUThread&, ppu_opcode_t); + static bool VMULOUB(PPUThread&, ppu_opcode_t); + static bool VMULOUH(PPUThread&, ppu_opcode_t); + static bool VNMSUBFP(PPUThread&, ppu_opcode_t); + static bool VNOR(PPUThread&, ppu_opcode_t); + static bool VOR(PPUThread&, ppu_opcode_t); + static bool VPERM(PPUThread&, ppu_opcode_t); + static bool VPKPX(PPUThread&, ppu_opcode_t); + static bool VPKSHSS(PPUThread&, ppu_opcode_t); + static bool VPKSHUS(PPUThread&, ppu_opcode_t); + static bool VPKSWSS(PPUThread&, ppu_opcode_t); + static bool VPKSWUS(PPUThread&, ppu_opcode_t); + static bool VPKUHUM(PPUThread&, ppu_opcode_t); + static bool VPKUHUS(PPUThread&, ppu_opcode_t); + static bool VPKUWUM(PPUThread&, ppu_opcode_t); + static bool VPKUWUS(PPUThread&, ppu_opcode_t); + static bool VREFP(PPUThread&, ppu_opcode_t); + static bool VRFIM(PPUThread&, ppu_opcode_t); + static bool VRFIN(PPUThread&, ppu_opcode_t); + static bool VRFIP(PPUThread&, ppu_opcode_t); + static bool VRFIZ(PPUThread&, ppu_opcode_t); + static bool VRLB(PPUThread&, ppu_opcode_t); + static bool VRLH(PPUThread&, ppu_opcode_t); + static bool VRLW(PPUThread&, ppu_opcode_t); + static bool VRSQRTEFP(PPUThread&, ppu_opcode_t); + static bool VSEL(PPUThread&, ppu_opcode_t); + static bool VSL(PPUThread&, ppu_opcode_t); + static bool VSLB(PPUThread&, ppu_opcode_t); + static bool VSLDOI(PPUThread&, ppu_opcode_t); + static bool VSLH(PPUThread&, ppu_opcode_t); + static bool VSLO(PPUThread&, ppu_opcode_t); + static bool VSLW(PPUThread&, ppu_opcode_t); + static bool VSPLTB(PPUThread&, ppu_opcode_t); + static bool VSPLTH(PPUThread&, ppu_opcode_t); + static bool VSPLTISB(PPUThread&, ppu_opcode_t); + static bool VSPLTISH(PPUThread&, ppu_opcode_t); + static bool VSPLTISW(PPUThread&, ppu_opcode_t); + static bool VSPLTW(PPUThread&, ppu_opcode_t); + static bool VSR(PPUThread&, ppu_opcode_t); + static bool VSRAB(PPUThread&, ppu_opcode_t); + static bool VSRAH(PPUThread&, ppu_opcode_t); + static bool VSRAW(PPUThread&, ppu_opcode_t); + static bool VSRB(PPUThread&, ppu_opcode_t); + static bool VSRH(PPUThread&, ppu_opcode_t); + static bool VSRO(PPUThread&, ppu_opcode_t); + static bool VSRW(PPUThread&, ppu_opcode_t); + static bool VSUBCUW(PPUThread&, ppu_opcode_t); + static bool VSUBFP(PPUThread&, ppu_opcode_t); + static bool VSUBSBS(PPUThread&, ppu_opcode_t); + static bool VSUBSHS(PPUThread&, ppu_opcode_t); + static bool VSUBSWS(PPUThread&, ppu_opcode_t); + static bool VSUBUBM(PPUThread&, ppu_opcode_t); + static bool VSUBUBS(PPUThread&, ppu_opcode_t); + static bool VSUBUHM(PPUThread&, ppu_opcode_t); + static bool VSUBUHS(PPUThread&, ppu_opcode_t); + static bool VSUBUWM(PPUThread&, ppu_opcode_t); + static bool VSUBUWS(PPUThread&, ppu_opcode_t); + static bool VSUMSWS(PPUThread&, ppu_opcode_t); + static bool VSUM2SWS(PPUThread&, ppu_opcode_t); + static bool VSUM4SBS(PPUThread&, ppu_opcode_t); + static bool VSUM4SHS(PPUThread&, ppu_opcode_t); + static bool VSUM4UBS(PPUThread&, ppu_opcode_t); + static bool VUPKHPX(PPUThread&, ppu_opcode_t); + static bool VUPKHSB(PPUThread&, ppu_opcode_t); + static bool VUPKHSH(PPUThread&, ppu_opcode_t); + static bool VUPKLPX(PPUThread&, ppu_opcode_t); + static bool VUPKLSB(PPUThread&, ppu_opcode_t); + static bool VUPKLSH(PPUThread&, ppu_opcode_t); + static bool VXOR(PPUThread&, ppu_opcode_t); + static bool TDI(PPUThread&, ppu_opcode_t); + static bool TWI(PPUThread&, ppu_opcode_t); + static bool MULLI(PPUThread&, ppu_opcode_t); + static bool SUBFIC(PPUThread&, ppu_opcode_t); + static bool CMPLI(PPUThread&, ppu_opcode_t); + static bool CMPI(PPUThread&, ppu_opcode_t); + static bool ADDIC(PPUThread&, ppu_opcode_t); + static bool ADDI(PPUThread&, ppu_opcode_t); + static bool ADDIS(PPUThread&, ppu_opcode_t); + static bool BC(PPUThread&, ppu_opcode_t); + static bool HACK(PPUThread&, ppu_opcode_t); + static bool SC(PPUThread&, ppu_opcode_t); + static bool B(PPUThread&, ppu_opcode_t); + static bool MCRF(PPUThread&, ppu_opcode_t); + static bool BCLR(PPUThread&, ppu_opcode_t); + static bool CRNOR(PPUThread&, ppu_opcode_t); + static bool CRANDC(PPUThread&, ppu_opcode_t); + static bool ISYNC(PPUThread&, ppu_opcode_t); + static bool CRXOR(PPUThread&, ppu_opcode_t); + static bool CRNAND(PPUThread&, ppu_opcode_t); + static bool CRAND(PPUThread&, ppu_opcode_t); + static bool CREQV(PPUThread&, ppu_opcode_t); + static bool CRORC(PPUThread&, ppu_opcode_t); + static bool CROR(PPUThread&, ppu_opcode_t); + static bool BCCTR(PPUThread&, ppu_opcode_t); + static bool RLWIMI(PPUThread&, ppu_opcode_t); + static bool RLWINM(PPUThread&, ppu_opcode_t); + static bool RLWNM(PPUThread&, ppu_opcode_t); + static bool ORI(PPUThread&, ppu_opcode_t); + static bool ORIS(PPUThread&, ppu_opcode_t); + static bool XORI(PPUThread&, ppu_opcode_t); + static bool XORIS(PPUThread&, ppu_opcode_t); + static bool ANDI(PPUThread&, ppu_opcode_t); + static bool ANDIS(PPUThread&, ppu_opcode_t); + static bool RLDICL(PPUThread&, ppu_opcode_t); + static bool RLDICR(PPUThread&, ppu_opcode_t); + static bool RLDIC(PPUThread&, ppu_opcode_t); + static bool RLDIMI(PPUThread&, ppu_opcode_t); + static bool RLDCL(PPUThread&, ppu_opcode_t); + static bool RLDCR(PPUThread&, ppu_opcode_t); + static bool CMP(PPUThread&, ppu_opcode_t); + static bool TW(PPUThread&, ppu_opcode_t); + static bool LVSL(PPUThread&, ppu_opcode_t); + static bool LVEBX(PPUThread&, ppu_opcode_t); + static bool SUBFC(PPUThread&, ppu_opcode_t); + static bool MULHDU(PPUThread&, ppu_opcode_t); + static bool ADDC(PPUThread&, ppu_opcode_t); + static bool MULHWU(PPUThread&, ppu_opcode_t); + static bool MFOCRF(PPUThread&, ppu_opcode_t); + static bool LWARX(PPUThread&, ppu_opcode_t); + static bool LDX(PPUThread&, ppu_opcode_t); + static bool LWZX(PPUThread&, ppu_opcode_t); + static bool SLW(PPUThread&, ppu_opcode_t); + static bool CNTLZW(PPUThread&, ppu_opcode_t); + static bool SLD(PPUThread&, ppu_opcode_t); + static bool AND(PPUThread&, ppu_opcode_t); + static bool CMPL(PPUThread&, ppu_opcode_t); + static bool LVSR(PPUThread&, ppu_opcode_t); + static bool LVEHX(PPUThread&, ppu_opcode_t); + static bool SUBF(PPUThread&, ppu_opcode_t); + static bool LDUX(PPUThread&, ppu_opcode_t); + static bool DCBST(PPUThread&, ppu_opcode_t); + static bool LWZUX(PPUThread&, ppu_opcode_t); + static bool CNTLZD(PPUThread&, ppu_opcode_t); + static bool ANDC(PPUThread&, ppu_opcode_t); + static bool TD(PPUThread&, ppu_opcode_t); + static bool LVEWX(PPUThread&, ppu_opcode_t); + static bool MULHD(PPUThread&, ppu_opcode_t); + static bool MULHW(PPUThread&, ppu_opcode_t); + static bool LDARX(PPUThread&, ppu_opcode_t); + static bool DCBF(PPUThread&, ppu_opcode_t); + static bool LBZX(PPUThread&, ppu_opcode_t); + static bool LVX(PPUThread&, ppu_opcode_t); + static bool NEG(PPUThread&, ppu_opcode_t); + static bool LBZUX(PPUThread&, ppu_opcode_t); + static bool NOR(PPUThread&, ppu_opcode_t); + static bool STVEBX(PPUThread&, ppu_opcode_t); + static bool SUBFE(PPUThread&, ppu_opcode_t); + static bool ADDE(PPUThread&, ppu_opcode_t); + static bool MTOCRF(PPUThread&, ppu_opcode_t); + static bool STDX(PPUThread&, ppu_opcode_t); + static bool STWCX(PPUThread&, ppu_opcode_t); + static bool STWX(PPUThread&, ppu_opcode_t); + static bool STVEHX(PPUThread&, ppu_opcode_t); + static bool STDUX(PPUThread&, ppu_opcode_t); + static bool STWUX(PPUThread&, ppu_opcode_t); + static bool STVEWX(PPUThread&, ppu_opcode_t); + static bool SUBFZE(PPUThread&, ppu_opcode_t); + static bool ADDZE(PPUThread&, ppu_opcode_t); + static bool STDCX(PPUThread&, ppu_opcode_t); + static bool STBX(PPUThread&, ppu_opcode_t); + static bool STVX(PPUThread&, ppu_opcode_t); + static bool MULLD(PPUThread&, ppu_opcode_t); + static bool SUBFME(PPUThread&, ppu_opcode_t); + static bool ADDME(PPUThread&, ppu_opcode_t); + static bool MULLW(PPUThread&, ppu_opcode_t); + static bool DCBTST(PPUThread&, ppu_opcode_t); + static bool STBUX(PPUThread&, ppu_opcode_t); + static bool ADD(PPUThread&, ppu_opcode_t); + static bool DCBT(PPUThread&, ppu_opcode_t); + static bool LHZX(PPUThread&, ppu_opcode_t); + static bool EQV(PPUThread&, ppu_opcode_t); + static bool ECIWX(PPUThread&, ppu_opcode_t); + static bool LHZUX(PPUThread&, ppu_opcode_t); + static bool XOR(PPUThread&, ppu_opcode_t); + static bool MFSPR(PPUThread&, ppu_opcode_t); + static bool LWAX(PPUThread&, ppu_opcode_t); + static bool DST(PPUThread&, ppu_opcode_t); + static bool LHAX(PPUThread&, ppu_opcode_t); + static bool LVXL(PPUThread&, ppu_opcode_t); + static bool MFTB(PPUThread&, ppu_opcode_t); + static bool LWAUX(PPUThread&, ppu_opcode_t); + static bool DSTST(PPUThread&, ppu_opcode_t); + static bool LHAUX(PPUThread&, ppu_opcode_t); + static bool STHX(PPUThread&, ppu_opcode_t); + static bool ORC(PPUThread&, ppu_opcode_t); + static bool ECOWX(PPUThread&, ppu_opcode_t); + static bool STHUX(PPUThread&, ppu_opcode_t); + static bool OR(PPUThread&, ppu_opcode_t); + static bool DIVDU(PPUThread&, ppu_opcode_t); + static bool DIVWU(PPUThread&, ppu_opcode_t); + static bool MTSPR(PPUThread&, ppu_opcode_t); + static bool DCBI(PPUThread&, ppu_opcode_t); + static bool NAND(PPUThread&, ppu_opcode_t); + static bool STVXL(PPUThread&, ppu_opcode_t); + static bool DIVD(PPUThread&, ppu_opcode_t); + static bool DIVW(PPUThread&, ppu_opcode_t); + static bool LVLX(PPUThread&, ppu_opcode_t); + static bool LDBRX(PPUThread&, ppu_opcode_t); + static bool LSWX(PPUThread&, ppu_opcode_t); + static bool LWBRX(PPUThread&, ppu_opcode_t); + static bool LFSX(PPUThread&, ppu_opcode_t); + static bool SRW(PPUThread&, ppu_opcode_t); + static bool SRD(PPUThread&, ppu_opcode_t); + static bool LVRX(PPUThread&, ppu_opcode_t); + static bool LSWI(PPUThread&, ppu_opcode_t); + static bool LFSUX(PPUThread&, ppu_opcode_t); + static bool SYNC(PPUThread&, ppu_opcode_t); + static bool LFDX(PPUThread&, ppu_opcode_t); + static bool LFDUX(PPUThread&, ppu_opcode_t); + static bool STVLX(PPUThread&, ppu_opcode_t); + static bool STDBRX(PPUThread&, ppu_opcode_t); + static bool STSWX(PPUThread&, ppu_opcode_t); + static bool STWBRX(PPUThread&, ppu_opcode_t); + static bool STFSX(PPUThread&, ppu_opcode_t); + static bool STVRX(PPUThread&, ppu_opcode_t); + static bool STFSUX(PPUThread&, ppu_opcode_t); + static bool STSWI(PPUThread&, ppu_opcode_t); + static bool STFDX(PPUThread&, ppu_opcode_t); + static bool STFDUX(PPUThread&, ppu_opcode_t); + static bool LVLXL(PPUThread&, ppu_opcode_t); + static bool LHBRX(PPUThread&, ppu_opcode_t); + static bool SRAW(PPUThread&, ppu_opcode_t); + static bool SRAD(PPUThread&, ppu_opcode_t); + static bool LVRXL(PPUThread&, ppu_opcode_t); + static bool DSS(PPUThread&, ppu_opcode_t); + static bool SRAWI(PPUThread&, ppu_opcode_t); + static bool SRADI(PPUThread&, ppu_opcode_t); + static bool EIEIO(PPUThread&, ppu_opcode_t); + static bool STVLXL(PPUThread&, ppu_opcode_t); + static bool STHBRX(PPUThread&, ppu_opcode_t); + static bool EXTSH(PPUThread&, ppu_opcode_t); + static bool STVRXL(PPUThread&, ppu_opcode_t); + static bool EXTSB(PPUThread&, ppu_opcode_t); + static bool STFIWX(PPUThread&, ppu_opcode_t); + static bool EXTSW(PPUThread&, ppu_opcode_t); + static bool ICBI(PPUThread&, ppu_opcode_t); + static bool DCBZ(PPUThread&, ppu_opcode_t); + static bool LWZ(PPUThread&, ppu_opcode_t); + static bool LWZU(PPUThread&, ppu_opcode_t); + static bool LBZ(PPUThread&, ppu_opcode_t); + static bool LBZU(PPUThread&, ppu_opcode_t); + static bool STW(PPUThread&, ppu_opcode_t); + static bool STWU(PPUThread&, ppu_opcode_t); + static bool STB(PPUThread&, ppu_opcode_t); + static bool STBU(PPUThread&, ppu_opcode_t); + static bool LHZ(PPUThread&, ppu_opcode_t); + static bool LHZU(PPUThread&, ppu_opcode_t); + static bool LHA(PPUThread&, ppu_opcode_t); + static bool LHAU(PPUThread&, ppu_opcode_t); + static bool STH(PPUThread&, ppu_opcode_t); + static bool STHU(PPUThread&, ppu_opcode_t); + static bool LMW(PPUThread&, ppu_opcode_t); + static bool STMW(PPUThread&, ppu_opcode_t); + static bool LFS(PPUThread&, ppu_opcode_t); + static bool LFSU(PPUThread&, ppu_opcode_t); + static bool LFD(PPUThread&, ppu_opcode_t); + static bool LFDU(PPUThread&, ppu_opcode_t); + static bool STFS(PPUThread&, ppu_opcode_t); + static bool STFSU(PPUThread&, ppu_opcode_t); + static bool STFD(PPUThread&, ppu_opcode_t); + static bool STFDU(PPUThread&, ppu_opcode_t); + static bool LD(PPUThread&, ppu_opcode_t); + static bool LDU(PPUThread&, ppu_opcode_t); + static bool LWA(PPUThread&, ppu_opcode_t); + static bool STD(PPUThread&, ppu_opcode_t); + static bool STDU(PPUThread&, ppu_opcode_t); + static bool FDIVS(PPUThread&, ppu_opcode_t); + static bool FSUBS(PPUThread&, ppu_opcode_t); + static bool FADDS(PPUThread&, ppu_opcode_t); + static bool FSQRTS(PPUThread&, ppu_opcode_t); + static bool FRES(PPUThread&, ppu_opcode_t); + static bool FMULS(PPUThread&, ppu_opcode_t); + static bool FMADDS(PPUThread&, ppu_opcode_t); + static bool FMSUBS(PPUThread&, ppu_opcode_t); + static bool FNMSUBS(PPUThread&, ppu_opcode_t); + static bool FNMADDS(PPUThread&, ppu_opcode_t); + static bool MTFSB1(PPUThread&, ppu_opcode_t); + static bool MCRFS(PPUThread&, ppu_opcode_t); + static bool MTFSB0(PPUThread&, ppu_opcode_t); + static bool MTFSFI(PPUThread&, ppu_opcode_t); + static bool MFFS(PPUThread&, ppu_opcode_t); + static bool MTFSF(PPUThread&, ppu_opcode_t); + static bool FCMPU(PPUThread&, ppu_opcode_t); + static bool FRSP(PPUThread&, ppu_opcode_t); + static bool FCTIW(PPUThread&, ppu_opcode_t); + static bool FCTIWZ(PPUThread&, ppu_opcode_t); + static bool FDIV(PPUThread&, ppu_opcode_t); + static bool FSUB(PPUThread&, ppu_opcode_t); + static bool FADD(PPUThread&, ppu_opcode_t); + static bool FSQRT(PPUThread&, ppu_opcode_t); + static bool FSEL(PPUThread&, ppu_opcode_t); + static bool FMUL(PPUThread&, ppu_opcode_t); + static bool FRSQRTE(PPUThread&, ppu_opcode_t); + static bool FMSUB(PPUThread&, ppu_opcode_t); + static bool FMADD(PPUThread&, ppu_opcode_t); + static bool FNMSUB(PPUThread&, ppu_opcode_t); + static bool FNMADD(PPUThread&, ppu_opcode_t); + static bool FCMPO(PPUThread&, ppu_opcode_t); + static bool FNEG(PPUThread&, ppu_opcode_t); + static bool FMR(PPUThread&, ppu_opcode_t); + static bool FNABS(PPUThread&, ppu_opcode_t); + static bool FABS(PPUThread&, ppu_opcode_t); + static bool FCTID(PPUThread&, ppu_opcode_t); + static bool FCTIDZ(PPUThread&, ppu_opcode_t); + static bool FCFID(PPUThread&, ppu_opcode_t); - static void UNK(PPUThread&, ppu_opcode_t); + static bool UNK(PPUThread&, ppu_opcode_t); }; struct ppu_interpreter_precise final : ppu_interpreter diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 56de5d7234..8bb313482a 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Utilities/AutoPause.h" #include "Crypto/sha1.h" #include "Loader/ELF.h" @@ -10,6 +11,99 @@ #include "Emu/Cell/lv2/sys_prx.h" +#include <unordered_set> + +LOG_CHANNEL(cellAdec); +LOG_CHANNEL(cellAtrac); +LOG_CHANNEL(cellAtracMulti); +LOG_CHANNEL(cellAudio); +LOG_CHANNEL(cellAvconfExt); +LOG_CHANNEL(cellBGDL); +LOG_CHANNEL(cellCamera); +LOG_CHANNEL(cellCelp8Enc); +LOG_CHANNEL(cellCelpEnc); +LOG_CHANNEL(cellDaisy); +LOG_CHANNEL(cellDmux); +LOG_CHANNEL(cellFiber); +LOG_CHANNEL(cellFont); +LOG_CHANNEL(cellFontFT); +LOG_CHANNEL(cellFs); +LOG_CHANNEL(cellGame); +LOG_CHANNEL(cellGameExec); +LOG_CHANNEL(cellGcmSys); +LOG_CHANNEL(cellGem); +LOG_CHANNEL(cellGifDec); +LOG_CHANNEL(cellHttp); +LOG_CHANNEL(cellHttpUtil); +LOG_CHANNEL(cellImeJp); +LOG_CHANNEL(cellJpgDec); +LOG_CHANNEL(cellJpgEnc); +LOG_CHANNEL(cellKey2char); +LOG_CHANNEL(cellL10n); +LOG_CHANNEL(cellMic); +LOG_CHANNEL(cellMusic); +LOG_CHANNEL(cellMusicDecode); +LOG_CHANNEL(cellMusicExport); +LOG_CHANNEL(cellNetCtl); +LOG_CHANNEL(cellOskDialog); +LOG_CHANNEL(cellOvis); +LOG_CHANNEL(cellPamf); +LOG_CHANNEL(cellPhotoDecode); +LOG_CHANNEL(cellPhotoExport); +LOG_CHANNEL(cellPhotoImportUtil); +LOG_CHANNEL(cellPngDec); +LOG_CHANNEL(cellPngEnc); +LOG_CHANNEL(cellPrint); +LOG_CHANNEL(cellRec); +LOG_CHANNEL(cellRemotePlay); +LOG_CHANNEL(cellResc); +LOG_CHANNEL(cellRtc); +LOG_CHANNEL(cellRudp); +LOG_CHANNEL(cellSail); +LOG_CHANNEL(cellSailRec); +LOG_CHANNEL(cellSaveData); +LOG_CHANNEL(cellScreenshot); +LOG_CHANNEL(cellSearch); +LOG_CHANNEL(cellSheap); +LOG_CHANNEL(cellSpudll); +LOG_CHANNEL(cellSpurs); +LOG_CHANNEL(cellSpursJq); +LOG_CHANNEL(cellSsl); +LOG_CHANNEL(cellSubdisplay); +LOG_CHANNEL(cellSync); +LOG_CHANNEL(cellSync2); +LOG_CHANNEL(cellSysconf); +LOG_CHANNEL(cellSysmodule); +LOG_CHANNEL(cellSysutil); +LOG_CHANNEL(cellSysutilAp); +LOG_CHANNEL(cellSysutilAvc); +LOG_CHANNEL(cellSysutilAvc2); +LOG_CHANNEL(cellSysutilMisc); +LOG_CHANNEL(cellUsbd); +LOG_CHANNEL(cellUsbPspcm); +LOG_CHANNEL(cellUserInfo); +LOG_CHANNEL(cellVdec); +LOG_CHANNEL(cellVideoExport); +LOG_CHANNEL(cellVideoUpload); +LOG_CHANNEL(cellVoice); +LOG_CHANNEL(cellVpost); +LOG_CHANNEL(libmixer); +LOG_CHANNEL(libsnd3); +LOG_CHANNEL(libsynth2); +LOG_CHANNEL(sceNp); +LOG_CHANNEL(sceNp2); +LOG_CHANNEL(sceNpClans); +LOG_CHANNEL(sceNpCommerce2); +LOG_CHANNEL(sceNpSns); +LOG_CHANNEL(sceNpTrophy); +LOG_CHANNEL(sceNpTus); +LOG_CHANNEL(sceNpUtil); +LOG_CHANNEL(sys_io); +LOG_CHANNEL(sys_libc); +LOG_CHANNEL(sys_lv2dbg); +LOG_CHANNEL(libnet); +LOG_CHANNEL(sysPrxForUser); + cfg::bool_entry g_cfg_hook_ppu_funcs(cfg::root.core, "Hook static functions"); cfg::bool_entry g_cfg_load_liblv2(cfg::root.core, "Load liblv2.sprx only"); @@ -41,12 +135,18 @@ extern void ppu_execute_function(PPUThread& ppu, u32 index) { func(ppu); } - catch (...) + catch (EmulationStopped) { LOG_WARNING(PPU, "Function '%s' aborted", ppu.last_function); ppu.last_function = previous_function; throw; } + catch (...) + { + LOG_ERROR(PPU, "Function '%s' aborted", ppu.last_function); + ppu.last_function = previous_function; + throw; + } LOG_TRACE(PPU, "Function '%s' finished, r3=0x%llx", ppu.last_function, ppu.GPR[3]); ppu.last_function = previous_function; @@ -917,7 +1017,7 @@ void ppu_exec_loader::load() const } else { - throw fmt::exception("Failed to load liblv2.sprx: %s", bijective_find<elf_error>(loader, "???")); + throw fmt::exception("Failed to load liblv2.sprx: %s", loader.get_error()); } } else @@ -939,7 +1039,7 @@ void ppu_exec_loader::load() const } else { - LOG_FATAL(LOADER, "Failed to load %s: %s", name, bijective_find<elf_error>(loader, "???")); + LOG_FATAL(LOADER, "Failed to load %s: %s", name, loader.get_error()); } } } @@ -1130,7 +1230,7 @@ void ppu_exec_loader::load() const auto ppu = idm::make_ptr<PPUThread>("main_thread"); - ppu->PC = entry.addr() & -0x1000; + ppu->pc = entry.addr() & -0x1000; ppu->stack_size = Emu.GetPrimaryStackSize(); ppu->prio = Emu.GetPrimaryPrio(); ppu->cpu_init(); @@ -1166,6 +1266,8 @@ void ppu_exec_loader::load() const ppu->GPR[9] = Emu.GetTLSFilesz(); ppu->GPR[10] = Emu.GetTLSMemsz(); + //ppu->state += cpu_state::interrupt; + // Set memory protections //for (const auto& prog : progs) //{ @@ -1175,7 +1277,7 @@ void ppu_exec_loader::load() const // if (prog.p_type == 0x1 /* LOAD */ && prog.p_memsz && (prog.p_flags & 0x2) == 0 /* W */) // { // // Set memory protection to read-only where necessary - // ASSERT(vm::page_protect(addr, ::align(size, 0x1000), 0, 0, vm::page_writable)); + // VERIFY(vm::page_protect(addr, ::align(size, 0x1000), 0, 0, vm::page_writable)); // } //} } diff --git a/rpcs3/Emu/Cell/PPUModule.h b/rpcs3/Emu/Cell/PPUModule.h index 5b1438968f..957f8b6a38 100644 --- a/rpcs3/Emu/Cell/PPUModule.h +++ b/rpcs3/Emu/Cell/PPUModule.h @@ -1,6 +1,5 @@ #pragma once -#include "Utilities/Config.h" #include "PPUFunction.h" #include "PPUCallback.h" #include "ErrorCodes.h" @@ -207,15 +206,9 @@ inline RT ppu_execute_function_or_callback(const char* name, PPUThread& ppu, Arg { return Func(std::forward<Args>(args)...); } - catch (const std::exception&) - { - LOG_ERROR(PPU, "Function '%s' aborted", ppu.last_function); - ppu.last_function = previous_function; - throw; - } catch (...) { - LOG_WARNING(PPU, "Function '%s' aborted", ppu.last_function); + LOG_ERROR(PPU, "Function call '%s' aborted", ppu.last_function); ppu.last_function = previous_function; throw; } diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index c3ddecefce..4f7b33ba06 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -93,7 +94,7 @@ void PPUThread::cpu_task() { const auto cpu = static_cast<PPUThread*>(get_current_cpu_thread()); - return fmt::format("%s [0x%08x]", cpu->get_name(), cpu->PC); + return fmt::format("%s [0x%08x]", cpu->get_name(), cpu->pc); }; const auto base = vm::_ptr<const u8>(0); @@ -104,45 +105,135 @@ void PPUThread::cpu_task() g_cfg_ppu_decoder.get() == ppu_decoder_type::fast ? &s_ppu_interpreter_fast.get_table() : throw std::logic_error("Invalid PPU decoder")); - u32 _pc{}; - u32 op0, op1, op2; - ppu_inter_func_t func0, func1, func2; + v128 _op; + decltype(&ppu_interpreter::UNK) func0, func1, func2, func3; while (true) { - if (LIKELY(_pc == PC && !state.load())) + if (UNLIKELY(state.load())) { - func0(*this, { op0 }); - - if (LIKELY((_pc += 4) == (PC += 4) && !state.load())) - { - func1(*this, { op1 }); - - if (LIKELY((_pc += 4) == (PC += 4))) - { - op0 = op2; - func0 = func2; - const auto ops = reinterpret_cast<const be_t<u32>*>(base + _pc); - func1 = table[ppu_decode(op1 = ops[1])]; - func2 = table[ppu_decode(op2 = ops[2])]; - continue; - } - } + if (check_status()) return; } // Reinitialize - _pc = PC; - const auto ops = reinterpret_cast<const be_t<u32>*>(base + _pc); - func0 = table[ppu_decode(op0 = ops[0])]; - func1 = table[ppu_decode(op1 = ops[1])]; - func2 = table[ppu_decode(op2 = ops[2])]; + { + const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast<const __m128i*>(base + pc)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3)); + _op.vi = _ops; + const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff))); + func0 = table[_i._u32[0]]; + func1 = table[_i._u32[1]]; + func2 = table[_i._u32[2]]; + func3 = table[_i._u32[3]]; + } - if (UNLIKELY(check_status())) return; + while (LIKELY(func0(*this, { _op._u32[0] }))) + { + if (pc += 4, LIKELY(func1(*this, { _op._u32[1] }))) + { + if (pc += 4, LIKELY(func2(*this, { _op._u32[2] }))) + { + pc += 4; + func0 = func3; + + const auto _ops = _mm_shuffle_epi8(_mm_lddqu_si128(reinterpret_cast<const __m128i*>(base + pc + 4)), _mm_set_epi8(12, 13, 14, 15, 8, 9, 10, 11, 4, 5, 6, 7, 0, 1, 2, 3)); + _op.vi = _mm_alignr_epi8(_ops, _op.vi, 12); + const v128 _i = v128::fromV(_mm_and_si128(_mm_or_si128(_mm_slli_epi32(_op.vi, 6), _mm_srli_epi32(_op.vi, 26)), _mm_set1_epi32(0x1ffff))); + func1 = table[_i._u32[1]]; + func2 = table[_i._u32[2]]; + func3 = table[_i._u32[3]]; + + if (UNLIKELY(state.load())) + { + break; + } + continue; + } + break; + } + break; + } } } +constexpr auto stop_state = make_bitset(cpu_state::stop, cpu_state::exit, cpu_state::suspend); + +atomic_t<u32> g_ppu_core[2]{}; + bool PPUThread::handle_interrupt() { + // Reschedule and wake up a new thread, possibly this one as well. + return false; + + // Check virtual core allocation + if (g_ppu_core[0] != id && g_ppu_core[1] != id) + { + auto cpu0 = idm::get<PPUThread>(g_ppu_core[0]); + auto cpu1 = idm::get<PPUThread>(g_ppu_core[1]); + + if (cpu0 && cpu1) + { + if (cpu1->prio > cpu0->prio) + { + cpu0 = std::move(cpu1); + } + + // Preempt thread with the lowest priority + if (prio < cpu0->prio) + { + cpu0->state += cpu_state::interrupt; + } + } + else + { + // Try to obtain a virtual core in optimistic way + if (g_ppu_core[0].compare_and_swap_test(0, id) || g_ppu_core[1].compare_and_swap_test(0, id)) + { + state -= cpu_state::interrupt; + return true; + } + } + + return false; + } + + // Select appropriate thread + u32 top_prio = -1; + u32 selected = -1; + + idm::select<PPUThread>([&](u32 id, PPUThread& ppu) + { + // Exclude suspended and low-priority threads + if (!ppu.state.test(stop_state) && ppu.prio < top_prio /*&& (!ppu.is_sleep() || ppu.state & cpu_state::signal)*/) + { + top_prio = ppu.prio; + selected = id; + } + }); + + // If current thread selected + if (selected == id) + { + state -= cpu_state::interrupt; + VERIFY(g_ppu_core[0] == id || g_ppu_core[1] == id); + return true; + } + + // If another thread selected + const auto thread = idm::get<PPUThread>(selected); + + // Lend virtual core to another thread + if (thread && thread->state.test_and_reset(cpu_state::interrupt)) + { + g_ppu_core[0].compare_and_swap(id, thread->id); + g_ppu_core[1].compare_and_swap(id, thread->id); + (*thread)->lock_notify(); + } + else + { + g_ppu_core[0].compare_and_swap(id, 0); + g_ppu_core[1].compare_and_swap(id, 0); + } + return false; } @@ -167,13 +258,13 @@ be_t<u64>* PPUThread::get_stack_arg(s32 i, u64 align) void PPUThread::fast_call(u32 addr, u32 rtoc) { - auto old_PC = PC; + auto old_PC = pc; auto old_stack = GPR[1]; auto old_rtoc = GPR[2]; auto old_LR = LR; auto old_task = std::move(custom_task); - PC = addr; + pc = addr; GPR[2] = rtoc; LR = Emu.GetCPUThreadStop(); custom_task = nullptr; @@ -190,7 +281,7 @@ void PPUThread::fast_call(u32 addr, u32 rtoc) state -= cpu_state::ret; - PC = old_PC; + pc = old_PC; if (GPR[1] != old_stack) // GPR[1] shouldn't change { @@ -200,4 +291,10 @@ void PPUThread::fast_call(u32 addr, u32 rtoc) GPR[2] = old_rtoc; LR = old_LR; custom_task = std::move(old_task); + + //if (custom_task) + //{ + // state += cpu_state::interrupt; + // handle_interrupt(); + //} } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 8507f54c44..8307245196 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -66,9 +66,9 @@ public: u64 LR{}; // Link Register u64 CTR{}; // Counter Register u32 VRSAVE{}; - u32 PC{}; - s32 prio = 0; // Thread priority + u32 pc = 0; + u32 prio = -1; // Thread priority u32 stack_addr = 0; // Stack address u32 stack_size = 0; // Stack size bool is_joinable = true; @@ -191,7 +191,7 @@ struct ppu_gpr_cast_impl<vm::_ptr_base<T, AT>, void> static inline vm::_ptr_base<T, AT> from(const u64 reg) { - return{ ppu_gpr_cast_impl<AT>::from(reg), vm::addr }; + return vm::cast(ppu_gpr_cast_impl<AT>::from(reg)); } }; @@ -205,7 +205,7 @@ struct ppu_gpr_cast_impl<vm::_ref_base<T, AT>, void> static inline vm::_ref_base<T, AT> from(const u64 reg) { - return{ ppu_gpr_cast_impl<AT>::from(reg), vm::addr }; + return vm::cast(ppu_gpr_cast_impl<AT>::from(reg)); } }; diff --git a/rpcs3/Emu/Cell/RawSPUThread.cpp b/rpcs3/Emu/Cell/RawSPUThread.cpp index 60033cfa2f..808c0a2900 100644 --- a/rpcs3/Emu/Cell/RawSPUThread.cpp +++ b/rpcs3/Emu/Cell/RawSPUThread.cpp @@ -31,7 +31,7 @@ void RawSPUThread::on_init() // Install correct SPU index and LS address const_cast<u32&>(index) = id; const_cast<u32&>(offset) = vm::falloc(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, 0x40000); - ASSERT(offset); + VERIFY(offset); SPUThread::on_init(); } @@ -101,7 +101,7 @@ bool RawSPUThread::write_reg(const u32 addr, const u32 value) })) { state -= cpu_state::stop; - lock_notify(); + (*this)->lock_notify(); } }; diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index 8ac7256513..35dec7108a 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -7,6 +7,8 @@ #include "SPUInterpreter.h" #include "SPUASMJITRecompiler.h" +#include <cmath> + #define ASMJIT_STATIC #define ASMJIT_DEBUG @@ -1962,8 +1964,8 @@ void spu_recompiler::CFLTS(spu_opcode_t op) { const XmmLink& va = XmmGet(op.ra, XmmType::Float); const XmmLink& vi = XmmAlloc(); - if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast<s16>(173 - op.i8))))); // scale - c->movaps(vi, XmmConst(_mm_set1_ps(exp2f(31)))); + if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast<float>(static_cast<s16>(173 - op.i8)))))); // scale + c->movaps(vi, XmmConst(_mm_set1_ps(std::exp2(31.f)))); c->cmpps(vi, va, 2); c->cvttps2dq(va, va); // convert to ints with truncation c->pxor(va, vi); // fix result saturation (0x80000000 -> 0x7fffffff) @@ -1976,16 +1978,16 @@ void spu_recompiler::CFLTU(spu_opcode_t op) const XmmLink& vs = XmmAlloc(); const XmmLink& vs2 = XmmAlloc(); const XmmLink& vs3 = XmmAlloc(); - if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast<s16>(173 - op.i8))))); // scale + if (op.i8 != 173) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast<float>(static_cast<s16>(173 - op.i8)))))); // scale c->maxps(va, XmmConst(_mm_set1_ps(0.0f))); // saturate c->movaps(vs, va); // copy scaled value c->movaps(vs2, va); - c->movaps(vs3, XmmConst(_mm_set1_ps(exp2f(31)))); + c->movaps(vs3, XmmConst(_mm_set1_ps(std::exp2(31.f)))); c->subps(vs2, vs3); c->cmpps(vs3, vs, 2); c->andps(vs2, vs3); c->cvttps2dq(va, va); - c->cmpps(vs, XmmConst(_mm_set1_ps(exp2f(32))), 5); + c->cmpps(vs, XmmConst(_mm_set1_ps(std::exp2(32.f))), 5); c->cvttps2dq(vs2, vs2); c->por(va, vs); c->por(va, vs2); @@ -1996,7 +1998,7 @@ void spu_recompiler::CSFLT(spu_opcode_t op) { const XmmLink& va = XmmGet(op.ra, XmmType::Int); c->cvtdq2ps(va, va); // convert to floats - if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast<s16>(op.i8 - 155))))); // scale + if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast<float>(static_cast<s16>(op.i8 - 155)))))); // scale c->movaps(SPU_OFF_128(gpr[op.rt]), va); } @@ -2008,9 +2010,9 @@ void spu_recompiler::CUFLT(spu_opcode_t op) c->pand(va, XmmConst(_mm_set1_epi32(0x7fffffff))); c->cvtdq2ps(va, va); // convert to floats c->psrad(v1, 31); // generate mask from sign bit - c->andps(v1, XmmConst(_mm_set1_ps(exp2f(31)))); // generate correction component + c->andps(v1, XmmConst(_mm_set1_ps(std::exp2(31.f)))); // generate correction component c->addps(va, v1); // add correction component - if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(exp2f(static_cast<s16>(op.i8 - 155))))); // scale + if (op.i8 != 155) c->mulps(va, XmmConst(_mm_set1_ps(std::exp2(static_cast<float>(static_cast<s16>(op.i8 - 155)))))); // scale c->movaps(SPU_OFF_128(gpr[op.rt]), va); } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index 217f35728c..139c91319f 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -5,7 +5,8 @@ #include "SPUThread.h" #include "SPUInterpreter.h" -#include <fenv.h> +#include <cmath> +#include <cfenv> // Compare 16 packed unsigned bytes (greater than) inline __m128i sse_cmpgt_epu8(__m128i A, __m128i B) @@ -942,8 +943,8 @@ void spu_interpreter_fast::FI(SPUThread& spu, spu_opcode_t op) const auto mask_sf = _mm_set1_epi32(0x000003ff); // step fraction mask const auto mask_yf = _mm_set1_epi32(0x0007ffff); // Y fraction mask (bits 13..31) const auto base = _mm_or_ps(_mm_and_ps(spu.gpr[op.rb].vf, mask_bf), _mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); - const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.rb].vi, mask_sf)), _mm_set1_ps(exp2f(-13))); - const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.ra].vi, mask_yf)), _mm_set1_ps(exp2f(-19))); + const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.rb].vi, mask_sf)), _mm_set1_ps(std::exp2(-13.f))); + const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(spu.gpr[op.ra].vi, mask_yf)), _mm_set1_ps(std::exp2(-19.f))); spu.gpr[op.rt].vf = _mm_or_ps(_mm_and_ps(mask_se, spu.gpr[op.rb].vf), _mm_andnot_ps(mask_se, _mm_sub_ps(base, _mm_mul_ps(step, y)))); } @@ -1409,9 +1410,9 @@ void spu_interpreter_precise::FRSQEST(SPUThread& spu, spu_opcode_t op) result = extended(0, 0x7FFFFF); } else if (isextended(a)) - result = 0.5f / sqrtf(fabsf(ldexpf_extended(a, -2))); + result = 0.5f / std::sqrt(std::fabs(ldexpf_extended(a, -2))); else - result = 1 / sqrtf(fabsf(a)); + result = 1 / std::sqrt(std::fabs(a)); spu.gpr[op.rt]._f[i] = result; } } @@ -1502,9 +1503,9 @@ static void FA_FS(SPUThread& spu, spu_opcode_t op, bool sub) else { result = a + b; - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { - result = ldexpf_extended(ldexpf(a, -1) + ldexpf(b, -1), 1); + result = ldexpf_extended(std::ldexp(a, -1) + std::ldexp(b, -1), 1); if (isextended(result)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); } @@ -1515,7 +1516,7 @@ static void FA_FS(SPUThread& spu, spu_opcode_t op, bool sub) } else if (result == 0.0f) { - if (fabsf(a) != fabsf(b)) + if (std::fabs(a) != std::fabs(b)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SUNF | FPSCR_SDIFF); result = +0.0f; } @@ -1560,7 +1561,7 @@ void spu_interpreter_precise::FM(SPUThread& spu, spu_opcode_t op) result = ldexpf_extended(a, -1) * b; else result = a * ldexpf_extended(b, -1); - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -1572,13 +1573,13 @@ void spu_interpreter_precise::FM(SPUThread& spu, spu_opcode_t op) else { result = a * b; - if (result == copysignf(FLOAT_MAX_NORMAL, result)) + if (result == std::copysign(FLOAT_MAX_NORMAL, result)) { feclearexcept(FE_ALL_EXCEPT); if (fexpf(a) > fexpf(b)) - result = ldexpf(a, -1) * b; + result = std::ldexp(a, -1) * b; else - result = a * ldexpf(b, -1); + result = a * std::ldexp(b, -1); result = ldexpf_extended(result, 1); if (isextended(result)) spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); @@ -1638,12 +1639,12 @@ static void DFASM(SPUThread& spu, spu_opcode_t op, DoubleOp operation) if (isdenormal(a)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - a = copysign(0.0, a); + a = std::copysign(0.0, a); } if (isdenormal(b)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - b = copysign(0.0, b); + b = std::copysign(0.0, b); } double result; if (std::isnan(a) || std::isnan(b)) @@ -1698,17 +1699,17 @@ static void DFMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) if (isdenormal(a)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - a = copysign(0.0, a); + a = std::copysign(0.0, a); } if (isdenormal(b)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - b = copysign(0.0, b); + b = std::copysign(0.0, b); } if (isdenormal(c)) { spu.fpscr.setDoublePrecisionExceptionFlags(i, FPSCR_DDENORM); - c = copysign(0.0, c); + c = std::copysign(0.0, c); } double result; if (std::isnan(a) || std::isnan(b) || std::isnan(c)) @@ -1857,9 +1858,9 @@ void spu_interpreter_precise::CFLTS(SPUThread& spu, spu_opcode_t op) const float a = spu.gpr[op.ra]._f[i]; float scaled; if ((fexpf(a) - 127) + scale >= 32) - scaled = copysignf(4294967296.0f, a); + scaled = std::copysign(4294967296.0f, a); else - scaled = ldexpf(a, scale); + scaled = std::ldexp(a, scale); s32 result; if (scaled >= 2147483648.0f) result = 0x7FFFFFFF; @@ -1879,9 +1880,9 @@ void spu_interpreter_precise::CFLTU(SPUThread& spu, spu_opcode_t op) const float a = spu.gpr[op.ra]._f[i]; float scaled; if ((fexpf(a) - 127) + scale >= 32) - scaled = copysignf(4294967296.0f, a); + scaled = std::copysign(4294967296.0f, a); else - scaled = ldexpf(a, scale); + scaled = std::ldexp(a, scale); u32 result; if (scaled >= 4294967296.0f) result = 0xFFFFFFFF; @@ -2002,9 +2003,9 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) } else { - result = fmaf(new_a, new_b, ldexpf_extended(c, -2)); + result = std::fma(new_a, new_b, ldexpf_extended(c, -2)); } - if (fabsf(result) >= ldexpf(1.0f, 127)) + if (std::fabs(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -2033,8 +2034,8 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) } else { - result = fmaf(ldexpf(a, -1), ldexpf(b, -1), ldexpf_extended(c, -2)); - if (fabsf(result) >= ldexpf(1.0f, 127)) + result = std::fma(std::ldexp(a, -1), std::ldexp(b, -1), ldexpf_extended(c, -2)); + if (std::fabs(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); @@ -2048,15 +2049,15 @@ static void FMA(SPUThread& spu, spu_opcode_t op, bool neg, bool sub) else { feclearexcept(FE_ALL_EXCEPT); - result = fmaf(a, b, c); + result = std::fma(a, b, c); if (fetestexcept(FE_OVERFLOW)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SDIFF); if (fexpf(a) > fexpf(b)) - result = fmaf(ldexpf(a, -2), b, ldexpf(c, -2)); + result = std::fma(std::ldexp(a, -2), b, std::ldexp(c, -2)); else - result = fmaf(a, ldexpf(b, -2), ldexpf(c, -2)); - if (fabsf(result) >= ldexpf(1.0f, 127)) + result = std::fma(a, std::ldexp(b, -2), std::ldexp(c, -2)); + if (fabsf(result) >= std::ldexp(1.0f, 127)) { spu.fpscr.setSinglePrecisionExceptionFlags(w, FPSCR_SOVF); result = extended(sign, 0x7FFFFF); diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index ed9b9aae64..355bde4bd5 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -2,6 +2,8 @@ #include "SPUAnalyser.h" +#include <mutex> + // SPU Recompiler instance base (must be global or PS3 process-local) class spu_recompiler_base { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 9ec1cd4643..b339abedf5 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -18,10 +18,14 @@ #include "Emu/Memory/wait_engine.h" +#include <cmath> #include <cfenv> +#include <thread> extern u64 get_timebased_time(); +extern std::mutex& get_current_thread_mutex(); + enum class spu_decoder_type { precise, @@ -54,13 +58,72 @@ void spu_int_ctrl_t::set(u64 ints) if (tag && tag->handler) { tag->handler->signal++; - tag->handler->thread->notify(); + (*tag->handler->thread)->notify(); } } } const spu_imm_table_t g_spu_imm; +spu_imm_table_t::scale_table_t::scale_table_t() +{ + for (s32 i = -155; i < 174; i++) + { + m_data[i + 155] = _mm_set1_ps(static_cast<float>(std::exp2(i))); + } +} + +spu_imm_table_t::spu_imm_table_t() +{ + for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++) + { + for (u32 j = 0; j < 4; j++) + { + fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0; + } + } + + for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++) + { + for (u32 j = 0; j < 8; j++) + { + fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0; + } + } + + for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0; + } + } + + for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + sldq_pshufb[i]._u8[j] = static_cast<u8>(j - i); + } + } + + for (u32 i = 0; i < sizeof(srdq_pshufb) / sizeof(srdq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + srdq_pshufb[i]._u8[j] = (j + i > 15) ? 0xff : static_cast<u8>(j + i); + } + } + + for (u32 i = 0; i < sizeof(rldq_pshufb) / sizeof(rldq_pshufb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + rldq_pshufb[i]._u8[j] = static_cast<u8>((j - i) & 0xf); + } + } +} + std::string SPUThread::get_name() const { return fmt::format("%sSPU[0x%x] Thread (%s)", offset > RAW_SPU_BASE_ADDR ? "Raw" : "", id, name); @@ -188,7 +251,7 @@ SPUThread::SPUThread(const std::string& name, u32 index) , index(index) , offset(vm::alloc(0x40000, vm::main)) { - Ensures(offset); + ENSURES(offset); } void SPUThread::push_snr(u32 number, u32 value) @@ -477,18 +540,13 @@ void SPUThread::set_events(u32 mask) throw EXCEPTION("Unimplemented events (0x%x)", unimpl); } - // set new events, get old event mask + // Set new events, get old event mask const u32 old_stat = ch_event_stat.fetch_or(mask); - // notify if some events were set - if (~old_stat & mask && old_stat & SPU_EVENT_WAITING) + // Notify if some events were set + if (~old_stat & mask && old_stat & SPU_EVENT_WAITING && ch_event_stat & SPU_EVENT_WAITING) { - std::lock_guard<std::mutex> lock(get_current_thread_mutex()); - - if (ch_event_stat & SPU_EVENT_WAITING) - { - notify(); - } + (*this)->lock_notify(); } } @@ -540,30 +598,14 @@ bool SPUThread::get_ch_value(u32 ch, u32& out) auto read_channel = [&](spu_channel_t& channel) { - std::unique_lock<std::mutex> lock(get_current_thread_mutex(), std::defer_lock); - - while (true) + if (!channel.try_pop(out)) { - if (channel.try_pop(out)) - { - return true; - } + cpu_thread_lock{*this}, thread_ctrl::wait(WRAP_EXPR(state & cpu_state::stop || channel.try_pop(out))); - CHECK_EMU_STATUS; - - if (state & cpu_state::stop) - { - return false; - } - - if (!lock) - { - lock.lock(); - continue; - } - - get_current_thread_cv().wait(lock); + return !state.test(cpu_state::stop); } + + return true; }; switch (ch) @@ -1103,7 +1145,7 @@ bool SPUThread::stop_and_signal(u32 code) { case 0x001: { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + std::this_thread::sleep_for(1ms); // hack return true; } @@ -1195,7 +1237,7 @@ bool SPUThread::stop_and_signal(u32 code) return false; } - group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + group->cv.wait_for(lv2_lock, 1ms); } // change group status @@ -1261,7 +1303,7 @@ bool SPUThread::stop_and_signal(u32 code) if (thread && thread.get() != this) { thread->state -= cpu_state::suspend; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -1300,7 +1342,7 @@ bool SPUThread::stop_and_signal(u32 code) if (thread && thread.get() != this) { thread->state += cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -1404,7 +1446,7 @@ void SPUThread::fast_call(u32 ls_addr) custom_task = std::move(old_task); } -void SPUThread::RegisterHleFunction(u32 addr, std::function<bool(SPUThread&SPU)> function) +void SPUThread::RegisterHleFunction(u32 addr, std::function<bool(SPUThread&)> function) { m_addr_to_hle_function_map[addr] = function; _ref<u32>(addr) = 0x00000003; // STOP 3 diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 38bb09e2b0..d75dd5e676 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -4,7 +4,6 @@ #include "Emu/CPU/CPUThread.h" #include "Emu/Cell/SPUInterpreter.h" #include "MFC.h" -#include <cmath> class lv2_event_queue_t; struct lv2_spu_group_t; @@ -380,13 +379,7 @@ struct spu_imm_table_t std::array<__m128, 155 + 174> m_data; public: - scale_table_t() - { - for (s32 i = -155; i < 174; i++) - { - m_data[i + 155] = _mm_set1_ps(static_cast<float>(std::exp2(i))); - } - } + scale_table_t(); force_inline __m128 operator [] (s32 scale) const { @@ -395,56 +388,7 @@ struct spu_imm_table_t } const scale; - spu_imm_table_t() - { - for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++) - { - for (u32 j = 0; j < 4; j++) - { - fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0; - } - } - - for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++) - { - for (u32 j = 0; j < 8; j++) - { - fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0; - } - } - - for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0; - } - } - - for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - sldq_pshufb[i]._u8[j] = static_cast<u8>(j - i); - } - } - - for (u32 i = 0; i < sizeof(srdq_pshufb) / sizeof(srdq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - srdq_pshufb[i]._u8[j] = (j + i > 15) ? 0xff : static_cast<u8>(j + i); - } - } - - for (u32 i = 0; i < sizeof(rldq_pshufb) / sizeof(rldq_pshufb[0]); i++) - { - for (u32 j = 0; j < 16; j++) - { - rldq_pshufb[i]._u8[j] = static_cast<u8>((j - i) & 0xf); - } - } - } + spu_imm_table_t(); }; extern const spu_imm_table_t g_spu_imm; @@ -646,7 +590,7 @@ public: return *_ptr<T>(lsa); } - void RegisterHleFunction(u32 addr, std::function<bool(SPUThread & SPU)> function); + void RegisterHleFunction(u32 addr, std::function<bool(SPUThread&)> function); void UnregisterHleFunction(u32 addr); void UnregisterHleFunctions(u32 start_addr, u32 end_addr); }; diff --git a/rpcs3/Emu/Cell/lv2/IPC.h b/rpcs3/Emu/Cell/lv2/IPC.h deleted file mode 100644 index 777409307a..0000000000 --- a/rpcs3/Emu/Cell/lv2/IPC.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include <memory> -#include <unordered_map> - -#include "Utilities/SharedMutex.h" - -// IPC manager for lv2 objects of type T and 64-bit IPC keys. -// External declaration of g_ipc is required. -template<typename T> -class ipc_manager final -{ - std::unordered_map<u64, std::weak_ptr<T>> m_map; - - shared_mutex m_mutex; - - static ipc_manager g_ipc; - -public: - // Add new object if specified ipc_key is not used - template<typename F> - static auto add(u64 ipc_key, F&& provider) -> decltype(static_cast<std::shared_ptr<T>>(provider())) - { - writer_lock lock(g_ipc.m_mutex); - - // Get object location - std::weak_ptr<T>& wptr = g_ipc.m_map[ipc_key]; - - if (wptr.expired()) - { - // Call a function which must return the object - std::shared_ptr<T> result = provider(); - wptr = result; - return result; - } - - return{}; - } - - // Get existing object with specified ipc_key - static std::shared_ptr<T> get(u64 ipc_key) - { - reader_lock lock(g_ipc.m_mutex); - - const auto found = g_ipc.m_map.find(ipc_key); - - if (found != g_ipc.m_map.end()) - { - return found->second.lock(); - } - - return{}; - } -}; diff --git a/rpcs3/Emu/Cell/lv2/lv2.cpp b/rpcs3/Emu/Cell/lv2/lv2.cpp index 771302c551..7a1788939b 100644 --- a/rpcs3/Emu/Cell/lv2/lv2.cpp +++ b/rpcs3/Emu/Cell/lv2/lv2.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "Utilities/Config.h" #include "Utilities/AutoPause.h" #include "Emu/System.h" @@ -29,6 +30,30 @@ #include "sys_fs.h" #include "sys_dbg.h" +LOG_CHANNEL(sys_cond); +LOG_CHANNEL(sys_dbg); +LOG_CHANNEL(sys_event); +LOG_CHANNEL(sys_event_flag); +LOG_CHANNEL(sys_fs); +LOG_CHANNEL(sys_interrupt); +LOG_CHANNEL(sys_lwcond); +LOG_CHANNEL(sys_lwmutex); +LOG_CHANNEL(sys_memory); +LOG_CHANNEL(sys_mmapper); +LOG_CHANNEL(sys_mutex); +LOG_CHANNEL(sys_ppu_thread); +LOG_CHANNEL(sys_process); +LOG_CHANNEL(sys_prx); +LOG_CHANNEL(sys_rsx); +LOG_CHANNEL(sys_rwlock); +LOG_CHANNEL(sys_semaphore); +LOG_CHANNEL(sys_spu); +LOG_CHANNEL(sys_time); +LOG_CHANNEL(sys_timer); +LOG_CHANNEL(sys_trace); +LOG_CHANNEL(sys_tty); +LOG_CHANNEL(sys_vm); + extern std::string ppu_get_syscall_name(u64 code); static void null_func(PPUThread& ppu) @@ -903,15 +928,21 @@ extern void ppu_execute_syscall(PPUThread& ppu, u64 code) { g_ppu_syscall_table[code](ppu); } - catch (...) + catch (EmulationStopped) { LOG_WARNING(PPU, "Syscall '%s' (%llu) aborted", ppu_get_syscall_name(code), code); ppu.last_function = previous_function; throw; } + catch (...) + { + LOG_ERROR(PPU, "Syscall '%s' (%llu) aborted", ppu_get_syscall_name(code), code); + ppu.last_function = previous_function; + throw; + } LOG_TRACE(PPU, "Syscall '%s' (%llu) finished, r3=0x%llx", ppu_get_syscall_name(code), code, ppu.GPR[3]); ppu.last_function = previous_function; } -lv2_lock_t::type::mutex_type lv2_lock_t::mutex; +DECLARE(lv2_lock_t::mutex); diff --git a/rpcs3/Emu/Cell/lv2/sys_cond.cpp b/rpcs3/Emu/Cell/lv2/sys_cond.cpp index 82853dac81..db5f2478fb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_cond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_cond.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,9 @@ #include "sys_mutex.h" #include "sys_cond.h" -LOG_CHANNEL(sys_cond); +#include <algorithm> + +logs::channel sys_cond("sys_cond", logs::level::notice); extern u64 get_system_time(); @@ -24,8 +25,8 @@ void lv2_cond_t::notify(lv2_lock_t, cpu_thread* thread) { mutex->owner = std::static_pointer_cast<cpu_thread>(thread->shared_from_this()); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp index 3890fc906f..7c73318b80 100644 --- a/rpcs3/Emu/Cell/lv2/sys_dbg.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_dbg.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,4 +6,4 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_dbg.h" -LOG_CHANNEL(sys_dbg); +logs::channel sys_dbg("sys_dbg", logs::level::notice); diff --git a/rpcs3/Emu/Cell/lv2/sys_event.cpp b/rpcs3/Emu/Cell/lv2/sys_event.cpp index ac105aabb5..2c1994419b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event.cpp @@ -1,25 +1,26 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" +#include "Emu/IPC.h" #include "Emu/Cell/ErrorCodes.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/SPUThread.h" #include "sys_process.h" #include "sys_event.h" -#include "IPC.h" -LOG_CHANNEL(sys_event); +logs::channel sys_event("sys_event", logs::level::notice); -template<> DECLARE(ipc_manager<lv2_event_queue_t>::g_ipc) {}; +template<> DECLARE(ipc_manager<lv2_event_queue_t, u64>::g_ipc) {}; extern u64 get_system_time(); std::shared_ptr<lv2_event_queue_t> lv2_event_queue_t::make(u32 protocol, s32 type, u64 name, u64 ipc_key, s32 size) { - auto make_expr = WRAP_EXPR(idm::import<lv2_event_queue_t>(WRAP_EXPR(std::make_shared<lv2_event_queue_t>(protocol, type, name, ipc_key, size)))); + auto queue = std::make_shared<lv2_event_queue_t>(protocol, type, name, ipc_key, size); + + auto make_expr = WRAP_EXPR(idm::import<lv2_event_queue_t>(WRAP_EXPR(queue))); if (ipc_key == SYS_EVENT_QUEUE_LOCAL) { @@ -28,7 +29,12 @@ std::shared_ptr<lv2_event_queue_t> lv2_event_queue_t::make(u32 protocol, s32 typ } // IPC queue - return ipc_manager<lv2_event_queue_t>::add(ipc_key, make_expr); + if (ipc_manager<lv2_event_queue_t, u64>::add(ipc_key, make_expr)) + { + return queue; + } + + return nullptr; } std::shared_ptr<lv2_event_queue_t> lv2_event_queue_t::find(u64 ipc_key) @@ -39,12 +45,12 @@ std::shared_ptr<lv2_event_queue_t> lv2_event_queue_t::find(u64 ipc_key) return{}; } - return ipc_manager<lv2_event_queue_t>::get(ipc_key); + return ipc_manager<lv2_event_queue_t, u64>::get(ipc_key); } void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 data3) { - Expects(m_sq.empty() || m_events.empty()); + EXPECTS(m_sq.empty() || m_events.empty()); // save event if no waiters if (m_sq.empty()) @@ -77,15 +83,15 @@ void lv2_event_queue_t::push(lv2_lock_t, u64 source, u64 data1, u64 data2, u64 d throw fmt::exception("Unexpected (queue.type=%d, thread.type=%d)" HERE, type, thread->type); } - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); return m_sq.pop_front(); } lv2_event_queue_t::event_type lv2_event_queue_t::pop(lv2_lock_t) { - Expects(m_events.size()); + EXPECTS(m_events.size()); auto result = m_events.front(); m_events.pop_front(); return result; @@ -171,7 +177,7 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) } thread->state += cpu_state::signal; - thread->notify(); + (*thread)->notify(); } return CELL_OK; @@ -270,7 +276,7 @@ s32 sys_event_queue_receive(PPUThread& ppu, u32 equeue_id, vm::ptr<sys_event_t> if (ppu.GPR[3]) { - Ensures(!idm::check<lv2_event_queue_t>(equeue_id)); + ENSURES(!idm::check<lv2_event_queue_t>(equeue_id)); return CELL_ECANCELED; } diff --git a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp index 87814cf8e4..d39ba434d0 100644 --- a/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_event_flag.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,9 @@ #include "Emu/Cell/PPUThread.h" #include "sys_event_flag.h" -LOG_CHANNEL(sys_event_flag); +#include <algorithm> + +logs::channel sys_event_flag("sys_event_flag", logs::level::notice); extern u64 get_system_time(); @@ -28,8 +29,8 @@ void lv2_event_flag_t::notify_all(lv2_lock_t) // save pattern ppu.GPR[4] = clear_pattern(bitptn, mode); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); return true; } @@ -291,8 +292,8 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr<u32> num) // clear "mode" as a sign of cancellation ppu.GPR[5] = 0; - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } eflag->sq.clear(); diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index a2e2899cb6..de95dfebdd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -10,7 +9,7 @@ #include "Utilities/StrUtil.h" #include <cerrno> -LOG_CHANNEL(sys_fs); +logs::channel sys_fs("sys_fs", logs::level::notice); s32 sys_fs_test(u32 arg1, u32 arg2, vm::ptr<u32> arg3, u32 arg4, vm::ptr<char> arg5, u32 arg6) { @@ -352,9 +351,9 @@ s32 sys_fs_rmdir(vm::cptr<char> path) if (!fs::remove_dir(vfs::get(path.get_ptr()))) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_rmdir(): unknown error %d", error); } @@ -372,9 +371,9 @@ s32 sys_fs_unlink(vm::cptr<char> path) if (!fs::remove_file(vfs::get(path.get_ptr()))) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_unlink(): unknown error %d", error); } @@ -451,9 +450,9 @@ s32 sys_fs_truncate(vm::cptr<char> path, u64 size) if (!fs::truncate_file(vfs::get(path.get_ptr()), size)) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case ENOENT: return CELL_FS_ENOENT; + case fs::error::noent: return CELL_FS_ENOENT; default: sys_fs.error("sys_fs_truncate(): unknown error %d", error); } @@ -478,9 +477,9 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) if (!file->file.trunc(size)) { - switch (auto error = fs::error) + switch (auto error = fs::g_tls_error) { - case 0: + case fs::error::ok: default: sys_fs.error("sys_fs_ftruncate(): unknown error %d", error); } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.h b/rpcs3/Emu/Cell/lv2/sys_fs.h index fd63e6df52..ad044f23a3 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.h +++ b/rpcs3/Emu/Cell/lv2/sys_fs.h @@ -2,6 +2,9 @@ #include "Utilities/Thread.h" +#include <mutex> +#include <condition_variable> + namespace vm { using namespace ps3; } #pragma pack(push, 4) diff --git a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp index ca2fe1f9d9..ec831f61e4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_interrupt.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,20 +7,20 @@ #include "Emu/Cell/PPUThread.h" #include "sys_interrupt.h" -LOG_CHANNEL(sys_interrupt); +logs::channel sys_interrupt("sys_interrupt", logs::level::notice); void lv2_int_serv_t::join(PPUThread& ppu, lv2_lock_t lv2_lock) { // Use is_joining to stop interrupt thread and signal thread->is_joining = true; - thread->notify(); + (*thread)->notify(); // Start joining while (!(thread->state & cpu_state::exit)) { CHECK_EMU_STATUS; - get_current_thread_cv().wait_for(lv2_lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lv2_lock, 1ms); } // Cleanup @@ -93,7 +92,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u32 intrthread it->custom_task = [handler, arg1, arg2](PPUThread& ppu) { - const u32 pc = ppu.PC; + const u32 pc = ppu.pc; const u32 rtoc = ppu.GPR[2]; LV2_LOCK; @@ -128,7 +127,7 @@ s32 _sys_interrupt_thread_establish(vm::ptr<u32> ih, u32 intrtag, u32 intrthread }; it->state -= cpu_state::stop; - it->lock_notify(); + (*it)->lock_notify(); *ih = handler->id; diff --git a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp index e56a69f78d..eaea8482bc 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwcond.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,9 @@ #include "sys_lwmutex.h" #include "sys_lwcond.h" -LOG_CHANNEL(sys_lwcond); +#include <algorithm> + +logs::channel sys_lwcond("sys_lwcond", logs::level::notice); extern u64 get_system_time(); @@ -29,8 +30,8 @@ void lv2_lwcond_t::notify(lv2_lock_t, cpu_thread* thread, const std::shared_ptr< mutex->signaled--; } - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } s32 _sys_lwcond_create(vm::ptr<u32> lwcond_id, u32 lwmutex_id, vm::ptr<sys_lwcond_t> control, u64 name, u32 arg5) diff --git a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp index 479030acf5..9178bda26d 100644 --- a/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_lwmutex.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_lwmutex.h" -LOG_CHANNEL(sys_lwmutex); +logs::channel sys_lwmutex("sys_lwmutex", logs::level::notice); extern u64 get_system_time(); @@ -22,8 +21,8 @@ void lv2_lwmutex_t::unlock(lv2_lock_t) if (sq.size()) { auto& thread = sq.front(); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); sq.pop_front(); } diff --git a/rpcs3/Emu/Cell/lv2/sys_memory.cpp b/rpcs3/Emu/Cell/lv2/sys_memory.cpp index 47a7fc79cc..ac850638f4 100644 --- a/rpcs3/Emu/Cell/lv2/sys_memory.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_memory.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,7 +6,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_memory.h" -LOG_CHANNEL(sys_memory); +logs::channel sys_memory("sys_memory", logs::level::notice); s32 sys_memory_allocate(u32 size, u64 flags, vm::ptr<u32> alloc_addr) { @@ -150,28 +149,27 @@ s32 sys_memory_free(u32 addr) const auto area = vm::get(vm::user_space); // Check all memory containers - for (auto& ct : idm::get_all<lv2_memory_container_t>()) + const auto ct = idm::select<lv2_memory_container_t>([&](u32, lv2_memory_container_t& ct) { - auto found = ct->allocs.find(addr); + return ct.allocs.count(addr) != 0; + }); - if (found != ct->allocs.end()) + if (ct) + { + const u32 size = ct->allocs.at(addr); + + if (!area->dealloc(addr)) { - const u32 size = found->second; - - if (!area->dealloc(addr)) - { - throw EXCEPTION("Memory not deallocated (cid=0x%x, addr=0x%x, size=0x%x)", ct->id, addr, size); - } - - // Return memory - ct->used -= size; - ct->allocs.erase(found); - - // Fix "physical" memory - area->used += size; - - return CELL_OK; + throw EXCEPTION("Memory not deallocated (cid=0x%x, addr=0x%x, size=0x%x)", ct->id, addr, size); } + + ct->allocs.erase(addr); + + // Return "memory" + ct->used -= size; + area->used += size; + + return CELL_OK; } if (!area->dealloc(addr)) @@ -205,10 +203,10 @@ s32 sys_memory_get_user_memory_size(vm::ptr<sys_memory_info_t> mem_info) u32 reserved = 0; // Check all memory containers - for (auto& ct : idm::get_all<lv2_memory_container_t>()) + idm::select<lv2_memory_container_t>([&](u32, lv2_memory_container_t& ct) { - reserved += ct->size; - } + reserved += ct.size; + }); const auto area = vm::get(vm::user_space); @@ -236,10 +234,10 @@ s32 sys_memory_container_create(vm::ptr<u32> cid, u32 size) u32 reserved = 0; // Check all memory containers - for (auto& ct : idm::get_all<lv2_memory_container_t>()) + idm::select<lv2_memory_container_t>([&](u32, lv2_memory_container_t& ct) { - reserved += ct->size; - } + reserved += ct.size; + }); const auto area = vm::get(vm::user_space); diff --git a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp index c8e70246cd..12d9218ccd 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mmapper.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -7,7 +6,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_mmapper.h" -LOG_CHANNEL(sys_mmapper); +logs::channel sys_mmapper("sys_mmapper", logs::level::notice); s32 sys_mmapper_allocate_address(u64 size, u64 flags, u64 alignment, vm::ptr<u32> alloc_addr) { @@ -334,24 +333,26 @@ s32 sys_mmapper_unmap_memory(u32 addr, vm::ptr<u32> mem_id) return CELL_EINVAL; } - for (auto& mem : idm::get_all<lv2_memory_t>()) + const auto mem = idm::select<lv2_memory_t>([&](u32, lv2_memory_t& mem) { - if (mem->addr == addr) - { - if (!area->dealloc(addr)) - { - throw EXCEPTION("Deallocation failed (mem_id=0x%x, addr=0x%x)", mem->id, addr); - } + return mem.addr == addr; + }); - mem->addr = 0; - - *mem_id = mem->id; - - return CELL_OK; - } + if (!mem) + { + return CELL_EINVAL; } - return CELL_EINVAL; + if (!area->dealloc(addr)) + { + throw EXCEPTION("Deallocation failed (mem_id=0x%x, addr=0x%x)", mem->id, addr); + } + + mem->addr = 0; + + *mem_id = mem->id; + + return CELL_OK; } s32 sys_mmapper_enable_page_fault_notification(u32 addr, u32 eq) diff --git a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp index 8e32dfb99e..fe0687cf67 100644 --- a/rpcs3/Emu/Cell/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_mutex.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_mutex.h" -LOG_CHANNEL(sys_mutex); +logs::channel sys_mutex("sys_mutex", logs::level::notice); extern u64 get_system_time(); @@ -21,8 +20,8 @@ void lv2_mutex_t::unlock(lv2_lock_t) // pick new owner; protocol is ignored in current implementation owner = std::static_pointer_cast<cpu_thread>(sq.front()->shared_from_this()); - ASSERT(!owner->state.test_and_set(cpu_state::signal)); - owner->notify(); + VERIFY(!owner->state.test_and_set(cpu_state::signal)); + (*owner)->notify(); } } diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp index a77a242c23..d269c71245 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,9 @@ #include "Emu/Cell/PPUThread.h" #include "sys_ppu_thread.h" -LOG_CHANNEL(sys_ppu_thread); +#include <thread> + +logs::channel sys_ppu_thread("sys_ppu_thread", logs::level::notice); void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) { @@ -29,6 +30,7 @@ void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode) //} ppu.state += cpu_state::exit; + //ppu.handle_interrupt(); // Delete detached thread if (!ppu.is_joinable) @@ -73,6 +75,8 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr<u64> vptr) return CELL_EDEADLK; } + ppu.sleep(); + // mark joining thread->is_joining = true; @@ -81,9 +85,11 @@ s32 sys_ppu_thread_join(PPUThread& ppu, u32 thread_id, vm::ptr<u64> vptr) { CHECK_EMU_STATUS; - get_current_thread_cv().wait_for(lv2_lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lv2_lock, 1ms); } + ppu.awake(); + // get exit status from the register if (vptr) *vptr = thread->GPR[3]; @@ -219,28 +225,6 @@ s32 sys_ppu_thread_restart(u32 thread_id) return CELL_OK; } -u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function<void(PPUThread&)> task) -{ - const auto ppu = idm::make_ptr<PPUThread>(name); - - ppu->prio = prio; - ppu->stack_size = stacksize; - ppu->custom_task = std::move(task); - ppu->cpu_init(); - - if (entry) - { - ppu->PC = vm::read32(entry); - ppu->GPR[2] = vm::read32(entry + 4); // rtoc - } - - ppu->GPR[3] = arg; - ppu->state -= cpu_state::stop; - ppu->lock_notify(); - - return ppu->id; -} - s32 _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::cptr<char> threadname) { sys_ppu_thread.warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", @@ -267,13 +251,14 @@ s32 _sys_ppu_thread_create(vm::ptr<u64> thread_id, vm::ptr<ppu_thread_param_t> p ppu->stack_size = std::max<u32>(stacksize, 0x4000); ppu->cpu_init(); - ppu->PC = vm::read32(param->entry); + ppu->pc = vm::read32(param->entry); ppu->GPR[2] = vm::read32(param->entry + 4); // rtoc ppu->GPR[3] = arg; ppu->GPR[4] = unk; // actually unknown ppu->GPR[13] = param->tls; ppu->is_joinable = is_joinable; + //ppu->state += cpu_state::interrupt; *thread_id = ppu->id; @@ -294,7 +279,7 @@ s32 sys_ppu_thread_start(u32 thread_id) } thread->state -= cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); return CELL_OK; } diff --git a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h index 8a103ae7bf..eefd4d047b 100644 --- a/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/Cell/lv2/sys_ppu_thread.h @@ -41,9 +41,6 @@ enum : u32 PPU_THREAD_STATUS_UNKNOWN, }; -// Aux -u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, const std::string& name, std::function<void(PPUThread&)> task = nullptr); - // SysCalls void _sys_ppu_thread_exit(PPUThread& ppu, u64 errorcode); void sys_ppu_thread_yield(); diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 8291849120..f1dcde9162 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -22,7 +21,9 @@ #include "sys_fs.h" #include "sys_process.h" -LOG_CHANNEL(sys_process); +#include <thread> + +logs::channel sys_process("sys_process", logs::level::notice); s32 process_getpid() { @@ -61,7 +62,7 @@ s32 sys_process_exit(s32 status) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } return CELL_OK; @@ -88,7 +89,7 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr<u32> nump) case SYS_LWMUTEX_OBJECT: *nump = idm::get_count<lv2_lwmutex_t>(); break; case SYS_TIMER_OBJECT: *nump = idm::get_count<lv2_timer_t>(); break; case SYS_SEMAPHORE_OBJECT: *nump = idm::get_count<lv2_sema_t>(); break; - case SYS_FS_FD_OBJECT: throw EXCEPTION("SYS_FS_FD_OBJECT"); + case SYS_FS_FD_OBJECT: *nump = idm::get_count<lv2_fs_object_t>(); break; case SYS_LWCOND_OBJECT: *nump = idm::get_count<lv2_lwcond_t>(); break; case SYS_EVENT_FLAG_OBJECT: *nump = idm::get_count<lv2_event_flag_t>(); break; @@ -101,6 +102,17 @@ s32 sys_process_get_number_of_object(u32 object, vm::ptr<u32> nump) return CELL_OK; } +#include <set> + +template<typename T> +void idm_get_set(std::set<u32>& out) +{ + idm::select<T>([&](u32 id, T&) + { + out.emplace(id); + }); +} + s32 sys_process_get_id(u32 object, vm::ptr<u32> buffer, u32 size, vm::ptr<u32> set_size) { sys_process.error("sys_process_get_id(object=0x%x, buffer=*0x%x, size=%d, set_size=*0x%x)", object, buffer, size, set_size); @@ -109,24 +121,24 @@ s32 sys_process_get_id(u32 object, vm::ptr<u32> buffer, u32 size, vm::ptr<u32> s switch (object) { - case SYS_MEM_OBJECT: objects = idm::get_set<lv2_memory_t>(); break; - case SYS_MUTEX_OBJECT: objects = idm::get_set<lv2_mutex_t>(); break; - case SYS_COND_OBJECT: objects = idm::get_set<lv2_cond_t>(); break; - case SYS_RWLOCK_OBJECT: objects = idm::get_set<lv2_rwlock_t>(); break; - case SYS_INTR_TAG_OBJECT: objects = idm::get_set<lv2_int_tag_t>(); break; - case SYS_INTR_SERVICE_HANDLE_OBJECT: objects = idm::get_set<lv2_int_serv_t>(); break; - case SYS_EVENT_QUEUE_OBJECT: objects = idm::get_set<lv2_event_queue_t>(); break; - case SYS_EVENT_PORT_OBJECT: objects = idm::get_set<lv2_event_port_t>(); break; + case SYS_MEM_OBJECT: idm_get_set<lv2_memory_t>(objects); break; + case SYS_MUTEX_OBJECT: idm_get_set<lv2_mutex_t>(objects); break; + case SYS_COND_OBJECT: idm_get_set<lv2_cond_t>(objects); break; + case SYS_RWLOCK_OBJECT: idm_get_set<lv2_rwlock_t>(objects); break; + case SYS_INTR_TAG_OBJECT: idm_get_set<lv2_int_tag_t>(objects); break; + case SYS_INTR_SERVICE_HANDLE_OBJECT: idm_get_set<lv2_int_serv_t>(objects); break; + case SYS_EVENT_QUEUE_OBJECT: idm_get_set<lv2_event_queue_t>(objects); break; + case SYS_EVENT_PORT_OBJECT: idm_get_set<lv2_event_port_t>(objects); break; case SYS_TRACE_OBJECT: throw EXCEPTION("SYS_TRACE_OBJECT"); case SYS_SPUIMAGE_OBJECT: throw EXCEPTION("SYS_SPUIMAGE_OBJECT"); - case SYS_PRX_OBJECT: objects = idm::get_set<lv2_prx_t>(); break; + case SYS_PRX_OBJECT: idm_get_set<lv2_prx_t>(objects); break; case SYS_SPUPORT_OBJECT: throw EXCEPTION("SYS_SPUPORT_OBJECT"); - case SYS_LWMUTEX_OBJECT: objects = idm::get_set<lv2_lwmutex_t>(); break; - case SYS_TIMER_OBJECT: objects = idm::get_set<lv2_timer_t>(); break; - case SYS_SEMAPHORE_OBJECT: objects = idm::get_set<lv2_sema_t>(); break; - case SYS_FS_FD_OBJECT: throw EXCEPTION("SYS_FS_FD_OBJECT"); - case SYS_LWCOND_OBJECT: objects = idm::get_set<lv2_lwcond_t>(); break; - case SYS_EVENT_FLAG_OBJECT: objects = idm::get_set<lv2_event_flag_t>(); break; + case SYS_LWMUTEX_OBJECT: idm_get_set<lv2_lwmutex_t>(objects); break; + case SYS_TIMER_OBJECT: idm_get_set<lv2_timer_t>(objects); break; + case SYS_SEMAPHORE_OBJECT: idm_get_set<lv2_sema_t>(objects); break; + case SYS_FS_FD_OBJECT: idm_get_set<lv2_fs_object_t>(objects); break; + case SYS_LWCOND_OBJECT: idm_get_set<lv2_lwcond_t>(objects); break; + case SYS_EVENT_FLAG_OBJECT: idm_get_set<lv2_event_flag_t>(objects); break; default: { diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 99ec5b9ac5..a7cf11a62c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,7 +8,7 @@ #include "Emu/Cell/ErrorCodes.h" #include "sys_prx.h" -LOG_CHANNEL(sys_prx); +logs::channel sys_prx("sys_prx", logs::level::notice); s32 prx_load_module(std::string path, u64 flags, vm::ptr<sys_prx_load_module_option_t> pOpt) { diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index 5d4d8ee83d..df512caf7a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_rsx.h" -LOG_CHANNEL(sys_rsx); +logs::channel sys_rsx("sys_rsx", logs::level::notice); s32 sys_rsx_device_open() { diff --git a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp index 351d9ca7bb..89c43c48f5 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rwlock.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_rwlock.h" -LOG_CHANNEL(sys_rwlock); +logs::channel sys_rwlock("sys_rwlock", logs::level::notice); extern u64 get_system_time(); @@ -19,8 +18,8 @@ void lv2_rwlock_t::notify_all(lv2_lock_t) { writer = std::static_pointer_cast<cpu_thread>(wsq.front()->shared_from_this()); - ASSERT(!writer->state.test_and_set(cpu_state::signal)); - writer->notify(); + VERIFY(!writer->state.test_and_set(cpu_state::signal)); + (*writer)->notify(); return wsq.pop_front(); } @@ -32,8 +31,8 @@ void lv2_rwlock_t::notify_all(lv2_lock_t) for (auto& thread : rsq) { - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); } return rsq.clear(); diff --git a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp index ec49e8c24d..c22bfa8a17 100644 --- a/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_semaphore.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "Emu/Cell/PPUThread.h" #include "sys_semaphore.h" -LOG_CHANNEL(sys_semaphore); +logs::channel sys_semaphore("sys_semaphore", logs::level::notice); extern u64 get_system_time(); @@ -174,8 +173,8 @@ s32 sys_semaphore_post(u32 sem_id, s32 count) count--; auto& thread = sem->sq.front(); - ASSERT(!thread->state.test_and_set(cpu_state::signal)); - thread->notify(); + VERIFY(!thread->state.test_and_set(cpu_state::signal)); + (*thread)->notify(); sem->sq.pop_front(); } diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index cdccda8e14..5ffa71ca81 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -12,7 +11,7 @@ #include "sys_event.h" #include "sys_spu.h" -LOG_CHANNEL(sys_spu); +logs::channel sys_spu("sys_spu", logs::level::notice); void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr) { @@ -20,7 +19,7 @@ void LoadSpuImage(const fs::file& stream, u32& spu_ep, u32 addr) if (loader != elf_error::ok) { - throw fmt::exception("Failed to load SPU image: %s" HERE, bijective_find<elf_error>(loader, "???")); + throw fmt::exception("Failed to load SPU image: %s" HERE, loader.get_error()); } for (const auto& prog : loader.progs) @@ -323,7 +322,7 @@ s32 sys_spu_thread_group_start(u32 id) if (thread) { thread->state -= cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -421,7 +420,7 @@ s32 sys_spu_thread_group_resume(u32 id) if (thread) { thread->state -= cpu_state::suspend; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -504,7 +503,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) if (thread) { thread->state += cpu_state::stop; - thread->lock_notify(); + (*thread)->lock_notify(); } } @@ -563,7 +562,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr<u32> cause, vm::ptr<u32> status) CHECK_EMU_STATUS; - group->cv.wait_for(lv2_lock, std::chrono::milliseconds(1)); + group->cv.wait_for(lv2_lock, 1ms); } switch (group->join_state & ~SPU_TGJSF_IS_JOINING) diff --git a/rpcs3/Emu/Cell/lv2/sys_sync.h b/rpcs3/Emu/Cell/lv2/sys_sync.h index e96c05f9f8..dbe76cf817 100644 --- a/rpcs3/Emu/Cell/lv2/sys_sync.h +++ b/rpcs3/Emu/Cell/lv2/sys_sync.h @@ -1,6 +1,8 @@ #pragma once #include "Utilities/SleepQueue.h" +#include <mutex> +#include <condition_variable> namespace vm { using namespace ps3; } @@ -43,7 +45,6 @@ enum SYS_SYNC_NOT_ADAPTIVE = 0x2000, }; -extern std::mutex& get_current_thread_mutex(); extern std::condition_variable& get_current_thread_cv(); // Simple class for global mutex to pass unique_lock and check it @@ -56,8 +57,8 @@ struct lv2_lock_t lv2_lock_t(type& lv2_lock) : ref(lv2_lock) { - Expects(ref.owns_lock()); - Expects(ref.mutex() == &mutex); + EXPECTS(ref.owns_lock()); + EXPECTS(ref.mutex() == &mutex); } operator type&() const diff --git a/rpcs3/Emu/Cell/lv2/sys_time.cpp b/rpcs3/Emu/Cell/lv2/sys_time.cpp index 39f4b1a156..e9a60295de 100644 --- a/rpcs3/Emu/Cell/lv2/sys_time.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_time.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -45,7 +44,7 @@ const g_time_aux_info = []() -> time_aux_info_t // initialize time-related value #endif -LOG_CHANNEL(sys_time); +logs::channel sys_time("sys_time", logs::level::notice); static const u64 g_timebase_freq = /*79800000*/ 80000000; // 80 Mhz diff --git a/rpcs3/Emu/Cell/lv2/sys_timer.cpp b/rpcs3/Emu/Cell/lv2/sys_timer.cpp index 5944157ad2..d4edeea141 100644 --- a/rpcs3/Emu/Cell/lv2/sys_timer.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_timer.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -9,10 +8,14 @@ #include "sys_process.h" #include "sys_timer.h" -LOG_CHANNEL(sys_timer); +#include <thread> + +logs::channel sys_timer("sys_timer", logs::level::notice); extern u64 get_system_time(); +extern std::mutex& get_current_thread_mutex(); + void lv2_timer_t::on_task() { std::unique_lock<std::mutex> lock(get_current_thread_mutex()); @@ -51,7 +54,7 @@ void lv2_timer_t::on_task() continue; } - get_current_thread_cv().wait_for(lock, std::chrono::milliseconds(1)); + get_current_thread_cv().wait_for(lock, 1ms); } } @@ -64,7 +67,7 @@ void lv2_timer_t::on_stop() { // Signal thread using invalid state and join state = -1; - lock_notify(); + (*this)->lock_notify(); named_thread::on_stop(); } @@ -170,7 +173,7 @@ s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) timer->period = period; timer->state = SYS_TIMER_STATE_RUN; - timer->lock_notify(); + (*timer)->lock_notify(); return CELL_OK; } @@ -244,6 +247,8 @@ s32 sys_timer_disconnect_event_queue(u32 timer_id) return CELL_OK; } +#include <thread> + s32 sys_timer_sleep(u32 sleep_time) { sys_timer.trace("sys_timer_sleep(sleep_time=%d)", sleep_time); @@ -258,7 +263,7 @@ s32 sys_timer_sleep(u32 sleep_time) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } if (useconds > passed) @@ -281,7 +286,7 @@ s32 sys_timer_usleep(const u64 sleep_time) { CHECK_EMU_STATUS; - std::this_thread::sleep_for(std::chrono::milliseconds(1)); + std::this_thread::sleep_for(1ms); } if (sleep_time > passed) diff --git a/rpcs3/Emu/Cell/lv2/sys_trace.cpp b/rpcs3/Emu/Cell/lv2/sys_trace.cpp index 78a10eb063..bf5fc20c61 100644 --- a/rpcs3/Emu/Cell/lv2/sys_trace.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_trace.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_trace.h" -LOG_CHANNEL(sys_trace); +logs::channel sys_trace("sys_trace", logs::level::notice); s32 sys_trace_create() { diff --git a/rpcs3/Emu/Cell/lv2/sys_tty.cpp b/rpcs3/Emu/Cell/lv2/sys_tty.cpp index c91ded14f4..4a9b62ca72 100644 --- a/rpcs3/Emu/Cell/lv2/sys_tty.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_tty.cpp @@ -1,12 +1,11 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/Cell/ErrorCodes.h" #include "sys_tty.h" -LOG_CHANNEL(sys_tty); +logs::channel sys_tty("sys_tty", logs::level::notice); extern fs::file g_tty; diff --git a/rpcs3/Emu/Cell/lv2/sys_vm.cpp b/rpcs3/Emu/Cell/lv2/sys_vm.cpp index 22492efb6e..8c5ec0613c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_vm.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_vm.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Utilities/Config.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/IdManager.h" @@ -8,7 +7,7 @@ #include "sys_memory.h" #include "sys_vm.h" -LOG_CHANNEL(sys_vm); +logs::channel sys_vm("sys_vm", logs::level::notice); s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, vm::ptr<u32> addr) {