move lots of source files around to match their actual placement in the original tree

This commit is contained in:
Ash Wolf
2023-01-26 11:30:47 +00:00
parent fc0c4c0df7
commit 094b96ca1d
120 changed files with 400 additions and 392 deletions

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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
};

View File

@@ -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,
&register_defs[(char) op->arg][op->data.reg.reg],
&register_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;
}