From 54dc617f391f2a028e2c8efbab963334ae2d85fa Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 2 May 2019 19:25:00 +0300 Subject: [PATCH] SPU analyser: internal spu_itype optimization Use only 1 byte for instruction type. Flags are transformed into range comparisons. --- rpcs3/Emu/Cell/SPUAnalyser.h | 198 +++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 92 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUAnalyser.h b/rpcs3/Emu/Cell/SPUAnalyser.h index 04779d2b97..808dd8ce70 100644 --- a/rpcs3/Emu/Cell/SPUAnalyser.h +++ b/rpcs3/Emu/Cell/SPUAnalyser.h @@ -3,20 +3,16 @@ // SPU Instruction Type struct spu_itype { - enum - { - memory = 1 << 8, // Memory Load/Store Instructions - constant = 1 << 9, // Constant Formation Instructions - integer = 1 << 10, // Integer and Logical Instructions - shiftrot = 1 << 11, // Shift and Rotate Instructions - compare = 1 << 12, // Compare Instructions - branch = 1 << 13, // Branch Instructions - floating = 1 << 14, // Floating-Point Instructions + static constexpr struct memory_tag{} memory{}; // Memory Load/Store Instructions + static constexpr struct constant_tag{} constant{}; // Constant Formation Instructions + static constexpr struct integer_tag{} integer{}; // Integer and Logical Instructions + static constexpr struct shiftrot_tag{} shiftrot{}; // Shift and Rotate Instructions + static constexpr struct compare_tag{} compare{}; // Compare Instructions + static constexpr struct branch_tag{} branch{}; // Branch Instructions + static constexpr struct floating_tag{} floating{}; // Floating-Point Instructions + static constexpr struct quadrop_tag{} _quadrop{}; // 4-op Instructions - _quadrop = 1 << 15, // 4-op Instructions - }; - - enum type + enum type : unsigned char { UNK = 0, @@ -43,16 +39,33 @@ struct spu_itype RCHCNT, WRCH, - LQD = memory, + BR, // branch_tag first + BRA, + BRNZ, + BRZ, + BRHNZ, + BRHZ, + BRSL, + BRASL, + IRET, + BI, + BISLED, + BISL, + BIZ, + BINZ, + BIHZ, + BIHNZ, // branch_tag last + + LQD, // memory_tag first LQX, LQA, LQR, STQD, STQX, STQA, - STQR, + STQR, // memory_tag last - CBD = constant, + CBD, // constant_tag first CBX, CHD, CHX, @@ -65,9 +78,9 @@ struct spu_itype IL, ILA, IOHL, - FSMBI, + FSMBI, // constant_tag last - AH = integer, + AH, // integer_tag first AHI, A, AI, @@ -124,79 +137,15 @@ struct spu_itype NOR, EQV, - MPYA = integer | _quadrop, + MPYA, // quadrop_tag first SELB, - SHUFB, + SHUFB, // integer_tag last - SHLH = shiftrot, - SHLHI, - SHL, - SHLI, - SHLQBI, - SHLQBII, - SHLQBY, - SHLQBYI, - SHLQBYBI, - ROTH, - ROTHI, - ROT, - ROTI, - ROTQBY, - ROTQBYI, - ROTQBYBI, - ROTQBI, - ROTQBII, - ROTHM, - ROTHMI, - ROTM, - ROTMI, - ROTQMBY, - ROTQMBYI, - ROTQMBYBI, - ROTQMBI, - ROTQMBII, - ROTMAH, - ROTMAHI, - ROTMA, - ROTMAI, + FMA, // floating_tag first + FNMS, + FMS, // quadrop_tag last - CEQB = compare, - CEQBI, - CEQH, - CEQHI, - CEQ, - CEQI, - CGTB, - CGTBI, - CGTH, - CGTHI, - CGT, - CGTI, - CLGTB, - CLGTBI, - CLGTH, - CLGTHI, - CLGT, - CLGTI, - - BR = branch, - BRA, - BRSL, - BRASL, - BI, - IRET, - BISLED, - BISL, - BRNZ, - BRZ, - BRHNZ, - BRHZ, - BIZ, - BINZ, - BIHZ, - BIHNZ, - - FA = floating, + FA, DFA, FS, DFS, @@ -226,11 +175,58 @@ struct spu_itype DFCMEQ, DFCGT, DFCMGT, - DFTSV, + DFTSV, // floating_tag last - FMA = floating | _quadrop, - FNMS, - FMS, + SHLH, // shiftrot_tag first + SHLHI, + SHL, + SHLI, + SHLQBI, + SHLQBII, + SHLQBY, + SHLQBYI, + SHLQBYBI, + ROTH, + ROTHI, + ROT, + ROTI, + ROTQBY, + ROTQBYI, + ROTQBYBI, + ROTQBI, + ROTQBII, + ROTHM, + ROTHMI, + ROTM, + ROTMI, + ROTQMBY, + ROTQMBYI, + ROTQMBYBI, + ROTQMBI, + ROTQMBII, + ROTMAH, + ROTMAHI, + ROTMA, + ROTMAI, // shiftrot_tag last + + CEQB, // compare_tag first + CEQBI, + CEQH, + CEQHI, + CEQ, + CEQI, + CGTB, + CGTBI, + CGTH, + CGTHI, + CGT, + CGTI, + CLGTB, + CLGTBI, + CLGTH, + CLGTHI, + CLGT, + CLGTI, // compare_tag last }; // Enable address-of operator for spu_decoder<> @@ -238,6 +234,24 @@ struct spu_itype { return value; } + + // Test for branch instruction + friend constexpr bool operator &(type value, branch_tag) + { + return value >= BR && value <= BIHNZ; + } + + // Test for floating point instruction + friend constexpr bool operator &(type value, floating_tag) + { + return value >= FMA && value <= DFTSV; + } + + // Test for 4-op instruction + friend constexpr bool operator &(type value, quadrop_tag) + { + return value >= MPYA && value <= FMS; + } }; struct spu_iflag