rpcsx/rpcs3/Emu/Cell/SPUAnalyser.h

277 lines
3.2 KiB
C
Raw Normal View History

#pragma once
#include "Emu/Cell/SPUOpcodes.h"
#include "Utilities/SharedMutex.h"
class SPUThread;
// Type of the runtime functions generated by SPU recompiler
using spu_jit_func_t = u32(*)(SPUThread* _spu, be_t<u32>* _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<spu_itype_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<be_t<u32>> data;
// basic blocks (start addresses)
std::set<u32> blocks;
// functions possibly called by this function (may not be available)
std::set<u32> adjacent;
// jump table values (start addresses)
std::set<u32> jtable;
2015-09-04 01:23:31 +02:00
// 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
{
2015-11-30 16:10:17 +01:00
shared_mutex m_mutex;
// All registered functions (uses addr and first instruction as a key)
std::unordered_multimap<u64, std::shared_ptr<spu_function_t>> m_db;
2015-09-04 01:23:31 +02:00
// For internal use
std::shared_ptr<spu_function_t> find(const be_t<u32>* data, u64 key, u32 max_size);
public:
SPUDatabase();
~SPUDatabase();
// Try to retrieve SPU function information
std::shared_ptr<spu_function_t> analyse(const be_t<u32>* ls, u32 entry, u32 limit = 0x40000);
};