#pragma once #include #include #include #include "Utilities/bit_set.h" #include "Utilities/BEType.h" #include "PPUOpcodes.h" // PPU Function Attributes enum class ppu_attr : u32 { known_addr, known_size, no_return, no_size, __bitset_enum_max }; // PPU Function Information struct ppu_function { u32 addr = 0; u32 toc = 0; u32 size = 0; bs_t attr{}; u32 stack_frame = 0; u32 trampoline = 0; std::map blocks; // Basic blocks: addr -> size std::set calls; // Set of called functions std::set callers; std::string name; // Function name }; // PPU Relocation Information struct ppu_reloc { u32 addr; u32 type; u64 data; // Operator for sorting bool operator <(const ppu_reloc& rhs) const { return addr < rhs.addr; } bool operator <(u32 rhs) const { return addr < rhs; } }; // PPU Segment Information struct ppu_segment { u32 addr; u32 size; u32 type; u32 flags; u32 filesz; }; // PPU Module Information struct ppu_module { uchar sha1[20]; std::string name; std::string path; std::string cache; std::vector relocs; std::vector segs; std::vector secs; std::vector funcs; // Copy info without functions void copy_part(const ppu_module& info) { std::memcpy(sha1, info.sha1, sizeof(sha1)); name = info.name; path = info.path; relocs = info.relocs; segs = info.segs; secs = info.secs; } void analyse(u32 lib_toc, u32 entry); void validate(u32 reloc); }; // Aux struct ppu_pattern { be_t opcode; be_t mask; ppu_pattern() = default; ppu_pattern(u32 op) : opcode(op) , mask(0xffffffff) { } ppu_pattern(u32 op, u32 ign) : opcode(op & ~ign) , mask(~ign) { } }; struct ppu_pattern_array { const ppu_pattern* ptr; std::size_t count; template constexpr ppu_pattern_array(const ppu_pattern(&array)[N]) : ptr(array) , count(N) { } constexpr const ppu_pattern* begin() const { return ptr; } constexpr const ppu_pattern* end() const { return ptr + count; } }; struct ppu_pattern_matrix { const ppu_pattern_array* ptr; std::size_t count; template constexpr ppu_pattern_matrix(const ppu_pattern_array(&array)[N]) : ptr(array) , count(N) { } constexpr const ppu_pattern_array* begin() const { return ptr; } constexpr const ppu_pattern_array* end() const { return ptr + count; } }; // PPU Instruction Type struct ppu_itype { enum type { UNK = 0, MFVSCR, MTVSCR, VADDCUW, VADDFP, VADDSBS, VADDSHS, VADDSWS, VADDUBM, VADDUBS, VADDUHM, VADDUHS, VADDUWM, VADDUWS, VAND, VANDC, VAVGSB, VAVGSH, VAVGSW, VAVGUB, VAVGUH, VAVGUW, VCFSX, VCFUX, VCMPBFP, VCMPEQFP, VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPGEFP, VCMPGTFP, VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTUB, VCMPGTUH, VCMPGTUW, VCTSXS, VCTUXS, VEXPTEFP, VLOGEFP, VMADDFP, VMAXFP, VMAXSB, VMAXSH, VMAXSW, VMAXUB, VMAXUH, VMAXUW, VMHADDSHS, VMHRADDSHS, VMINFP, VMINSB, VMINSH, VMINSW, VMINUB, VMINUH, VMINUW, VMLADDUHM, VMRGHB, VMRGHH, VMRGHW, VMRGLB, VMRGLH, VMRGLW, VMSUMMBM, VMSUMSHM, VMSUMSHS, VMSUMUBM, VMSUMUHM, VMSUMUHS, VMULESB, VMULESH, VMULEUB, VMULEUH, VMULOSB, VMULOSH, VMULOUB, VMULOUH, VNMSUBFP, VNOR, VOR, VPERM, VPKPX, VPKSHSS, VPKSHUS, VPKSWSS, VPKSWUS, VPKUHUM, VPKUHUS, VPKUWUM, VPKUWUS, VREFP, VRFIM, VRFIN, VRFIP, VRFIZ, VRLB, VRLH, VRLW, VRSQRTEFP, VSEL, VSL, VSLB, VSLDOI, VSLH, VSLO, VSLW, VSPLTB, VSPLTH, VSPLTISB, VSPLTISH, VSPLTISW, VSPLTW, VSR, VSRAB, VSRAH, VSRAW, VSRB, VSRH, VSRO, VSRW, VSUBCUW, VSUBFP, VSUBSBS, VSUBSHS, VSUBSWS, VSUBUBM, VSUBUBS, VSUBUHM, VSUBUHS, VSUBUWM, VSUBUWS, VSUMSWS, VSUM2SWS, VSUM4SBS, VSUM4SHS, VSUM4UBS, VUPKHPX, VUPKHSB, VUPKHSH, VUPKLPX, VUPKLSB, VUPKLSH, VXOR, TDI, TWI, MULLI, SUBFIC, CMPLI, CMPI, ADDIC, ADDI, ADDIS, BC, SC, B, MCRF, BCLR, CRNOR, CRANDC, ISYNC, CRXOR, CRNAND, CRAND, CREQV, CRORC, CROR, BCCTR, RLWIMI, RLWINM, RLWNM, ORI, ORIS, XORI, XORIS, ANDI, ANDIS, RLDICL, RLDICR, RLDIC, RLDIMI, RLDCL, RLDCR, CMP, TW, LVSL, LVEBX, SUBFC, ADDC, MULHDU, MULHWU, MFOCRF, LWARX, LDX, LWZX, SLW, CNTLZW, SLD, AND, CMPL, LVSR, LVEHX, SUBF, LDUX, DCBST, LWZUX, CNTLZD, ANDC, TD, LVEWX, MULHD, MULHW, LDARX, DCBF, LBZX, LVX, NEG, LBZUX, NOR, STVEBX, SUBFE, ADDE, MTOCRF, STDX, STWCX, STWX, STVEHX, STDUX, STWUX, STVEWX, SUBFZE, ADDZE, STDCX, STBX, STVX, SUBFME, MULLD, ADDME, MULLW, DCBTST, STBUX, ADD, DCBT, LHZX, EQV, ECIWX, LHZUX, XOR, MFSPR, LWAX, DST, LHAX, LVXL, MFTB, LWAUX, DSTST, LHAUX, STHX, ORC, ECOWX, STHUX, OR, DIVDU, DIVWU, MTSPR, DCBI, NAND, STVXL, DIVD, DIVW, LVLX, LDBRX, LSWX, LWBRX, LFSX, SRW, SRD, LVRX, LSWI, LFSUX, SYNC, LFDX, LFDUX, STVLX, STDBRX, STSWX, STWBRX, STFSX, STVRX, STFSUX, STSWI, STFDX, STFDUX, LVLXL, LHBRX, SRAW, SRAD, LVRXL, DSS, SRAWI, SRADI, EIEIO, STVLXL, STHBRX, EXTSH, STVRXL, EXTSB, STFIWX, EXTSW, ICBI, DCBZ, LWZ, LWZU, LBZ, LBZU, STW, STWU, STB, STBU, LHZ, LHZU, LHA, LHAU, STH, STHU, LMW, STMW, LFS, LFSU, LFD, LFDU, STFS, STFSU, STFD, STFDU, LD, LDU, LWA, STD, STDU, FDIVS, FSUBS, FADDS, FSQRTS, FRES, FMULS, FMADDS, FMSUBS, FNMSUBS, FNMADDS, MTFSB1, MCRFS, MTFSB0, MTFSFI, MFFS, MTFSF, FCMPU, FRSP, FCTIW, FCTIWZ, FDIV, FSUB, FADD, FSQRT, FSEL, FMUL, FRSQRTE, FMSUB, FMADD, FNMSUB, FNMADD, FCMPO, FNEG, FMR, FNABS, FABS, FCTID, FCTIDZ, FCFID, }; // Enable address-of operator for ppu_decoder<> friend constexpr type operator &(type value) { return value; } }; // Encode instruction name: 6 bits per character (0x20..0x5f), max 10 static constexpr u64 ppu_iname_encode(const char* ptr, u64 value = 0) { return *ptr == '\0' ? value : ppu_iname_encode(ptr + 1, (*ptr - 0x20) | (value << 6)); } struct ppu_iname { #define NAME(x) x = ppu_iname_encode(#x), enum type : u64 { NAME(UNK) NAME(MFVSCR) NAME(MTVSCR) NAME(VADDCUW) NAME(VADDFP) NAME(VADDSBS) NAME(VADDSHS) NAME(VADDSWS) NAME(VADDUBM) NAME(VADDUBS) NAME(VADDUHM) NAME(VADDUHS) NAME(VADDUWM) NAME(VADDUWS) NAME(VAND) NAME(VANDC) NAME(VAVGSB) NAME(VAVGSH) NAME(VAVGSW) NAME(VAVGUB) NAME(VAVGUH) NAME(VAVGUW) NAME(VCFSX) NAME(VCFUX) NAME(VCMPBFP) NAME(VCMPEQFP) NAME(VCMPEQUB) NAME(VCMPEQUH) NAME(VCMPEQUW) NAME(VCMPGEFP) NAME(VCMPGTFP) NAME(VCMPGTSB) NAME(VCMPGTSH) NAME(VCMPGTSW) NAME(VCMPGTUB) NAME(VCMPGTUH) NAME(VCMPGTUW) NAME(VCTSXS) NAME(VCTUXS) NAME(VEXPTEFP) NAME(VLOGEFP) NAME(VMADDFP) NAME(VMAXFP) NAME(VMAXSB) NAME(VMAXSH) NAME(VMAXSW) NAME(VMAXUB) NAME(VMAXUH) NAME(VMAXUW) NAME(VMHADDSHS) NAME(VMHRADDSHS) NAME(VMINFP) NAME(VMINSB) NAME(VMINSH) NAME(VMINSW) NAME(VMINUB) NAME(VMINUH) NAME(VMINUW) NAME(VMLADDUHM) NAME(VMRGHB) NAME(VMRGHH) NAME(VMRGHW) NAME(VMRGLB) NAME(VMRGLH) NAME(VMRGLW) NAME(VMSUMMBM) NAME(VMSUMSHM) NAME(VMSUMSHS) NAME(VMSUMUBM) NAME(VMSUMUHM) NAME(VMSUMUHS) NAME(VMULESB) NAME(VMULESH) NAME(VMULEUB) NAME(VMULEUH) NAME(VMULOSB) NAME(VMULOSH) NAME(VMULOUB) NAME(VMULOUH) NAME(VNMSUBFP) NAME(VNOR) NAME(VOR) NAME(VPERM) NAME(VPKPX) NAME(VPKSHSS) NAME(VPKSHUS) NAME(VPKSWSS) NAME(VPKSWUS) NAME(VPKUHUM) NAME(VPKUHUS) NAME(VPKUWUM) NAME(VPKUWUS) NAME(VREFP) NAME(VRFIM) NAME(VRFIN) NAME(VRFIP) NAME(VRFIZ) NAME(VRLB) NAME(VRLH) NAME(VRLW) NAME(VRSQRTEFP) NAME(VSEL) NAME(VSL) NAME(VSLB) NAME(VSLDOI) NAME(VSLH) NAME(VSLO) NAME(VSLW) NAME(VSPLTB) NAME(VSPLTH) NAME(VSPLTISB) NAME(VSPLTISH) NAME(VSPLTISW) NAME(VSPLTW) NAME(VSR) NAME(VSRAB) NAME(VSRAH) NAME(VSRAW) NAME(VSRB) NAME(VSRH) NAME(VSRO) NAME(VSRW) NAME(VSUBCUW) NAME(VSUBFP) NAME(VSUBSBS) NAME(VSUBSHS) NAME(VSUBSWS) NAME(VSUBUBM) NAME(VSUBUBS) NAME(VSUBUHM) NAME(VSUBUHS) NAME(VSUBUWM) NAME(VSUBUWS) NAME(VSUMSWS) NAME(VSUM2SWS) NAME(VSUM4SBS) NAME(VSUM4SHS) NAME(VSUM4UBS) NAME(VUPKHPX) NAME(VUPKHSB) NAME(VUPKHSH) NAME(VUPKLPX) NAME(VUPKLSB) NAME(VUPKLSH) NAME(VXOR) NAME(TDI) NAME(TWI) NAME(MULLI) NAME(SUBFIC) NAME(CMPLI) NAME(CMPI) NAME(ADDIC) NAME(ADDI) NAME(ADDIS) NAME(BC) NAME(SC) NAME(B) NAME(MCRF) NAME(BCLR) NAME(CRNOR) NAME(CRANDC) NAME(ISYNC) NAME(CRXOR) NAME(CRNAND) NAME(CRAND) NAME(CREQV) NAME(CRORC) NAME(CROR) NAME(BCCTR) NAME(RLWIMI) NAME(RLWINM) NAME(RLWNM) NAME(ORI) NAME(ORIS) NAME(XORI) NAME(XORIS) NAME(ANDI) NAME(ANDIS) NAME(RLDICL) NAME(RLDICR) NAME(RLDIC) NAME(RLDIMI) NAME(RLDCL) NAME(RLDCR) NAME(CMP) NAME(TW) NAME(LVSL) NAME(LVEBX) NAME(SUBFC) NAME(ADDC) NAME(MULHDU) NAME(MULHWU) NAME(MFOCRF) NAME(LWARX) NAME(LDX) NAME(LWZX) NAME(SLW) NAME(CNTLZW) NAME(SLD) NAME(AND) NAME(CMPL) NAME(LVSR) NAME(LVEHX) NAME(SUBF) NAME(LDUX) NAME(DCBST) NAME(LWZUX) NAME(CNTLZD) NAME(ANDC) NAME(TD) NAME(LVEWX) NAME(MULHD) NAME(MULHW) NAME(LDARX) NAME(DCBF) NAME(LBZX) NAME(LVX) NAME(NEG) NAME(LBZUX) NAME(NOR) NAME(STVEBX) NAME(SUBFE) NAME(ADDE) NAME(MTOCRF) NAME(STDX) NAME(STWCX) NAME(STWX) NAME(STVEHX) NAME(STDUX) NAME(STWUX) NAME(STVEWX) NAME(SUBFZE) NAME(ADDZE) NAME(STDCX) NAME(STBX) NAME(STVX) NAME(SUBFME) NAME(MULLD) NAME(ADDME) NAME(MULLW) NAME(DCBTST) NAME(STBUX) NAME(ADD) NAME(DCBT) NAME(LHZX) NAME(EQV) NAME(ECIWX) NAME(LHZUX) NAME(XOR) NAME(MFSPR) NAME(LWAX) NAME(DST) NAME(LHAX) NAME(LVXL) NAME(MFTB) NAME(LWAUX) NAME(DSTST) NAME(LHAUX) NAME(STHX) NAME(ORC) NAME(ECOWX) NAME(STHUX) NAME(OR) NAME(DIVDU) NAME(DIVWU) NAME(MTSPR) NAME(DCBI) NAME(NAND) NAME(STVXL) NAME(DIVD) NAME(DIVW) NAME(LVLX) NAME(LDBRX) NAME(LSWX) NAME(LWBRX) NAME(LFSX) NAME(SRW) NAME(SRD) NAME(LVRX) NAME(LSWI) NAME(LFSUX) NAME(SYNC) NAME(LFDX) NAME(LFDUX) NAME(STVLX) NAME(STDBRX) NAME(STSWX) NAME(STWBRX) NAME(STFSX) NAME(STVRX) NAME(STFSUX) NAME(STSWI) NAME(STFDX) NAME(STFDUX) NAME(LVLXL) NAME(LHBRX) NAME(SRAW) NAME(SRAD) NAME(LVRXL) NAME(DSS) NAME(SRAWI) NAME(SRADI) NAME(EIEIO) NAME(STVLXL) NAME(STHBRX) NAME(EXTSH) NAME(STVRXL) NAME(EXTSB) NAME(STFIWX) NAME(EXTSW) NAME(ICBI) NAME(DCBZ) NAME(LWZ) NAME(LWZU) NAME(LBZ) NAME(LBZU) NAME(STW) NAME(STWU) NAME(STB) NAME(STBU) NAME(LHZ) NAME(LHZU) NAME(LHA) NAME(LHAU) NAME(STH) NAME(STHU) NAME(LMW) NAME(STMW) NAME(LFS) NAME(LFSU) NAME(LFD) NAME(LFDU) NAME(STFS) NAME(STFSU) NAME(STFD) NAME(STFDU) NAME(LD) NAME(LDU) NAME(LWA) NAME(STD) NAME(STDU) NAME(FDIVS) NAME(FSUBS) NAME(FADDS) NAME(FSQRTS) NAME(FRES) NAME(FMULS) NAME(FMADDS) NAME(FMSUBS) NAME(FNMSUBS) NAME(FNMADDS) NAME(MTFSB1) NAME(MCRFS) NAME(MTFSB0) NAME(MTFSFI) NAME(MFFS) NAME(MTFSF) NAME(FCMPU) NAME(FRSP) NAME(FCTIW) NAME(FCTIWZ) NAME(FDIV) NAME(FSUB) NAME(FADD) NAME(FSQRT) NAME(FSEL) NAME(FMUL) NAME(FRSQRTE) NAME(FMSUB) NAME(FMADD) NAME(FNMSUB) NAME(FNMADD) NAME(FCMPO) NAME(FNEG) NAME(FMR) NAME(FNABS) NAME(FABS) NAME(FCTID) NAME(FCTIDZ) NAME(FCFID) }; #undef NAME // Enable address-of operator for ppu_decoder<> friend constexpr type operator &(type value) { return value; } }; // PPU Analyser Context struct ppu_acontext { // General-purpose register range struct spec_gpr { // Integral range: normalized undef = (0;UINT64_MAX), unnormalized undefs are possible (when max = min - 1) // Bit range: constant 0 = (0;0), constant 1 = (1;1), normalized undef = (0;1), unnormalized undef = (1;0) u64 imin = 0ull; // Integral range begin u64 imax = -1ull; // Integral range end u64 bmin = 0ull; // Bit range begin u64 bmax = -1ull; // Bit range end void set_undef() { imin = 0; imax = -1; bmin = 0; bmax = -1; } // (Number of possible values - 1), 0 = const u64 div() const { return imax - imin; } // Return zero bits for zeros, ones for ones or undefs u64 mask() const { return bmin | bmax; } // Return one bits for ones, zeros for zeros or undefs u64 ones() const { return bmin & bmax; } // Return one bits for undefs u64 undefs() const { return bmin ^ bmax; } // Return number of trailing zero bits u64 tz() const { return utils::cnttz64(mask()); } // Range NOT spec_gpr operator ~() const { spec_gpr r; r.imin = ~imax; r.imax = ~imin; r.bmin = ~bmax; r.bmax = ~bmin; return r; } // Range ADD spec_gpr operator +(const spec_gpr& rhs) const { spec_gpr r{}; const u64 adiv = div(); const u64 bdiv = rhs.div(); // Check overflow, generate normalized range if (adiv != -1 && bdiv != -1 && adiv <= adiv + bdiv) { r = range(imin + rhs.imin, imax + rhs.imax); } // Carry for bitrange computation u64 cmin = 0; u64 cmax = 0; const u64 amask = mask(); const u64 bmask = rhs.mask(); const u64 aones = ones(); const u64 bones = rhs.ones(); for (u32 i = 0; i < 64; i++) { cmin += ((amask >> i) & 1) + ((bmask >> i) & 1); cmax += ((aones >> i) & 1) + ((bones >> i) & 1); // Discover some constant bits if (cmin == cmax) { r.bmin |= (cmin & 1) << i; r.bmax &= ~((~cmin & 1) << i); } cmin >>= 1; cmax >>= 1; } return r; } // Range AND spec_gpr operator &(const spec_gpr& rhs) const { // Ignore inverted ranges (TODO) if (imin > imax || rhs.imin > rhs.imax) { return approx(ones() & rhs.ones(), mask() & rhs.mask()); } // Const (TODO: remove when unnecessary) if (imin == imax && rhs.imin == rhs.imax) { return fixed(imin & rhs.imin); } // Swap (TODO: remove when unnecessary) if (imin == imax || rhs.undefs() > undefs()) { return rhs & *this; } // Copy and attempt to partially preserve integral range spec_gpr r = *this; for (u32 i = 63; ~i; i--) { const u64 m = 1ull << i; if (!(rhs.mask() & m)) { if (r.undefs() & m) { // undef -> 0 r.imin &= ~(m - 1); r.imax |= (m - 1); r.imin &= ~m; r.imax &= ~m; } else if (r.ones() & m) { // 1 -> 0 if ((r.imin ^ r.imax) > (m - 1)) { r.imin &= ~(m - 1); r.imax |= (m - 1); } r.imin &= ~m; r.imax &= ~m; } } else if (rhs.undefs() & m) { // -> undef r.imin &= ~(m - 1); r.imax |= (m - 1); r.imin &= ~m; r.imax |= m; } } r.bmin = ones() & rhs.ones(); r.bmax = mask() & rhs.mask(); return r; } // Range OR spec_gpr operator |(const spec_gpr& rhs) const { // Ignore inverted ranges (TODO) if (imin > imax || rhs.imin > rhs.imax) { return approx(ones() | rhs.ones(), mask() | rhs.mask()); } // Const (TODO: remove when unnecessary) if (imin == imax && rhs.imin == rhs.imax) { return fixed(imin | rhs.imin); } // Swap (TODO: remove when unnecessary) if (imin == imax || rhs.undefs() > undefs()) { return rhs | *this; } // Copy and attempt to partially preserve integral range spec_gpr r = *this; for (u32 i = 63; ~i; i--) { const u64 m = 1ull << i; if (rhs.ones() & m) { if (r.undefs() & m) { // undef -> 1 r.imin &= ~(m - 1); r.imax |= (m - 1); r.imin |= m; r.imax |= m; } else if (!(r.mask() & m)) { // 0 -> 1 if ((r.imin ^ r.imax) > (m - 1)) { r.imin &= ~(m - 1); r.imax |= (m - 1); } r.imin |= m; r.imax |= m; } } else if (rhs.undefs() & m) { // -> undef r.imin &= ~(m - 1); r.imax |= (m - 1); r.imin &= ~m; r.imax |= m; } } r.bmin = ones() | rhs.ones(); r.bmax = mask() | rhs.mask(); return r; } // Range XOR spec_gpr operator ^(const spec_gpr& rhs) { return (~*this & rhs) | (*this & ~rhs); } // Check whether the value is in range bool test(u64 value) const { if (imin <= imax) { if (value < imin || value > imax) { return false; } } else { if (value < imin && value > imax) { return false; } } if ((value & mask()) != value) { return false; } if ((value | ones()) != value) { return false; } return true; } // Constant value static spec_gpr fixed(u64 value) { spec_gpr r; r.imin = value; r.imax = value; r.bmin = value; r.bmax = value; return r; } // Range (tz = number of constant trailing zeros) static spec_gpr range(u64 min, u64 max, u64 tz = 0) { const u64 mask = tz < 64 ? ~0ull << tz : 0ull; spec_gpr r; r.bmin = 0; r.bmax = mask; // Normalize min/max for tz (TODO) if (min < max) { // Inverted constant MSB mask const u64 mix = ~0ull >> utils::cntlz64(min ^ max, true); r.bmin |= min & ~mix; r.bmax &= max | mix; r.imin = (min + ~mask) & mask; r.imax = max & mask; verify("Impossible range" HERE), r.imin <= r.imax; } else { r.imin = min & mask; r.imax = (max + ~mask) & mask; verify("Impossible range" HERE), r.imin >= r.imax; } // Fix const values if (r.imin == r.imax) { r.bmin = r.imin; r.bmax = r.imax; } return r; } // Make from bitrange (normalize, approximate range values) static spec_gpr approx(u64 bmin, u64 bmax) { spec_gpr r; r.imin = bmin & ~(bmin ^ bmax); r.imax = bmax | (bmin ^ bmax); r.bmin = bmin & ~(bmin ^ bmax); r.bmax = bmax | (bmin ^ bmax); return r; } } gpr[32]{}; // Vector registers (draft) struct spec_vec { u8 imin8[16]{}; u8 imax8[16]{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; u16 imin16[8]{}; u16 imax16[8]{0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; u32 imin32[4]{}; u32 imax32[4]{0xffffffffu, 0xffffffffu, 0xffffffffu, 0xffffffffu}; u64 bmin64[2]{}; u64 bmax64[2]{0xffffffffffffffffull, 0xffffffffffffffffull}; }; // Info u32 cia; // Analyser step void UNK(ppu_opcode_t); void MFVSCR(ppu_opcode_t); void MTVSCR(ppu_opcode_t); void VADDCUW(ppu_opcode_t); void VADDFP(ppu_opcode_t); void VADDSBS(ppu_opcode_t); void VADDSHS(ppu_opcode_t); void VADDSWS(ppu_opcode_t); void VADDUBM(ppu_opcode_t); void VADDUBS(ppu_opcode_t); void VADDUHM(ppu_opcode_t); void VADDUHS(ppu_opcode_t); void VADDUWM(ppu_opcode_t); void VADDUWS(ppu_opcode_t); void VAND(ppu_opcode_t); void VANDC(ppu_opcode_t); void VAVGSB(ppu_opcode_t); void VAVGSH(ppu_opcode_t); void VAVGSW(ppu_opcode_t); void VAVGUB(ppu_opcode_t); void VAVGUH(ppu_opcode_t); void VAVGUW(ppu_opcode_t); void VCFSX(ppu_opcode_t); void VCFUX(ppu_opcode_t); void VCMPBFP(ppu_opcode_t); void VCMPEQFP(ppu_opcode_t); void VCMPEQUB(ppu_opcode_t); void VCMPEQUH(ppu_opcode_t); void VCMPEQUW(ppu_opcode_t); void VCMPGEFP(ppu_opcode_t); void VCMPGTFP(ppu_opcode_t); void VCMPGTSB(ppu_opcode_t); void VCMPGTSH(ppu_opcode_t); void VCMPGTSW(ppu_opcode_t); void VCMPGTUB(ppu_opcode_t); void VCMPGTUH(ppu_opcode_t); void VCMPGTUW(ppu_opcode_t); void VCTSXS(ppu_opcode_t); void VCTUXS(ppu_opcode_t); void VEXPTEFP(ppu_opcode_t); void VLOGEFP(ppu_opcode_t); void VMADDFP(ppu_opcode_t); void VMAXFP(ppu_opcode_t); void VMAXSB(ppu_opcode_t); void VMAXSH(ppu_opcode_t); void VMAXSW(ppu_opcode_t); void VMAXUB(ppu_opcode_t); void VMAXUH(ppu_opcode_t); void VMAXUW(ppu_opcode_t); void VMHADDSHS(ppu_opcode_t); void VMHRADDSHS(ppu_opcode_t); void VMINFP(ppu_opcode_t); void VMINSB(ppu_opcode_t); void VMINSH(ppu_opcode_t); void VMINSW(ppu_opcode_t); void VMINUB(ppu_opcode_t); void VMINUH(ppu_opcode_t); void VMINUW(ppu_opcode_t); void VMLADDUHM(ppu_opcode_t); void VMRGHB(ppu_opcode_t); void VMRGHH(ppu_opcode_t); void VMRGHW(ppu_opcode_t); void VMRGLB(ppu_opcode_t); void VMRGLH(ppu_opcode_t); void VMRGLW(ppu_opcode_t); void VMSUMMBM(ppu_opcode_t); void VMSUMSHM(ppu_opcode_t); void VMSUMSHS(ppu_opcode_t); void VMSUMUBM(ppu_opcode_t); void VMSUMUHM(ppu_opcode_t); void VMSUMUHS(ppu_opcode_t); void VMULESB(ppu_opcode_t); void VMULESH(ppu_opcode_t); void VMULEUB(ppu_opcode_t); void VMULEUH(ppu_opcode_t); void VMULOSB(ppu_opcode_t); void VMULOSH(ppu_opcode_t); void VMULOUB(ppu_opcode_t); void VMULOUH(ppu_opcode_t); void VNMSUBFP(ppu_opcode_t); void VNOR(ppu_opcode_t); void VOR(ppu_opcode_t); void VPERM(ppu_opcode_t); void VPKPX(ppu_opcode_t); void VPKSHSS(ppu_opcode_t); void VPKSHUS(ppu_opcode_t); void VPKSWSS(ppu_opcode_t); void VPKSWUS(ppu_opcode_t); void VPKUHUM(ppu_opcode_t); void VPKUHUS(ppu_opcode_t); void VPKUWUM(ppu_opcode_t); void VPKUWUS(ppu_opcode_t); void VREFP(ppu_opcode_t); void VRFIM(ppu_opcode_t); void VRFIN(ppu_opcode_t); void VRFIP(ppu_opcode_t); void VRFIZ(ppu_opcode_t); void VRLB(ppu_opcode_t); void VRLH(ppu_opcode_t); void VRLW(ppu_opcode_t); void VRSQRTEFP(ppu_opcode_t); void VSEL(ppu_opcode_t); void VSL(ppu_opcode_t); void VSLB(ppu_opcode_t); void VSLDOI(ppu_opcode_t); void VSLH(ppu_opcode_t); void VSLO(ppu_opcode_t); void VSLW(ppu_opcode_t); void VSPLTB(ppu_opcode_t); void VSPLTH(ppu_opcode_t); void VSPLTISB(ppu_opcode_t); void VSPLTISH(ppu_opcode_t); void VSPLTISW(ppu_opcode_t); void VSPLTW(ppu_opcode_t); void VSR(ppu_opcode_t); void VSRAB(ppu_opcode_t); void VSRAH(ppu_opcode_t); void VSRAW(ppu_opcode_t); void VSRB(ppu_opcode_t); void VSRH(ppu_opcode_t); void VSRO(ppu_opcode_t); void VSRW(ppu_opcode_t); void VSUBCUW(ppu_opcode_t); void VSUBFP(ppu_opcode_t); void VSUBSBS(ppu_opcode_t); void VSUBSHS(ppu_opcode_t); void VSUBSWS(ppu_opcode_t); void VSUBUBM(ppu_opcode_t); void VSUBUBS(ppu_opcode_t); void VSUBUHM(ppu_opcode_t); void VSUBUHS(ppu_opcode_t); void VSUBUWM(ppu_opcode_t); void VSUBUWS(ppu_opcode_t); void VSUMSWS(ppu_opcode_t); void VSUM2SWS(ppu_opcode_t); void VSUM4SBS(ppu_opcode_t); void VSUM4SHS(ppu_opcode_t); void VSUM4UBS(ppu_opcode_t); void VUPKHPX(ppu_opcode_t); void VUPKHSB(ppu_opcode_t); void VUPKHSH(ppu_opcode_t); void VUPKLPX(ppu_opcode_t); void VUPKLSB(ppu_opcode_t); void VUPKLSH(ppu_opcode_t); void VXOR(ppu_opcode_t); void TDI(ppu_opcode_t); void TWI(ppu_opcode_t); void MULLI(ppu_opcode_t); void SUBFIC(ppu_opcode_t); void CMPLI(ppu_opcode_t); void CMPI(ppu_opcode_t); void ADDIC(ppu_opcode_t); void ADDI(ppu_opcode_t); void ADDIS(ppu_opcode_t); void BC(ppu_opcode_t); void SC(ppu_opcode_t); void B(ppu_opcode_t); void MCRF(ppu_opcode_t); void BCLR(ppu_opcode_t); void CRNOR(ppu_opcode_t); void CRANDC(ppu_opcode_t); void ISYNC(ppu_opcode_t); void CRXOR(ppu_opcode_t); void CRNAND(ppu_opcode_t); void CRAND(ppu_opcode_t); void CREQV(ppu_opcode_t); void CRORC(ppu_opcode_t); void CROR(ppu_opcode_t); void BCCTR(ppu_opcode_t); void RLWIMI(ppu_opcode_t); void RLWINM(ppu_opcode_t); void RLWNM(ppu_opcode_t); void ORI(ppu_opcode_t); void ORIS(ppu_opcode_t); void XORI(ppu_opcode_t); void XORIS(ppu_opcode_t); void ANDI(ppu_opcode_t); void ANDIS(ppu_opcode_t); void RLDICL(ppu_opcode_t); void RLDICR(ppu_opcode_t); void RLDIC(ppu_opcode_t); void RLDIMI(ppu_opcode_t); void RLDCL(ppu_opcode_t); void RLDCR(ppu_opcode_t); void CMP(ppu_opcode_t); void TW(ppu_opcode_t); void LVSL(ppu_opcode_t); void LVEBX(ppu_opcode_t); void SUBFC(ppu_opcode_t); void ADDC(ppu_opcode_t); void MULHDU(ppu_opcode_t); void MULHWU(ppu_opcode_t); void MFOCRF(ppu_opcode_t); void LWARX(ppu_opcode_t); void LDX(ppu_opcode_t); void LWZX(ppu_opcode_t); void SLW(ppu_opcode_t); void CNTLZW(ppu_opcode_t); void SLD(ppu_opcode_t); void AND(ppu_opcode_t); void CMPL(ppu_opcode_t); void LVSR(ppu_opcode_t); void LVEHX(ppu_opcode_t); void SUBF(ppu_opcode_t); void LDUX(ppu_opcode_t); void DCBST(ppu_opcode_t); void LWZUX(ppu_opcode_t); void CNTLZD(ppu_opcode_t); void ANDC(ppu_opcode_t); void TD(ppu_opcode_t); void LVEWX(ppu_opcode_t); void MULHD(ppu_opcode_t); void MULHW(ppu_opcode_t); void LDARX(ppu_opcode_t); void DCBF(ppu_opcode_t); void LBZX(ppu_opcode_t); void LVX(ppu_opcode_t); void NEG(ppu_opcode_t); void LBZUX(ppu_opcode_t); void NOR(ppu_opcode_t); void STVEBX(ppu_opcode_t); void SUBFE(ppu_opcode_t); void ADDE(ppu_opcode_t); void MTOCRF(ppu_opcode_t); void STDX(ppu_opcode_t); void STWCX(ppu_opcode_t); void STWX(ppu_opcode_t); void STVEHX(ppu_opcode_t); void STDUX(ppu_opcode_t); void STWUX(ppu_opcode_t); void STVEWX(ppu_opcode_t); void SUBFZE(ppu_opcode_t); void ADDZE(ppu_opcode_t); void STDCX(ppu_opcode_t); void STBX(ppu_opcode_t); void STVX(ppu_opcode_t); void SUBFME(ppu_opcode_t); void MULLD(ppu_opcode_t); void ADDME(ppu_opcode_t); void MULLW(ppu_opcode_t); void DCBTST(ppu_opcode_t); void STBUX(ppu_opcode_t); void ADD(ppu_opcode_t); void DCBT(ppu_opcode_t); void LHZX(ppu_opcode_t); void EQV(ppu_opcode_t); void ECIWX(ppu_opcode_t); void LHZUX(ppu_opcode_t); void XOR(ppu_opcode_t); void MFSPR(ppu_opcode_t); void LWAX(ppu_opcode_t); void DST(ppu_opcode_t); void LHAX(ppu_opcode_t); void LVXL(ppu_opcode_t); void MFTB(ppu_opcode_t); void LWAUX(ppu_opcode_t); void DSTST(ppu_opcode_t); void LHAUX(ppu_opcode_t); void STHX(ppu_opcode_t); void ORC(ppu_opcode_t); void ECOWX(ppu_opcode_t); void STHUX(ppu_opcode_t); void OR(ppu_opcode_t); void DIVDU(ppu_opcode_t); void DIVWU(ppu_opcode_t); void MTSPR(ppu_opcode_t); void DCBI(ppu_opcode_t); void NAND(ppu_opcode_t); void STVXL(ppu_opcode_t); void DIVD(ppu_opcode_t); void DIVW(ppu_opcode_t); void LVLX(ppu_opcode_t); void LDBRX(ppu_opcode_t); void LSWX(ppu_opcode_t); void LWBRX(ppu_opcode_t); void LFSX(ppu_opcode_t); void SRW(ppu_opcode_t); void SRD(ppu_opcode_t); void LVRX(ppu_opcode_t); void LSWI(ppu_opcode_t); void LFSUX(ppu_opcode_t); void SYNC(ppu_opcode_t); void LFDX(ppu_opcode_t); void LFDUX(ppu_opcode_t); void STVLX(ppu_opcode_t); void STDBRX(ppu_opcode_t); void STSWX(ppu_opcode_t); void STWBRX(ppu_opcode_t); void STFSX(ppu_opcode_t); void STVRX(ppu_opcode_t); void STFSUX(ppu_opcode_t); void STSWI(ppu_opcode_t); void STFDX(ppu_opcode_t); void STFDUX(ppu_opcode_t); void LVLXL(ppu_opcode_t); void LHBRX(ppu_opcode_t); void SRAW(ppu_opcode_t); void SRAD(ppu_opcode_t); void LVRXL(ppu_opcode_t); void DSS(ppu_opcode_t); void SRAWI(ppu_opcode_t); void SRADI(ppu_opcode_t); void EIEIO(ppu_opcode_t); void STVLXL(ppu_opcode_t); void STHBRX(ppu_opcode_t); void EXTSH(ppu_opcode_t); void STVRXL(ppu_opcode_t); void EXTSB(ppu_opcode_t); void STFIWX(ppu_opcode_t); void EXTSW(ppu_opcode_t); void ICBI(ppu_opcode_t); void DCBZ(ppu_opcode_t); void LWZ(ppu_opcode_t); void LWZU(ppu_opcode_t); void LBZ(ppu_opcode_t); void LBZU(ppu_opcode_t); void STW(ppu_opcode_t); void STWU(ppu_opcode_t); void STB(ppu_opcode_t); void STBU(ppu_opcode_t); void LHZ(ppu_opcode_t); void LHZU(ppu_opcode_t); void LHA(ppu_opcode_t); void LHAU(ppu_opcode_t); void STH(ppu_opcode_t); void STHU(ppu_opcode_t); void LMW(ppu_opcode_t); void STMW(ppu_opcode_t); void LFS(ppu_opcode_t); void LFSU(ppu_opcode_t); void LFD(ppu_opcode_t); void LFDU(ppu_opcode_t); void STFS(ppu_opcode_t); void STFSU(ppu_opcode_t); void STFD(ppu_opcode_t); void STFDU(ppu_opcode_t); void LD(ppu_opcode_t); void LDU(ppu_opcode_t); void LWA(ppu_opcode_t); void STD(ppu_opcode_t); void STDU(ppu_opcode_t); void FDIVS(ppu_opcode_t); void FSUBS(ppu_opcode_t); void FADDS(ppu_opcode_t); void FSQRTS(ppu_opcode_t); void FRES(ppu_opcode_t); void FMULS(ppu_opcode_t); void FMADDS(ppu_opcode_t); void FMSUBS(ppu_opcode_t); void FNMSUBS(ppu_opcode_t); void FNMADDS(ppu_opcode_t); void MTFSB1(ppu_opcode_t); void MCRFS(ppu_opcode_t); void MTFSB0(ppu_opcode_t); void MTFSFI(ppu_opcode_t); void MFFS(ppu_opcode_t); void MTFSF(ppu_opcode_t); void FCMPU(ppu_opcode_t); void FRSP(ppu_opcode_t); void FCTIW(ppu_opcode_t); void FCTIWZ(ppu_opcode_t); void FDIV(ppu_opcode_t); void FSUB(ppu_opcode_t); void FADD(ppu_opcode_t); void FSQRT(ppu_opcode_t); void FSEL(ppu_opcode_t); void FMUL(ppu_opcode_t); void FRSQRTE(ppu_opcode_t); void FMSUB(ppu_opcode_t); void FMADD(ppu_opcode_t); void FNMSUB(ppu_opcode_t); void FNMADD(ppu_opcode_t); void FCMPO(ppu_opcode_t); void FNEG(ppu_opcode_t); void FMR(ppu_opcode_t); void FNABS(ppu_opcode_t); void FABS(ppu_opcode_t); void FCTID(ppu_opcode_t); void FCTIDZ(ppu_opcode_t); void FCFID(ppu_opcode_t); };