From 712c04b2adf1ec5fcf48c70fee1179a780c3c10e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 24 Jul 2016 20:54:15 +0300 Subject: [PATCH] PPU Analyser update WIP, nothing changed --- rpcs3/Emu/Cell/PPUAnalyser.cpp | 9 +- rpcs3/Emu/Cell/PPUAnalyser.h | 429 ++++++++++++++++++++++++++++++++- 2 files changed, 433 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 356a28ed76..4df9e91edf 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -321,7 +321,7 @@ std::vector ppu_analyse(const std::vector>& se if (func.addr) { - // Update TOC (TODO: this doesn't work well) + // Update TOC (TODO: this doesn't work well, must update TOC recursively) if (func.toc == 0 || toc == -1) { func.toc = toc; @@ -592,6 +592,8 @@ std::vector ppu_analyse(const std::vector>& se func.size = 0x4; func.blocks.emplace(func.addr, func.size); func.attr += new_func.attr & ppu_attr::no_return; + func.called_from.emplace(target); + func.gate_target = target; continue; } } @@ -620,7 +622,9 @@ std::vector ppu_analyse(const std::vector>& se func.size = 0x10; func.blocks.emplace(func.addr, func.size); - func.attr += new_func.attr & ppu_attr::no_return; + func.attr += new_func.attr & ppu_attr::no_return; + func.called_from.emplace(target); + func.gate_target = target; continue; } } @@ -909,6 +913,7 @@ std::vector ppu_analyse(const std::vector>& se { if (target < func.addr || target >= func.addr + func.size) { + func.called_from.emplace(target); add_func(target, func.toc, func.addr); } } diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index ce0c48e7b6..859d61038b 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "Utilities/BitSet.h" #include "Utilities/BEType.h" @@ -14,17 +15,22 @@ enum class ppu_attr : u32 no_size, uses_r0, entry_point, + complex_stack, }; // PPU Function Information struct ppu_function { - u32 addr{}; - u32 toc{}; - u32 size{}; + u32 addr = 0; + u32 toc = 0; + u32 size = 0; bitset_t attr{}; + u32 stack_frame = 0; + u32 gate_target = 0; + std::map blocks; // Basic blocks: addr -> size + std::set called_from; // Set of called functions }; // Aux @@ -448,6 +454,423 @@ struct ppu_itype } }; +// PPU Instruction Flags +struct ppu_iflag +{ + // Various flags (TODO) + enum : u32 + { + write_rd = 1 << 0, + write_ra = 1 << 1, + read_ra = 1 << 2, + read_rb = 1 << 3, + read_rs = 1 << 4, + write_vd = 1 << 5, + read_va = 1 << 6, + read_vb = 1 << 7, + read_vc = 1 << 8, + read_vs = 1 << 9, + write_frd = 1 << 10, + read_fra = 1 << 11, + read_frb = 1 << 12, + read_frc = 1 << 13, + read_frs = 1 << 14, + rw_all = 1 << 15, + }; + + enum flags : u32 + { + UNK = 0, + + MFVSCR = 0, + MTVSCR = 0, + VADDCUW = 0, + VADDFP = 0, + VADDSBS = 0, + VADDSHS = 0, + VADDSWS = 0, + VADDUBM = 0, + VADDUBS = 0, + VADDUHM = 0, + VADDUHS = 0, + VADDUWM = 0, + VADDUWS = 0, + VAND = 0, + VANDC = 0, + VAVGSB = 0, + VAVGSH = 0, + VAVGSW = 0, + VAVGUB = 0, + VAVGUH = 0, + VAVGUW = 0, + VCFSX = 0, + VCFUX = 0, + VCMPBFP = 0, + VCMPEQFP = 0, + VCMPEQUB = 0, + VCMPEQUH = 0, + VCMPEQUW = 0, + VCMPGEFP = 0, + VCMPGTFP = 0, + VCMPGTSB = 0, + VCMPGTSH = 0, + VCMPGTSW = 0, + VCMPGTUB = 0, + VCMPGTUH = 0, + VCMPGTUW = 0, + VCTSXS = 0, + VCTUXS = 0, + VEXPTEFP = 0, + VLOGEFP = 0, + VMADDFP = 0, + VMAXFP = 0, + VMAXSB = 0, + VMAXSH = 0, + VMAXSW = 0, + VMAXUB = 0, + VMAXUH = 0, + VMAXUW = 0, + VMHADDSHS = 0, + VMHRADDSHS = 0, + VMINFP = 0, + VMINSB = 0, + VMINSH = 0, + VMINSW = 0, + VMINUB = 0, + VMINUH = 0, + VMINUW = 0, + VMLADDUHM = 0, + VMRGHB = 0, + VMRGHH = 0, + VMRGHW = 0, + VMRGLB = 0, + VMRGLH = 0, + VMRGLW = 0, + VMSUMMBM = 0, + VMSUMSHM = 0, + VMSUMSHS = 0, + VMSUMUBM = 0, + VMSUMUHM = 0, + VMSUMUHS = 0, + VMULESB = 0, + VMULESH = 0, + VMULEUB = 0, + VMULEUH = 0, + VMULOSB = 0, + VMULOSH = 0, + VMULOUB = 0, + VMULOUH = 0, + VNMSUBFP = 0, + VNOR = 0, + VOR = 0, + VPERM = 0, + VPKPX = 0, + VPKSHSS = 0, + VPKSHUS = 0, + VPKSWSS = 0, + VPKSWUS = 0, + VPKUHUM = 0, + VPKUHUS = 0, + VPKUWUM = 0, + VPKUWUS = 0, + VREFP = 0, + VRFIM = 0, + VRFIN = 0, + VRFIP = 0, + VRFIZ = 0, + VRLB = 0, + VRLH = 0, + VRLW = 0, + VRSQRTEFP = 0, + VSEL = 0, + VSL = 0, + VSLB = 0, + VSLDOI = 0, + VSLH = 0, + VSLO = 0, + VSLW = 0, + VSPLTB = 0, + VSPLTH = 0, + VSPLTISB = 0, + VSPLTISH = 0, + VSPLTISW = 0, + VSPLTW = 0, + VSR = 0, + VSRAB = 0, + VSRAH = 0, + VSRAW = 0, + VSRB = 0, + VSRH = 0, + VSRO = 0, + VSRW = 0, + VSUBCUW = 0, + VSUBFP = 0, + VSUBSBS = 0, + VSUBSHS = 0, + VSUBSWS = 0, + VSUBUBM = 0, + VSUBUBS = 0, + VSUBUHM = 0, + VSUBUHS = 0, + VSUBUWM = 0, + VSUBUWS = 0, + VSUMSWS = 0, + VSUM2SWS = 0, + VSUM4SBS = 0, + VSUM4SHS = 0, + VSUM4UBS = 0, + VUPKHPX = 0, + VUPKHSB = 0, + VUPKHSH = 0, + VUPKLPX = 0, + VUPKLSB = 0, + VUPKLSH = 0, + VXOR = 0, + TDI = read_ra, + TWI = read_ra, + MULLI = read_ra, + SUBFIC = read_ra, + CMPLI = read_ra, + CMPI = read_ra, + ADDIC = read_ra, + ADDI = read_ra, + ADDIS = read_ra, + BC = 0, + HACK = 0, + SC = 0, + B = 0, + MCRF = 0, + BCLR = 0, + CRNOR = 0, + CRANDC = 0, + ISYNC = 0, + CRXOR = 0, + CRNAND = 0, + CRAND = 0, + CREQV = 0, + CRORC = 0, + CROR = 0, + BCCTR = 0, + RLWIMI = read_ra | read_rs, + RLWINM = read_rs, + RLWNM = read_rs | read_rb, + ORI = read_rs, + ORIS = read_rs, + XORI = read_rs, + XORIS = read_rs, + ANDI = read_rs, + ANDIS = read_rs, + RLDICL = read_rs, + RLDICR = read_rs, + RLDIC = read_rs, + RLDIMI = read_ra | read_rs, + RLDCL = read_rs | read_rb, + RLDCR = read_rs | read_rb, + CMP = read_ra | read_rb, + TW = read_ra | read_rb, + LVSL = read_ra | read_rb, + LVEBX = read_ra | read_rb, + SUBFC = read_ra | read_rb, + ADDC = read_ra | read_rb, + MULHDU = read_ra | read_rb, + MULHWU = read_ra | read_rb, + MFOCRF = 0, + LWARX = read_ra | read_rb, + LDX = read_ra | read_rb, + LWZX = read_ra | read_rb, + SLW = read_rs | read_rb, + CNTLZW = read_rs, + SLD = read_rs | read_rb, + AND = read_rs | read_rb, + CMPL = read_ra | read_rb, + LVSR = read_ra | read_rb, + LVEHX = read_ra | read_rb, + SUBF = read_ra | read_rb, + LDUX = read_ra | read_rb, + DCBST = 0, + LWZUX = read_ra | read_rb, + CNTLZD = read_rs, + ANDC = read_rs | read_rb, + TD = read_ra | read_rb, + LVEWX = read_ra | read_rb, + MULHD = read_ra | read_rb, + MULHW = read_ra | read_rb, + LDARX = read_ra | read_rb, + DCBF = 0, + LBZX = read_ra | read_rb, + LVX = read_ra | read_rb, + NEG = read_ra, + LBZUX = read_ra | read_rb, + NOR = read_rs | read_rb, + STVEBX = read_ra | read_rb, + SUBFE = read_ra | read_rb, + ADDE = read_ra | read_rb, + MTOCRF = read_rs, + STDX = read_rs | read_ra | read_rb, + STWCX = read_rs | read_ra | read_rb, + STWX = read_rs | read_ra | read_rb, + STVEHX = read_ra | read_rb, + STDUX = read_rs | read_ra | read_rb, + STWUX = read_rs | read_ra | read_rb, + STVEWX = read_ra | read_rb, + SUBFZE = read_ra, + ADDZE = read_ra, + STDCX = read_rs | read_ra | read_rb, + STBX = read_rs | read_ra | read_rb, + STVX = read_ra | read_rb, + SUBFME = read_ra, + MULLD = read_ra | read_rb, + ADDME = read_ra | read_rb, + MULLW = read_ra | read_rb, + DCBTST = 0, + STBUX = read_rs | read_ra | read_rb, + ADD = read_ra | read_rb, + DCBT = 0, + LHZX = read_ra | read_rb, + EQV = read_rs | read_rb, + ECIWX = read_ra | read_rb, + LHZUX = read_ra | read_rb, + XOR = read_rs | read_rb, + MFSPR = 0, + LWAX = read_ra | read_rb, + DST = 0, + LHAX = read_ra | read_rb, + LVXL = LVX, + MFTB = MFSPR, + LWAUX = read_ra | read_rb, + DSTST = 0, + LHAUX = read_ra | read_rb, + STHX = read_rs | read_ra | read_rb, + ORC = read_rs | read_rb, + ECOWX = read_rs | read_ra | read_rb, + STHUX = read_rs | read_ra | read_rb, + OR = read_rs | read_rb, + DIVDU = read_ra | read_rb, + DIVWU = read_ra | read_rb, + MTSPR = read_rs, + DCBI = 0, + NAND = read_rs | read_rb, + STVXL = STVX, + DIVD = read_ra | read_rb, + DIVW = read_ra | read_rb, + LVLX = read_ra | read_rb, + LDBRX = read_ra | read_rb, + LSWX = read_ra | read_rb | rw_all, + LWBRX = read_ra | read_rb, + LFSX = read_ra | read_rb, + SRW = read_rs | read_rb, + SRD = read_rs | read_rb, + LVRX = read_ra | read_rb, + LSWI = rw_all, + LFSUX = read_ra | read_rb, + SYNC = 0, + LFDX = read_ra | read_rb, + LFDUX = read_ra | read_rb, + STVLX = read_ra | read_rb, + STDBRX = read_rs | read_ra | read_rb, + STSWX = rw_all, + STWBRX = read_rs | read_ra | read_rb, + STFSX = read_ra | read_rb, + STVRX = read_ra | read_rb, + STFSUX = read_ra | read_rb, + STSWI = rw_all, + STFDX = read_ra | read_rb, + STFDUX = read_ra | read_rb, + LVLXL = LVLX, + LHBRX = read_ra | read_rb, + SRAW = read_rs | read_rb, + SRAD = read_rs | read_rb, + LVRXL = LVRX, + DSS = 0, + SRAWI = read_rs, + SRADI = read_rs, + EIEIO = 0, + STVLXL = STVLX, + STHBRX = read_rs | read_ra | read_rb, + EXTSH = read_rs, + STVRXL = STVRX, + EXTSB = read_rs, + STFIWX = read_ra | read_rb, + EXTSW = read_rs, + ICBI = 0, + DCBZ = read_ra | read_rb, + LWZ = read_ra, + LWZU = read_ra, + LBZ = read_ra, + LBZU = read_ra, + STW = read_rs | read_ra, + STWU = read_rs | read_ra, + STB = read_rs | read_ra, + STBU = read_rs | read_ra, + LHZ = read_ra, + LHZU = read_ra, + LHA = read_ra, + LHAU = read_ra, + STH = read_rs | read_ra, + STHU = read_rs | read_ra, + LMW = rw_all, + STMW = rw_all, + LFS = read_ra, + LFSU = read_ra, + LFD = read_ra, + LFDU = read_ra, + STFS = read_ra, + STFSU = read_ra, + STFD = read_ra, + STFDU = read_ra, + LD = read_ra, + LDU = read_ra, + LWA = read_ra, + STD = read_rs | read_ra, + STDU = read_rs | read_ra, + FDIVS = 0, + FSUBS = 0, + FADDS = 0, + FSQRTS = 0, + FRES = 0, + FMULS = 0, + FMADDS = 0, + FMSUBS = 0, + FNMSUBS = 0, + FNMADDS = 0, + MTFSB1 = 0, + MCRFS = 0, + MTFSB0 = 0, + MTFSFI = 0, + MFFS = 0, + MTFSF = 0, + FCMPU = 0, + FRSP = 0, + FCTIW = 0, + FCTIWZ = 0, + FDIV = 0, + FSUB = 0, + FADD = 0, + FSQRT = 0, + FSEL = 0, + FMUL = 0, + FRSQRTE = 0, + FMSUB = 0, + FMADD = 0, + FNMSUB = 0, + FNMADD = 0, + FCMPO = 0, + FNEG = 0, + FMR = 0, + FNABS = 0, + FABS = 0, + FCTID = 0, + FCTIDZ = 0, + FCFID = 0, + }; + + // Enable address-of operator for ppu_decoder<> + friend constexpr flags operator &(flags 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) {