Created
July 7, 2016 09:37
-
-
Save vadixidav/7664b4b3111451f8ed82899e49f58c1b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include "../../../Utilities/BitField.h" | |
| 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 | |
| }; | |
| 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; | |
| } | |
| static u32 spu_decode(u32 inst) | |
| { | |
| return inst >> 21; | |
| } | |
| template<typename D, typename T> | |
| struct instruction_info | |
| { | |
| u32 magn; // Count = 2 ^ magn | |
| u32 value; | |
| T pointer; | |
| }; | |
| // SPU decoder object. D provides functions. T is function pointer type returned. | |
| template<typename D, typename T = decltype(&D::UNK)> | |
| class spu_decoder | |
| { | |
| // Fast lookup table | |
| std::array<T, 2048> m_table; | |
| struct instruction_info | |
| { | |
| u32 magn; // Count = 2 ^ magn | |
| u32 value; | |
| T pointer; | |
| }; | |
| constexpr static std::array<instruction_info, 199> instructions = {{ | |
| { 0, 0x1, &D::LNOP }, | |
| { 0, 0x2, &D::SYNC }, | |
| { 0, 0x3, &D::DSYNC }, | |
| { 0, 0xc, &D::MFSPR }, | |
| { 0, 0xd, &D::RDCH }, | |
| { 0, 0xf, &D::RCHCNT }, | |
| { 0, 0x40, &D::SF }, | |
| { 0, 0x41, &D::OR }, | |
| { 0, 0x42, &D::BG }, | |
| { 0, 0x48, &D::SFH }, | |
| { 0, 0x49, &D::NOR }, | |
| { 0, 0x53, &D::ABSDB }, | |
| { 0, 0x58, &D::ROT }, | |
| { 0, 0x59, &D::ROTM }, | |
| { 0, 0x5a, &D::ROTMA }, | |
| { 0, 0x5b, &D::SHL }, | |
| { 0, 0x5c, &D::ROTH }, | |
| { 0, 0x5d, &D::ROTHM }, | |
| { 0, 0x5e, &D::ROTMAH }, | |
| { 0, 0x5f, &D::SHLH }, | |
| { 0, 0x78, &D::ROTI }, | |
| { 0, 0x79, &D::ROTMI }, | |
| { 0, 0x7a, &D::ROTMAI }, | |
| { 0, 0x7b, &D::SHLI }, | |
| { 0, 0x7c, &D::ROTHI }, | |
| { 0, 0x7d, &D::ROTHMI }, | |
| { 0, 0x7e, &D::ROTMAHI }, | |
| { 0, 0x7f, &D::SHLHI }, | |
| { 0, 0xc0, &D::A }, | |
| { 0, 0xc1, &D::AND }, | |
| { 0, 0xc2, &D::CG }, | |
| { 0, 0xc8, &D::AH }, | |
| { 0, 0xc9, &D::NAND }, | |
| { 0, 0xd3, &D::AVGB }, | |
| { 0, 0x10c, &D::MTSPR }, | |
| { 0, 0x10d, &D::WRCH }, | |
| { 0, 0x128, &D::BIZ }, | |
| { 0, 0x129, &D::BINZ }, | |
| { 0, 0x12a, &D::BIHZ }, | |
| { 0, 0x12b, &D::BIHNZ }, | |
| { 0, 0x140, &D::STOPD }, | |
| { 0, 0x144, &D::STQX }, | |
| { 0, 0x1a8, &D::BI }, | |
| { 0, 0x1a9, &D::BISL }, | |
| { 0, 0x1aa, &D::IRET }, | |
| { 0, 0x1ab, &D::BISLED }, | |
| { 0, 0x1ac, &D::HBR }, | |
| { 0, 0x1b0, &D::GB }, | |
| { 0, 0x1b1, &D::GBH }, | |
| { 0, 0x1b2, &D::GBB }, | |
| { 0, 0x1b4, &D::FSM }, | |
| { 0, 0x1b5, &D::FSMH }, | |
| { 0, 0x1b6, &D::FSMB }, | |
| { 0, 0x1b8, &D::FREST }, | |
| { 0, 0x1b9, &D::FRSQEST }, | |
| { 0, 0x1c4, &D::LQX }, | |
| { 0, 0x1cc, &D::ROTQBYBI }, | |
| { 0, 0x1cd, &D::ROTQMBYBI }, | |
| { 0, 0x1cf, &D::SHLQBYBI }, | |
| { 0, 0x1d4, &D::CBX }, | |
| { 0, 0x1d5, &D::CHX }, | |
| { 0, 0x1d6, &D::CWX }, | |
| { 0, 0x1d7, &D::CDX }, | |
| { 0, 0x1d8, &D::ROTQBI }, | |
| { 0, 0x1d9, &D::ROTQMBI }, | |
| { 0, 0x1db, &D::SHLQBI }, | |
| { 0, 0x1dc, &D::ROTQBY }, | |
| { 0, 0x1dd, &D::ROTQMBY }, | |
| { 0, 0x1df, &D::SHLQBY }, | |
| { 0, 0x1f0, &D::ORX }, | |
| { 0, 0x1f4, &D::CBD }, | |
| { 0, 0x1f5, &D::CHD }, | |
| { 0, 0x1f6, &D::CWD }, | |
| { 0, 0x1f7, &D::CDD }, | |
| { 0, 0x1f8, &D::ROTQBII }, | |
| { 0, 0x1f9, &D::ROTQMBII }, | |
| { 0, 0x1fb, &D::SHLQBII }, | |
| { 0, 0x1fc, &D::ROTQBYI }, | |
| { 0, 0x1fd, &D::ROTQMBYI }, | |
| { 0, 0x1ff, &D::SHLQBYI }, | |
| { 0, 0x201, &D::NOP }, | |
| { 0, 0x240, &D::CGT }, | |
| { 0, 0x241, &D::XOR }, | |
| { 0, 0x248, &D::CGTH }, | |
| { 0, 0x249, &D::EQV }, | |
| { 0, 0x250, &D::CGTB }, | |
| { 0, 0x253, &D::SUMB }, | |
| { 0, 0x258, &D::HGT }, | |
| { 0, 0x2a5, &D::CLZ }, | |
| { 0, 0x2a6, &D::XSWD }, | |
| { 0, 0x2ae, &D::XSHW }, | |
| { 0, 0x2b4, &D::CNTB }, | |
| { 0, 0x2b6, &D::XSBH }, | |
| { 0, 0x2c0, &D::CLGT }, | |
| { 0, 0x2c1, &D::ANDC }, | |
| { 0, 0x2c2, &D::FCGT }, | |
| { 0, 0x2c3, &D::DFCGT }, | |
| { 0, 0x2c4, &D::FA }, | |
| { 0, 0x2c5, &D::FS }, | |
| { 0, 0x2c6, &D::FM }, | |
| { 0, 0x2c8, &D::CLGTH }, | |
| { 0, 0x2c9, &D::ORC }, | |
| { 0, 0x2ca, &D::FCMGT }, | |
| { 0, 0x2cb, &D::DFCMGT }, | |
| { 0, 0x2cc, &D::DFA }, | |
| { 0, 0x2cd, &D::DFS }, | |
| { 0, 0x2ce, &D::DFM }, | |
| { 0, 0x2d0, &D::CLGTB }, | |
| { 0, 0x2d8, &D::HLGT }, | |
| { 0, 0x35c, &D::DFMA }, | |
| { 0, 0x35d, &D::DFMS }, | |
| { 0, 0x35e, &D::DFNMS }, | |
| { 0, 0x35f, &D::DFNMA }, | |
| { 0, 0x3c0, &D::CEQ }, | |
| { 0, 0x3ce, &D::MPYHHU }, | |
| { 0, 0x340, &D::ADDX }, | |
| { 0, 0x341, &D::SFX }, | |
| { 0, 0x342, &D::CGX }, | |
| { 0, 0x343, &D::BGX }, | |
| { 0, 0x346, &D::MPYHHA }, | |
| { 0, 0x34e, &D::MPYHHAU }, | |
| { 0, 0x398, &D::FSCRRD }, | |
| { 0, 0x3b8, &D::FESD }, | |
| { 0, 0x3b9, &D::FRDS }, | |
| { 0, 0x3ba, &D::FSCRWR }, | |
| { 0, 0x3bf, &D::DFTSV }, | |
| { 0, 0x3c2, &D::FCEQ }, | |
| { 0, 0x3c3, &D::DFCEQ }, | |
| { 0, 0x3c4, &D::MPY }, | |
| { 0, 0x3c5, &D::MPYH }, | |
| { 0, 0x3c6, &D::MPYHH }, | |
| { 0, 0x3c7, &D::MPYS }, | |
| { 0, 0x3c8, &D::CEQH }, | |
| { 0, 0x3ca, &D::FCMEQ }, | |
| { 0, 0x3cb, &D::DFCMEQ }, | |
| { 0, 0x3cc, &D::MPYU }, | |
| { 0, 0x3d0, &D::CEQB }, | |
| { 0, 0x3d4, &D::FI }, | |
| { 0, 0x3d8, &D::HEQ }, | |
| { 1, 0x1d8, &D::CFLTS }, | |
| { 1, 0x1d9, &D::CFLTU }, | |
| { 1, 0x1da, &D::CSFLT }, | |
| { 1, 0x1db, &D::CUFLT }, | |
| { 2, 0x40, &D::BRZ }, | |
| { 2, 0x41, &D::STQA }, | |
| { 2, 0x42, &D::BRNZ }, | |
| { 2, 0x44, &D::BRHZ }, | |
| { 2, 0x46, &D::BRHNZ }, | |
| { 2, 0x47, &D::STQR }, | |
| { 2, 0x60, &D::BRA }, | |
| { 2, 0x61, &D::LQA }, | |
| { 2, 0x62, &D::BRASL }, | |
| { 2, 0x64, &D::BR }, | |
| { 2, 0x65, &D::FSMBI }, | |
| { 2, 0x66, &D::BRSL }, | |
| { 2, 0x67, &D::LQR }, | |
| { 2, 0x81, &D::IL }, | |
| { 2, 0x82, &D::ILHU }, | |
| { 2, 0x83, &D::ILH }, | |
| { 2, 0xc1, &D::IOHL }, | |
| { 3, 0x4, &D::ORI }, | |
| { 3, 0x5, &D::ORHI }, | |
| { 3, 0x6, &D::ORBI }, | |
| { 3, 0xc, &D::SFI }, | |
| { 3, 0xd, &D::SFHI }, | |
| { 3, 0x14, &D::ANDI }, | |
| { 3, 0x15, &D::ANDHI }, | |
| { 3, 0x16, &D::ANDBI }, | |
| { 3, 0x1c, &D::AI }, | |
| { 3, 0x1d, &D::AHI }, | |
| { 3, 0x24, &D::STQD }, | |
| { 3, 0x34, &D::LQD }, | |
| { 3, 0x44, &D::XORI }, | |
| { 3, 0x45, &D::XORHI }, | |
| { 3, 0x46, &D::XORBI }, | |
| { 3, 0x4c, &D::CGTI }, | |
| { 3, 0x4d, &D::CGTHI }, | |
| { 3, 0x4e, &D::CGTBI }, | |
| { 3, 0x4f, &D::HGTI }, | |
| { 3, 0x5c, &D::CLGTI }, | |
| { 3, 0x5d, &D::CLGTHI }, | |
| { 3, 0x5e, &D::CLGTBI }, | |
| { 3, 0x5f, &D::HLGTI }, | |
| { 3, 0x74, &D::MPYI }, | |
| { 3, 0x75, &D::MPYUI }, | |
| { 3, 0x7c, &D::CEQI }, | |
| { 3, 0x7d, &D::CEQHI }, | |
| { 3, 0x7e, &D::CEQBI }, | |
| { 3, 0x7f, &D::HEQI }, | |
| { 4, 0x8, &D::HBRA }, | |
| { 4, 0x9, &D::HBRR }, | |
| { 4, 0x21, &D::ILA }, | |
| { 7, 0x8, &D::SELB }, | |
| { 7, 0xb, &D::SHUFB }, | |
| { 7, 0xc, &D::MPYA }, | |
| { 7, 0xd, &D::FNMS }, | |
| { 7, 0xe, &D::FMA }, | |
| { 7, 0xf, &D::FMS }, | |
| }}; | |
| public: | |
| spu_decoder() | |
| { | |
| m_table.fill(&D::UNK); | |
| for (auto& entry : instructions) | |
| { | |
| for (u32 i = 0; i < 1u << entry.magn; i++) | |
| { | |
| m_table[entry.value << entry.magn | i] = entry.pointer; | |
| } | |
| } | |
| } | |
| const std::array<T, 2048>& get_table() const | |
| { | |
| return m_table; | |
| } | |
| T decode(u32 inst) const | |
| { | |
| return m_table[spu_decode(inst)]; | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment