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