#pragma once #include "Emu/Cell/SPUOpcodes.h" class SPUThread; // Type of the runtime functions generated by SPU recompiler using spu_jit_func_t = u32(*)(SPUThread* _spu, be_t* _ls); // SPU instruction classification namespace namespace spu_itype { enum spu_itype_t : u32 { UNK = 0, STOP, LNOP, SYNC, DSYNC, MFSPR, RDCH, RCHCNT, SF, OR, BG, SFH, NOR, ABSDB, ROT, ROTM, ROTMA, SHL, ROTH, ROTHM, ROTMAH, SHLH, ROTI, ROTMI, ROTMAI, SHLI, ROTHI, ROTHMI, ROTMAHI, SHLHI, A, AND, CG, AH, NAND, AVGB, MTSPR, WRCH, BIZ, BINZ, BIHZ, BIHNZ, STOPD, STQX, BI, BISL, IRET, BISLED, HBR, GB, GBH, GBB, FSM, FSMH, FSMB, FREST, FRSQEST, LQX, ROTQBYBI, ROTQMBYBI, SHLQBYBI, CBX, CHX, CWX, CDX, ROTQBI, ROTQMBI, SHLQBI, ROTQBY, ROTQMBY, SHLQBY, ORX, CBD, CHD, CWD, CDD, ROTQBII, ROTQMBII, SHLQBII, ROTQBYI, ROTQMBYI, SHLQBYI, NOP, CGT, XOR, CGTH, EQV, CGTB, SUMB, HGT, CLZ, XSWD, XSHW, CNTB, XSBH, CLGT, ANDC, FCGT, DFCGT, FA, FS, FM, CLGTH, ORC, FCMGT, DFCMGT, DFA, DFS, DFM, CLGTB, HLGT, DFMA, DFMS, DFNMS, DFNMA, CEQ, MPYHHU, ADDX, SFX, CGX, BGX, MPYHHA, MPYHHAU, FSCRRD, FESD, FRDS, FSCRWR, DFTSV, FCEQ, DFCEQ, MPY, MPYH, MPYHH, MPYS, CEQH, FCMEQ, DFCMEQ, MPYU, CEQB, FI, HEQ, CFLTS, CFLTU, CSFLT, CUFLT, BRZ, STQA, BRNZ, BRHZ, BRHNZ, STQR, BRA, LQA, BRASL, BR, FSMBI, BRSL, LQR, IL, ILHU, ILH, IOHL, ORI, ORHI, ORBI, SFI, SFHI, ANDI, ANDHI, ANDBI, AI, AHI, STQD, LQD, XORI, XORHI, XORBI, CGTI, CGTHI, CGTBI, HGTI, CLGTI, CLGTHI, CLGTBI, HLGTI, MPYI, MPYUI, CEQI, CEQHI, CEQBI, HEQI, HBRA, HBRR, ILA, SELB, SHUFB, MPYA, FNMS, FMA, FMS, }; } using spu_itype::spu_itype_t; // SPU Instruction Classification table extern const spu_opcode_table_t g_spu_itype; // SPU basic function information structure struct spu_function_t { // entry point (LS address) const u32 addr; // function size (in bytes) const u32 size; // function contents (binary copy) std::vector> data; // basic blocks (start addresses) std::set blocks; // functions possibly called by this function (may not be available) std::set adjacent; // jump table values (start addresses) std::set jtable; // whether ila $SP,* instruction found bool does_reset_stack; // pointer to the compiled function spu_jit_func_t compiled = nullptr; spu_function_t(u32 addr, u32 size) : addr(addr) , size(size) { } }; // SPU Function Database (must be global or PS3 process-local) class SPUDatabase final { std::mutex m_mutex; // All registered functions (uses addr and first instruction as a key) std::unordered_multimap> m_db; // For internal use std::shared_ptr find(const be_t* data, u64 key, u32 max_size); public: SPUDatabase(); ~SPUDatabase(); // Try to retrieve SPU function information std::shared_ptr analyse(const be_t* ls, u32 entry, u32 limit = 0x40000); };