rpcs3/rpcs3/Emu/Cell/SPUOpcodes.h
Nekotekina a974ee009e vm::var improved, cleanup
Mostly vm::var initialization introduced.
Added vm::make_var function.
2015-10-14 18:17:37 +03:00

274 lines
6.8 KiB
C++

#pragma once
union spu_opcode_t
{
u32 opcode;
bf_t<u32, 0, 7> rt; // 25..31, for 3-op instructions
bf_t<u32, 0, 7> rc; // 25..31
bf_t<u32, 7, 7> ra; // 18..24
bf_t<u32, 14, 7> rb; // 11..17
bf_t<u32, 21, 7> rt4; // 4..10, for 4-op instructions
bf_t<u32, 18, 1> e; // 13, "enable interrupts" bit
bf_t<u32, 19, 1> d; // 12, "disable interrupts" bit
bf_t<u32, 20, 1> c; // 11, "C" bit for SYNC instruction
bf_t<s32, 23, 2> r0h; // 7..8, signed
bf_t<s32, 14, 2> roh; // 16..17, signed
bf_t<u32, 14, 7> i7; // 11..17
bf_t<s32, 14, 7> si7; // 11..17, signed
bf_t<u32, 14, 8> i8; // 10..17
bf_t<s32, 14, 10> si10; // 8..17, signed
bf_t<u32, 7, 16> i16; // 9..24
bf_t<s32, 7, 16> si16; // 9..24, signed
bf_t<u32, 7, 18> i18; // 7..24
};
#define DEFINE_SPU_OPCODES(ns) { \
{ 10, 0x0, ns STOP }, \
{ 10, 0x1, ns LNOP }, \
{ 10, 0x2, ns SYNC }, \
{ 10, 0x3, ns DSYNC }, \
{ 10, 0xc, ns MFSPR }, \
{ 10, 0xd, ns RDCH }, \
{ 10, 0xf, ns RCHCNT }, \
{ 10, 0x40, ns SF }, \
{ 10, 0x41, ns OR }, \
{ 10, 0x42, ns BG }, \
{ 10, 0x48, ns SFH }, \
{ 10, 0x49, ns NOR }, \
{ 10, 0x53, ns ABSDB }, \
{ 10, 0x58, ns ROT }, \
{ 10, 0x59, ns ROTM }, \
{ 10, 0x5a, ns ROTMA }, \
{ 10, 0x5b, ns SHL }, \
{ 10, 0x5c, ns ROTH }, \
{ 10, 0x5d, ns ROTHM }, \
{ 10, 0x5e, ns ROTMAH }, \
{ 10, 0x5f, ns SHLH }, \
{ 10, 0x78, ns ROTI }, \
{ 10, 0x79, ns ROTMI }, \
{ 10, 0x7a, ns ROTMAI }, \
{ 10, 0x7b, ns SHLI }, \
{ 10, 0x7c, ns ROTHI }, \
{ 10, 0x7d, ns ROTHMI }, \
{ 10, 0x7e, ns ROTMAHI }, \
{ 10, 0x7f, ns SHLHI }, \
{ 10, 0xc0, ns A }, \
{ 10, 0xc1, ns AND }, \
{ 10, 0xc2, ns CG }, \
{ 10, 0xc8, ns AH }, \
{ 10, 0xc9, ns NAND }, \
{ 10, 0xd3, ns AVGB }, \
{ 10, 0x10c, ns MTSPR }, \
{ 10, 0x10d, ns WRCH }, \
{ 10, 0x128, ns BIZ }, \
{ 10, 0x129, ns BINZ }, \
{ 10, 0x12a, ns BIHZ }, \
{ 10, 0x12b, ns BIHNZ }, \
{ 10, 0x140, ns STOPD }, \
{ 10, 0x144, ns STQX }, \
{ 10, 0x1a8, ns BI }, \
{ 10, 0x1a9, ns BISL }, \
{ 10, 0x1aa, ns IRET }, \
{ 10, 0x1ab, ns BISLED }, \
{ 10, 0x1ac, ns HBR }, \
{ 10, 0x1b0, ns GB }, \
{ 10, 0x1b1, ns GBH }, \
{ 10, 0x1b2, ns GBB }, \
{ 10, 0x1b4, ns FSM }, \
{ 10, 0x1b5, ns FSMH }, \
{ 10, 0x1b6, ns FSMB }, \
{ 10, 0x1b8, ns FREST }, \
{ 10, 0x1b9, ns FRSQEST }, \
{ 10, 0x1c4, ns LQX }, \
{ 10, 0x1cc, ns ROTQBYBI }, \
{ 10, 0x1cd, ns ROTQMBYBI }, \
{ 10, 0x1cf, ns SHLQBYBI }, \
{ 10, 0x1d4, ns CBX }, \
{ 10, 0x1d5, ns CHX }, \
{ 10, 0x1d6, ns CWX }, \
{ 10, 0x1d7, ns CDX }, \
{ 10, 0x1d8, ns ROTQBI }, \
{ 10, 0x1d9, ns ROTQMBI }, \
{ 10, 0x1db, ns SHLQBI }, \
{ 10, 0x1dc, ns ROTQBY }, \
{ 10, 0x1dd, ns ROTQMBY }, \
{ 10, 0x1df, ns SHLQBY }, \
{ 10, 0x1f0, ns ORX }, \
{ 10, 0x1f4, ns CBD }, \
{ 10, 0x1f5, ns CHD }, \
{ 10, 0x1f6, ns CWD }, \
{ 10, 0x1f7, ns CDD }, \
{ 10, 0x1f8, ns ROTQBII }, \
{ 10, 0x1f9, ns ROTQMBII }, \
{ 10, 0x1fb, ns SHLQBII }, \
{ 10, 0x1fc, ns ROTQBYI }, \
{ 10, 0x1fd, ns ROTQMBYI }, \
{ 10, 0x1ff, ns SHLQBYI }, \
{ 10, 0x201, ns NOP }, \
{ 10, 0x240, ns CGT }, \
{ 10, 0x241, ns XOR }, \
{ 10, 0x248, ns CGTH }, \
{ 10, 0x249, ns EQV }, \
{ 10, 0x250, ns CGTB }, \
{ 10, 0x253, ns SUMB }, \
{ 10, 0x258, ns HGT }, \
{ 10, 0x2a5, ns CLZ }, \
{ 10, 0x2a6, ns XSWD }, \
{ 10, 0x2ae, ns XSHW }, \
{ 10, 0x2b4, ns CNTB }, \
{ 10, 0x2b6, ns XSBH }, \
{ 10, 0x2c0, ns CLGT }, \
{ 10, 0x2c1, ns ANDC }, \
{ 10, 0x2c2, ns FCGT }, \
{ 10, 0x2c3, ns DFCGT }, \
{ 10, 0x2c4, ns FA }, \
{ 10, 0x2c5, ns FS }, \
{ 10, 0x2c6, ns FM }, \
{ 10, 0x2c8, ns CLGTH }, \
{ 10, 0x2c9, ns ORC }, \
{ 10, 0x2ca, ns FCMGT }, \
{ 10, 0x2cb, ns DFCMGT }, \
{ 10, 0x2cc, ns DFA }, \
{ 10, 0x2cd, ns DFS }, \
{ 10, 0x2ce, ns DFM }, \
{ 10, 0x2d0, ns CLGTB }, \
{ 10, 0x2d8, ns HLGT }, \
{ 10, 0x35c, ns DFMA }, \
{ 10, 0x35d, ns DFMS }, \
{ 10, 0x35e, ns DFNMS }, \
{ 10, 0x35f, ns DFNMA }, \
{ 10, 0x3c0, ns CEQ }, \
{ 10, 0x3ce, ns MPYHHU }, \
{ 10, 0x340, ns ADDX }, \
{ 10, 0x341, ns SFX }, \
{ 10, 0x342, ns CGX }, \
{ 10, 0x343, ns BGX }, \
{ 10, 0x346, ns MPYHHA }, \
{ 10, 0x34e, ns MPYHHAU }, \
{ 10, 0x398, ns FSCRRD }, \
{ 10, 0x3b8, ns FESD }, \
{ 10, 0x3b9, ns FRDS }, \
{ 10, 0x3ba, ns FSCRWR }, \
{ 10, 0x3bf, ns DFTSV }, \
{ 10, 0x3c2, ns FCEQ }, \
{ 10, 0x3c3, ns DFCEQ }, \
{ 10, 0x3c4, ns MPY }, \
{ 10, 0x3c5, ns MPYH }, \
{ 10, 0x3c6, ns MPYHH }, \
{ 10, 0x3c7, ns MPYS }, \
{ 10, 0x3c8, ns CEQH }, \
{ 10, 0x3ca, ns FCMEQ }, \
{ 10, 0x3cb, ns DFCMEQ }, \
{ 10, 0x3cc, ns MPYU }, \
{ 10, 0x3d0, ns CEQB }, \
{ 10, 0x3d4, ns FI }, \
{ 10, 0x3d8, ns HEQ }, \
{ 9, 0x1d8, ns CFLTS }, \
{ 9, 0x1d9, ns CFLTU }, \
{ 9, 0x1da, ns CSFLT }, \
{ 9, 0x1db, ns CUFLT }, \
{ 8, 0x40, ns BRZ }, \
{ 8, 0x41, ns STQA }, \
{ 8, 0x42, ns BRNZ }, \
{ 8, 0x44, ns BRHZ }, \
{ 8, 0x46, ns BRHNZ }, \
{ 8, 0x47, ns STQR }, \
{ 8, 0x60, ns BRA }, \
{ 8, 0x61, ns LQA }, \
{ 8, 0x62, ns BRASL }, \
{ 8, 0x64, ns BR }, \
{ 8, 0x65, ns FSMBI }, \
{ 8, 0x66, ns BRSL }, \
{ 8, 0x67, ns LQR }, \
{ 8, 0x81, ns IL }, \
{ 8, 0x82, ns ILHU }, \
{ 8, 0x83, ns ILH }, \
{ 8, 0xc1, ns IOHL }, \
{ 7, 0x4, ns ORI }, \
{ 7, 0x5, ns ORHI }, \
{ 7, 0x6, ns ORBI }, \
{ 7, 0xc, ns SFI }, \
{ 7, 0xd, ns SFHI }, \
{ 7, 0x14, ns ANDI }, \
{ 7, 0x15, ns ANDHI }, \
{ 7, 0x16, ns ANDBI }, \
{ 7, 0x1c, ns AI }, \
{ 7, 0x1d, ns AHI }, \
{ 7, 0x24, ns STQD }, \
{ 7, 0x34, ns LQD }, \
{ 7, 0x44, ns XORI }, \
{ 7, 0x45, ns XORHI }, \
{ 7, 0x46, ns XORBI }, \
{ 7, 0x4c, ns CGTI }, \
{ 7, 0x4d, ns CGTHI }, \
{ 7, 0x4e, ns CGTBI }, \
{ 7, 0x4f, ns HGTI }, \
{ 7, 0x5c, ns CLGTI }, \
{ 7, 0x5d, ns CLGTHI }, \
{ 7, 0x5e, ns CLGTBI }, \
{ 7, 0x5f, ns HLGTI }, \
{ 7, 0x74, ns MPYI }, \
{ 7, 0x75, ns MPYUI }, \
{ 7, 0x7c, ns CEQI }, \
{ 7, 0x7d, ns CEQHI }, \
{ 7, 0x7e, ns CEQBI }, \
{ 7, 0x7f, ns HEQI }, \
{ 6, 0x8, ns HBRA }, \
{ 6, 0x9, ns HBRR }, \
{ 6, 0x21, ns ILA }, \
{ 3, 0x8, ns SELB }, \
{ 3, 0xb, ns SHUFB }, \
{ 3, 0xc, ns MPYA }, \
{ 3, 0xd, ns FNMS }, \
{ 3, 0xe, ns FMA }, \
{ 3, 0xf, ns FMS }, \
}
template<typename T> class spu_opcode_table_t
{
std::array<T, 2048> m_data;
struct opcode_entry_t
{
u32 group;
u32 value;
T pointer;
};
public:
// opcode table initialization (TODO: optimize it a bit)
spu_opcode_table_t(std::initializer_list<opcode_entry_t> opcodes, T default_value = {})
{
for (u32 i = 0; i < 2048; i++)
{
m_data[i] = default_value;
for (auto& op : opcodes)
{
if (((i << 21) & (INT_MIN >> op.group)) == (op.value << (31 - op.group)))
{
m_data[i] = op.pointer;
break;
}
}
}
}
// access opcode table
T operator [](u32 opcode_data) const
{
// the whole decoding process is shifting opcode data
return m_data[opcode_data >> 21];
}
};
inline u32 spu_branch_target(u32 pc, u32 imm = 0)
{
return (pc + (imm << 2)) & 0x3fffc;
}
inline u32 spu_ls_target(u32 pc, u32 imm = 0)
{
return (pc + (imm << 2)) & 0x3fff0;
}