diff options
Diffstat (limited to 'compiler_and_linker/BackEnd/PowerPC/Scheduler')
9 files changed, 5834 insertions, 0 deletions
diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation601.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation601.c new file mode 100644 index 0000000..2d54678 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation601.c @@ -0,0 +1,552 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://stuff.mit.edu/afs/sipb/contrib/doc/specs/ic/cpu/powerpc/mpc601.pdf +// https://www.nxp.com/docs/en/user-guide/MPC601UMAD.pdf + +typedef enum Stage { + IU, // Integer Unit + FD, // FP Decode + FPM, // FP Multiply + FPA, // FP Add + FWA, // FP Arithmetic Writeback + BPU, // Branch Processing Unit + NumStages, + Serialize, // special form for instructions that use IU but are serialised + Unsupported // instructions not supported by this processor +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[4]; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 1, // PC_B + BPU, 0, 0, 0, 0, 1, // PC_BL + BPU, 0, 0, 0, 0, 1, // PC_BC + BPU, 0, 0, 0, 0, 1, // PC_BCLR + BPU, 0, 0, 0, 0, 1, // PC_BCCTR + BPU, 0, 0, 0, 0, 1, // PC_BT + BPU, 0, 0, 0, 0, 1, // PC_BTLR + BPU, 0, 0, 0, 0, 1, // PC_BTCTR + BPU, 0, 0, 0, 0, 1, // PC_BF + BPU, 0, 0, 0, 0, 1, // PC_BFLR + BPU, 0, 0, 0, 0, 1, // PC_BFCTR + BPU, 0, 0, 0, 0, 1, // PC_BDNZ + BPU, 0, 0, 0, 0, 1, // PC_BDNZT + BPU, 0, 0, 0, 0, 1, // PC_BDNZF + BPU, 0, 0, 0, 0, 1, // PC_BDZ + BPU, 0, 0, 0, 0, 1, // PC_BDZT + BPU, 0, 0, 0, 0, 1, // PC_BDZF + BPU, 0, 0, 0, 0, 1, // PC_BLR + BPU, 0, 0, 0, 0, 1, // PC_BCTR + BPU, 0, 0, 0, 0, 1, // PC_BCTRL + BPU, 0, 0, 0, 0, 1, // PC_BLRL + IU, 2, 1, 0, 0, 0, // PC_LBZ + IU, 2, 1, 0, 0, 0, // PC_LBZU + IU, 2, 1, 0, 0, 0, // PC_LBZX + IU, 2, 1, 0, 0, 0, // PC_LBZUX + IU, 2, 1, 0, 0, 0, // PC_LHZ + IU, 2, 1, 0, 0, 0, // PC_LHZU + IU, 2, 1, 0, 0, 0, // PC_LHZX + IU, 2, 1, 0, 0, 0, // PC_LHZUX + IU, 2, 1, 0, 0, 0, // PC_LHA + IU, 2, 1, 0, 0, 0, // PC_LHAU + IU, 2, 1, 0, 0, 0, // PC_LHAX + IU, 2, 1, 0, 0, 0, // PC_LHAUX + IU, 2, 1, 0, 0, 0, // PC_LHBRX + IU, 2, 1, 0, 0, 0, // PC_LWZ + IU, 2, 1, 0, 0, 0, // PC_LWZU + IU, 2, 1, 0, 0, 0, // PC_LWZX + IU, 2, 1, 0, 0, 0, // PC_LWZUX + IU, 2, 1, 0, 0, 0, // PC_LWBRX + IU, 1, 1, 0, 0, 0, // PC_LMW + IU, 1, 1, 0, 0, 0, // PC_STB + IU, 1, 1, 0, 0, 0, // PC_STBU + IU, 1, 1, 0, 0, 0, // PC_STBX + IU, 1, 1, 0, 0, 0, // PC_STBUX + IU, 1, 1, 0, 0, 0, // PC_STH + IU, 1, 1, 0, 0, 0, // PC_STHU + IU, 1, 1, 0, 0, 0, // PC_STHX + IU, 1, 1, 0, 0, 0, // PC_STHUX + IU, 1, 1, 0, 0, 0, // PC_STHBRX + IU, 1, 1, 0, 0, 0, // PC_STW + IU, 1, 1, 0, 0, 0, // PC_STWU + IU, 1, 1, 0, 0, 0, // PC_STWX + IU, 1, 1, 0, 0, 0, // PC_STWUX + IU, 1, 1, 0, 0, 0, // PC_STWBRX + IU, 1, 1, 0, 0, 0, // PC_STMW + IU, 2, 1, 0, 0, 0, // PC_DCBF + IU, 2, 1, 0, 0, 0, // PC_DCBST + IU, 2, 1, 0, 0, 0, // PC_DCBT + IU, 2, 1, 0, 0, 0, // PC_DCBTST + IU, 2, 1, 0, 0, 0, // PC_DCBZ + IU, 1, 1, 0, 0, 0, // PC_ADD + IU, 1, 1, 0, 0, 0, // PC_ADDC + IU, 1, 1, 0, 0, 0, // PC_ADDE + IU, 1, 1, 0, 0, 0, // PC_ADDI + IU, 1, 1, 0, 0, 0, // PC_ADDIC + IU, 1, 1, 0, 0, 0, // PC_ADDICR + IU, 1, 1, 0, 0, 0, // PC_ADDIS + IU, 1, 1, 0, 0, 0, // PC_ADDME + IU, 1, 1, 0, 0, 0, // PC_ADDZE + IU, 36, 36, 0, 0, 0, // PC_DIVW + IU, 36, 36, 0, 0, 0, // PC_DIVWU + IU, 5, 5, 0, 0, 0, // PC_MULHW + IU, 5, 5, 0, 0, 0, // PC_MULHWU + IU, 5, 5, 0, 0, 0, // PC_MULLI + IU, 5, 5, 0, 0, 0, // PC_MULLW + IU, 1, 1, 0, 0, 0, // PC_NEG + IU, 1, 1, 0, 0, 0, // PC_SUBF + IU, 1, 1, 0, 0, 0, // PC_SUBFC + IU, 1, 1, 0, 0, 0, // PC_SUBFE + IU, 1, 1, 0, 0, 0, // PC_SUBFIC + IU, 1, 1, 0, 0, 0, // PC_SUBFME + IU, 1, 1, 0, 0, 0, // PC_SUBFZE + IU, 3, 1, 0, 0, 0, // PC_CMPI + IU, 3, 1, 0, 0, 0, // PC_CMP + IU, 3, 1, 0, 0, 0, // PC_CMPLI + IU, 3, 1, 0, 0, 0, // PC_CMPL + IU, 1, 1, 0, 0, 0, // PC_ANDI + IU, 1, 1, 0, 0, 0, // PC_ANDIS + IU, 1, 1, 0, 0, 0, // PC_ORI + IU, 1, 1, 0, 0, 0, // PC_ORIS + IU, 1, 1, 0, 0, 0, // PC_XORI + IU, 1, 1, 0, 0, 0, // PC_XORIS + IU, 1, 1, 0, 0, 0, // PC_AND + IU, 1, 1, 0, 0, 0, // PC_OR + IU, 1, 1, 0, 0, 0, // PC_XOR + IU, 1, 1, 0, 0, 0, // PC_NAND + IU, 1, 1, 0, 0, 0, // PC_NOR + IU, 1, 1, 0, 0, 0, // PC_EQV + IU, 1, 1, 0, 0, 0, // PC_ANDC + IU, 1, 1, 0, 0, 0, // PC_ORC + IU, 1, 1, 0, 0, 0, // PC_EXTSB + IU, 1, 1, 0, 0, 0, // PC_EXTSH + IU, 1, 1, 0, 0, 0, // PC_CNTLZW + IU, 1, 1, 0, 0, 0, // PC_RLWINM + IU, 1, 1, 0, 0, 0, // PC_RLWNM + IU, 1, 1, 0, 0, 0, // PC_RLWIMI + IU, 1, 1, 0, 0, 0, // PC_SLW + IU, 1, 1, 0, 0, 0, // PC_SRW + IU, 1, 1, 0, 0, 0, // PC_SRAWI + IU, 1, 1, 0, 0, 0, // PC_SRAW + IU, 1, 1, 0, 0, 0, // PC_CRAND + IU, 1, 1, 0, 0, 0, // PC_CRANDC + IU, 1, 1, 0, 0, 0, // PC_CREQV + IU, 1, 1, 0, 0, 0, // PC_CRNAND + IU, 1, 1, 0, 0, 0, // PC_CRNOR + IU, 1, 1, 0, 0, 0, // PC_CROR + IU, 1, 1, 0, 0, 0, // PC_CRORC + IU, 1, 1, 0, 0, 0, // PC_CRXOR + IU, 1, 1, 0, 0, 0, // PC_MCRF + IU, 4, 1, 0, 0, 0, // PC_MTXER + IU, 4, 1, 0, 0, 0, // PC_MTCTR + IU, 4, 1, 0, 0, 0, // PC_MTLR + IU, 2, 1, 0, 0, 0, // PC_MTCRF + IU, 1, 0, 0, 0, 0, // PC_MTMSR + IU, 1, 0, 0, 0, 0, // PC_MTSPR + IU, 1, 0, 0, 0, 0, // PC_MFMSR + IU, 1, 0, 0, 0, 0, // PC_MFSPR + IU, 1, 1, 0, 0, 0, // PC_MFXER + IU, 1, 1, 0, 0, 0, // PC_MFCTR + IU, 1, 1, 0, 0, 0, // PC_MFLR + IU, 1, 1, 0, 0, 0, // PC_MFCR + FD, 4, 1, 1, 1, 1, // PC_MFFS + FD, 4, 1, 1, 1, 1, // PC_MTFSF + Serialize, 1, 1, 0, 0, 1, // PC_EIEIO + Serialize, 1, 1, 0, 0, 1, // PC_ISYNC + Serialize, 1, 1, 0, 0, 1, // PC_SYNC + Serialize, 0, 0, 0, 0, 1, // PC_RFI + IU, 1, 1, 0, 0, 0, // PC_LI + IU, 1, 1, 0, 0, 0, // PC_LIS + IU, 1, 1, 0, 0, 0, // PC_MR + IU, 1, 1, 0, 0, 0, // PC_NOP + IU, 1, 1, 0, 0, 0, // PC_NOT + IU, 3, 1, 0, 0, 0, // PC_LFS + IU, 3, 1, 0, 0, 0, // PC_LFSU + IU, 3, 1, 0, 0, 0, // PC_LFSX + IU, 3, 1, 0, 0, 0, // PC_LFSUX + IU, 3, 1, 0, 0, 0, // PC_LFD + IU, 3, 1, 0, 0, 0, // PC_LFDU + IU, 3, 1, 0, 0, 0, // PC_LFDX + IU, 3, 1, 0, 0, 0, // PC_LFDUX + IU, 1, 1, 0, 0, 0, // PC_STFS + IU, 1, 1, 0, 0, 0, // PC_STFSU + IU, 1, 1, 0, 0, 0, // PC_STFSX + IU, 1, 1, 0, 0, 0, // PC_STFSUX + IU, 1, 1, 0, 0, 0, // PC_STFD + IU, 1, 1, 0, 0, 0, // PC_STFDU + IU, 1, 1, 0, 0, 0, // PC_STFDX + IU, 1, 1, 0, 0, 0, // PC_STFDUX + FD, 4, 1, 1, 1, 1, // PC_FMR + FD, 4, 1, 1, 1, 1, // PC_FABS + FD, 4, 1, 1, 1, 1, // PC_FNEG + FD, 4, 1, 1, 1, 1, // PC_FNABS + FD, 4, 1, 1, 1, 1, // PC_FADD + FD, 4, 1, 1, 1, 1, // PC_FADDS + FD, 4, 1, 1, 1, 1, // PC_FSUB + FD, 4, 1, 1, 1, 1, // PC_FSUBS + FD, 5, 1, 1, 2, 1, // PC_FMUL + FD, 4, 1, 1, 1, 1, // PC_FMULS + FD, 31, 1, 1, 28, 1, // PC_FDIV + FD, 17, 1, 1, 14, 1, // PC_FDIVS + FD, 5, 1, 1, 2, 1, // PC_FMADD + FD, 4, 1, 1, 1, 1, // PC_FMADDS + FD, 5, 1, 1, 2, 1, // PC_FMSUB + FD, 4, 1, 1, 1, 1, // PC_FMSUBS + FD, 5, 1, 1, 2, 1, // PC_FNMADD + FD, 4, 1, 1, 1, 1, // PC_FNMADDS + FD, 5, 1, 1, 2, 1, // PC_FNMSUB + FD, 4, 1, 1, 1, 1, // PC_FNMSUBS + FD, 4, 1, 1, 1, 1, // PC_FRES + FD, 4, 1, 1, 1, 1, // PC_FRSQRTE + FD, 4, 1, 1, 1, 1, // PC_FSEL + FD, 4, 1, 1, 1, 1, // PC_FRSP + FD, 4, 1, 1, 1, 1, // PC_FCTIW + FD, 4, 1, 1, 1, 1, // PC_FCTIWZ + FD, 6, 1, 1, 1, 1, // PC_FCMPU + FD, 6, 1, 1, 1, 1, // PC_FCMPO + IU, 0, 0, 0, 0, 0, // PC_LWARX + IU, 0, 0, 0, 0, 0, // PC_LSWI + IU, 0, 0, 0, 0, 0, // PC_LSWX + IU, 0, 0, 0, 0, 0, // PC_STFIWX + IU, 0, 0, 0, 0, 0, // PC_STSWI + IU, 0, 0, 0, 0, 0, // PC_STSWX + IU, 0, 0, 0, 0, 0, // PC_STWCX + IU, 0, 0, 0, 0, 0, // PC_ECIWX + IU, 0, 0, 0, 0, 0, // PC_ECOWX + IU, 0, 0, 0, 0, 0, // PC_DCBI + IU, 0, 0, 0, 0, 0, // PC_ICBI + IU, 0, 0, 0, 0, 0, // PC_MCRFS + IU, 0, 0, 0, 0, 0, // PC_MCRXR + IU, 0, 0, 0, 0, 0, // PC_MFTB + IU, 0, 0, 0, 0, 0, // PC_MFSR + IU, 0, 0, 0, 0, 0, // PC_MTSR + IU, 0, 0, 0, 0, 0, // PC_MFSRIN + IU, 0, 0, 0, 0, 0, // PC_MTSRIN + IU, 0, 0, 0, 0, 0, // PC_MTFSB0 + IU, 0, 0, 0, 0, 0, // PC_MTFSB1 + IU, 0, 0, 0, 0, 0, // PC_MTFSFI + Serialize, 0, 0, 0, 0, 0, // PC_SC + IU, 0, 0, 0, 0, 0, // PC_FSQRT + IU, 0, 0, 0, 0, 0, // PC_FSQRTS + IU, 0, 0, 0, 0, 0, // PC_TLBIA + IU, 0, 0, 0, 0, 0, // PC_TLBIE + IU, 0, 0, 0, 0, 0, // PC_TLBLD + IU, 0, 0, 0, 0, 0, // PC_TLBLI + IU, 0, 0, 0, 0, 0, // PC_TLBSYNC + Serialize, 0, 0, 0, 0, 0, // PC_TW + Serialize, 0, 0, 0, 0, 0, // PC_TRAP + Serialize, 0, 0, 0, 0, 0, // PC_TWI + Serialize, 0, 0, 0, 0, 0, // PC_OPWORD + IU, 0, 0, 0, 0, 0, // PC_MFROM + IU, 0, 0, 0, 0, 0, // PC_DSA + IU, 0, 0, 0, 0, 0, // PC_ESA + IU, 0, 0, 0, 0, 0, // PC_DCCCI + IU, 0, 0, 0, 0, 0, // PC_DCREAD + IU, 0, 0, 0, 0, 0, // PC_ICBT + IU, 0, 0, 0, 0, 0, // PC_ICCCI + IU, 0, 0, 0, 0, 0, // PC_ICREAD + IU, 0, 0, 0, 0, 0, // PC_RFCI + IU, 0, 0, 0, 0, 0, // PC_TLBRE + IU, 0, 0, 0, 0, 0, // PC_TLBSX + IU, 0, 0, 0, 0, 0, // PC_TLBWE + IU, 0, 0, 0, 0, 0, // PC_WRTEE + IU, 0, 0, 0, 0, 0, // PC_WRTEEI + IU, 0, 0, 0, 0, 0, // PC_MFDCR + IU, 0, 0, 0, 0, 0, // PC_MTDCR + Unsupported, 0, 0, 0, 0, 0, // PC_DCBA + Unsupported, 0, 0, 0, 0, 0, // PC_DSS + Unsupported, 0, 0, 0, 0, 0, // PC_DSSALL + Unsupported, 0, 0, 0, 0, 0, // PC_DST + Unsupported, 0, 0, 0, 0, 0, // PC_DSTT + Unsupported, 0, 0, 0, 0, 0, // PC_DSTST + Unsupported, 0, 0, 0, 0, 0, // PC_DSTSTT + Unsupported, 0, 0, 0, 0, 0, // PC_LVEBX + Unsupported, 0, 0, 0, 0, 0, // PC_LVEHX + Unsupported, 0, 0, 0, 0, 0, // PC_LVEWX + Unsupported, 0, 0, 0, 0, 0, // PC_LVSL + Unsupported, 0, 0, 0, 0, 0, // PC_LVSR + Unsupported, 0, 0, 0, 0, 0, // PC_LVX + Unsupported, 0, 0, 0, 0, 0, // PC_LVXL + Unsupported, 0, 0, 0, 0, 0, // PC_STVEBX + Unsupported, 0, 0, 0, 0, 0, // PC_STVEHX + Unsupported, 0, 0, 0, 0, 0, // PC_STVEWX + Unsupported, 0, 0, 0, 0, 0, // PC_STVX + Unsupported, 0, 0, 0, 0, 0, // PC_STVXL + Unsupported, 0, 0, 0, 0, 0, // PC_MFVSCR + Unsupported, 0, 0, 0, 0, 0, // PC_MTVSCR + Unsupported, 0, 0, 0, 0, 0, // PC_VADDCUW + Unsupported, 0, 0, 0, 0, 0, // PC_VADDFP + Unsupported, 0, 0, 0, 0, 0, // PC_VADDSBS + Unsupported, 0, 0, 0, 0, 0, // PC_VADDSHS + Unsupported, 0, 0, 0, 0, 0, // PC_VADDSWS + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUBM + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUBS + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUHM + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUHS + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUWM + Unsupported, 0, 0, 0, 0, 0, // PC_VADDUWS + Unsupported, 0, 0, 0, 0, 0, // PC_VAND + Unsupported, 0, 0, 0, 0, 0, // PC_VANDC + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSB + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSH + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGSW + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUB + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUH + Unsupported, 0, 0, 0, 0, 0, // PC_VAVGUW + Unsupported, 0, 0, 0, 0, 0, // PC_VCFSX + Unsupported, 0, 0, 0, 0, 0, // PC_VCFUX + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPBFP + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQFP + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUB + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUH + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPEQUW + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGEFP + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTFP + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSB + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSH + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTSW + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUB + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUH + Unsupported, 0, 0, 0, 0, 0, // PC_VCMPGTUW + Unsupported, 0, 0, 0, 0, 0, // PC_VCTSXS + Unsupported, 0, 0, 0, 0, 0, // PC_VCTUXS + Unsupported, 0, 0, 0, 0, 0, // PC_VEXPTEFP + Unsupported, 0, 0, 0, 0, 0, // PC_VLOGEFP + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXFP + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSB + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSH + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXSW + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUB + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUH + Unsupported, 0, 0, 0, 0, 0, // PC_VMAXUW + Unsupported, 0, 0, 0, 0, 0, // PC_VMINFP + Unsupported, 0, 0, 0, 0, 0, // PC_VMINSB + Unsupported, 0, 0, 0, 0, 0, // PC_VMINSH + Unsupported, 0, 0, 0, 0, 0, // PC_VMINSW + Unsupported, 0, 0, 0, 0, 0, // PC_VMINUB + Unsupported, 0, 0, 0, 0, 0, // PC_VMINUH + Unsupported, 0, 0, 0, 0, 0, // PC_VMINUW + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHB + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHH + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGHW + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLB + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLH + Unsupported, 0, 0, 0, 0, 0, // PC_VMRGLW + Unsupported, 0, 0, 0, 0, 0, // PC_VMULESB + Unsupported, 0, 0, 0, 0, 0, // PC_VMULESH + Unsupported, 0, 0, 0, 0, 0, // PC_VMULEUB + Unsupported, 0, 0, 0, 0, 0, // PC_VMULEUH + Unsupported, 0, 0, 0, 0, 0, // PC_VMULOSB + Unsupported, 0, 0, 0, 0, 0, // PC_VMULOSH + Unsupported, 0, 0, 0, 0, 0, // PC_VMULOUB + Unsupported, 0, 0, 0, 0, 0, // PC_VMULOUH + Unsupported, 0, 0, 0, 0, 0, // PC_VNOR + Unsupported, 0, 0, 0, 0, 0, // PC_VOR + Unsupported, 0, 0, 0, 0, 0, // PC_VPKPX + Unsupported, 0, 0, 0, 0, 0, // PC_VPKSHSS + Unsupported, 0, 0, 0, 0, 0, // PC_VPKSHUS + Unsupported, 0, 0, 0, 0, 0, // PC_VPKSWSS + Unsupported, 0, 0, 0, 0, 0, // PC_VPKSWUS + Unsupported, 0, 0, 0, 0, 0, // PC_VPKUHUM + Unsupported, 0, 0, 0, 0, 0, // PC_VPKUHUS + Unsupported, 0, 0, 0, 0, 0, // PC_VPKUWUM + Unsupported, 0, 0, 0, 0, 0, // PC_VPKUWUS + Unsupported, 0, 0, 0, 0, 0, // PC_VREFP + Unsupported, 0, 0, 0, 0, 0, // PC_VRFIM + Unsupported, 0, 0, 0, 0, 0, // PC_VRFIN + Unsupported, 0, 0, 0, 0, 0, // PC_VRFIP + Unsupported, 0, 0, 0, 0, 0, // PC_VRFIZ + Unsupported, 0, 0, 0, 0, 0, // PC_VRLB + Unsupported, 0, 0, 0, 0, 0, // PC_VRLH + Unsupported, 0, 0, 0, 0, 0, // PC_VRLW + Unsupported, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + Unsupported, 0, 0, 0, 0, 0, // PC_VSL + Unsupported, 0, 0, 0, 0, 0, // PC_VSLB + Unsupported, 0, 0, 0, 0, 0, // PC_VSLH + Unsupported, 0, 0, 0, 0, 0, // PC_VSLO + Unsupported, 0, 0, 0, 0, 0, // PC_VSLW + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTB + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTH + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTW + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISB + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISH + Unsupported, 0, 0, 0, 0, 0, // PC_VSPLTISW + Unsupported, 0, 0, 0, 0, 0, // PC_VSR + Unsupported, 0, 0, 0, 0, 0, // PC_VSRAB + Unsupported, 0, 0, 0, 0, 0, // PC_VSRAH + Unsupported, 0, 0, 0, 0, 0, // PC_VSRAW + Unsupported, 0, 0, 0, 0, 0, // PC_VSRB + Unsupported, 0, 0, 0, 0, 0, // PC_VSRH + Unsupported, 0, 0, 0, 0, 0, // PC_VSRO + Unsupported, 0, 0, 0, 0, 0, // PC_VSRW + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBCUW + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBFP + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSBS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSHS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBSWS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUBM + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUBS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUHM + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUHS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUWM + Unsupported, 0, 0, 0, 0, 0, // PC_VSUBUWS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUMSWS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUFPMSWS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWASBS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWASHS + Unsupported, 0, 0, 0, 0, 0, // PC_VSUFWAUBS + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHPX + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHSB + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKHSH + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLPX + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLSB + Unsupported, 0, 0, 0, 0, 0, // PC_VUPKLSH + Unsupported, 0, 0, 0, 0, 0, // PC_VXOR + Unsupported, 0, 0, 0, 0, 0, // PC_VMADDFP + Unsupported, 0, 0, 0, 0, 0, // PC_VMHADDSHS + Unsupported, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + Unsupported, 0, 0, 0, 0, 0, // PC_VMLADDUHM + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMMBM + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMSHM + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMSHS + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUBM + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUHM + Unsupported, 0, 0, 0, 0, 0, // PC_VMSUMUHS + Unsupported, 0, 0, 0, 0, 0, // PC_VNMSUBFP + Unsupported, 0, 0, 0, 0, 0, // PC_VPERM + Unsupported, 0, 0, 0, 0, 0, // PC_VSEL + Unsupported, 0, 0, 0, 0, 0, // PC_VSLDOI + Unsupported, 0, 0, 0, 0, 0, // PC_VMR + Unsupported, 0, 0, 0, 0, 0, // PC_VMRP + IU, 0, 0, 0, 0, 0, // PC_SLE + IU, 0, 0, 0, 0, 0, // PC_SLEQ + IU, 0, 0, 0, 0, 0, // PC_SLIQ + IU, 0, 0, 0, 0, 0, // PC_SLLIQ + IU, 0, 0, 0, 0, 0, // PC_SLLQ + IU, 0, 0, 0, 0, 0, // PC_SLQ + IU, 0, 0, 0, 0, 0, // PC_SRAIQ + IU, 0, 0, 0, 0, 0, // PC_SRAQ + IU, 0, 0, 0, 0, 0, // PC_SRE + IU, 0, 0, 0, 0, 0, // PC_SREA + IU, 0, 0, 0, 0, 0, // PC_SREQ + IU, 0, 0, 0, 0, 0, // PC_SRIQ + IU, 0, 0, 0, 0, 0, // PC_SRLIQ + IU, 0, 0, 0, 0, 0, // PC_SRLQ + IU, 0, 0, 0, 0, 0, // PC_SRQ + IU, 0, 0, 0, 0, 0, // PC_MASKG + IU, 0, 0, 0, 0, 0, // PC_MASKIR + IU, 0, 0, 0, 0, 0, // PC_LSCBX + IU, 0, 0, 0, 0, 0, // PC_DIV + IU, 0, 0, 0, 0, 0, // PC_DIVS + IU, 0, 0, 0, 0, 0, // PC_DOZ + IU, 0, 0, 0, 0, 0, // PC_MUL + IU, 0, 0, 0, 0, 0, // PC_NABS + IU, 0, 0, 0, 0, 0, // PC_ABS + IU, 0, 0, 0, 0, 0, // PC_CLCS + IU, 0, 0, 0, 0, 0, // PC_DOZI + IU, 0, 0, 0, 0, 0, // PC_RLMI + IU, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int stageCount, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - stageCount]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void complete_instruction(int stage) { + pipeline[stage].instr = NULL; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; +} + +static int can_issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + if (stage == Serialize) + stage = IU; + if (pipeline[stage].instr) + return 0; + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[IU]; + if (stage == Serialize) + stage = IU; + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (pipeline[IU].instr && pipeline[IU].remaining == 0) + complete_instruction(IU); + if (pipeline[FWA].instr && pipeline[FWA].remaining == 0) + complete_instruction(FWA); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + + if (pipeline[FPA].instr && pipeline[FPA].remaining == 0 && !pipeline[FWA].instr) + advance(1, FPA, FWA); + if (pipeline[FPM].instr && pipeline[FPM].remaining == 0 && !pipeline[FPA].instr) + advance(1, FPM, FPA); + if (pipeline[FD].instr && pipeline[FD].remaining == 0 && !pipeline[FPM].instr) + advance(1, FD, FPM); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].stage == Serialize; +} + +MachineInfo machine601 = { + 2, + 0, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603.c new file mode 100644 index 0000000..49d1ea0 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603.c @@ -0,0 +1,626 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// this is actually for 603e, but i couldn't find the 603 doc +// https://www.nxp.com/docs/en/reference-manual/MPC603EUM.pdf + +typedef enum Stage { + BPU, // Branch Prediction Unit + IU, // Integer Unit + LSU1, // Load/Store Unit + LSU2, + FPU1, // Floating Point Unit + FPU2, + FPU3, + SRU, // System Register Unit + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +enum { + MaxEntries = 5 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 1, // PC_B + BPU, 0, 0, 0, 0, 1, // PC_BL + BPU, 0, 0, 0, 0, 1, // PC_BC + BPU, 0, 0, 0, 0, 1, // PC_BCLR + BPU, 0, 0, 0, 0, 1, // PC_BCCTR + BPU, 0, 0, 0, 0, 1, // PC_BT + BPU, 0, 0, 0, 0, 1, // PC_BTLR + BPU, 0, 0, 0, 0, 1, // PC_BTCTR + BPU, 0, 0, 0, 0, 1, // PC_BF + BPU, 0, 0, 0, 0, 1, // PC_BFLR + BPU, 0, 0, 0, 0, 1, // PC_BFCTR + BPU, 0, 0, 0, 0, 1, // PC_BDNZ + BPU, 0, 0, 0, 0, 1, // PC_BDNZT + BPU, 0, 0, 0, 0, 1, // PC_BDNZF + BPU, 0, 0, 0, 0, 1, // PC_BDZ + BPU, 0, 0, 0, 0, 1, // PC_BDZT + BPU, 0, 0, 0, 0, 1, // PC_BDZF + BPU, 0, 0, 0, 0, 1, // PC_BLR + BPU, 0, 0, 0, 0, 1, // PC_BCTR + BPU, 0, 0, 0, 0, 1, // PC_BCTRL + BPU, 0, 0, 0, 0, 1, // PC_BLRL + LSU1, 2, 1, 1, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 2, 1, 1, 0, 0, // PC_DCBF + LSU1, 2, 1, 1, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 2, 1, 1, 0, 0, // PC_DCBZ + IU, 1, 1, 0, 0, 0, // PC_ADD + IU, 1, 1, 0, 0, 0, // PC_ADDC + IU, 1, 1, 0, 0, 0, // PC_ADDE + IU, 1, 1, 0, 0, 0, // PC_ADDI + IU, 1, 1, 0, 0, 0, // PC_ADDIC + IU, 1, 1, 0, 0, 0, // PC_ADDICR + IU, 1, 1, 0, 0, 0, // PC_ADDIS + IU, 1, 1, 0, 0, 0, // PC_ADDME + IU, 1, 1, 0, 0, 0, // PC_ADDZE + IU, 37, 37, 0, 0, 0, // PC_DIVW + IU, 37, 37, 0, 0, 0, // PC_DIVWU + IU, 5, 5, 0, 0, 0, // PC_MULHW + IU, 5, 5, 0, 0, 0, // PC_MULHWU + IU, 3, 3, 0, 0, 0, // PC_MULLI + IU, 5, 5, 0, 0, 0, // PC_MULLW + IU, 1, 1, 0, 0, 0, // PC_NEG + IU, 1, 1, 0, 0, 0, // PC_SUBF + IU, 1, 1, 0, 0, 0, // PC_SUBFC + IU, 1, 1, 0, 0, 0, // PC_SUBFE + IU, 1, 1, 0, 0, 0, // PC_SUBFIC + IU, 1, 1, 0, 0, 0, // PC_SUBFME + IU, 1, 1, 0, 0, 0, // PC_SUBFZE + IU, 3, 1, 0, 0, 0, // PC_CMPI + IU, 3, 1, 0, 0, 0, // PC_CMP + IU, 3, 1, 0, 0, 0, // PC_CMPLI + IU, 3, 1, 0, 0, 0, // PC_CMPL + IU, 1, 1, 0, 0, 0, // PC_ANDI + IU, 1, 1, 0, 0, 0, // PC_ANDIS + IU, 1, 1, 0, 0, 0, // PC_ORI + IU, 1, 1, 0, 0, 0, // PC_ORIS + IU, 1, 1, 0, 0, 0, // PC_XORI + IU, 1, 1, 0, 0, 0, // PC_XORIS + IU, 1, 1, 0, 0, 0, // PC_AND + IU, 1, 1, 0, 0, 0, // PC_OR + IU, 1, 1, 0, 0, 0, // PC_XOR + IU, 1, 1, 0, 0, 0, // PC_NAND + IU, 1, 1, 0, 0, 0, // PC_NOR + IU, 1, 1, 0, 0, 0, // PC_EQV + IU, 1, 1, 0, 0, 0, // PC_ANDC + IU, 1, 1, 0, 0, 0, // PC_ORC + IU, 1, 1, 0, 0, 0, // PC_EXTSB + IU, 1, 1, 0, 0, 0, // PC_EXTSH + IU, 1, 1, 0, 0, 0, // PC_CNTLZW + IU, 1, 1, 0, 0, 0, // PC_RLWINM + IU, 1, 1, 0, 0, 0, // PC_RLWNM + IU, 1, 1, 0, 0, 0, // PC_RLWIMI + IU, 1, 1, 0, 0, 0, // PC_SLW + IU, 1, 1, 0, 0, 0, // PC_SRW + IU, 1, 1, 0, 0, 0, // PC_SRAWI + IU, 1, 1, 0, 0, 0, // PC_SRAW + SRU, 1, 1, 0, 0, 0, // PC_CRAND + SRU, 1, 1, 0, 0, 0, // PC_CRANDC + SRU, 1, 1, 0, 0, 0, // PC_CREQV + SRU, 1, 1, 0, 0, 0, // PC_CRNAND + SRU, 1, 1, 0, 0, 0, // PC_CRNOR + SRU, 1, 1, 0, 0, 0, // PC_CROR + SRU, 1, 1, 0, 0, 0, // PC_CRORC + SRU, 1, 1, 0, 0, 0, // PC_CRXOR + SRU, 1, 1, 0, 0, 0, // PC_MCRF + SRU, 2, 2, 0, 0, 0, // PC_MTXER + SRU, 2, 2, 0, 0, 0, // PC_MTCTR + SRU, 2, 2, 0, 0, 0, // PC_MTLR + SRU, 1, 1, 0, 0, 0, // PC_MTCRF + SRU, 1, 1, 0, 0, 1, // PC_MTMSR + SRU, 1, 1, 0, 0, 1, // PC_MTSPR + SRU, 1, 1, 0, 0, 1, // PC_MFMSR + SRU, 1, 1, 0, 0, 1, // PC_MFSPR + SRU, 1, 1, 0, 0, 0, // PC_MFXER + SRU, 1, 1, 0, 0, 0, // PC_MFCTR + SRU, 1, 1, 0, 0, 0, // PC_MFLR + SRU, 1, 1, 0, 0, 0, // PC_MFCR + FPU1, 3, 1, 1, 1, 0, // PC_MFFS + FPU1, 3, 1, 1, 1, 0, // PC_MTFSF + SRU, 1, 1, 0, 0, 1, // PC_EIEIO + SRU, 1, 1, 0, 0, 1, // PC_ISYNC + SRU, 1, 1, 0, 0, 1, // PC_SYNC + SRU, 1, 1, 0, 0, 1, // PC_RFI + IU, 1, 1, 0, 0, 0, // PC_LI + IU, 1, 1, 0, 0, 0, // PC_LIS + IU, 1, 1, 0, 0, 0, // PC_MR + IU, 1, 1, 0, 0, 0, // PC_NOP + IU, 1, 1, 0, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, // PC_STFSUX + LSU1, 2, 1, 1, 0, 0, // PC_STFD + LSU1, 2, 1, 1, 0, 0, // PC_STFDU + LSU1, 2, 1, 1, 0, 0, // PC_STFDX + LSU1, 2, 1, 1, 0, 0, // PC_STFDUX + FPU1, 3, 1, 1, 1, 0, // PC_FMR + FPU1, 3, 1, 1, 1, 0, // PC_FABS + FPU1, 3, 1, 1, 1, 0, // PC_FNEG + FPU1, 3, 1, 1, 1, 0, // PC_FNABS + FPU1, 3, 1, 1, 1, 0, // PC_FADD + FPU1, 3, 1, 1, 1, 0, // PC_FADDS + FPU1, 3, 1, 1, 1, 0, // PC_FSUB + FPU1, 3, 1, 1, 1, 0, // PC_FSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FMUL + FPU1, 3, 1, 1, 1, 0, // PC_FMULS + FPU1, 33, 33, 0, 0, 0, // PC_FDIV + FPU1, 18, 18, 0, 0, 0, // PC_FDIVS + FPU1, 4, 2, 1, 1, 0, // PC_FMADD + FPU1, 3, 1, 1, 1, 0, // PC_FMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FNMADD + FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS + FPU1, 18, 18, 0, 0, 0, // PC_FRES + FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE + FPU1, 3, 1, 1, 1, 0, // PC_FSEL + FPU1, 3, 1, 1, 1, 0, // PC_FRSP + FPU1, 3, 1, 1, 1, 0, // PC_FCTIW + FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ + FPU1, 5, 1, 1, 1, 0, // PC_FCMPU + FPU1, 5, 1, 1, 1, 0, // PC_FCMPO + LSU1, 1, 1, 0, 0, 0, // PC_LWARX + LSU1, 1, 1, 0, 0, 0, // PC_LSWI + LSU1, 1, 1, 0, 0, 0, // PC_LSWX + LSU1, 1, 1, 0, 0, 0, // PC_STFIWX + LSU1, 1, 1, 0, 0, 0, // PC_STSWI + LSU1, 1, 1, 0, 0, 0, // PC_STSWX + LSU1, 1, 1, 0, 0, 0, // PC_STWCX + IU, 1, 1, 0, 0, 1, // PC_ECIWX + IU, 1, 1, 0, 0, 1, // PC_ECOWX + IU, 1, 1, 0, 0, 0, // PC_DCBI + IU, 1, 1, 0, 0, 0, // PC_ICBI + IU, 1, 1, 0, 0, 0, // PC_MCRFS + IU, 1, 1, 0, 0, 0, // PC_MCRXR + IU, 1, 1, 0, 0, 0, // PC_MFTB + IU, 1, 1, 0, 0, 0, // PC_MFSR + IU, 1, 1, 0, 0, 0, // PC_MTSR + IU, 1, 1, 0, 0, 0, // PC_MFSRIN + IU, 1, 1, 0, 0, 0, // PC_MTSRIN + IU, 1, 1, 0, 0, 0, // PC_MTFSB0 + IU, 1, 1, 0, 0, 0, // PC_MTFSB1 + IU, 1, 1, 0, 0, 0, // PC_MTFSFI + IU, 1, 1, 0, 0, 1, // PC_SC + FPU1, 1, 1, 0, 0, 0, // PC_FSQRT + FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS + IU, 1, 1, 0, 0, 0, // PC_TLBIA + IU, 1, 1, 0, 0, 0, // PC_TLBIE + IU, 1, 1, 0, 0, 0, // PC_TLBLD + IU, 1, 1, 0, 0, 0, // PC_TLBLI + IU, 1, 1, 0, 0, 0, // PC_TLBSYNC + IU, 1, 1, 0, 0, 1, // PC_TW + IU, 1, 1, 0, 0, 1, // PC_TRAP + IU, 1, 1, 0, 0, 1, // PC_TWI + IU, 1, 1, 0, 0, 1, // PC_OPWORD + IU, 1, 1, 0, 0, 0, // PC_MFROM + IU, 1, 1, 0, 0, 1, // PC_DSA + IU, 1, 1, 0, 0, 1, // PC_ESA + IU, 0, 0, 0, 0, 0, // PC_DCCCI + IU, 0, 0, 0, 0, 0, // PC_DCREAD + IU, 0, 0, 0, 0, 0, // PC_ICBT + IU, 0, 0, 0, 0, 0, // PC_ICCCI + IU, 0, 0, 0, 0, 0, // PC_ICREAD + IU, 0, 0, 0, 0, 0, // PC_RFCI + IU, 0, 0, 0, 0, 0, // PC_TLBRE + IU, 0, 0, 0, 0, 0, // PC_TLBSX + IU, 0, 0, 0, 0, 0, // PC_TLBWE + IU, 0, 0, 0, 0, 0, // PC_WRTEE + IU, 0, 0, 0, 0, 0, // PC_WRTEEI + IU, 0, 0, 0, 0, 0, // PC_MFDCR + IU, 0, 0, 0, 0, 0, // PC_MTDCR + IU, 0, 0, 0, 0, 0, // PC_DCBA + BPU, 0, 0, 0, 0, 0, // PC_DSS + BPU, 0, 0, 0, 0, 0, // PC_DSSALL + BPU, 0, 0, 0, 0, 0, // PC_DST + BPU, 0, 0, 0, 0, 0, // PC_DSTT + BPU, 0, 0, 0, 0, 0, // PC_DSTST + BPU, 0, 0, 0, 0, 0, // PC_DSTSTT + BPU, 0, 0, 0, 0, 0, // PC_LVEBX + BPU, 0, 0, 0, 0, 0, // PC_LVEHX + BPU, 0, 0, 0, 0, 0, // PC_LVEWX + BPU, 0, 0, 0, 0, 0, // PC_LVSL + BPU, 0, 0, 0, 0, 0, // PC_LVSR + BPU, 0, 0, 0, 0, 0, // PC_LVX + BPU, 0, 0, 0, 0, 0, // PC_LVXL + BPU, 0, 0, 0, 0, 0, // PC_STVEBX + BPU, 0, 0, 0, 0, 0, // PC_STVEHX + BPU, 0, 0, 0, 0, 0, // PC_STVEWX + BPU, 0, 0, 0, 0, 0, // PC_STVX + BPU, 0, 0, 0, 0, 0, // PC_STVXL + BPU, 0, 0, 0, 0, 0, // PC_MFVSCR + BPU, 0, 0, 0, 0, 0, // PC_MTVSCR + BPU, 0, 0, 0, 0, 0, // PC_VADDCUW + BPU, 0, 0, 0, 0, 0, // PC_VADDFP + BPU, 0, 0, 0, 0, 0, // PC_VADDSBS + BPU, 0, 0, 0, 0, 0, // PC_VADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VADDSWS + BPU, 0, 0, 0, 0, 0, // PC_VADDUBM + BPU, 0, 0, 0, 0, 0, // PC_VADDUBS + BPU, 0, 0, 0, 0, 0, // PC_VADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VADDUHS + BPU, 0, 0, 0, 0, 0, // PC_VADDUWM + BPU, 0, 0, 0, 0, 0, // PC_VADDUWS + BPU, 0, 0, 0, 0, 0, // PC_VAND + BPU, 0, 0, 0, 0, 0, // PC_VANDC + BPU, 0, 0, 0, 0, 0, // PC_VAVGSB + BPU, 0, 0, 0, 0, 0, // PC_VAVGSH + BPU, 0, 0, 0, 0, 0, // PC_VAVGSW + BPU, 0, 0, 0, 0, 0, // PC_VAVGUB + BPU, 0, 0, 0, 0, 0, // PC_VAVGUH + BPU, 0, 0, 0, 0, 0, // PC_VAVGUW + BPU, 0, 0, 0, 0, 0, // PC_VCFSX + BPU, 0, 0, 0, 0, 0, // PC_VCFUX + BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW + BPU, 0, 0, 0, 0, 0, // PC_VCTSXS + BPU, 0, 0, 0, 0, 0, // PC_VCTUXS + BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP + BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXSB + BPU, 0, 0, 0, 0, 0, // PC_VMAXSH + BPU, 0, 0, 0, 0, 0, // PC_VMAXSW + BPU, 0, 0, 0, 0, 0, // PC_VMAXUB + BPU, 0, 0, 0, 0, 0, // PC_VMAXUH + BPU, 0, 0, 0, 0, 0, // PC_VMAXUW + BPU, 0, 0, 0, 0, 0, // PC_VMINFP + BPU, 0, 0, 0, 0, 0, // PC_VMINSB + BPU, 0, 0, 0, 0, 0, // PC_VMINSH + BPU, 0, 0, 0, 0, 0, // PC_VMINSW + BPU, 0, 0, 0, 0, 0, // PC_VMINUB + BPU, 0, 0, 0, 0, 0, // PC_VMINUH + BPU, 0, 0, 0, 0, 0, // PC_VMINUW + BPU, 0, 0, 0, 0, 0, // PC_VMRGHB + BPU, 0, 0, 0, 0, 0, // PC_VMRGHH + BPU, 0, 0, 0, 0, 0, // PC_VMRGHW + BPU, 0, 0, 0, 0, 0, // PC_VMRGLB + BPU, 0, 0, 0, 0, 0, // PC_VMRGLH + BPU, 0, 0, 0, 0, 0, // PC_VMRGLW + BPU, 0, 0, 0, 0, 0, // PC_VMULESB + BPU, 0, 0, 0, 0, 0, // PC_VMULESH + BPU, 0, 0, 0, 0, 0, // PC_VMULEUB + BPU, 0, 0, 0, 0, 0, // PC_VMULEUH + BPU, 0, 0, 0, 0, 0, // PC_VMULOSB + BPU, 0, 0, 0, 0, 0, // PC_VMULOSH + BPU, 0, 0, 0, 0, 0, // PC_VMULOUB + BPU, 0, 0, 0, 0, 0, // PC_VMULOUH + BPU, 0, 0, 0, 0, 0, // PC_VNOR + BPU, 0, 0, 0, 0, 0, // PC_VOR + BPU, 0, 0, 0, 0, 0, // PC_VPKPX + BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS + BPU, 0, 0, 0, 0, 0, // PC_VREFP + BPU, 0, 0, 0, 0, 0, // PC_VRFIM + BPU, 0, 0, 0, 0, 0, // PC_VRFIN + BPU, 0, 0, 0, 0, 0, // PC_VRFIP + BPU, 0, 0, 0, 0, 0, // PC_VRFIZ + BPU, 0, 0, 0, 0, 0, // PC_VRLB + BPU, 0, 0, 0, 0, 0, // PC_VRLH + BPU, 0, 0, 0, 0, 0, // PC_VRLW + BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + BPU, 0, 0, 0, 0, 0, // PC_VSL + BPU, 0, 0, 0, 0, 0, // PC_VSLB + BPU, 0, 0, 0, 0, 0, // PC_VSLH + BPU, 0, 0, 0, 0, 0, // PC_VSLO + BPU, 0, 0, 0, 0, 0, // PC_VSLW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW + BPU, 0, 0, 0, 0, 0, // PC_VSR + BPU, 0, 0, 0, 0, 0, // PC_VSRAB + BPU, 0, 0, 0, 0, 0, // PC_VSRAH + BPU, 0, 0, 0, 0, 0, // PC_VSRAW + BPU, 0, 0, 0, 0, 0, // PC_VSRB + BPU, 0, 0, 0, 0, 0, // PC_VSRH + BPU, 0, 0, 0, 0, 0, // PC_VSRO + BPU, 0, 0, 0, 0, 0, // PC_VSRW + BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW + BPU, 0, 0, 0, 0, 0, // PC_VSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS + BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS + BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH + BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH + BPU, 0, 0, 0, 0, 0, // PC_VXOR + BPU, 0, 0, 0, 0, 0, // PC_VMADDFP + BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS + BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VPERM + BPU, 0, 0, 0, 0, 0, // PC_VSEL + BPU, 0, 0, 0, 0, 0, // PC_VSLDOI + BPU, 0, 0, 0, 0, 0, // PC_VMR + BPU, 0, 0, 0, 0, 0, // PC_VMRP + BPU, 0, 0, 0, 0, 0, // PC_SLE + BPU, 0, 0, 0, 0, 0, // PC_SLEQ + BPU, 0, 0, 0, 0, 0, // PC_SLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLQ + BPU, 0, 0, 0, 0, 0, // PC_SLQ + BPU, 0, 0, 0, 0, 0, // PC_SRAIQ + BPU, 0, 0, 0, 0, 0, // PC_SRAQ + BPU, 0, 0, 0, 0, 0, // PC_SRE + BPU, 0, 0, 0, 0, 0, // PC_SREA + BPU, 0, 0, 0, 0, 0, // PC_SREQ + BPU, 0, 0, 0, 0, 0, // PC_SRIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLQ + BPU, 0, 0, 0, 0, 0, // PC_SRQ + BPU, 0, 0, 0, 0, 0, // PC_MASKG + BPU, 0, 0, 0, 0, 0, // PC_MASKIR + BPU, 0, 0, 0, 0, 0, // PC_LSCBX + BPU, 0, 0, 0, 0, 0, // PC_DIV + BPU, 0, 0, 0, 0, 0, // PC_DIVS + BPU, 0, 0, 0, 0, 0, // PC_DOZ + BPU, 0, 0, 0, 0, 0, // PC_MUL + BPU, 0, 0, 0, 0, 0, // PC_NABS + BPU, 0, 0, 0, 0, 0, // PC_ABS + BPU, 0, 0, 0, 0, 0, // PC_CLCS + BPU, 0, 0, 0, 0, 0, // PC_DOZI + BPU, 0, 0, 0, 0, 0, // PC_RLMI + BPU, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = 5; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; +} + +static int can_issue(PCode *instr) { + if (completionbuffers.free == 0) + return 0; + if (pipeline[instruction_timing[instr->op].stage].instr) + return 0; + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[IU].instr && pipeline[IU].remaining == 0) + complete_instruction(IU); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0) + complete_instruction(FPU3); + if (pipeline[SRU].instr && pipeline[SRU].remaining == 0) + complete_instruction(SRU); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + + if ( + pipeline[FPU1].instr && + pipeline[FPU1].remaining == 0 && + (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS) + ) + complete_instruction(FPU1); + + if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr) + advance(FPU1, FPU2, FPU3); + if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr) + advance(FPU1, FPU1, FPU2); + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine603 = { + 2, + 1, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603e.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603e.c new file mode 100644 index 0000000..d3e1e47 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation603e.c @@ -0,0 +1,650 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/reference-manual/MPC603EUM.pdf + +typedef enum Stage { + BPU, // Branch Prediction Unit + IU, // Integer Unit + LSU1, // Load/Store Unit + LSU2, + FPU1, // Floating Point Unit + FPU2, + FPU3, + SRU, // System Register Unit + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +enum { + MaxEntries = 5 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 1, // PC_B + BPU, 0, 0, 0, 0, 1, // PC_BL + BPU, 0, 0, 0, 0, 1, // PC_BC + BPU, 0, 0, 0, 0, 1, // PC_BCLR + BPU, 0, 0, 0, 0, 1, // PC_BCCTR + BPU, 0, 0, 0, 0, 1, // PC_BT + BPU, 0, 0, 0, 0, 1, // PC_BTLR + BPU, 0, 0, 0, 0, 1, // PC_BTCTR + BPU, 0, 0, 0, 0, 1, // PC_BF + BPU, 0, 0, 0, 0, 1, // PC_BFLR + BPU, 0, 0, 0, 0, 1, // PC_BFCTR + BPU, 0, 0, 0, 0, 1, // PC_BDNZ + BPU, 0, 0, 0, 0, 1, // PC_BDNZT + BPU, 0, 0, 0, 0, 1, // PC_BDNZF + BPU, 0, 0, 0, 0, 1, // PC_BDZ + BPU, 0, 0, 0, 0, 1, // PC_BDZT + BPU, 0, 0, 0, 0, 1, // PC_BDZF + BPU, 0, 0, 0, 0, 1, // PC_BLR + BPU, 0, 0, 0, 0, 1, // PC_BCTR + BPU, 0, 0, 0, 0, 1, // PC_BCTRL + BPU, 0, 0, 0, 0, 1, // PC_BLRL + LSU1, 2, 1, 1, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 2, 1, 1, 0, 0, // PC_DCBF + LSU1, 2, 1, 1, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 2, 1, 1, 0, 0, // PC_DCBZ + IU, 1, 1, 0, 0, 0, // PC_ADD + IU, 1, 1, 0, 0, 0, // PC_ADDC + IU, 1, 1, 0, 0, 0, // PC_ADDE + IU, 1, 1, 0, 0, 0, // PC_ADDI + IU, 1, 1, 0, 0, 0, // PC_ADDIC + IU, 1, 1, 0, 0, 0, // PC_ADDICR + IU, 1, 1, 0, 0, 0, // PC_ADDIS + IU, 1, 1, 0, 0, 0, // PC_ADDME + IU, 1, 1, 0, 0, 0, // PC_ADDZE + IU, 37, 37, 0, 0, 0, // PC_DIVW + IU, 37, 37, 0, 0, 0, // PC_DIVWU + IU, 5, 5, 0, 0, 0, // PC_MULHW + IU, 5, 5, 0, 0, 0, // PC_MULHWU + IU, 3, 3, 0, 0, 0, // PC_MULLI + IU, 5, 5, 0, 0, 0, // PC_MULLW + IU, 1, 1, 0, 0, 0, // PC_NEG + IU, 1, 1, 0, 0, 0, // PC_SUBF + IU, 1, 1, 0, 0, 0, // PC_SUBFC + IU, 1, 1, 0, 0, 0, // PC_SUBFE + IU, 1, 1, 0, 0, 0, // PC_SUBFIC + IU, 1, 1, 0, 0, 0, // PC_SUBFME + IU, 1, 1, 0, 0, 0, // PC_SUBFZE + IU, 3, 1, 0, 0, 0, // PC_CMPI + IU, 3, 1, 0, 0, 0, // PC_CMP + IU, 3, 1, 0, 0, 0, // PC_CMPLI + IU, 3, 1, 0, 0, 0, // PC_CMPL + IU, 1, 1, 0, 0, 0, // PC_ANDI + IU, 1, 1, 0, 0, 0, // PC_ANDIS + IU, 1, 1, 0, 0, 0, // PC_ORI + IU, 1, 1, 0, 0, 0, // PC_ORIS + IU, 1, 1, 0, 0, 0, // PC_XORI + IU, 1, 1, 0, 0, 0, // PC_XORIS + IU, 1, 1, 0, 0, 0, // PC_AND + IU, 1, 1, 0, 0, 0, // PC_OR + IU, 1, 1, 0, 0, 0, // PC_XOR + IU, 1, 1, 0, 0, 0, // PC_NAND + IU, 1, 1, 0, 0, 0, // PC_NOR + IU, 1, 1, 0, 0, 0, // PC_EQV + IU, 1, 1, 0, 0, 0, // PC_ANDC + IU, 1, 1, 0, 0, 0, // PC_ORC + IU, 1, 1, 0, 0, 0, // PC_EXTSB + IU, 1, 1, 0, 0, 0, // PC_EXTSH + IU, 1, 1, 0, 0, 0, // PC_CNTLZW + IU, 1, 1, 0, 0, 0, // PC_RLWINM + IU, 1, 1, 0, 0, 0, // PC_RLWNM + IU, 1, 1, 0, 0, 0, // PC_RLWIMI + IU, 1, 1, 0, 0, 0, // PC_SLW + IU, 1, 1, 0, 0, 0, // PC_SRW + IU, 1, 1, 0, 0, 0, // PC_SRAWI + IU, 1, 1, 0, 0, 0, // PC_SRAW + SRU, 1, 1, 0, 0, 0, // PC_CRAND + SRU, 1, 1, 0, 0, 0, // PC_CRANDC + SRU, 1, 1, 0, 0, 0, // PC_CREQV + SRU, 1, 1, 0, 0, 0, // PC_CRNAND + SRU, 1, 1, 0, 0, 0, // PC_CRNOR + SRU, 1, 1, 0, 0, 0, // PC_CROR + SRU, 1, 1, 0, 0, 0, // PC_CRORC + SRU, 1, 1, 0, 0, 0, // PC_CRXOR + SRU, 1, 1, 0, 0, 0, // PC_MCRF + SRU, 2, 2, 0, 0, 0, // PC_MTXER + SRU, 2, 2, 0, 0, 0, // PC_MTCTR + SRU, 2, 2, 0, 0, 0, // PC_MTLR + SRU, 1, 1, 0, 0, 0, // PC_MTCRF + SRU, 1, 1, 0, 0, 1, // PC_MTMSR + SRU, 1, 1, 0, 0, 1, // PC_MTSPR + SRU, 1, 1, 0, 0, 1, // PC_MFMSR + SRU, 1, 1, 0, 0, 1, // PC_MFSPR + SRU, 1, 1, 0, 0, 0, // PC_MFXER + SRU, 1, 1, 0, 0, 0, // PC_MFCTR + SRU, 1, 1, 0, 0, 0, // PC_MFLR + SRU, 1, 1, 0, 0, 0, // PC_MFCR + FPU1, 3, 1, 1, 1, 0, // PC_MFFS + FPU1, 3, 1, 1, 1, 0, // PC_MTFSF + SRU, 1, 1, 0, 0, 1, // PC_EIEIO + SRU, 1, 1, 0, 0, 1, // PC_ISYNC + SRU, 1, 1, 0, 0, 1, // PC_SYNC + SRU, 1, 1, 0, 0, 1, // PC_RFI + IU, 1, 1, 0, 0, 0, // PC_LI + IU, 1, 1, 0, 0, 0, // PC_LIS + IU, 1, 1, 0, 0, 0, // PC_MR + IU, 1, 1, 0, 0, 0, // PC_NOP + IU, 1, 1, 0, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, // PC_STFSUX + LSU1, 2, 1, 1, 0, 0, // PC_STFD + LSU1, 2, 1, 1, 0, 0, // PC_STFDU + LSU1, 2, 1, 1, 0, 0, // PC_STFDX + LSU1, 2, 1, 1, 0, 0, // PC_STFDUX + FPU1, 3, 1, 1, 1, 0, // PC_FMR + FPU1, 3, 1, 1, 1, 0, // PC_FABS + FPU1, 3, 1, 1, 1, 0, // PC_FNEG + FPU1, 3, 1, 1, 1, 0, // PC_FNABS + FPU1, 3, 1, 1, 1, 0, // PC_FADD + FPU1, 3, 1, 1, 1, 0, // PC_FADDS + FPU1, 3, 1, 1, 1, 0, // PC_FSUB + FPU1, 3, 1, 1, 1, 0, // PC_FSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FMUL + FPU1, 3, 1, 1, 1, 0, // PC_FMULS + FPU1, 33, 33, 0, 0, 0, // PC_FDIV + FPU1, 18, 18, 0, 0, 0, // PC_FDIVS + FPU1, 4, 2, 1, 1, 0, // PC_FMADD + FPU1, 3, 1, 1, 1, 0, // PC_FMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FNMADD + FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS + FPU1, 18, 18, 0, 0, 0, // PC_FRES + FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE + FPU1, 3, 1, 1, 1, 0, // PC_FSEL + FPU1, 3, 1, 1, 1, 0, // PC_FRSP + FPU1, 3, 1, 1, 1, 0, // PC_FCTIW + FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ + FPU1, 5, 1, 1, 1, 0, // PC_FCMPU + FPU1, 5, 1, 1, 1, 0, // PC_FCMPO + LSU1, 1, 1, 0, 0, 0, // PC_LWARX + LSU1, 1, 1, 0, 0, 0, // PC_LSWI + LSU1, 1, 1, 0, 0, 0, // PC_LSWX + LSU1, 1, 1, 0, 0, 0, // PC_STFIWX + LSU1, 1, 1, 0, 0, 0, // PC_STSWI + LSU1, 1, 1, 0, 0, 0, // PC_STSWX + LSU1, 1, 1, 0, 0, 0, // PC_STWCX + IU, 1, 1, 0, 0, 1, // PC_ECIWX + IU, 1, 1, 0, 0, 1, // PC_ECOWX + IU, 1, 1, 0, 0, 0, // PC_DCBI + IU, 1, 1, 0, 0, 0, // PC_ICBI + IU, 1, 1, 0, 0, 0, // PC_MCRFS + IU, 1, 1, 0, 0, 0, // PC_MCRXR + IU, 1, 1, 0, 0, 0, // PC_MFTB + IU, 1, 1, 0, 0, 0, // PC_MFSR + IU, 1, 1, 0, 0, 0, // PC_MTSR + IU, 1, 1, 0, 0, 0, // PC_MFSRIN + IU, 1, 1, 0, 0, 0, // PC_MTSRIN + IU, 1, 1, 0, 0, 0, // PC_MTFSB0 + IU, 1, 1, 0, 0, 0, // PC_MTFSB1 + IU, 1, 1, 0, 0, 0, // PC_MTFSFI + IU, 1, 1, 0, 0, 1, // PC_SC + FPU1, 1, 1, 0, 0, 0, // PC_FSQRT + FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS + IU, 1, 1, 0, 0, 0, // PC_TLBIA + IU, 1, 1, 0, 0, 0, // PC_TLBIE + IU, 1, 1, 0, 0, 0, // PC_TLBLD + IU, 1, 1, 0, 0, 0, // PC_TLBLI + IU, 1, 1, 0, 0, 0, // PC_TLBSYNC + IU, 1, 1, 0, 0, 1, // PC_TW + IU, 1, 1, 0, 0, 1, // PC_TRAP + IU, 1, 1, 0, 0, 1, // PC_TWI + IU, 1, 1, 0, 0, 1, // PC_OPWORD + IU, 1, 1, 0, 0, 0, // PC_MFROM + IU, 1, 1, 0, 0, 1, // PC_DSA + IU, 1, 1, 0, 0, 1, // PC_ESA + IU, 0, 0, 0, 0, 0, // PC_DCCCI + IU, 0, 0, 0, 0, 0, // PC_DCREAD + IU, 0, 0, 0, 0, 0, // PC_ICBT + IU, 0, 0, 0, 0, 0, // PC_ICCCI + IU, 0, 0, 0, 0, 0, // PC_ICREAD + IU, 0, 0, 0, 0, 0, // PC_RFCI + IU, 0, 0, 0, 0, 0, // PC_TLBRE + IU, 0, 0, 0, 0, 0, // PC_TLBSX + IU, 0, 0, 0, 0, 0, // PC_TLBWE + IU, 0, 0, 0, 0, 0, // PC_WRTEE + IU, 0, 0, 0, 0, 0, // PC_WRTEEI + IU, 0, 0, 0, 0, 0, // PC_MFDCR + IU, 0, 0, 0, 0, 0, // PC_MTDCR + IU, 0, 0, 0, 0, 0, // PC_DCBA + BPU, 0, 0, 0, 0, 0, // PC_DSS + BPU, 0, 0, 0, 0, 0, // PC_DSSALL + BPU, 0, 0, 0, 0, 0, // PC_DST + BPU, 0, 0, 0, 0, 0, // PC_DSTT + BPU, 0, 0, 0, 0, 0, // PC_DSTST + BPU, 0, 0, 0, 0, 0, // PC_DSTSTT + BPU, 0, 0, 0, 0, 0, // PC_LVEBX + BPU, 0, 0, 0, 0, 0, // PC_LVEHX + BPU, 0, 0, 0, 0, 0, // PC_LVEWX + BPU, 0, 0, 0, 0, 0, // PC_LVSL + BPU, 0, 0, 0, 0, 0, // PC_LVSR + BPU, 0, 0, 0, 0, 0, // PC_LVX + BPU, 0, 0, 0, 0, 0, // PC_LVXL + BPU, 0, 0, 0, 0, 0, // PC_STVEBX + BPU, 0, 0, 0, 0, 0, // PC_STVEHX + BPU, 0, 0, 0, 0, 0, // PC_STVEWX + BPU, 0, 0, 0, 0, 0, // PC_STVX + BPU, 0, 0, 0, 0, 0, // PC_STVXL + BPU, 0, 0, 0, 0, 0, // PC_MFVSCR + BPU, 0, 0, 0, 0, 0, // PC_MTVSCR + BPU, 0, 0, 0, 0, 0, // PC_VADDCUW + BPU, 0, 0, 0, 0, 0, // PC_VADDFP + BPU, 0, 0, 0, 0, 0, // PC_VADDSBS + BPU, 0, 0, 0, 0, 0, // PC_VADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VADDSWS + BPU, 0, 0, 0, 0, 0, // PC_VADDUBM + BPU, 0, 0, 0, 0, 0, // PC_VADDUBS + BPU, 0, 0, 0, 0, 0, // PC_VADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VADDUHS + BPU, 0, 0, 0, 0, 0, // PC_VADDUWM + BPU, 0, 0, 0, 0, 0, // PC_VADDUWS + BPU, 0, 0, 0, 0, 0, // PC_VAND + BPU, 0, 0, 0, 0, 0, // PC_VANDC + BPU, 0, 0, 0, 0, 0, // PC_VAVGSB + BPU, 0, 0, 0, 0, 0, // PC_VAVGSH + BPU, 0, 0, 0, 0, 0, // PC_VAVGSW + BPU, 0, 0, 0, 0, 0, // PC_VAVGUB + BPU, 0, 0, 0, 0, 0, // PC_VAVGUH + BPU, 0, 0, 0, 0, 0, // PC_VAVGUW + BPU, 0, 0, 0, 0, 0, // PC_VCFSX + BPU, 0, 0, 0, 0, 0, // PC_VCFUX + BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW + BPU, 0, 0, 0, 0, 0, // PC_VCTSXS + BPU, 0, 0, 0, 0, 0, // PC_VCTUXS + BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP + BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXSB + BPU, 0, 0, 0, 0, 0, // PC_VMAXSH + BPU, 0, 0, 0, 0, 0, // PC_VMAXSW + BPU, 0, 0, 0, 0, 0, // PC_VMAXUB + BPU, 0, 0, 0, 0, 0, // PC_VMAXUH + BPU, 0, 0, 0, 0, 0, // PC_VMAXUW + BPU, 0, 0, 0, 0, 0, // PC_VMINFP + BPU, 0, 0, 0, 0, 0, // PC_VMINSB + BPU, 0, 0, 0, 0, 0, // PC_VMINSH + BPU, 0, 0, 0, 0, 0, // PC_VMINSW + BPU, 0, 0, 0, 0, 0, // PC_VMINUB + BPU, 0, 0, 0, 0, 0, // PC_VMINUH + BPU, 0, 0, 0, 0, 0, // PC_VMINUW + BPU, 0, 0, 0, 0, 0, // PC_VMRGHB + BPU, 0, 0, 0, 0, 0, // PC_VMRGHH + BPU, 0, 0, 0, 0, 0, // PC_VMRGHW + BPU, 0, 0, 0, 0, 0, // PC_VMRGLB + BPU, 0, 0, 0, 0, 0, // PC_VMRGLH + BPU, 0, 0, 0, 0, 0, // PC_VMRGLW + BPU, 0, 0, 0, 0, 0, // PC_VMULESB + BPU, 0, 0, 0, 0, 0, // PC_VMULESH + BPU, 0, 0, 0, 0, 0, // PC_VMULEUB + BPU, 0, 0, 0, 0, 0, // PC_VMULEUH + BPU, 0, 0, 0, 0, 0, // PC_VMULOSB + BPU, 0, 0, 0, 0, 0, // PC_VMULOSH + BPU, 0, 0, 0, 0, 0, // PC_VMULOUB + BPU, 0, 0, 0, 0, 0, // PC_VMULOUH + BPU, 0, 0, 0, 0, 0, // PC_VNOR + BPU, 0, 0, 0, 0, 0, // PC_VOR + BPU, 0, 0, 0, 0, 0, // PC_VPKPX + BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS + BPU, 0, 0, 0, 0, 0, // PC_VREFP + BPU, 0, 0, 0, 0, 0, // PC_VRFIM + BPU, 0, 0, 0, 0, 0, // PC_VRFIN + BPU, 0, 0, 0, 0, 0, // PC_VRFIP + BPU, 0, 0, 0, 0, 0, // PC_VRFIZ + BPU, 0, 0, 0, 0, 0, // PC_VRLB + BPU, 0, 0, 0, 0, 0, // PC_VRLH + BPU, 0, 0, 0, 0, 0, // PC_VRLW + BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + BPU, 0, 0, 0, 0, 0, // PC_VSL + BPU, 0, 0, 0, 0, 0, // PC_VSLB + BPU, 0, 0, 0, 0, 0, // PC_VSLH + BPU, 0, 0, 0, 0, 0, // PC_VSLO + BPU, 0, 0, 0, 0, 0, // PC_VSLW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW + BPU, 0, 0, 0, 0, 0, // PC_VSR + BPU, 0, 0, 0, 0, 0, // PC_VSRAB + BPU, 0, 0, 0, 0, 0, // PC_VSRAH + BPU, 0, 0, 0, 0, 0, // PC_VSRAW + BPU, 0, 0, 0, 0, 0, // PC_VSRB + BPU, 0, 0, 0, 0, 0, // PC_VSRH + BPU, 0, 0, 0, 0, 0, // PC_VSRO + BPU, 0, 0, 0, 0, 0, // PC_VSRW + BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW + BPU, 0, 0, 0, 0, 0, // PC_VSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS + BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS + BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH + BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH + BPU, 0, 0, 0, 0, 0, // PC_VXOR + BPU, 0, 0, 0, 0, 0, // PC_VMADDFP + BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS + BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VPERM + BPU, 0, 0, 0, 0, 0, // PC_VSEL + BPU, 0, 0, 0, 0, 0, // PC_VSLDOI + BPU, 0, 0, 0, 0, 0, // PC_VMR + BPU, 0, 0, 0, 0, 0, // PC_VMRP + BPU, 0, 0, 0, 0, 0, // PC_SLE + BPU, 0, 0, 0, 0, 0, // PC_SLEQ + BPU, 0, 0, 0, 0, 0, // PC_SLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLQ + BPU, 0, 0, 0, 0, 0, // PC_SLQ + BPU, 0, 0, 0, 0, 0, // PC_SRAIQ + BPU, 0, 0, 0, 0, 0, // PC_SRAQ + BPU, 0, 0, 0, 0, 0, // PC_SRE + BPU, 0, 0, 0, 0, 0, // PC_SREA + BPU, 0, 0, 0, 0, 0, // PC_SREQ + BPU, 0, 0, 0, 0, 0, // PC_SRIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLQ + BPU, 0, 0, 0, 0, 0, // PC_SRQ + BPU, 0, 0, 0, 0, 0, // PC_MASKG + BPU, 0, 0, 0, 0, 0, // PC_MASKIR + BPU, 0, 0, 0, 0, 0, // PC_LSCBX + BPU, 0, 0, 0, 0, 0, // PC_DIV + BPU, 0, 0, 0, 0, 0, // PC_DIVS + BPU, 0, 0, 0, 0, 0, // PC_DOZ + BPU, 0, 0, 0, 0, 0, // PC_MUL + BPU, 0, 0, 0, 0, 0, // PC_NABS + BPU, 0, 0, 0, 0, 0, // PC_ABS + BPU, 0, 0, 0, 0, 0, // PC_CLCS + BPU, 0, 0, 0, 0, 0, // PC_DOZI + BPU, 0, 0, 0, 0, 0, // PC_RLMI + BPU, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + if (pipeline[stage].instr) { + if (stage == IU) { + switch (instr->op) { + case PC_ADD: + case PC_ADDC: + case PC_ADDI: + case PC_ADDIS: + case PC_CMPI: + case PC_CMP: + case PC_CMPLI: + case PC_CMPL: + if (is_dependent(instr, pipeline[IU].instr, RegClass_GPR)) + return 0; + if (!pipeline[SRU].instr) + return 1; + } + } + return 0; + } + + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + if (stage == IU && pipeline[IU].instr) + stage = SRU; + assign_completion_buffer(instr); + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[IU].instr && pipeline[IU].remaining == 0) + complete_instruction(IU); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0) + complete_instruction(FPU3); + if (pipeline[SRU].instr && pipeline[SRU].remaining == 0) + complete_instruction(SRU); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + + if ( + pipeline[FPU1].instr && + pipeline[FPU1].remaining == 0 && + (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS) + ) + complete_instruction(FPU1); + + if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr) + advance(FPU1, FPU2, FPU3); + if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr) + advance(FPU1, FPU1, FPU2); + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine603e = { + 2, + 1, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation604.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation604.c new file mode 100644 index 0000000..9775c9e --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation604.c @@ -0,0 +1,670 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://archive.org/details/bitsavers_motorolaPosManualNov94_22719504 + +typedef enum Stage { + SCIU, // Single-Cycle Integer Unit 1 + SCIU2, // Single-Cycle Integer Unit 2 + MCIU, // Multiple-Cycle Integer Unit + FPU1, // Floating Point Unit + FPU2, + FPU3, + LSU1, // Load/Store Unit + LSU2, + BPU, // Branch Prediction Unit + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +enum { + MaxEntries = 16 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static PCode *sciu_completed_instruction; +static PCode *sciu2_completed_instruction; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 1, // PC_B + BPU, 0, 0, 0, 0, 1, // PC_BL + BPU, 0, 0, 0, 0, 1, // PC_BC + BPU, 0, 0, 0, 0, 1, // PC_BCLR + BPU, 0, 0, 0, 0, 1, // PC_BCCTR + BPU, 0, 0, 0, 0, 1, // PC_BT + BPU, 0, 0, 0, 0, 1, // PC_BTLR + BPU, 0, 0, 0, 0, 1, // PC_BTCTR + BPU, 0, 0, 0, 0, 1, // PC_BF + BPU, 0, 0, 0, 0, 1, // PC_BFLR + BPU, 0, 0, 0, 0, 1, // PC_BFCTR + BPU, 0, 0, 0, 0, 1, // PC_BDNZ + BPU, 0, 0, 0, 0, 1, // PC_BDNZT + BPU, 0, 0, 0, 0, 1, // PC_BDNZF + BPU, 0, 0, 0, 0, 1, // PC_BDZ + BPU, 0, 0, 0, 0, 1, // PC_BDZT + BPU, 0, 0, 0, 0, 1, // PC_BDZF + BPU, 0, 0, 0, 0, 1, // PC_BLR + BPU, 0, 0, 0, 0, 1, // PC_BCTR + BPU, 0, 0, 0, 0, 1, // PC_BCTRL + BPU, 0, 0, 0, 0, 1, // PC_BLRL + LSU1, 2, 1, 1, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 3, 1, 1, 0, 0, // PC_STB + LSU1, 3, 1, 1, 0, 0, // PC_STBU + LSU1, 3, 1, 1, 0, 0, // PC_STBX + LSU1, 3, 1, 1, 0, 0, // PC_STBUX + LSU1, 3, 1, 1, 0, 0, // PC_STH + LSU1, 3, 1, 1, 0, 0, // PC_STHU + LSU1, 3, 1, 1, 0, 0, // PC_STHX + LSU1, 3, 1, 1, 0, 0, // PC_STHUX + LSU1, 3, 1, 1, 0, 0, // PC_STHBRX + LSU1, 3, 1, 1, 0, 0, // PC_STW + LSU1, 3, 1, 1, 0, 0, // PC_STWU + LSU1, 3, 1, 1, 0, 0, // PC_STWX + LSU1, 3, 1, 1, 0, 0, // PC_STWUX + LSU1, 3, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 2, 1, 1, 0, 0, // PC_DCBF + LSU1, 2, 1, 1, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 2, 1, 1, 0, 0, // PC_DCBZ + SCIU, 1, 1, 0, 0, 0, // PC_ADD + SCIU, 1, 1, 0, 0, 0, // PC_ADDC + SCIU, 1, 1, 0, 0, 0, // PC_ADDE + SCIU, 1, 1, 0, 0, 0, // PC_ADDI + SCIU, 1, 1, 0, 0, 0, // PC_ADDIC + SCIU, 1, 1, 0, 0, 0, // PC_ADDICR + SCIU, 1, 1, 0, 0, 0, // PC_ADDIS + SCIU, 1, 1, 0, 0, 0, // PC_ADDME + SCIU, 1, 1, 0, 0, 0, // PC_ADDZE + MCIU, 20, 20, 0, 0, 0, // PC_DIVW + MCIU, 20, 20, 0, 0, 0, // PC_DIVWU + MCIU, 4, 4, 0, 0, 0, // PC_MULHW + MCIU, 4, 4, 0, 0, 0, // PC_MULHWU + MCIU, 3, 3, 0, 0, 0, // PC_MULLI + MCIU, 4, 4, 0, 0, 0, // PC_MULLW + SCIU, 1, 1, 0, 0, 0, // PC_NEG + SCIU, 1, 1, 0, 0, 0, // PC_SUBF + SCIU, 1, 1, 0, 0, 0, // PC_SUBFC + SCIU, 1, 1, 0, 0, 0, // PC_SUBFE + SCIU, 1, 1, 0, 0, 0, // PC_SUBFIC + SCIU, 1, 1, 0, 0, 0, // PC_SUBFME + SCIU, 1, 1, 0, 0, 0, // PC_SUBFZE + SCIU, 3, 1, 0, 0, 0, // PC_CMPI + SCIU, 3, 1, 0, 0, 0, // PC_CMP + SCIU, 3, 1, 0, 0, 0, // PC_CMPLI + SCIU, 3, 1, 0, 0, 0, // PC_CMPL + SCIU, 1, 1, 0, 0, 0, // PC_ANDI + SCIU, 1, 1, 0, 0, 0, // PC_ANDIS + SCIU, 1, 1, 0, 0, 0, // PC_ORI + SCIU, 1, 1, 0, 0, 0, // PC_ORIS + SCIU, 1, 1, 0, 0, 0, // PC_XORI + SCIU, 1, 1, 0, 0, 0, // PC_XORIS + SCIU, 1, 1, 0, 0, 0, // PC_AND + SCIU, 1, 1, 0, 0, 0, // PC_OR + SCIU, 1, 1, 0, 0, 0, // PC_XOR + SCIU, 1, 1, 0, 0, 0, // PC_NAND + SCIU, 1, 1, 0, 0, 0, // PC_NOR + SCIU, 1, 1, 0, 0, 0, // PC_EQV + SCIU, 1, 1, 0, 0, 0, // PC_ANDC + SCIU, 1, 1, 0, 0, 0, // PC_ORC + SCIU, 1, 1, 0, 0, 0, // PC_EXTSB + SCIU, 1, 1, 0, 0, 0, // PC_EXTSH + SCIU, 1, 1, 0, 0, 0, // PC_CNTLZW + SCIU, 1, 1, 0, 0, 0, // PC_RLWINM + SCIU, 1, 1, 0, 0, 0, // PC_RLWNM + SCIU, 1, 1, 0, 0, 0, // PC_RLWIMI + SCIU, 1, 1, 0, 0, 0, // PC_SLW + SCIU, 1, 1, 0, 0, 0, // PC_SRW + SCIU, 1, 1, 0, 0, 0, // PC_SRAWI + SCIU, 1, 1, 0, 0, 0, // PC_SRAW + BPU, 1, 1, 0, 0, 0, // PC_CRAND + BPU, 1, 1, 0, 0, 0, // PC_CRANDC + BPU, 1, 1, 0, 0, 0, // PC_CREQV + BPU, 1, 1, 0, 0, 0, // PC_CRNAND + BPU, 1, 1, 0, 0, 0, // PC_CRNOR + BPU, 1, 1, 0, 0, 0, // PC_CROR + BPU, 1, 1, 0, 0, 0, // PC_CRORC + BPU, 1, 1, 0, 0, 0, // PC_CRXOR + BPU, 1, 1, 0, 0, 0, // PC_MCRF + MCIU, 1, 1, 0, 0, 0, // PC_MTXER + MCIU, 1, 1, 0, 0, 0, // PC_MTCTR + MCIU, 1, 1, 0, 0, 0, // PC_MTLR + MCIU, 1, 1, 0, 0, 0, // PC_MTCRF + MCIU, 1, 1, 0, 0, 0, // PC_MTMSR + MCIU, 1, 1, 0, 0, 0, // PC_MTSPR + MCIU, 1, 1, 0, 0, 0, // PC_MFMSR + MCIU, 1, 1, 0, 0, 0, // PC_MFSPR + MCIU, 3, 3, 0, 0, 0, // PC_MFXER + MCIU, 3, 3, 0, 0, 0, // PC_MFCTR + MCIU, 3, 3, 0, 0, 0, // PC_MFLR + MCIU, 3, 3, 0, 0, 0, // PC_MFCR + FPU1, 3, 1, 1, 1, 0, // PC_MFFS + FPU1, 3, 1, 1, 1, 0, // PC_MTFSF + LSU1, 1, 0, 0, 0, 1, // PC_EIEIO + LSU1, 1, 0, 0, 0, 1, // PC_ISYNC + LSU1, 1, 0, 0, 0, 1, // PC_SYNC + LSU1, 1, 1, 0, 0, 1, // PC_RFI + SCIU, 1, 1, 0, 0, 0, // PC_LI + SCIU, 1, 1, 0, 0, 0, // PC_LIS + SCIU, 1, 1, 0, 0, 0, // PC_MR + SCIU, 1, 1, 0, 0, 0, // PC_NOP + SCIU, 1, 1, 0, 0, 0, // PC_NOT + LSU1, 3, 1, 1, 0, 0, // PC_LFS + LSU1, 3, 1, 1, 0, 0, // PC_LFSU + LSU1, 3, 1, 1, 0, 0, // PC_LFSX + LSU1, 3, 1, 1, 0, 0, // PC_LFSUX + LSU1, 3, 1, 1, 0, 0, // PC_LFD + LSU1, 3, 1, 1, 0, 0, // PC_LFDU + LSU1, 3, 1, 1, 0, 0, // PC_LFDX + LSU1, 3, 1, 1, 0, 0, // PC_LFDUX + LSU1, 3, 1, 1, 0, 0, // PC_STFS + LSU1, 3, 1, 1, 0, 0, // PC_STFSU + LSU1, 3, 1, 1, 0, 0, // PC_STFSX + LSU1, 3, 1, 1, 0, 0, // PC_STFSUX + LSU1, 3, 1, 1, 0, 0, // PC_STFD + LSU1, 3, 1, 1, 0, 0, // PC_STFDU + LSU1, 3, 1, 1, 0, 0, // PC_STFDX + LSU1, 3, 1, 1, 0, 0, // PC_STFDUX + FPU1, 3, 1, 1, 1, 0, // PC_FMR + FPU1, 3, 1, 1, 1, 0, // PC_FABS + FPU1, 3, 1, 1, 1, 0, // PC_FNEG + FPU1, 3, 1, 1, 1, 0, // PC_FNABS + FPU1, 3, 1, 1, 1, 0, // PC_FADD + FPU1, 3, 1, 1, 1, 0, // PC_FADDS + FPU1, 3, 1, 1, 1, 0, // PC_FSUB + FPU1, 3, 1, 1, 1, 0, // PC_FSUBS + FPU1, 3, 1, 1, 1, 0, // PC_FMUL + FPU1, 3, 1, 1, 1, 0, // PC_FMULS + FPU1, 32, 32, 0, 0, 0, // PC_FDIV + FPU1, 18, 18, 0, 0, 0, // PC_FDIVS + FPU1, 3, 1, 1, 1, 0, // PC_FMADD + FPU1, 3, 1, 1, 1, 0, // PC_FMADDS + FPU1, 3, 1, 1, 1, 0, // PC_FMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS + FPU1, 3, 1, 1, 1, 0, // PC_FNMADD + FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS + FPU1, 3, 1, 1, 1, 0, // PC_FNMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS + FPU1, 18, 18, 0, 0, 0, // PC_FRES + FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE + FPU1, 3, 1, 1, 1, 0, // PC_FSEL + FPU1, 3, 1, 1, 1, 0, // PC_FRSP + FPU1, 3, 1, 1, 1, 0, // PC_FCTIW + FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ + FPU1, 5, 1, 1, 1, 0, // PC_FCMPU + FPU1, 5, 1, 1, 1, 0, // PC_FCMPO + LSU1, 1, 1, 0, 0, 0, // PC_LWARX + LSU1, 1, 1, 0, 0, 0, // PC_LSWI + LSU1, 1, 1, 0, 0, 0, // PC_LSWX + LSU1, 1, 1, 0, 0, 0, // PC_STFIWX + LSU1, 1, 1, 0, 0, 0, // PC_STSWI + LSU1, 1, 1, 0, 0, 0, // PC_STSWX + LSU1, 1, 1, 0, 0, 0, // PC_STWCX + MCIU, 1, 1, 0, 0, 1, // PC_ECIWX + MCIU, 1, 1, 0, 0, 1, // PC_ECOWX + MCIU, 1, 1, 0, 0, 0, // PC_DCBI + MCIU, 1, 1, 0, 0, 0, // PC_ICBI + MCIU, 1, 1, 0, 0, 0, // PC_MCRFS + MCIU, 1, 1, 0, 0, 0, // PC_MCRXR + MCIU, 1, 1, 0, 0, 0, // PC_MFTB + MCIU, 1, 1, 0, 0, 0, // PC_MFSR + MCIU, 1, 1, 0, 0, 0, // PC_MTSR + MCIU, 1, 1, 0, 0, 0, // PC_MFSRIN + MCIU, 1, 1, 0, 0, 0, // PC_MTSRIN + MCIU, 1, 1, 0, 0, 0, // PC_MTFSB0 + MCIU, 1, 1, 0, 0, 0, // PC_MTFSB1 + MCIU, 1, 1, 0, 0, 0, // PC_MTFSFI + MCIU, 1, 1, 0, 0, 1, // PC_SC + FPU1, 1, 1, 0, 0, 0, // PC_FSQRT + FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS + MCIU, 1, 1, 0, 0, 0, // PC_TLBIA + MCIU, 1, 1, 0, 0, 0, // PC_TLBIE + MCIU, 1, 1, 0, 0, 0, // PC_TLBLD + MCIU, 1, 1, 0, 0, 0, // PC_TLBLI + MCIU, 1, 1, 0, 0, 0, // PC_TLBSYNC + MCIU, 1, 1, 0, 0, 1, // PC_TW + MCIU, 1, 1, 0, 0, 1, // PC_TRAP + MCIU, 1, 1, 0, 0, 1, // PC_TWI + MCIU, 1, 1, 0, 0, 1, // PC_OPWORD + MCIU, 1, 1, 0, 0, 0, // PC_MFROM + MCIU, 1, 1, 0, 0, 1, // PC_DSA + MCIU, 1, 1, 0, 0, 1, // PC_ESA + MCIU, 0, 0, 0, 0, 0, // PC_DCCCI + MCIU, 0, 0, 0, 0, 0, // PC_DCREAD + MCIU, 0, 0, 0, 0, 0, // PC_ICBT + MCIU, 0, 0, 0, 0, 0, // PC_ICCCI + MCIU, 0, 0, 0, 0, 0, // PC_ICREAD + MCIU, 0, 0, 0, 0, 0, // PC_RFCI + MCIU, 0, 0, 0, 0, 0, // PC_TLBRE + MCIU, 0, 0, 0, 0, 0, // PC_TLBSX + MCIU, 0, 0, 0, 0, 0, // PC_TLBWE + MCIU, 0, 0, 0, 0, 0, // PC_WRTEE + MCIU, 0, 0, 0, 0, 0, // PC_WRTEEI + MCIU, 0, 0, 0, 0, 0, // PC_MFDCR + MCIU, 0, 0, 0, 0, 0, // PC_MTDCR + MCIU, 0, 0, 0, 0, 0, // PC_DCBA + SCIU, 0, 0, 0, 0, 0, // PC_DSS + SCIU, 0, 0, 0, 0, 0, // PC_DSSALL + SCIU, 0, 0, 0, 0, 0, // PC_DST + SCIU, 0, 0, 0, 0, 0, // PC_DSTT + SCIU, 0, 0, 0, 0, 0, // PC_DSTST + SCIU, 0, 0, 0, 0, 0, // PC_DSTSTT + SCIU, 0, 0, 0, 0, 0, // PC_LVEBX + SCIU, 0, 0, 0, 0, 0, // PC_LVEHX + SCIU, 0, 0, 0, 0, 0, // PC_LVEWX + SCIU, 0, 0, 0, 0, 0, // PC_LVSL + SCIU, 0, 0, 0, 0, 0, // PC_LVSR + SCIU, 0, 0, 0, 0, 0, // PC_LVX + SCIU, 0, 0, 0, 0, 0, // PC_LVXL + SCIU, 0, 0, 0, 0, 0, // PC_STVEBX + SCIU, 0, 0, 0, 0, 0, // PC_STVEHX + SCIU, 0, 0, 0, 0, 0, // PC_STVEWX + SCIU, 0, 0, 0, 0, 0, // PC_STVX + SCIU, 0, 0, 0, 0, 0, // PC_STVXL + SCIU, 0, 0, 0, 0, 0, // PC_MFVSCR + SCIU, 0, 0, 0, 0, 0, // PC_MTVSCR + SCIU, 0, 0, 0, 0, 0, // PC_VADDCUW + SCIU, 0, 0, 0, 0, 0, // PC_VADDFP + SCIU, 0, 0, 0, 0, 0, // PC_VADDSBS + SCIU, 0, 0, 0, 0, 0, // PC_VADDSHS + SCIU, 0, 0, 0, 0, 0, // PC_VADDSWS + SCIU, 0, 0, 0, 0, 0, // PC_VADDUBM + SCIU, 0, 0, 0, 0, 0, // PC_VADDUBS + SCIU, 0, 0, 0, 0, 0, // PC_VADDUHM + SCIU, 0, 0, 0, 0, 0, // PC_VADDUHS + SCIU, 0, 0, 0, 0, 0, // PC_VADDUWM + SCIU, 0, 0, 0, 0, 0, // PC_VADDUWS + SCIU, 0, 0, 0, 0, 0, // PC_VAND + SCIU, 0, 0, 0, 0, 0, // PC_VANDC + SCIU, 0, 0, 0, 0, 0, // PC_VAVGSB + SCIU, 0, 0, 0, 0, 0, // PC_VAVGSH + SCIU, 0, 0, 0, 0, 0, // PC_VAVGSW + SCIU, 0, 0, 0, 0, 0, // PC_VAVGUB + SCIU, 0, 0, 0, 0, 0, // PC_VAVGUH + SCIU, 0, 0, 0, 0, 0, // PC_VAVGUW + SCIU, 0, 0, 0, 0, 0, // PC_VCFSX + SCIU, 0, 0, 0, 0, 0, // PC_VCFUX + SCIU, 0, 0, 0, 0, 0, // PC_VCMPBFP + SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQFP + SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUB + SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUH + SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUW + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGEFP + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTFP + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSB + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSH + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSW + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUB + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUH + SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUW + SCIU, 0, 0, 0, 0, 0, // PC_VCTSXS + SCIU, 0, 0, 0, 0, 0, // PC_VCTUXS + SCIU, 0, 0, 0, 0, 0, // PC_VEXPTEFP + SCIU, 0, 0, 0, 0, 0, // PC_VLOGEFP + SCIU, 0, 0, 0, 0, 0, // PC_VMAXFP + SCIU, 0, 0, 0, 0, 0, // PC_VMAXSB + SCIU, 0, 0, 0, 0, 0, // PC_VMAXSH + SCIU, 0, 0, 0, 0, 0, // PC_VMAXSW + SCIU, 0, 0, 0, 0, 0, // PC_VMAXUB + SCIU, 0, 0, 0, 0, 0, // PC_VMAXUH + SCIU, 0, 0, 0, 0, 0, // PC_VMAXUW + SCIU, 0, 0, 0, 0, 0, // PC_VMINFP + SCIU, 0, 0, 0, 0, 0, // PC_VMINSB + SCIU, 0, 0, 0, 0, 0, // PC_VMINSH + SCIU, 0, 0, 0, 0, 0, // PC_VMINSW + SCIU, 0, 0, 0, 0, 0, // PC_VMINUB + SCIU, 0, 0, 0, 0, 0, // PC_VMINUH + SCIU, 0, 0, 0, 0, 0, // PC_VMINUW + SCIU, 0, 0, 0, 0, 0, // PC_VMRGHB + SCIU, 0, 0, 0, 0, 0, // PC_VMRGHH + SCIU, 0, 0, 0, 0, 0, // PC_VMRGHW + SCIU, 0, 0, 0, 0, 0, // PC_VMRGLB + SCIU, 0, 0, 0, 0, 0, // PC_VMRGLH + SCIU, 0, 0, 0, 0, 0, // PC_VMRGLW + SCIU, 0, 0, 0, 0, 0, // PC_VMULESB + SCIU, 0, 0, 0, 0, 0, // PC_VMULESH + SCIU, 0, 0, 0, 0, 0, // PC_VMULEUB + SCIU, 0, 0, 0, 0, 0, // PC_VMULEUH + SCIU, 0, 0, 0, 0, 0, // PC_VMULOSB + SCIU, 0, 0, 0, 0, 0, // PC_VMULOSH + SCIU, 0, 0, 0, 0, 0, // PC_VMULOUB + SCIU, 0, 0, 0, 0, 0, // PC_VMULOUH + SCIU, 0, 0, 0, 0, 0, // PC_VNOR + SCIU, 0, 0, 0, 0, 0, // PC_VOR + SCIU, 0, 0, 0, 0, 0, // PC_VPKPX + SCIU, 0, 0, 0, 0, 0, // PC_VPKSHSS + SCIU, 0, 0, 0, 0, 0, // PC_VPKSHUS + SCIU, 0, 0, 0, 0, 0, // PC_VPKSWSS + SCIU, 0, 0, 0, 0, 0, // PC_VPKSWUS + SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUM + SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUS + SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUM + SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUS + SCIU, 0, 0, 0, 0, 0, // PC_VREFP + SCIU, 0, 0, 0, 0, 0, // PC_VRFIM + SCIU, 0, 0, 0, 0, 0, // PC_VRFIN + SCIU, 0, 0, 0, 0, 0, // PC_VRFIP + SCIU, 0, 0, 0, 0, 0, // PC_VRFIZ + SCIU, 0, 0, 0, 0, 0, // PC_VRLB + SCIU, 0, 0, 0, 0, 0, // PC_VRLH + SCIU, 0, 0, 0, 0, 0, // PC_VRLW + SCIU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + SCIU, 0, 0, 0, 0, 0, // PC_VSL + SCIU, 0, 0, 0, 0, 0, // PC_VSLB + SCIU, 0, 0, 0, 0, 0, // PC_VSLH + SCIU, 0, 0, 0, 0, 0, // PC_VSLO + SCIU, 0, 0, 0, 0, 0, // PC_VSLW + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTB + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTH + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTW + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISB + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISH + SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISW + SCIU, 0, 0, 0, 0, 0, // PC_VSR + SCIU, 0, 0, 0, 0, 0, // PC_VSRAB + SCIU, 0, 0, 0, 0, 0, // PC_VSRAH + SCIU, 0, 0, 0, 0, 0, // PC_VSRAW + SCIU, 0, 0, 0, 0, 0, // PC_VSRB + SCIU, 0, 0, 0, 0, 0, // PC_VSRH + SCIU, 0, 0, 0, 0, 0, // PC_VSRO + SCIU, 0, 0, 0, 0, 0, // PC_VSRW + SCIU, 0, 0, 0, 0, 0, // PC_VSUBCUW + SCIU, 0, 0, 0, 0, 0, // PC_VSUBFP + SCIU, 0, 0, 0, 0, 0, // PC_VSUBSBS + SCIU, 0, 0, 0, 0, 0, // PC_VSUBSHS + SCIU, 0, 0, 0, 0, 0, // PC_VSUBSWS + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBM + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBS + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHM + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHS + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWM + SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWS + SCIU, 0, 0, 0, 0, 0, // PC_VSUMSWS + SCIU, 0, 0, 0, 0, 0, // PC_VSUM2SWS + SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SBS + SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SHS + SCIU, 0, 0, 0, 0, 0, // PC_VSUM4UBS + SCIU, 0, 0, 0, 0, 0, // PC_VUPKHPX + SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSB + SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSH + SCIU, 0, 0, 0, 0, 0, // PC_VUPKLPX + SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSB + SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSH + SCIU, 0, 0, 0, 0, 0, // PC_VXOR + SCIU, 0, 0, 0, 0, 0, // PC_VMADDFP + SCIU, 0, 0, 0, 0, 0, // PC_VMHADDSHS + SCIU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + SCIU, 0, 0, 0, 0, 0, // PC_VMLADDUHM + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMMBM + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHM + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHS + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUBM + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHM + SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHS + SCIU, 0, 0, 0, 0, 0, // PC_VNMSUBFP + SCIU, 0, 0, 0, 0, 0, // PC_VPERM + SCIU, 0, 0, 0, 0, 0, // PC_VSEL + SCIU, 0, 0, 0, 0, 0, // PC_VSLDOI + SCIU, 0, 0, 0, 0, 0, // PC_VMR + SCIU, 0, 0, 0, 0, 0, // PC_VMRP + SCIU, 0, 0, 0, 0, 0, // PC_SLE + SCIU, 0, 0, 0, 0, 0, // PC_SLEQ + SCIU, 0, 0, 0, 0, 0, // PC_SLIQ + SCIU, 0, 0, 0, 0, 0, // PC_SLLIQ + SCIU, 0, 0, 0, 0, 0, // PC_SLLQ + SCIU, 0, 0, 0, 0, 0, // PC_SLQ + SCIU, 0, 0, 0, 0, 0, // PC_SRAIQ + SCIU, 0, 0, 0, 0, 0, // PC_SRAQ + SCIU, 0, 0, 0, 0, 0, // PC_SRE + SCIU, 0, 0, 0, 0, 0, // PC_SREA + SCIU, 0, 0, 0, 0, 0, // PC_SREQ + SCIU, 0, 0, 0, 0, 0, // PC_SRIQ + SCIU, 0, 0, 0, 0, 0, // PC_SRLIQ + SCIU, 0, 0, 0, 0, 0, // PC_SRLQ + SCIU, 0, 0, 0, 0, 0, // PC_SRQ + SCIU, 0, 0, 0, 0, 0, // PC_MASKG + SCIU, 0, 0, 0, 0, 0, // PC_MASKIR + SCIU, 0, 0, 0, 0, 0, // PC_LSCBX + SCIU, 0, 0, 0, 0, 0, // PC_DIV + SCIU, 0, 0, 0, 0, 0, // PC_DIVS + SCIU, 0, 0, 0, 0, 0, // PC_DOZ + SCIU, 0, 0, 0, 0, 0, // PC_MUL + SCIU, 0, 0, 0, 0, 0, // PC_NABS + SCIU, 0, 0, 0, 0, 0, // PC_ABS + SCIU, 0, 0, 0, 0, 0, // PC_CLCS + SCIU, 0, 0, 0, 0, 0, // PC_DOZI + SCIU, 0, 0, 0, 0, 0, // PC_RLMI + SCIU, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; + + if (stage == SCIU) + sciu_completed_instruction = instr; + else if (stage == SCIU2) + sciu2_completed_instruction = instr; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; + + sciu_completed_instruction = NULL; + sciu2_completed_instruction = NULL; +} + +static int can_issue(PCode *instr) { + PCode *check; + int stage = instruction_timing[instr->op].stage; + + if (completionbuffers.free == 0) + return 0; + + if (stage == SCIU) { + int isClear1 = !pipeline[SCIU].instr; + int isClear2 = !pipeline[SCIU2].instr; + if (!isClear1 && !isClear2) + return 0; + if (isClear1 && isClear2) + return 1; + + if (isClear1) + check = pipeline[SCIU2].instr; + else + check = pipeline[SCIU].instr; + + if (is_dependent(instr, check, RegClass_GPR)) + return 0; + if (is_dependent(instr, sciu_completed_instruction, RegClass_GPR)) + return 0; + if (is_dependent(instr, sciu2_completed_instruction, RegClass_GPR)) + return 0; + } else { + if (pipeline[stage].instr) + return 0; + } + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + if (stage == SCIU && pipeline[SCIU].instr) + stage = SCIU2; + assign_completion_buffer(instr); + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + int i; + + sciu_completed_instruction = NULL; + sciu2_completed_instruction = NULL; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + for (i = 0; i < 5; i++) { + if (completionbuffers.used == 0) + break; + if (completionbuffers.entries[completionbuffers.nextToRetire].completed == 0) + break; + retire_instruction(); + } + + if (pipeline[SCIU].instr && pipeline[SCIU].remaining == 0) + complete_instruction(SCIU); + if (pipeline[SCIU2].instr && pipeline[SCIU2].remaining == 0) + complete_instruction(SCIU2); + if (pipeline[MCIU].instr && pipeline[MCIU].remaining == 0) + complete_instruction(MCIU); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0) + complete_instruction(FPU3); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + + if ( + pipeline[FPU1].instr && + pipeline[FPU1].remaining == 0 && + (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS) + ) + complete_instruction(FPU1); + + if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr) + advance(FPU1, FPU2, FPU3); + if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr) + advance(FPU1, FPU1, FPU2); + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine604 = { + 4, + 1, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation7400.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation7400.c new file mode 100644 index 0000000..56b375c --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation7400.c @@ -0,0 +1,744 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/reference-manual/MPC7410UM.pdf + +typedef enum Stage { + BPU, // Branch Prediction Unit + IU1, // Integer Unit 1 + IU2, // Integer Unit 2 + + LSU1, // Load/Store Unit + LSU2, + + FPU1, // Floating Point Unit + FPU2, + FPU3, + + SRU, // System Register Unit + VSIU, // Vector Simple Integer Unit + VPU, // AltiVec Permute Unit + + VCIU1, // Vector Complex Integer Unit + VCIU2, + VCIU3, + + VFPU1, // Vector Floating-Point Unit + VFPU2, + VFPU3, + VFPU4, + + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +static PCode *iu1_completed_instruction; +static PCode *iu2_completed_instruction; + +enum { + MaxEntries = 8 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[4]; + + // does this instruction serialise? + char serializes; + + char unused; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_B + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BL + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BC + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCLR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCCTR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BT + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTLR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTCTR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BF + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFLR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFCTR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZT + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZF + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZT + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZF + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTRL + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLRL + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STMW + LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBF + LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DCBTST + LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBZ + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADD + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDE + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDICR + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIS + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDME + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ADDZE + IU1, 19, 19, 0, 0, 0, 0, 0, // PC_DIVW + IU1, 19, 19, 0, 0, 0, 0, 0, // PC_DIVWU + IU1, 5, 5, 0, 0, 0, 0, 0, // PC_MULHW + IU1, 6, 5, 0, 0, 0, 0, 0, // PC_MULHWU + IU1, 3, 3, 0, 0, 0, 0, 0, // PC_MULLI + IU1, 5, 5, 0, 0, 0, 0, 0, // PC_MULLW + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NEG + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBF + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFE + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFIC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFME + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFZE + IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPI + IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMP + IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPLI + IU2, 3, 1, 0, 0, 0, 0, 0, // PC_CMPL + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDIS + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORIS + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XORI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XORIS + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_AND + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_OR + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_XOR + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NAND + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOR + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EQV + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ANDC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ORC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSB + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSH + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_CNTLZW + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWINM + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWNM + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_RLWIMI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SLW + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRW + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRAWI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_SRAW + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRAND + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRANDC + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CREQV + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRNAND + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRNOR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CROR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRORC + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_CRXOR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRF + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTXER + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTCTR + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTLR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MTCRF + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MTMSR + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSPR + SRU, 1, 1, 0, 0, 0, 0, 0, // PC_MFMSR + SRU, 3, 3, 0, 0, 0, 1, 0, // PC_MFSPR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFXER + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFCTR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFLR + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MFCR + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_MFFS + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_MTFSF + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_EIEIO + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_ISYNC + SRU, 3, 3, 0, 0, 0, 1, 0, // PC_SYNC + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_RFI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_LI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_LIS + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_MR + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOP + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFSUX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFD + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDU + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFDUX + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMR + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FABS + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNEG + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNABS + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FADD + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FADDS + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSUB + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSUBS + FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMUL + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMULS + FPU1, 31, 31, 0, 0, 0, 0, 0, // PC_FDIV + FPU1, 17, 17, 0, 0, 0, 0, 0, // PC_FDIVS + FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMADD + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMADDS + FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FMSUB + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FMSUBS + FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FNMADD + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNMADDS + FPU1, 4, 2, 1, 1, 0, 0, 0, // PC_FNMSUB + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FNMSUBS + FPU1, 10, 10, 0, 0, 0, 0, 0, // PC_FRES + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FRSQRTE + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FSEL + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FRSP + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCTIW + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCTIWZ + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCMPU + FPU1, 3, 1, 1, 1, 0, 0, 0, // PC_FCMPO + LSU1, 2, 1, 1, 0, 0, 1, 0, // PC_LWARX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LSWI + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LSWX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STFIWX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STSWI + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STSWX + LSU1, 2, 1, 1, 0, 0, 1, 0, // PC_STWCX + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ECIWX + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ECOWX + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_DCBI + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ICBI + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRFS + SRU, 1, 1, 0, 0, 0, 1, 0, // PC_MCRXR + SRU, 1, 1, 0, 0, 0, 0, 0, // PC_MFTB + SRU, 3, 3, 0, 0, 0, 0, 0, // PC_MFSR + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSR + SRU, 3, 3, 0, 0, 0, 0, 0, // PC_MFSRIN + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_MTSRIN + FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSB0 + FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSB1 + FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_MTFSFI + SRU, 2, 2, 0, 0, 0, 1, 0, // PC_SC + FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRT + FPU1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRTS + LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIA + LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIE + LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBLD + LSU1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBLI + LSU1, 1, 1, 0, 0, 0, 1, 0, // PC_TLBSYNC + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TW + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TRAP + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_TWI + IU2, 1, 1, 0, 0, 0, 1, 0, // PC_OPWORD + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_MFROM + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_DSA + IU2, 1, 1, 0, 0, 0, 0, 0, // PC_ESA + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_DCCCI + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_DCREAD + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICBT + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICCCI + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_ICREAD + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_RFCI + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBRE + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBSX + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_TLBWE + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEE + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEEI + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_MFDCR + IU2, 1, 0, 0, 0, 0, 0, 0, // PC_MTDCR + LSU1, 3, 1, 2, 0, 0, 0, 0, // PC_DCBA + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSS + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSSALL + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DST + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTT + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTST + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_DSTSTT + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEBX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEHX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVEWX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVSL + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVSR + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_LVXL + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEBX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEHX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVEWX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVX + LSU1, 2, 1, 1, 0, 0, 0, 0, // PC_STVXL + VSIU, 1, 1, 0, 0, 0, 1, 0, // PC_MFVSCR + VSIU, 1, 1, 0, 0, 0, 1, 0, // PC_MTVSCR + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDCUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VADDFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSBS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSHS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSWS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAND + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VANDC + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFSX + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFUX + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPBFP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPEQFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPGEFP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCMPGTFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTSXS + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTUXS + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VEXPTEFP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VLOGEFP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMAXFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMINFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUW + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGHW + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRGLW + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULESB + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULESH + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULEUB + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULEUH + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOSB + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOSH + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOUB + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMULOUH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VNOR + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VOR + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKPX + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSHSS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSHUS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSWSS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKSWUS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUHUM + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUHUS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUWUM + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPKUWUS + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VREFP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIM + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIN + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIP + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIZ + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VRLW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VRSQRTEFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSL + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLO + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLW + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTW + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSPLTISW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSR + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRB + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRO + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSRW + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBCUW + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUBFP + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSBS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSHS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSWS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHS + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUMSWS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM2SWS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4SBS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4SHS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VSUM4UBS + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHPX + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHSB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKHSH + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLPX + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLSB + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VUPKLSH + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VXOR + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VMADDFP + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMHADDSHS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMHRADDSHS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMLADDUHM + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMMBM + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMSHM + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMSHS + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUBM + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUHM + VCIU1, 3, 1, 1, 1, 0, 0, 0, // PC_VMSUMUHS + VFPU1, 4, 1, 1, 1, 1, 0, 0, // PC_VNMSUBFP + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VPERM + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VSEL + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VSLDOI + VSIU, 1, 1, 0, 0, 0, 0, 0, // PC_VMR + VPU, 1, 1, 0, 0, 0, 0, 0, // PC_VMRP + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLE + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLEQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLIQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLLIQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLLQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SLQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRAIQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRAQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRE + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SREA + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SREQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRIQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRLIQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRLQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_SRQ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MASKG + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MASKIR + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_LSCBX + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DIV + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DIVS + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DOZ + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_MUL + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_NABS + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_ABS + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_CLCS + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_DOZI + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_RLMI + BPU, 0, 0, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; + + if (stage == IU1) + iu1_completed_instruction = instr; + else if (stage == IU2) + iu2_completed_instruction = instr; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; + + iu1_completed_instruction = NULL; + iu2_completed_instruction = NULL; +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + + if (stage == IU2) { + PCode *check; + int isClear1 = !pipeline[IU1].instr; + int isClear2 = !pipeline[IU2].instr; + if (!isClear1 && !isClear2) + return 0; + if (isClear1 && isClear2) + return 1; + + if (isClear1) + check = pipeline[IU2].instr; + else + check = pipeline[IU1].instr; + + if (is_dependent(instr, check, RegClass_GPR)) + return 0; + if (is_dependent(instr, iu1_completed_instruction, RegClass_GPR)) + return 0; + if (is_dependent(instr, iu2_completed_instruction, RegClass_GPR)) + return 0; + } else if (stage == VFPU1 || stage == VCIU1 || stage == VSIU || stage == VPU) { + PCode *check; + int isVpuClear = !pipeline[VPU].instr; + int isVFpuClear = !pipeline[VFPU1].instr; + int isVCiuClear = !pipeline[VCIU1].instr; + int isVSiuClear = !pipeline[VSIU].instr; + + if (stage == VPU) { + if (!isVpuClear) + return 0; + + if (!isVFpuClear) + check = pipeline[VFPU1].instr; + else if (!isVCiuClear) + check = pipeline[VCIU1].instr; + else if (!isVSiuClear) + check = pipeline[VSIU].instr; + else + check = NULL; + + if (is_dependent(instr, check, RegClass_VR)) + return 0; + } else { + if (!isVFpuClear || !isVCiuClear || !isVSiuClear) + return 0; + + if (!isVpuClear && is_dependent(instr, pipeline[VPU].instr, RegClass_VR)) + return 0; + } + } else { + if (pipeline[stage].instr) + return 0; + } + + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + if (stage == IU2 && !pipeline[IU1].instr) + stage = IU1; + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + iu1_completed_instruction = NULL; + iu2_completed_instruction = NULL; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[IU1].instr && pipeline[IU1].remaining == 0) + complete_instruction(IU1); + if (pipeline[VPU].instr && pipeline[VPU].remaining == 0) + complete_instruction(VPU); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0) + complete_instruction(FPU3); + if (pipeline[SRU].instr && pipeline[SRU].remaining == 0) + complete_instruction(SRU); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + if (pipeline[VSIU].instr && pipeline[VSIU].remaining == 0) + complete_instruction(VSIU); + if (pipeline[VCIU3].instr && pipeline[VCIU3].remaining == 0) + complete_instruction(VCIU3); + if (pipeline[VFPU4].instr && pipeline[VFPU4].remaining == 0) + complete_instruction(VFPU4); + if (pipeline[IU2].instr && pipeline[IU2].remaining == 0) + complete_instruction(IU2); + + if ( + pipeline[FPU1].instr && + pipeline[FPU1].remaining == 0 && + (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS) + ) + complete_instruction(FPU1); + + if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr) + advance(FPU1, FPU2, FPU3); + if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr) + advance(FPU1, FPU1, FPU2); + + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); + + if (pipeline[VCIU2].instr && pipeline[VCIU2].remaining == 0 && !pipeline[VCIU3].instr) + advance(VCIU1, VCIU2, VCIU3); + if (pipeline[VCIU1].instr && pipeline[VCIU1].remaining == 0 && !pipeline[VCIU2].instr) + advance(VCIU1, VCIU1, VCIU2); + + if (pipeline[VFPU3].instr && pipeline[VFPU3].remaining == 0 && !pipeline[VFPU4].instr) + advance(VFPU1, VFPU3, VFPU4); + if (pipeline[VFPU2].instr && pipeline[VFPU2].remaining == 0 && !pipeline[VFPU3].instr) + advance(VFPU1, VFPU2, VFPU3); + if (pipeline[VFPU1].instr && pipeline[VFPU1].remaining == 0 && !pipeline[VFPU2].instr) + advance(VFPU1, VFPU1, VFPU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +static int uses_vpermute_unit_7400(PCode *instr) { + return instruction_timing[instr->op].stage == VPU; +} + +MachineInfo machine7400 = { + 2, + 1, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &uses_vpermute_unit_7400 +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation750.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation750.c new file mode 100644 index 0000000..d412df3 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation750.c @@ -0,0 +1,678 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/reference-manual/MPC750UM.pdf + +typedef enum Stage { + BPU, // Branch Prediction Unit + IU1, // Integer Unit 1 + IU2, // Integer Unit 2 + + LSU1, // Load/Store Unit + LSU2, + + FPU1, // Floating Point Unit + FPU2, + FPU3, + + SRU, // System Register Unit + + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +static PCode *iu1_completed_instruction; +static PCode *iu2_completed_instruction; + +enum { + MaxEntries = 6 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BPU, 0, 0, 0, 0, 1, // PC_B + BPU, 0, 0, 0, 0, 1, // PC_BL + BPU, 0, 0, 0, 0, 1, // PC_BC + BPU, 0, 0, 0, 0, 1, // PC_BCLR + BPU, 0, 0, 0, 0, 1, // PC_BCCTR + BPU, 0, 0, 0, 0, 1, // PC_BT + BPU, 0, 0, 0, 0, 1, // PC_BTLR + BPU, 0, 0, 0, 0, 1, // PC_BTCTR + BPU, 0, 0, 0, 0, 1, // PC_BF + BPU, 0, 0, 0, 0, 1, // PC_BFLR + BPU, 0, 0, 0, 0, 1, // PC_BFCTR + BPU, 0, 0, 0, 0, 1, // PC_BDNZ + BPU, 0, 0, 0, 0, 1, // PC_BDNZT + BPU, 0, 0, 0, 0, 1, // PC_BDNZF + BPU, 0, 0, 0, 0, 1, // PC_BDZ + BPU, 0, 0, 0, 0, 1, // PC_BDZT + BPU, 0, 0, 0, 0, 1, // PC_BDZF + BPU, 0, 0, 0, 0, 1, // PC_BLR + BPU, 0, 0, 0, 0, 1, // PC_BCTR + BPU, 0, 0, 0, 0, 1, // PC_BCTRL + BPU, 0, 0, 0, 0, 1, // PC_BLRL + LSU1, 2, 1, 1, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 3, 1, 2, 0, 0, // PC_DCBF + LSU1, 3, 1, 2, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 3, 1, 2, 0, 0, // PC_DCBZ + IU2, 1, 1, 0, 0, 0, // PC_ADD + IU2, 1, 1, 0, 0, 0, // PC_ADDC + IU2, 1, 1, 0, 0, 0, // PC_ADDE + IU2, 1, 1, 0, 0, 0, // PC_ADDI + IU2, 1, 1, 0, 0, 0, // PC_ADDIC + IU2, 1, 1, 0, 0, 0, // PC_ADDICR + IU2, 1, 1, 0, 0, 0, // PC_ADDIS + IU2, 1, 1, 0, 0, 0, // PC_ADDME + IU2, 1, 1, 0, 0, 0, // PC_ADDZE + IU1, 19, 19, 0, 0, 0, // PC_DIVW + IU1, 19, 19, 0, 0, 0, // PC_DIVWU + IU1, 5, 5, 0, 0, 0, // PC_MULHW + IU1, 6, 5, 0, 0, 0, // PC_MULHWU + IU1, 3, 3, 0, 0, 0, // PC_MULLI + IU1, 5, 5, 0, 0, 0, // PC_MULLW + IU2, 1, 1, 0, 0, 0, // PC_NEG + IU2, 1, 1, 0, 0, 0, // PC_SUBF + IU2, 1, 1, 0, 0, 0, // PC_SUBFC + IU2, 1, 1, 0, 0, 0, // PC_SUBFE + IU2, 1, 1, 0, 0, 0, // PC_SUBFIC + IU2, 1, 1, 0, 0, 0, // PC_SUBFME + IU2, 1, 1, 0, 0, 0, // PC_SUBFZE + IU2, 3, 1, 0, 0, 0, // PC_CMPI + IU2, 3, 1, 0, 0, 0, // PC_CMP + IU2, 3, 1, 0, 0, 0, // PC_CMPLI + IU2, 3, 1, 0, 0, 0, // PC_CMPL + IU2, 1, 1, 0, 0, 0, // PC_ANDI + IU2, 1, 1, 0, 0, 0, // PC_ANDIS + IU2, 1, 1, 0, 0, 0, // PC_ORI + IU2, 1, 1, 0, 0, 0, // PC_ORIS + IU2, 1, 1, 0, 0, 0, // PC_XORI + IU2, 1, 1, 0, 0, 0, // PC_XORIS + IU2, 1, 1, 0, 0, 0, // PC_AND + IU2, 1, 1, 0, 0, 0, // PC_OR + IU2, 1, 1, 0, 0, 0, // PC_XOR + IU2, 1, 1, 0, 0, 0, // PC_NAND + IU2, 1, 1, 0, 0, 0, // PC_NOR + IU2, 1, 1, 0, 0, 0, // PC_EQV + IU2, 1, 1, 0, 0, 0, // PC_ANDC + IU2, 1, 1, 0, 0, 0, // PC_ORC + IU2, 1, 1, 0, 0, 0, // PC_EXTSB + IU2, 1, 1, 0, 0, 0, // PC_EXTSH + IU2, 1, 1, 0, 0, 0, // PC_CNTLZW + IU2, 1, 1, 0, 0, 0, // PC_RLWINM + IU2, 1, 1, 0, 0, 0, // PC_RLWNM + IU2, 1, 1, 0, 0, 0, // PC_RLWIMI + IU2, 1, 1, 0, 0, 0, // PC_SLW + IU2, 1, 1, 0, 0, 0, // PC_SRW + IU2, 1, 1, 0, 0, 0, // PC_SRAWI + IU2, 1, 1, 0, 0, 0, // PC_SRAW + SRU, 1, 1, 0, 0, 1, // PC_CRAND + SRU, 1, 1, 0, 0, 1, // PC_CRANDC + SRU, 1, 1, 0, 0, 1, // PC_CREQV + SRU, 1, 1, 0, 0, 1, // PC_CRNAND + SRU, 1, 1, 0, 0, 1, // PC_CRNOR + SRU, 1, 1, 0, 0, 1, // PC_CROR + SRU, 1, 1, 0, 0, 1, // PC_CRORC + SRU, 1, 1, 0, 0, 1, // PC_CRXOR + SRU, 1, 1, 0, 0, 1, // PC_MCRF + SRU, 2, 2, 0, 0, 1, // PC_MTXER + SRU, 2, 2, 0, 0, 1, // PC_MTCTR + SRU, 2, 2, 0, 0, 1, // PC_MTLR + SRU, 1, 1, 0, 0, 1, // PC_MTCRF + SRU, 1, 1, 0, 0, 0, // PC_MTMSR + SRU, 1, 1, 0, 0, 1, // PC_MTSPR + SRU, 1, 1, 0, 0, 1, // PC_MFMSR + SRU, 1, 1, 0, 0, 1, // PC_MFSPR + SRU, 1, 1, 0, 0, 1, // PC_MFXER + SRU, 1, 1, 0, 0, 1, // PC_MFCTR + SRU, 1, 1, 0, 0, 1, // PC_MFLR + SRU, 1, 1, 0, 0, 1, // PC_MFCR + FPU1, 3, 1, 1, 1, 0, // PC_MFFS + FPU1, 3, 1, 1, 1, 0, // PC_MTFSF + SRU, 1, 1, 0, 0, 1, // PC_EIEIO + SRU, 2, 2, 0, 0, 1, // PC_ISYNC + SRU, 3, 3, 0, 0, 1, // PC_SYNC + SRU, 1, 1, 0, 0, 1, // PC_RFI + IU2, 1, 1, 0, 0, 0, // PC_LI + IU2, 1, 1, 0, 0, 0, // PC_LIS + IU2, 1, 1, 0, 0, 0, // PC_MR + IU2, 1, 1, 0, 0, 0, // PC_NOP + IU2, 1, 1, 0, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, // PC_STFSUX + LSU1, 2, 1, 1, 0, 0, // PC_STFD + LSU1, 2, 1, 1, 0, 0, // PC_STFDU + LSU1, 2, 1, 1, 0, 0, // PC_STFDX + LSU1, 2, 1, 1, 0, 0, // PC_STFDUX + FPU1, 3, 1, 1, 1, 0, // PC_FMR + FPU1, 3, 1, 1, 1, 0, // PC_FABS + FPU1, 3, 1, 1, 1, 0, // PC_FNEG + FPU1, 3, 1, 1, 1, 0, // PC_FNABS + FPU1, 3, 1, 1, 1, 0, // PC_FADD + FPU1, 3, 1, 1, 1, 0, // PC_FADDS + FPU1, 3, 1, 1, 1, 0, // PC_FSUB + FPU1, 3, 1, 1, 1, 0, // PC_FSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FMUL + FPU1, 3, 1, 1, 1, 0, // PC_FMULS + FPU1, 31, 31, 0, 0, 0, // PC_FDIV + FPU1, 17, 17, 0, 0, 0, // PC_FDIVS + FPU1, 4, 2, 1, 1, 0, // PC_FMADD + FPU1, 3, 1, 1, 1, 0, // PC_FMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS + FPU1, 4, 2, 1, 1, 0, // PC_FNMADD + FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS + FPU1, 4, 2, 1, 1, 0, // PC_FNMSUB + FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS + FPU1, 10, 10, 0, 0, 0, // PC_FRES + FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE + FPU1, 3, 1, 1, 1, 0, // PC_FSEL + FPU1, 3, 1, 1, 1, 0, // PC_FRSP + FPU1, 3, 1, 1, 1, 0, // PC_FCTIW + FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ + FPU1, 3, 1, 1, 1, 0, // PC_FCMPU + FPU1, 3, 1, 1, 1, 0, // PC_FCMPO + LSU1, 1, 1, 0, 0, 0, // PC_LWARX + LSU1, 1, 1, 0, 0, 0, // PC_LSWI + LSU1, 1, 1, 0, 0, 0, // PC_LSWX + LSU1, 1, 1, 0, 0, 0, // PC_STFIWX + LSU1, 1, 1, 0, 0, 0, // PC_STSWI + LSU1, 1, 1, 0, 0, 0, // PC_STSWX + LSU1, 1, 1, 0, 0, 0, // PC_STWCX + IU1, 1, 1, 0, 0, 1, // PC_ECIWX + IU1, 1, 1, 0, 0, 1, // PC_ECOWX + IU1, 1, 1, 0, 0, 0, // PC_DCBI + IU1, 1, 1, 0, 0, 0, // PC_ICBI + IU1, 1, 1, 0, 0, 0, // PC_MCRFS + IU1, 1, 1, 0, 0, 0, // PC_MCRXR + IU1, 1, 1, 0, 0, 0, // PC_MFTB + IU1, 1, 1, 0, 0, 0, // PC_MFSR + IU1, 1, 1, 0, 0, 0, // PC_MTSR + IU1, 1, 1, 0, 0, 0, // PC_MFSRIN + IU1, 1, 1, 0, 0, 0, // PC_MTSRIN + IU1, 1, 1, 0, 0, 0, // PC_MTFSB0 + IU1, 1, 1, 0, 0, 0, // PC_MTFSB1 + IU1, 1, 1, 0, 0, 0, // PC_MTFSFI + IU1, 1, 1, 0, 0, 1, // PC_SC + FPU1, 1, 1, 0, 0, 0, // PC_FSQRT + FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS + IU1, 1, 1, 0, 0, 0, // PC_TLBIA + IU1, 1, 1, 0, 0, 0, // PC_TLBIE + IU1, 1, 1, 0, 0, 0, // PC_TLBLD + IU1, 1, 1, 0, 0, 0, // PC_TLBLI + IU1, 1, 1, 0, 0, 0, // PC_TLBSYNC + IU1, 1, 1, 0, 0, 1, // PC_TW + IU1, 1, 1, 0, 0, 1, // PC_TRAP + IU1, 1, 1, 0, 0, 1, // PC_TWI + IU1, 1, 1, 0, 0, 1, // PC_OPWORD + IU1, 1, 1, 0, 0, 0, // PC_MFROM + IU1, 1, 1, 0, 0, 1, // PC_DSA + IU1, 1, 1, 0, 0, 1, // PC_ESA + IU1, 0, 0, 0, 0, 0, // PC_DCCCI + IU1, 0, 0, 0, 0, 0, // PC_DCREAD + IU1, 0, 0, 0, 0, 0, // PC_ICBT + IU1, 0, 0, 0, 0, 0, // PC_ICCCI + IU1, 0, 0, 0, 0, 0, // PC_ICREAD + IU1, 0, 0, 0, 0, 0, // PC_RFCI + IU1, 0, 0, 0, 0, 0, // PC_TLBRE + IU1, 0, 0, 0, 0, 0, // PC_TLBSX + IU1, 0, 0, 0, 0, 0, // PC_TLBWE + IU1, 0, 0, 0, 0, 0, // PC_WRTEE + IU1, 0, 0, 0, 0, 0, // PC_WRTEEI + IU1, 0, 0, 0, 0, 0, // PC_MFDCR + IU1, 0, 0, 0, 0, 0, // PC_MTDCR + IU1, 0, 0, 0, 0, 0, // PC_DCBA + BPU, 0, 0, 0, 0, 0, // PC_DSS + BPU, 0, 0, 0, 0, 0, // PC_DSSALL + BPU, 0, 0, 0, 0, 0, // PC_DST + BPU, 0, 0, 0, 0, 0, // PC_DSTT + BPU, 0, 0, 0, 0, 0, // PC_DSTST + BPU, 0, 0, 0, 0, 0, // PC_DSTSTT + BPU, 0, 0, 0, 0, 0, // PC_LVEBX + BPU, 0, 0, 0, 0, 0, // PC_LVEHX + BPU, 0, 0, 0, 0, 0, // PC_LVEWX + BPU, 0, 0, 0, 0, 0, // PC_LVSL + BPU, 0, 0, 0, 0, 0, // PC_LVSR + BPU, 0, 0, 0, 0, 0, // PC_LVX + BPU, 0, 0, 0, 0, 0, // PC_LVXL + BPU, 0, 0, 0, 0, 0, // PC_STVEBX + BPU, 0, 0, 0, 0, 0, // PC_STVEHX + BPU, 0, 0, 0, 0, 0, // PC_STVEWX + BPU, 0, 0, 0, 0, 0, // PC_STVX + BPU, 0, 0, 0, 0, 0, // PC_STVXL + BPU, 0, 0, 0, 0, 0, // PC_MFVSCR + BPU, 0, 0, 0, 0, 0, // PC_MTVSCR + BPU, 0, 0, 0, 0, 0, // PC_VADDCUW + BPU, 0, 0, 0, 0, 0, // PC_VADDFP + BPU, 0, 0, 0, 0, 0, // PC_VADDSBS + BPU, 0, 0, 0, 0, 0, // PC_VADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VADDSWS + BPU, 0, 0, 0, 0, 0, // PC_VADDUBM + BPU, 0, 0, 0, 0, 0, // PC_VADDUBS + BPU, 0, 0, 0, 0, 0, // PC_VADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VADDUHS + BPU, 0, 0, 0, 0, 0, // PC_VADDUWM + BPU, 0, 0, 0, 0, 0, // PC_VADDUWS + BPU, 0, 0, 0, 0, 0, // PC_VAND + BPU, 0, 0, 0, 0, 0, // PC_VANDC + BPU, 0, 0, 0, 0, 0, // PC_VAVGSB + BPU, 0, 0, 0, 0, 0, // PC_VAVGSH + BPU, 0, 0, 0, 0, 0, // PC_VAVGSW + BPU, 0, 0, 0, 0, 0, // PC_VAVGUB + BPU, 0, 0, 0, 0, 0, // PC_VAVGUH + BPU, 0, 0, 0, 0, 0, // PC_VAVGUW + BPU, 0, 0, 0, 0, 0, // PC_VCFSX + BPU, 0, 0, 0, 0, 0, // PC_VCFUX + BPU, 0, 0, 0, 0, 0, // PC_VCMPBFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPEQUW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGEFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTFP + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTSW + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUB + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUH + BPU, 0, 0, 0, 0, 0, // PC_VCMPGTUW + BPU, 0, 0, 0, 0, 0, // PC_VCTSXS + BPU, 0, 0, 0, 0, 0, // PC_VCTUXS + BPU, 0, 0, 0, 0, 0, // PC_VEXPTEFP + BPU, 0, 0, 0, 0, 0, // PC_VLOGEFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXFP + BPU, 0, 0, 0, 0, 0, // PC_VMAXSB + BPU, 0, 0, 0, 0, 0, // PC_VMAXSH + BPU, 0, 0, 0, 0, 0, // PC_VMAXSW + BPU, 0, 0, 0, 0, 0, // PC_VMAXUB + BPU, 0, 0, 0, 0, 0, // PC_VMAXUH + BPU, 0, 0, 0, 0, 0, // PC_VMAXUW + BPU, 0, 0, 0, 0, 0, // PC_VMINFP + BPU, 0, 0, 0, 0, 0, // PC_VMINSB + BPU, 0, 0, 0, 0, 0, // PC_VMINSH + BPU, 0, 0, 0, 0, 0, // PC_VMINSW + BPU, 0, 0, 0, 0, 0, // PC_VMINUB + BPU, 0, 0, 0, 0, 0, // PC_VMINUH + BPU, 0, 0, 0, 0, 0, // PC_VMINUW + BPU, 0, 0, 0, 0, 0, // PC_VMRGHB + BPU, 0, 0, 0, 0, 0, // PC_VMRGHH + BPU, 0, 0, 0, 0, 0, // PC_VMRGHW + BPU, 0, 0, 0, 0, 0, // PC_VMRGLB + BPU, 0, 0, 0, 0, 0, // PC_VMRGLH + BPU, 0, 0, 0, 0, 0, // PC_VMRGLW + BPU, 0, 0, 0, 0, 0, // PC_VMULESB + BPU, 0, 0, 0, 0, 0, // PC_VMULESH + BPU, 0, 0, 0, 0, 0, // PC_VMULEUB + BPU, 0, 0, 0, 0, 0, // PC_VMULEUH + BPU, 0, 0, 0, 0, 0, // PC_VMULOSB + BPU, 0, 0, 0, 0, 0, // PC_VMULOSH + BPU, 0, 0, 0, 0, 0, // PC_VMULOUB + BPU, 0, 0, 0, 0, 0, // PC_VMULOUH + BPU, 0, 0, 0, 0, 0, // PC_VNOR + BPU, 0, 0, 0, 0, 0, // PC_VOR + BPU, 0, 0, 0, 0, 0, // PC_VPKPX + BPU, 0, 0, 0, 0, 0, // PC_VPKSHSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWSS + BPU, 0, 0, 0, 0, 0, // PC_VPKSWUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUHUS + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUM + BPU, 0, 0, 0, 0, 0, // PC_VPKUWUS + BPU, 0, 0, 0, 0, 0, // PC_VREFP + BPU, 0, 0, 0, 0, 0, // PC_VRFIM + BPU, 0, 0, 0, 0, 0, // PC_VRFIN + BPU, 0, 0, 0, 0, 0, // PC_VRFIP + BPU, 0, 0, 0, 0, 0, // PC_VRFIZ + BPU, 0, 0, 0, 0, 0, // PC_VRLB + BPU, 0, 0, 0, 0, 0, // PC_VRLH + BPU, 0, 0, 0, 0, 0, // PC_VRLW + BPU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + BPU, 0, 0, 0, 0, 0, // PC_VSL + BPU, 0, 0, 0, 0, 0, // PC_VSLB + BPU, 0, 0, 0, 0, 0, // PC_VSLH + BPU, 0, 0, 0, 0, 0, // PC_VSLO + BPU, 0, 0, 0, 0, 0, // PC_VSLW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTW + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISB + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISH + BPU, 0, 0, 0, 0, 0, // PC_VSPLTISW + BPU, 0, 0, 0, 0, 0, // PC_VSR + BPU, 0, 0, 0, 0, 0, // PC_VSRAB + BPU, 0, 0, 0, 0, 0, // PC_VSRAH + BPU, 0, 0, 0, 0, 0, // PC_VSRAW + BPU, 0, 0, 0, 0, 0, // PC_VSRB + BPU, 0, 0, 0, 0, 0, // PC_VSRH + BPU, 0, 0, 0, 0, 0, // PC_VSRO + BPU, 0, 0, 0, 0, 0, // PC_VSRW + BPU, 0, 0, 0, 0, 0, // PC_VSUBCUW + BPU, 0, 0, 0, 0, 0, // PC_VSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VSUBSBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUBS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUHS + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWM + BPU, 0, 0, 0, 0, 0, // PC_VSUBUWS + BPU, 0, 0, 0, 0, 0, // PC_VSUMSWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM2SWS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SBS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4SHS + BPU, 0, 0, 0, 0, 0, // PC_VSUM4UBS + BPU, 0, 0, 0, 0, 0, // PC_VUPKHPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKHSH + BPU, 0, 0, 0, 0, 0, // PC_VUPKLPX + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSB + BPU, 0, 0, 0, 0, 0, // PC_VUPKLSH + BPU, 0, 0, 0, 0, 0, // PC_VXOR + BPU, 0, 0, 0, 0, 0, // PC_VMADDFP + BPU, 0, 0, 0, 0, 0, // PC_VMHADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + BPU, 0, 0, 0, 0, 0, // PC_VMLADDUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMMBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMSHS + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUBM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHM + BPU, 0, 0, 0, 0, 0, // PC_VMSUMUHS + BPU, 0, 0, 0, 0, 0, // PC_VNMSUBFP + BPU, 0, 0, 0, 0, 0, // PC_VPERM + BPU, 0, 0, 0, 0, 0, // PC_VSEL + BPU, 0, 0, 0, 0, 0, // PC_VSLDOI + BPU, 0, 0, 0, 0, 0, // PC_VMR + BPU, 0, 0, 0, 0, 0, // PC_VMRP + BPU, 0, 0, 0, 0, 0, // PC_SLE + BPU, 0, 0, 0, 0, 0, // PC_SLEQ + BPU, 0, 0, 0, 0, 0, // PC_SLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLIQ + BPU, 0, 0, 0, 0, 0, // PC_SLLQ + BPU, 0, 0, 0, 0, 0, // PC_SLQ + BPU, 0, 0, 0, 0, 0, // PC_SRAIQ + BPU, 0, 0, 0, 0, 0, // PC_SRAQ + BPU, 0, 0, 0, 0, 0, // PC_SRE + BPU, 0, 0, 0, 0, 0, // PC_SREA + BPU, 0, 0, 0, 0, 0, // PC_SREQ + BPU, 0, 0, 0, 0, 0, // PC_SRIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLIQ + BPU, 0, 0, 0, 0, 0, // PC_SRLQ + BPU, 0, 0, 0, 0, 0, // PC_SRQ + BPU, 0, 0, 0, 0, 0, // PC_MASKG + BPU, 0, 0, 0, 0, 0, // PC_MASKIR + BPU, 0, 0, 0, 0, 0, // PC_LSCBX + BPU, 0, 0, 0, 0, 0, // PC_DIV + BPU, 0, 0, 0, 0, 0, // PC_DIVS + BPU, 0, 0, 0, 0, 0, // PC_DOZ + BPU, 0, 0, 0, 0, 0, // PC_MUL + BPU, 0, 0, 0, 0, 0, // PC_NABS + BPU, 0, 0, 0, 0, 0, // PC_ABS + BPU, 0, 0, 0, 0, 0, // PC_CLCS + BPU, 0, 0, 0, 0, 0, // PC_DOZI + BPU, 0, 0, 0, 0, 0, // PC_RLMI + BPU, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; + + if (stage == IU1) + iu1_completed_instruction = instr; + else if (stage == IU2) + iu2_completed_instruction = instr; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; + + iu1_completed_instruction = NULL; + iu2_completed_instruction = NULL; +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + + if (stage == IU2) { + PCode *check; + int isClear1 = !pipeline[IU1].instr; + int isClear2 = !pipeline[IU2].instr; + if (!isClear1 && !isClear2) + return 0; + if (isClear1 && isClear2) + return 1; + + if (isClear1) + check = pipeline[IU2].instr; + else + check = pipeline[IU1].instr; + + if (is_dependent(instr, check, RegClass_GPR)) + return 0; + if (is_dependent(instr, iu1_completed_instruction, RegClass_GPR)) + return 0; + if (is_dependent(instr, iu2_completed_instruction, RegClass_GPR)) + return 0; + } else { + if (pipeline[stage].instr) + return 0; + } + + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + if (stage == IU2 && !pipeline[IU1].instr) + stage = IU1; + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + iu1_completed_instruction = NULL; + iu2_completed_instruction = NULL; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[IU1].instr && pipeline[IU1].remaining == 0) + complete_instruction(IU1); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0) + complete_instruction(FPU3); + if (pipeline[SRU].instr && pipeline[SRU].remaining == 0) + complete_instruction(SRU); + if (pipeline[BPU].instr && pipeline[BPU].remaining == 0) + complete_instruction(BPU); + if (pipeline[IU2].instr && pipeline[IU2].remaining == 0) + complete_instruction(IU2); + + if ( + pipeline[FPU1].instr && + pipeline[FPU1].remaining == 0 && + (pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS) + ) + complete_instruction(FPU1); + + if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr) + advance(FPU1, FPU2, FPU3); + if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr) + advance(FPU1, FPU1, FPU2); + + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine750 = { + 2, + 1, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c new file mode 100644 index 0000000..bbf0509 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c @@ -0,0 +1,615 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/user-guide/MPC821UM.pdf + +typedef enum Stage { + BranchUnit, + Stage1, + Stage2, + LSU1, + LSU2, + CRUnit, + NumStages, + Stage7 +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +enum { + MaxEntries = 6 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BranchUnit, 0, 0, 0, 0, 0, // PC_B + BranchUnit, 0, 0, 0, 0, 0, // PC_BL + BranchUnit, 0, 0, 0, 0, 0, // PC_BC + BranchUnit, 0, 0, 0, 0, 0, // PC_BCLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BT + BranchUnit, 0, 0, 0, 0, 0, // PC_BTLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BTCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BF + BranchUnit, 0, 0, 0, 0, 0, // PC_BFLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BFCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZ + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZT + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZF + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZ + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZT + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZF + BranchUnit, 0, 0, 0, 0, 0, // PC_BLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCTRL + BranchUnit, 0, 0, 0, 0, 0, // PC_BLRL + BranchUnit, 0, 0, 0, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 2, 1, 1, 0, 0, // PC_DCBF + LSU1, 2, 1, 1, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 2, 1, 1, 0, 0, // PC_DCBZ + LSU1, 2, 1, 1, 0, 0, // PC_ADD + Stage1, 1, 1, 0, 0, 0, // PC_ADDC + Stage1, 1, 1, 0, 0, 0, // PC_ADDE + Stage1, 1, 1, 0, 0, 0, // PC_ADDI + Stage1, 1, 1, 0, 0, 0, // PC_ADDIC + Stage1, 1, 1, 0, 0, 0, // PC_ADDICR + Stage1, 1, 1, 0, 0, 0, // PC_ADDIS + Stage1, 1, 1, 0, 0, 0, // PC_ADDME + Stage1, 1, 1, 0, 0, 0, // PC_ADDZE + Stage1, 1, 1, 0, 0, 0, // PC_DIVW + Stage1, 37, 37, 0, 0, 0, // PC_DIVWU + Stage1, 37, 37, 0, 0, 0, // PC_MULHW + Stage1, 5, 5, 0, 0, 0, // PC_MULHWU + Stage1, 5, 5, 0, 0, 0, // PC_MULLI + Stage1, 3, 3, 0, 0, 0, // PC_MULLW + Stage1, 5, 5, 0, 0, 0, // PC_NEG + Stage1, 1, 1, 0, 0, 0, // PC_SUBF + Stage1, 1, 1, 0, 0, 0, // PC_SUBFC + Stage1, 1, 1, 0, 0, 0, // PC_SUBFE + Stage1, 1, 1, 0, 0, 0, // PC_SUBFIC + Stage1, 1, 1, 0, 0, 0, // PC_SUBFME + Stage1, 1, 1, 0, 0, 0, // PC_SUBFZE + Stage1, 1, 1, 0, 0, 0, // PC_CMPI + Stage1, 3, 1, 0, 0, 0, // PC_CMP + Stage1, 3, 1, 0, 0, 0, // PC_CMPLI + Stage1, 3, 1, 0, 0, 0, // PC_CMPL + Stage1, 3, 1, 0, 0, 0, // PC_ANDI + Stage1, 1, 1, 0, 0, 0, // PC_ANDIS + Stage1, 1, 1, 0, 0, 0, // PC_ORI + Stage1, 1, 1, 0, 0, 0, // PC_ORIS + Stage1, 1, 1, 0, 0, 0, // PC_XORI + Stage1, 1, 1, 0, 0, 0, // PC_XORIS + Stage1, 1, 1, 0, 0, 0, // PC_AND + Stage1, 1, 1, 0, 0, 0, // PC_OR + Stage1, 1, 1, 0, 0, 0, // PC_XOR + Stage1, 1, 1, 0, 0, 0, // PC_NAND + Stage1, 1, 1, 0, 0, 0, // PC_NOR + Stage1, 1, 1, 0, 0, 0, // PC_EQV + Stage1, 1, 1, 0, 0, 0, // PC_ANDC + Stage1, 1, 1, 0, 0, 0, // PC_ORC + Stage1, 1, 1, 0, 0, 0, // PC_EXTSB + Stage1, 1, 1, 0, 0, 0, // PC_EXTSH + Stage1, 1, 1, 0, 0, 0, // PC_CNTLZW + Stage1, 1, 1, 0, 0, 0, // PC_RLWINM + Stage1, 1, 1, 0, 0, 0, // PC_RLWNM + Stage1, 1, 1, 0, 0, 0, // PC_RLWIMI + Stage1, 1, 1, 0, 0, 0, // PC_SLW + Stage1, 1, 1, 0, 0, 0, // PC_SRW + Stage1, 1, 1, 0, 0, 0, // PC_SRAWI + Stage1, 1, 1, 0, 0, 0, // PC_SRAW + Stage1, 1, 1, 0, 0, 0, // PC_CRAND + CRUnit, 1, 1, 0, 0, 0, // PC_CRANDC + CRUnit, 1, 1, 0, 0, 0, // PC_CREQV + CRUnit, 1, 1, 0, 0, 0, // PC_CRNAND + CRUnit, 1, 1, 0, 0, 0, // PC_CRNOR + CRUnit, 1, 1, 0, 0, 0, // PC_CROR + CRUnit, 1, 1, 0, 0, 0, // PC_CRORC + CRUnit, 1, 1, 0, 0, 0, // PC_CRXOR + CRUnit, 1, 1, 0, 0, 0, // PC_MCRF + CRUnit, 1, 1, 0, 0, 0, // PC_MTXER + Stage1, 1, 1, 0, 0, 0, // PC_MTCTR + BranchUnit, 2, 2, 0, 0, 0, // PC_MTLR + BranchUnit, 2, 2, 0, 0, 0, // PC_MTCRF + Stage1, 1, 1, 0, 0, 0, // PC_MTMSR + Stage1, 1, 1, 0, 0, 0, // PC_MTSPR + Stage1, 1, 1, 0, 0, 0, // PC_MFMSR + Stage1, 1, 1, 0, 0, 0, // PC_MFSPR + Stage1, 1, 1, 0, 0, 0, // PC_MFXER + Stage7, 3, 1, 1, 1, 0, // PC_MFCTR + Stage7, 3, 1, 1, 1, 0, // PC_MFLR + Stage1, 1, 1, 0, 0, 0, // PC_MFCR + Stage1, 1, 1, 0, 0, 0, // PC_MFFS + Stage1, 1, 1, 0, 0, 0, // PC_MTFSF + Stage1, 1, 1, 0, 0, 0, // PC_EIEIO + Stage1, 1, 1, 0, 0, 0, // PC_ISYNC + Stage1, 1, 1, 0, 0, 0, // PC_SYNC + Stage1, 1, 1, 0, 0, 0, // PC_RFI + Stage1, 1, 1, 0, 0, 0, // PC_LI + LSU1, 2, 1, 1, 0, 0, // PC_LIS + LSU1, 2, 1, 1, 0, 0, // PC_MR + LSU1, 2, 1, 1, 0, 0, // PC_NOP + LSU1, 2, 1, 1, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, // PC_STFSUX + Stage7, 3, 1, 1, 1, 0, // PC_STFD + Stage7, 3, 1, 1, 1, 0, // PC_STFDU + Stage7, 3, 1, 1, 1, 0, // PC_STFDX + Stage7, 3, 1, 1, 1, 0, // PC_STFDUX + Stage7, 3, 1, 1, 1, 0, // PC_FMR + Stage7, 3, 1, 1, 1, 0, // PC_FABS + Stage7, 3, 1, 1, 1, 0, // PC_FNEG + Stage7, 3, 1, 1, 1, 0, // PC_FNABS + Stage7, 4, 2, 1, 1, 0, // PC_FADD + Stage7, 3, 1, 1, 1, 0, // PC_FADDS + Stage7, 33, 33, 0, 0, 0, // PC_FSUB + Stage7, 18, 18, 0, 0, 0, // PC_FSUBS + Stage7, 4, 2, 1, 1, 0, // PC_FMUL + Stage7, 3, 1, 1, 1, 0, // PC_FMULS + Stage7, 4, 2, 1, 1, 0, // PC_FDIV + Stage7, 3, 1, 1, 1, 0, // PC_FDIVS + Stage7, 4, 2, 1, 1, 0, // PC_FMADD + Stage7, 3, 1, 1, 1, 0, // PC_FMADDS + Stage7, 4, 2, 1, 1, 0, // PC_FMSUB + Stage7, 3, 1, 1, 1, 0, // PC_FMSUBS + Stage7, 18, 18, 0, 0, 0, // PC_FNMADD + Stage7, 3, 1, 1, 1, 0, // PC_FNMADDS + Stage7, 3, 1, 1, 1, 0, // PC_FNMSUB + Stage7, 3, 1, 1, 1, 0, // PC_FNMSUBS + Stage7, 3, 1, 1, 1, 0, // PC_FRES + Stage7, 3, 1, 1, 1, 0, // PC_FRSQRTE + Stage7, 5, 1, 1, 1, 0, // PC_FSEL + Stage7, 5, 1, 1, 1, 0, // PC_FRSP + LSU1, 1, 0, 0, 0, 0, // PC_FCTIW + LSU1, 1, 0, 0, 0, 0, // PC_FCTIWZ + LSU1, 1, 0, 0, 0, 0, // PC_FCMPU + LSU1, 1, 0, 0, 0, 0, // PC_FCMPO + LSU1, 1, 0, 0, 0, 0, // PC_LWARX + LSU1, 1, 0, 0, 0, 0, // PC_LSWI + LSU1, 1, 0, 0, 0, 0, // PC_LSWX + Stage1, 1, 0, 0, 0, 0, // PC_STFIWX + Stage1, 1, 0, 0, 0, 0, // PC_STSWI + Stage1, 1, 0, 0, 0, 0, // PC_STSWX + Stage1, 1, 0, 0, 0, 0, // PC_STWCX + Stage1, 1, 0, 0, 0, 0, // PC_ECIWX + Stage1, 1, 0, 0, 0, 0, // PC_ECOWX + Stage1, 1, 0, 0, 0, 0, // PC_DCBI + Stage1, 1, 0, 0, 0, 0, // PC_ICBI + Stage1, 1, 0, 0, 0, 0, // PC_MCRFS + Stage1, 1, 0, 0, 0, 0, // PC_MCRXR + Stage1, 1, 0, 0, 0, 0, // PC_MFTB + Stage1, 1, 0, 0, 0, 0, // PC_MFSR + Stage1, 1, 0, 0, 0, 0, // PC_MTSR + Stage1, 1, 0, 0, 0, 0, // PC_MFSRIN + Stage1, 1, 0, 0, 0, 0, // PC_MTSRIN + Stage1, 1, 0, 0, 0, 0, // PC_MTFSB0 + Stage1, 1, 0, 0, 0, 0, // PC_MTFSB1 + Stage1, 1, 0, 0, 0, 0, // PC_MTFSFI + Stage1, 1, 0, 0, 0, 1, // PC_SC + Stage1, 1, 0, 0, 0, 1, // PC_FSQRT + Stage1, 1, 0, 0, 0, 0, // PC_FSQRTS + Stage1, 1, 0, 0, 0, 0, // PC_TLBIA + Stage1, 1, 0, 0, 0, 0, // PC_TLBIE + Stage1, 1, 0, 0, 0, 0, // PC_TLBLD + Stage1, 1, 0, 0, 0, 0, // PC_TLBLI + Stage1, 1, 0, 0, 0, 0, // PC_TLBSYNC + Stage1, 1, 0, 0, 0, 0, // PC_TW + Stage1, 1, 0, 0, 0, 1, // PC_TRAP + Stage1, 1, 0, 0, 0, 1, // PC_TWI + Stage1, 1, 0, 0, 0, 1, // PC_OPWORD + Stage1, 1, 0, 0, 0, 1, // PC_MFROM + Stage1, 1, 0, 0, 0, 0, // PC_DSA + Stage1, 1, 0, 0, 0, 0, // PC_ESA + Stage1, 1, 0, 0, 0, 0, // PC_DCCCI + Stage1, 0, 0, 0, 0, 0, // PC_DCREAD + Stage1, 0, 0, 0, 0, 0, // PC_ICBT + Stage1, 0, 0, 0, 0, 0, // PC_ICCCI + Stage1, 0, 0, 0, 0, 0, // PC_ICREAD + Stage1, 0, 0, 0, 0, 0, // PC_RFCI + Stage1, 0, 0, 0, 0, 0, // PC_TLBRE + Stage1, 0, 0, 0, 0, 0, // PC_TLBSX + Stage1, 0, 0, 0, 0, 0, // PC_TLBWE + Stage1, 0, 0, 0, 0, 0, // PC_WRTEE + Stage1, 0, 0, 0, 0, 0, // PC_WRTEEI + Stage1, 0, 0, 0, 0, 0, // PC_MFDCR + Stage1, 0, 0, 0, 0, 0, // PC_MTDCR + Stage1, 0, 0, 0, 0, 0, // PC_DCBA + Stage1, 0, 0, 0, 0, 0, // PC_DSS + BranchUnit, 0, 0, 0, 0, 0, // PC_DSSALL + BranchUnit, 0, 0, 0, 0, 0, // PC_DST + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTT + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTST + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTSTT + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEBX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEHX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEWX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVSL + BranchUnit, 0, 0, 0, 0, 0, // PC_LVSR + BranchUnit, 0, 0, 0, 0, 0, // PC_LVX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVXL + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEBX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEHX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEWX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVXL + BranchUnit, 0, 0, 0, 0, 0, // PC_MFVSCR + BranchUnit, 0, 0, 0, 0, 0, // PC_MTVSCR + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDCUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VAND + BranchUnit, 0, 0, 0, 0, 0, // PC_VANDC + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCFSX + BranchUnit, 0, 0, 0, 0, 0, // PC_VCFUX + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCTSXS + BranchUnit, 0, 0, 0, 0, 0, // PC_VCTUXS + BranchUnit, 0, 0, 0, 0, 0, // PC_VEXPTEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VLOGEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VNOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHSS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWSS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUM + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUM + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VREFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIM + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIN + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIP + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIZ + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VSL + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLO + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSR + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRO + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBCUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUMSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM2SWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4UBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VXOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VMADDFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMHADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMLADDUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMMBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VNMSUBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VPERM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSEL + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLDOI + BranchUnit, 0, 0, 0, 0, 0, // PC_VMR + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRP + BranchUnit, 0, 0, 0, 0, 0, // PC_SLE + BranchUnit, 0, 0, 0, 0, 0, // PC_SLEQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRAIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRAQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRE + BranchUnit, 0, 0, 0, 0, 0, // PC_SREA + BranchUnit, 0, 0, 0, 0, 0, // PC_SREQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRQ + BranchUnit, 0, 0, 0, 0, 0, // PC_MASKG + BranchUnit, 0, 0, 0, 0, 0, // PC_MASKIR + BranchUnit, 0, 0, 0, 0, 0, // PC_LSCBX + BranchUnit, 0, 0, 0, 0, 0, // PC_DIV + BranchUnit, 0, 0, 0, 0, 0, // PC_DIVS + BranchUnit, 0, 0, 0, 0, 0, // PC_DOZ + BranchUnit, 0, 0, 0, 0, 0, // PC_MUL + BranchUnit, 0, 0, 0, 0, 0, // PC_NABS + BranchUnit, 0, 0, 0, 0, 0, // PC_ABS + BranchUnit, 0, 0, 0, 0, 0, // PC_CLCS + BranchUnit, 0, 0, 0, 0, 0, // PC_DOZI + BranchUnit, 0, 0, 0, 0, 0, // PC_RLMI + BranchUnit, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + if (pipeline[stage].instr) + return 0; + + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[Stage1].instr && pipeline[Stage1].remaining == 0) + complete_instruction(Stage1); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[BranchUnit].instr && pipeline[BranchUnit].remaining == 0) + complete_instruction(BranchUnit); + + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine821 = { + 1, + 0, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulationAltiVec.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulationAltiVec.c new file mode 100644 index 0000000..d261ee9 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulationAltiVec.c @@ -0,0 +1,752 @@ +#include "compiler/Scheduler.h" +#include "compiler/CError.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/reference-manual/MPC7450UM.pdf + +typedef enum Stage { + BPU, // Branch Prediction Unit + + IU2_1, // Multiple-Cycle Integer Unit + IU2_2, + IU2_3, + + IU1a, // Single-Cycle Integer Unit + IU1b, // Single-Cycle Integer Unit + IU1c, // Single-Cycle Integer Unit + + LSU_1, // Load/Store Unit + LSU_2, + LSU_3, + LSU_4, + + FPU_1, // Floating-Point Unit + FPU_2, + FPU_3, + FPU_4, + + VIU1, // Vector Simple Integer Unit + + VPU_1, // Vector Permute Unit + VPU_2, + + VIU2_1, // Vector Complex Integer Unit + VIU2_2, + VIU2_3, + VIU2_4, + + VFPU_1, // Vector Floating-Point Unit + VFPU_2, + VFPU_3, + VFPU_4, + + NumStages +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline_altivec[NumStages]; + +enum { + Queue0, + Queue1, + Queue2, + Queue3, + Queue4, + Queue5, + Queue6, + Queue7, + NumQueues +}; + +static int fetchqueues[NumQueues]; + +enum { + MaxEntries = 16 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + short index; + + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[4]; + + // does this instruction serialise? + char serializes; + + char unused; +} instruction_timing[] = { + 0, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_B + 1, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BL + 2, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BC + 3, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCLR + 4, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCCTR + 5, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BT + 6, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTLR + 7, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BTCTR + 8, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BF + 9, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFLR + 10, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BFCTR + 11, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZ + 12, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZT + 13, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDNZF + 14, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZ + 15, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZT + 16, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BDZF + 17, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLR + 18, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTR + 19, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BCTRL + 20, BPU, 0, 0, 0, 0, 0, 0, 0, // PC_BLRL + 21, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZ + 22, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZU + 23, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZX + 24, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LBZUX + 25, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZ + 26, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZU + 27, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZX + 28, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHZUX + 29, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHA + 30, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAU + 31, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAX + 32, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHAUX + 33, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LHBRX + 34, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZ + 35, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZU + 36, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZX + 37, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWZUX + 38, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LWBRX + 39, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_LMW + 40, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STB + 41, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBU + 42, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBX + 43, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STBUX + 44, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STH + 45, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHU + 46, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHX + 47, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHUX + 48, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STHBRX + 49, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STW + 50, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWU + 51, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWX + 52, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWUX + 53, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STWBRX + 54, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STMW + 55, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBF + 56, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBST + 57, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBT + 58, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBTST + 59, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBZ + 60, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADD + 61, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDC + 62, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDE + 63, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDI + 64, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIC + 65, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDICR + 66, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDIS + 67, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDME + 68, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ADDZE + 69, IU2_1, 23, 23, 0, 0, 0, 0, 0, // PC_DIVW + 70, IU2_1, 23, 23, 0, 0, 0, 0, 0, // PC_DIVWU + 71, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULHW + 72, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULHWU + 73, IU2_1, 3, 1, 1, 1, 0, 0, 0, // PC_MULLI + 74, IU2_1, 4, 2, 2, 0, 0, 0, 0, // PC_MULLW + 75, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NEG + 76, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBF + 77, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFC + 78, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFE + 79, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFIC + 80, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFME + 81, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SUBFZE + 82, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPI + 83, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMP + 84, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPLI + 85, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CMPL + 86, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDI + 87, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDIS + 88, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORI + 89, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORIS + 90, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XORI + 91, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XORIS + 92, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_AND + 93, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_OR + 94, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_XOR + 95, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NAND + 96, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOR + 97, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EQV + 98, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ANDC + 99, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ORC + 100, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSB + 101, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_EXTSH + 102, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_CNTLZW + 103, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWINM + 104, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWNM + 105, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_RLWIMI + 106, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SLW + 107, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_SRW + 108, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_SRAWI + 109, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_SRAW + 110, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRAND + 111, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRANDC + 112, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CREQV + 113, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRNAND + 114, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRNOR + 115, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CROR + 116, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRORC + 117, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_CRXOR + 118, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MCRF + 119, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTXER + 120, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTCTR + 121, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTLR + 122, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MTCRF + 123, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTMSR + 124, IU2_1, 3, 3, 0, 0, 0, 1, 0, // PC_MTSPR + 125, IU2_1, 3, 2, 1, 0, 0, 0, 0, // PC_MFMSR + 126, IU2_1, 3, 3, 0, 0, 0, 1, 0, // PC_MFSPR + 127, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFXER + 128, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFCTR + 129, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_MFLR + 130, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MFCR + 131, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MFFS + 132, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSF + 133, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_EIEIO + 134, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_ISYNC + 135, LSU_1, 35, 35, 0, 0, 0, 1, 0, // PC_SYNC + 136, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_RFI + 137, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_LI + 138, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_LIS + 139, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MR + 140, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOP + 141, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_NOT + 142, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFS + 143, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSU + 144, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSX + 145, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFSUX + 146, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFD + 147, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDU + 148, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDX + 149, LSU_1, 4, 1, 1, 1, 1, 0, 0, // PC_LFDUX + 150, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFS + 151, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSU + 152, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSX + 153, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFSUX + 154, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFD + 155, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDU + 156, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDX + 157, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STFDUX + 158, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMR + 159, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FABS + 160, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNEG + 161, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNABS + 162, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FADD + 163, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FADDS + 164, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSUB + 165, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSUBS + 166, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMUL + 167, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMULS + 168, FPU_1, 35, 35, 0, 0, 0, 0, 0, // PC_FDIV + 169, FPU_1, 21, 21, 0, 0, 0, 0, 0, // PC_FDIVS + 170, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMADD + 171, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMADDS + 172, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMSUB + 173, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FMSUBS + 174, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMADD + 175, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMADDS + 176, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMSUB + 177, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FNMSUBS + 178, FPU_1, 14, 14, 0, 0, 0, 0, 0, // PC_FRES + 179, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FRSQRTE + 180, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FSEL + 181, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FRSP + 182, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCTIW + 183, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCTIWZ + 184, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCMPU + 185, FPU_1, 5, 1, 1, 1, 2, 0, 0, // PC_FCMPO + 186, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_LWARX + 187, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LSWI + 188, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_LSWX + 189, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STFIWX + 190, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STSWI + 191, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_STSWX + 192, LSU_1, 3, 1, 1, 1, 0, 1, 0, // PC_STWCX + 193, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ECIWX + 194, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ECOWX + 195, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_DCBI + 196, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_ICBI + 197, IU2_1, 5, 5, 0, 0, 0, 1, 0, // PC_MCRFS + 198, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MCRXR + 199, IU2_1, 5, 5, 0, 0, 0, 0, 0, // PC_MFTB + 200, IU2_1, 4, 1, 3, 0, 0, 0, 0, // PC_MFSR + 201, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTSR + 202, IU2_1, 4, 1, 3, 0, 0, 0, 0, // PC_MFSRIN + 203, IU2_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTSRIN + 204, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSB0 + 205, FPU_1, 5, 5, 0, 0, 0, 1, 0, // PC_MTFSB1 + 206, FPU_1, 5, 5, 0, 0, 0, 0, 0, // PC_MTFSFI + 207, IU2_1, 1, 1, 0, 0, 0, 1, 0, // PC_SC + 208, FPU_1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRT + 209, FPU_1, 1, 1, 0, 0, 0, 0, 0, // PC_FSQRTS + 210, LSU_1, 1, 1, 0, 0, 0, 0, 0, // PC_TLBIA + 211, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_TLBIE + 212, LSU_1, 3, 3, 0, 0, 0, 0, 0, // PC_TLBLD + 213, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_TLBLI + 214, LSU_1, 3, 3, 0, 0, 0, 1, 0, // PC_TLBSYNC + 215, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_TW + 216, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_TRAP + 217, IU1a, 2, 2, 0, 0, 0, 0, 0, // PC_TWI + 218, IU1a, 1, 1, 0, 0, 0, 1, 0, // PC_OPWORD + 219, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_MFROM + 220, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_DSA + 221, IU1a, 1, 1, 0, 0, 0, 0, 0, // PC_ESA + 222, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_DCCCI + 223, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_DCREAD + 224, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICBT + 225, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICCCI + 226, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_ICREAD + 227, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_RFCI + 228, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBRE + 229, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBSX + 230, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_TLBWE + 231, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEE + 232, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_WRTEEI + 233, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_MFDCR + 234, IU1a, 1, 0, 0, 0, 0, 0, 0, // PC_MTDCR + 235, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DCBA + 236, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSS + 237, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSSALL + 238, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DST + 239, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTT + 240, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTST + 241, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_DSTSTT + 242, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEBX + 243, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEHX + 244, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVEWX + 245, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVSL + 246, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVSR + 247, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVX + 248, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_LVXL + 249, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEBX + 250, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEHX + 251, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVEWX + 252, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVX + 253, LSU_1, 3, 1, 1, 1, 0, 0, 0, // PC_STVXL + 254, VFPU_1, 2, 2, 0, 0, 0, 1, 0, // PC_MFVSCR + 255, VFPU_1, 2, 2, 0, 0, 0, 1, 0, // PC_MTVSCR + 256, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDCUW + 257, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VADDFP + 258, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSBS + 259, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSHS + 260, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDSWS + 261, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBM + 262, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUBS + 263, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHM + 264, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUHS + 265, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWM + 266, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VADDUWS + 267, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAND + 268, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VANDC + 269, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSB + 270, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSH + 271, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGSW + 272, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUB + 273, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUH + 274, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VAVGUW + 275, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFSX + 276, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCFUX + 277, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPBFP + 278, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPEQFP + 279, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUB + 280, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUH + 281, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPEQUW + 282, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPGEFP + 283, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VCMPGTFP + 284, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSB + 285, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSH + 286, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTSW + 287, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUB + 288, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUH + 289, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VCMPGTUW + 290, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTSXS + 291, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VCTUXS + 292, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VEXPTEFP + 293, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VLOGEFP + 294, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMAXFP + 295, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSB + 296, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSH + 297, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXSW + 298, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUB + 299, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUH + 300, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMAXUW + 301, VFPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMINFP + 302, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSB + 303, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSH + 304, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINSW + 305, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUB + 306, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUH + 307, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMINUW + 308, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHB + 309, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHH + 310, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGHW + 311, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLB + 312, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLH + 313, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRGLW + 314, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULESB + 315, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULESH + 316, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULEUB + 317, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULEUH + 318, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOSB + 319, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOSH + 320, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOUB + 321, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMULOUH + 322, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VNOR + 323, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VOR + 324, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKPX + 325, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSHSS + 326, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSHUS + 327, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSWSS + 328, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKSWUS + 329, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUHUM + 330, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUHUS + 331, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUWUM + 332, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPKUWUS + 333, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VREFP + 334, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIM + 335, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIN + 336, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIP + 337, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRFIZ + 338, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLB + 339, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLH + 340, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VRLW + 341, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VRSQRTEFP + 342, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSL + 343, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLB + 344, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLH + 345, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSLO + 346, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSLW + 347, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTB + 348, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTH + 349, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTW + 350, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISB + 351, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISH + 352, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSPLTISW + 353, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSR + 354, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAB + 355, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAH + 356, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRAW + 357, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRB + 358, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRH + 359, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSRO + 360, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSRW + 361, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBCUW + 362, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUBFP + 363, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSBS + 364, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSHS + 365, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBSWS + 366, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBM + 367, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUBS + 368, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHM + 369, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUHS + 370, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWM + 371, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSUBUWS + 372, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUMSWS + 373, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM2SWS + 374, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4SBS + 375, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4SHS + 376, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VSUM4UBS + 377, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHPX + 378, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHSB + 379, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKHSH + 380, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLPX + 381, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLSB + 382, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VUPKLSH + 383, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VXOR + 384, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMADDFP + 385, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMHADDSHS + 386, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMHRADDSHS + 387, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMLADDUHM + 388, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMMBM + 389, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMSHM + 390, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMSHS + 391, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUBM + 392, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUHM + 393, VIU2_1, 4, 1, 1, 1, 1, 0, 0, // PC_VMSUMUHS + 394, VFPU_1, 4, 1, 1, 1, 1, 0, 0, // PC_VNMSUBFP + 395, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VPERM + 396, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VSEL + 397, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VSLDOI + 398, VIU1, 1, 1, 0, 0, 0, 0, 0, // PC_VMR + 399, VPU_1, 2, 1, 1, 0, 0, 0, 0, // PC_VMRP + -1, IU2_1, 1, 1, 0, 0, 0, 1, 0 +}; + +enum { NumPipelineUnits = 6 }; +static struct { + Stage start, end; +} pipeline_units[8] = { + IU2_1, IU2_3, + LSU_1, LSU_4, + FPU_1, FPU_4, + VPU_1, VPU_2, + VIU2_1, VIU2_4, + VFPU_1, VFPU_4 +}; + +enum { NumFinalStages = 11 }; +static Stage finalstages[16] = { + BPU, IU2_3, IU1a, IU1b, + IU1c, LSU_4, FPU_4, VIU1, + VPU_2, VIU2_4, VFPU_4 +}; + +// forward decl +static void complete_instruction(int stage); + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline_altivec[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline_altivec[newStage].instr = instr; + pipeline_altivec[newStage].remaining = cycles; + pipeline_altivec[oldStage].instr = NULL; + pipeline_altivec[oldStage].remaining = 0; + if (cycles == 0) + complete_instruction(newStage); +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline_altivec[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline_altivec[stage].instr = NULL; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.entries[completionbuffers.nextToRetire].completed = 0; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 1; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + fetchqueues[Queue0] = 1; + for (i = 1; i < NumQueues; i++) + fetchqueues[i] = 0; + + for (stage = 0; stage < NumStages; stage++) + pipeline_altivec[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) { + completionbuffers.entries[i].instr = NULL; + completionbuffers.entries[i].completed = 0; + } +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + + if (stage == IU1a) { + int isClear1 = !pipeline_altivec[IU1a].instr; + int isClear2 = !pipeline_altivec[IU1b].instr; + if (!isClear1 && !isClear2) + return 0; + } else { + if (pipeline_altivec[stage].instr) + return 0; + } + + if (fetchqueues[Queue1] <= 0) + return 0; + + if (stage == FPU_1) { + if (fetchqueues[Queue2] < 1 || fetchqueues[Queue5] >= 1) + return 0; + } else if (stage >= VIU1 && stage <= VFPU_1) { + if (fetchqueues[Queue4] < 1 || fetchqueues[Queue7] >= 2) + return 0; + } else if (stage != BPU) { + if (fetchqueues[Queue3] < 1 || fetchqueues[Queue6] >= 3) + return 0; + } + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + + CError_ASSERT(879, --fetchqueues[Queue1] >= 0); + + if (stage == FPU_1) { + fetchqueues[Queue2]--; + fetchqueues[Queue5]++; + } else if (stage >= VIU1 && stage <= VFPU_1) { + fetchqueues[Queue4]--; + fetchqueues[Queue7]++; + } else if (stage != BPU) { + fetchqueues[Queue3]--; + fetchqueues[Queue6]++; + } + + fetchqueues[Queue2] = (fetchqueues[Queue1] < fetchqueues[Queue2]) ? fetchqueues[Queue1] : fetchqueues[Queue2]; + fetchqueues[Queue3] = (fetchqueues[Queue1] < fetchqueues[Queue3]) ? fetchqueues[Queue1] : fetchqueues[Queue3]; + fetchqueues[Queue4] = (fetchqueues[Queue1] < fetchqueues[Queue4]) ? fetchqueues[Queue1] : fetchqueues[Queue4]; + + if (stage == IU1a) { + if (!pipeline_altivec[IU1a].instr) + stage = IU1a; + else if (!pipeline_altivec[IU1b].instr) + stage = IU1b; + else if (!pipeline_altivec[IU1c].instr) + stage = IU1c; + } + + pipeline_altivec[stage].instr = instr; + pipeline_altivec[stage].remaining = cycles; +} + +static void advance_clock(void) { + int num; + int i; + unsigned int unit; + + for (i = 0; i < NumStages; i++) { + if (pipeline_altivec[i].instr && pipeline_altivec[i].remaining) + --pipeline_altivec[i].remaining; + } + + for (i = 0; i < 3; i++) { + if (completionbuffers.used == 0) + break; + if (completionbuffers.entries[completionbuffers.nextToRetire].completed == 0) + break; + retire_instruction(); + } + + unit = 0; + do { + if (pipeline_altivec[finalstages[unit]].instr && pipeline_altivec[finalstages[unit]].remaining == 0) + complete_instruction(finalstages[unit]); + } while (++unit < NumFinalStages); + + unit = 0; + do { + Stage first; + Stage current; + first = pipeline_units[unit].start; + for (current = first; current < pipeline_units[unit].end; current++) { + if (pipeline_altivec[current].instr && pipeline_altivec[current].remaining == 0 && !pipeline_altivec[current + 1].instr) + advance(first, current, current + 1); + } + } while (++unit < NumPipelineUnits); + + fetchqueues[Queue5] = 0; + fetchqueues[Queue6] = 0; + fetchqueues[Queue7] = 0; + +#define CHEAP_MIN(a, b) ( ((a) < (b)) ? (a) : (b) ) + num = 2 - fetchqueues[Queue2]; + num += 6 - fetchqueues[Queue3]; + num += 4 - fetchqueues[Queue4]; + num = (num > 3) ? 3 : num; + num = (completionbuffers.free < num) ? completionbuffers.free : num; + if (fetchqueues[Queue0] < num) + num = fetchqueues[Queue0]; + + fetchqueues[Queue1] += num; + fetchqueues[Queue0] -= num; + + fetchqueues[Queue2] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(2, fetchqueues[Queue2] + num)); + fetchqueues[Queue3] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(6, fetchqueues[Queue3] + num)); + fetchqueues[Queue4] = CHEAP_MIN(fetchqueues[Queue1], CHEAP_MIN(4, fetchqueues[Queue4] + num)); + + CError_ASSERT(991, fetchqueues[Queue1] <= (fetchqueues[Queue2] + fetchqueues[Queue3] + fetchqueues[Queue4])); + + if (fetchqueues[Queue0] <= 8) + fetchqueues[Queue0] += 4; +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +static int uses_vpermute_unit_altivec(PCode *instr) { + return instruction_timing[instr->op].stage == VPU_1; +} + +MachineInfo machine7450 = { + 6, + 1, + 4, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &uses_vpermute_unit_altivec +}; diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/Scheduler.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/Scheduler.c new file mode 100644 index 0000000..23b580f --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/Scheduler.c @@ -0,0 +1,547 @@ +#include "compiler/Scheduler.h" +#include "compiler/CError.h" +#include "compiler/CParser.h" +#include "compiler/Alias.h" +#include "compiler/CompilerTools.h" +#include "compiler/PCode.h" +#include "compiler/Registers.h" + +#ifdef __MWERKS__ +#pragma options align=mac68k +#endif +typedef struct DGNode { + struct DGNode *x0; + struct DGNode *x4; + struct DGSuccessor *successors; + PCode *instr; + UInt16 x10; + UInt16 x12; + UInt16 x14; + UInt16 x16; + short predCount; +} DGNode; + +typedef struct DGSuccessor { + struct DGSuccessor *next; + DGNode *node; + UInt16 x8; +} DGSuccessor; + +typedef struct DGNodeList { + struct DGNodeList *next; + DGNode *node; +} DGNodeList; +#ifdef __MWERKS__ +#pragma options align=reset +#endif + +static DGNodeList **register_uses[RegClassMax]; +static DGNodeList **register_defs[RegClassMax]; +static DGNodeList *memory_uses; +static DGNodeList *memory_defs; +static DGNodeList *side_effects; +static DGNodeList *volatile_refs; +static DGNode *defaultsuccessor; +static UInt16 criticalpath; +static MachineInfo *MI; + +static void initresources(void) { + int rclass; + int i; + + for (rclass = 0; (char) rclass < RegClassMax; rclass++) { + register_uses[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]); + register_defs[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]); + for (i = 0; i < used_virtual_registers[(char) rclass]; i++) { + register_uses[(char) rclass][i] = register_defs[(char) rclass][i] = NULL; + } + } + + memory_uses = memory_defs = NULL; + side_effects = NULL; + volatile_refs = NULL; + criticalpath = 0; +} + +static DGNode *makedgnode(PCode *instr) { + DGNode *node; + + node = oalloc(sizeof(DGNode)); + node->x0 = NULL; + node->x4 = NULL; + node->successors = NULL; + node->instr = instr; + node->x10 = node->x16 = MI->latency(instr); + node->x12 = 0; + node->x14 = 0; + node->predCount = 0; + return node; +} + +static DGNode *adddgnode(DGNode *head, DGNode *node) { + if (head) + head->x4 = node; + node->x0 = head; + return node; +} + +static DGNode *removedgnode(DGNode *head, DGNode *node) { + if (node->x4) + node->x4->x0 = node->x0; + else + head = node->x0; + + if (node->x0) + node->x0->x4 = node->x4; + + return head; +} + +static void addtolist(DGNodeList **list, DGNode *node) { + DGNodeList *entry = oalloc(sizeof(DGNodeList)); + entry->node = node; + entry->next = *list; + *list = entry; +} + +static DGNodeList *makedglistnode(DGNode *node) { + DGNodeList *list = oalloc(sizeof(DGNodeList)); + list->next = NULL; + list->node = node; + return list; +} + +int is_same_operand(PCodeArg *a, PCodeArg *b) { + if (a->kind != b->kind) + return 0; + + switch (a->kind) { + case PCOp_IMMEDIATE: + if (a->data.imm.value != b->data.imm.value) + return 0; + break; + case PCOp_REGISTER: + if ((char) a->arg != (char) b->arg) + return 0; + if (a->data.reg.reg != b->data.reg.reg) + return 0; + break; + case PCOp_MEMORY: + if (a->data.mem.offset != b->data.mem.offset) + return 0; + if (a->data.mem.obj != b->data.mem.obj) + return 0; + break; + case PCOp_LABEL: + if (a->data.label.label != b->data.label.label) + return 0; + break; + } + + return 1; +} + +static void addsuccessor(DGNode *a, DGNode *b, Boolean flag) { + int v6; + int r29; + DGSuccessor *succ; + + if (flag) + v6 = a->x10; + else + v6 = 0; + + if (a != b) { + r29 = (v6 > 0) ? v6 : 0; + for (succ = a->successors; succ; succ = succ->next) { + if (succ->node == b) { + if (succ->x8 < r29) { + succ->x8 = r29; + if (b->x16 + succ->x8 > a->x16) + a->x16 = b->x16 + succ->x8; + } + return; + } + } + + succ = oalloc(sizeof(DGSuccessor)); + succ->node = b; + succ->next = a->successors; + a->successors = succ; + succ->x8 = r29; + + if (flag && (succ->node->instr->flags & fIsBranch)) + succ->x8 += MI->x8; + + b->predCount++; + + if (b->x16 + succ->x8 > a->x16) + a->x16 = b->x16 + succ->x8; + } +} + +static void serializeall(DGNode *nodes, DGNode *node) { + DGNode *scan; + + for (scan = nodes; scan; scan = scan->x0) + addsuccessor(node, scan, 0); +} + +static void serializelist(DGNode *node, DGNodeList *list) { + while (list) { + if (list->node != node) + addsuccessor(node, list->node, 0); + list = list->next; + } +} + +static void serializeregister(int rclass, DGNode *node, DGNodeList **defs, DGNodeList **uses, int isWrite) { + DGNodeList *list; + + if (isWrite) { + for (list = *uses; list; list = list->next) { + if (list->node != node) + addsuccessor(node, list->node, 1); + } + for (list = *defs; list; list = list->next) { + if (list->node != node) + addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0)); + } + + list = makedglistnode(node); + list->next = *defs; + *defs = list; + } else { + for (list = *defs; list; list = list->next) { + if (list->node != node) + addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0)); + } + + list = makedglistnode(node); + list->next = *uses; + *uses = list; + } +} + +static void serialize_load(DGNode *node) { + DGNodeList *list; + + for (list = memory_defs; list; list = list->next) { + if (may_alias(node->instr, list->node->instr)) + addsuccessor(node, list->node, 1); + } + + addtolist(&memory_uses, node); +} + +static void serialize_store(DGNode *node) { + DGNodeList *list; + + for (list = memory_uses; list; list = list->next) { + if (may_alias(node->instr, list->node->instr)) + addsuccessor(node, list->node, 1); + } + for (list = memory_defs; list; list = list->next) { + if (may_alias(node->instr, list->node->instr)) + addsuccessor(node, list->node, 1); + } + + addtolist(&memory_defs, node); + if (node->instr->flags & fPCodeFlag40000) + addtolist(&memory_uses, node); +} + +static void findsuccessors(DGNode *nodes, DGNode *node) { + PCode *instr; + PCodeArg *op; + int i; + + instr = node->instr; + for (i = 0, op = instr->args; i < instr->argCount; i++, op++) { + switch (op->kind) { + case PCOp_IMMEDIATE: + case PCOp_MEMORY: + break; + case PCOp_REGISTER: + if ( + op->data.reg.reg < 0 || + op->data.reg.reg > used_virtual_registers[(char) op->arg] + ) + { + CError_FATAL(491); + } + + if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) { + if (op->data.reg.reg == Register2) + break; + if (op->data.reg.reg == Register0 && !(op->data.reg.effect & (EffectRead | EffectWrite))) + break; + } + + serializeregister( + op->arg, + node, + ®ister_defs[(char) op->arg][op->data.reg.reg], + ®ister_uses[(char) op->arg][op->data.reg.reg], + op->data.reg.effect & EffectWrite + ); + + break; + } + } + + if (instr->flags & (fIsRead | fPCodeFlag20000)) + serialize_load(node); + else if (instr->flags & (fIsWrite | fPCodeFlag40000)) + serialize_store(node); + + if (instr->flags & fIsVolatile) { + serializelist(node, volatile_refs); + addtolist(&volatile_refs, node); + } + + if ( + ((instr->flags & fIsCall | fIsBranch) && (instr->flags & fLink)) || + (instr->flags & fSideEffects) || + MI->serializes(instr) + ) + { + serializeall(nodes, node); + addtolist(&side_effects, node); + } + + if (side_effects) + serializelist(node, side_effects); + + if (!node->successors && defaultsuccessor) + addsuccessor(node, defaultsuccessor, 0); + + if (node->x16 > criticalpath) + criticalpath = node->x16; +} + +static void computedeadlines(DGNode *nodes) { + while (nodes) { + nodes->x14 = criticalpath - nodes->x16; + nodes = nodes->x0; + } +} + +static int uncovering(DGNode *node) { + int counter; + DGSuccessor *succ; + + counter = 0; + for (succ = node->successors; succ; succ = succ->next) { + if (succ->node->predCount == 1) + counter++; + } + + return counter; +} + +static DGNode *selectinstruction(DGNode *nodes, UInt16 counter) { + DGNode *node; + DGNode *node2; + int a; + int b; + + node = nodes; + while (node) { + if (node->predCount == 0 && node->x12 <= counter && MI->can_issue(node->instr)) + break; + node = node->x0; + } + + if (!node) + return NULL; + + for (node2 = node->x0; node2; node2 = node2->x0) { + if ( + node2->predCount == 0 && + node2->x12 <= counter && + MI->can_issue(node2->instr) && + (node->x14 > counter || node2->x14 <= counter) + ) + { + if (node->x14 > counter && node2->x14 <= counter) { + node = node2; + continue; + } + + if ((a = uncovering(node)) > (b = uncovering(node2))) + continue; + + if (a < b) { + node = node2; + continue; + } + + if (node->x16 > node2->x16) + continue; + + if (node->x16 < node2->x16) { + node = node2; + continue; + } + + if (coloring) { + if (opcodeinfo[node->instr->op].x9 < opcodeinfo[node2->instr->op].x9) + continue; + + if (opcodeinfo[node->instr->op].x9 > opcodeinfo[node2->instr->op].x9) + node = node2; + } + } + } + + return node; +} + +static void holdoffsuccessors(DGNode *node, UInt16 counter) { + DGSuccessor *succ; + DGNode *n; + + for (succ = node->successors; succ; succ = succ->next) { + n = succ->node; + n->predCount--; + if (n->x12 < counter + succ->x8) + n->x12 = counter + succ->x8; + } +} + +static void scheduleblock(PCodeBlock *block) { + DGNode *node; + UInt16 counter; + PCode *instr; + UInt16 i; + DGNode *head; + + initresources(); + defaultsuccessor = NULL; + head = NULL; + + for (instr = block->lastPCode; instr; instr = instr->prevPCode) { + DGNode *n = makedgnode(instr); + findsuccessors(head, n); + if (instr->flags & fIsBranch) + defaultsuccessor = n; + head = adddgnode(head, n); + } + + computedeadlines(head); + block->firstPCode = block->lastPCode = NULL; + block->pcodeCount = 0; + + MI->initialize(); + counter = 0; + while (head != NULL) { + for (i = 0; i < MI->x0; i++) { + if (head == NULL) + break; + + node = selectinstruction(head, counter); + if (!node) + break; + + instr = node->instr; + if (node->successors) + holdoffsuccessors(node, counter); + + appendpcode(block, instr); + MI->issue(instr); + head = removedgnode(head, node); + } + + MI->advance_clock(); + counter++; + } + + freeoheap(); +} + +void scheduleinstructions(Boolean flag) { + PCodeBlock *block; + int cpu; + + cpu = copts.scheduling; + if (cpu == 10) { + MI = &machine7450; + } else if (copts.altivec_model != 0 || cpu == 7) { + MI = &machine7400; + } else if (cpu == 2) { + MI = &machine603; + } else if (cpu == 5) { + MI = &machine603e; + } else if (cpu == 3) { + MI = &machine604; + } else if (cpu == 6) { + MI = &machine604; + } else if (cpu == 4) { + MI = &machine750; + } else if (cpu == 1) { + MI = &machine601; + } else if (cpu == 9) { + MI = &machine821; + } else { + MI = &machine603; + } + + gather_alias_info(); + + for (block = pcbasicblocks; block; block = block->nextBlock) { + if ( + block->pcodeCount > 2 && + (flag || !(block->flags & (fIsProlog | fIsEpilogue))) && + !(block->flags & fScheduled) + ) + { + scheduleblock(block); + block->flags |= fScheduled; + } + } +} + +int is_dependent(PCode *a, PCode *b, char rclass) { + int i; + int reg; + PCodeArg *op; + + if ( + b && + b->argCount >= 1 && + b->args[0].kind == PCOp_REGISTER && + (char) b->args[0].arg == rclass && + (b->args[0].data.reg.effect & EffectWrite) + ) + { + reg = b->args[0].data.reg.reg; + for (i = 0; i < a->argCount; i++) { + op = &a->args[i]; + if ( + op->kind == PCOp_REGISTER && + (char) op->arg == rclass && + (op->data.reg.effect & (EffectRead | EffectWrite)) && + op->data.reg.reg == reg + ) + return 1; + } + } + + return 0; +} + +int uses_vpermute_unit(PCode *instr) { + int cpu; + + cpu = copts.scheduling; + if (cpu == 10) + return machine7450.uses_vpermute_unit(instr); + if (copts.altivec_model != 0 || cpu == 7) + return machine7400.uses_vpermute_unit(instr); + return 0; +} + +int default_uses_vpermute_unit(PCode *instr) { + return 0; +} |