mirror of
https://git.wuffs.org/MWCC
synced 2025-12-19 01:46:20 +00:00
move lots of source files around to match their actual placement in the original tree
This commit is contained in:
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
547
compiler_and_linker/BackEnd/PowerPC/Scheduler/Scheduler.c
Normal file
547
compiler_and_linker/BackEnd/PowerPC/Scheduler/Scheduler.c
Normal file
@@ -0,0 +1,547 @@
|
||||
#include "compiler/Scheduler.h"
|
||||
#include "compiler/CError.h"
|
||||
#include "compiler/CParser.h"
|
||||
#include "compiler/Alias.h"
|
||||
#include "compiler/CompilerTools.h"
|
||||
#include "compiler/PCode.h"
|
||||
#include "compiler/Registers.h"
|
||||
|
||||
#ifdef __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
typedef struct DGNode {
|
||||
struct DGNode *x0;
|
||||
struct DGNode *x4;
|
||||
struct DGSuccessor *successors;
|
||||
PCode *instr;
|
||||
UInt16 x10;
|
||||
UInt16 x12;
|
||||
UInt16 x14;
|
||||
UInt16 x16;
|
||||
short predCount;
|
||||
} DGNode;
|
||||
|
||||
typedef struct DGSuccessor {
|
||||
struct DGSuccessor *next;
|
||||
DGNode *node;
|
||||
UInt16 x8;
|
||||
} DGSuccessor;
|
||||
|
||||
typedef struct DGNodeList {
|
||||
struct DGNodeList *next;
|
||||
DGNode *node;
|
||||
} DGNodeList;
|
||||
#ifdef __MWERKS__
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
static DGNodeList **register_uses[RegClassMax];
|
||||
static DGNodeList **register_defs[RegClassMax];
|
||||
static DGNodeList *memory_uses;
|
||||
static DGNodeList *memory_defs;
|
||||
static DGNodeList *side_effects;
|
||||
static DGNodeList *volatile_refs;
|
||||
static DGNode *defaultsuccessor;
|
||||
static UInt16 criticalpath;
|
||||
static MachineInfo *MI;
|
||||
|
||||
static void initresources(void) {
|
||||
int rclass;
|
||||
int i;
|
||||
|
||||
for (rclass = 0; (char) rclass < RegClassMax; rclass++) {
|
||||
register_uses[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]);
|
||||
register_defs[(char) rclass] = oalloc(sizeof(DGNodeList *) * used_virtual_registers[(char) rclass]);
|
||||
for (i = 0; i < used_virtual_registers[(char) rclass]; i++) {
|
||||
register_uses[(char) rclass][i] = register_defs[(char) rclass][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
memory_uses = memory_defs = NULL;
|
||||
side_effects = NULL;
|
||||
volatile_refs = NULL;
|
||||
criticalpath = 0;
|
||||
}
|
||||
|
||||
static DGNode *makedgnode(PCode *instr) {
|
||||
DGNode *node;
|
||||
|
||||
node = oalloc(sizeof(DGNode));
|
||||
node->x0 = NULL;
|
||||
node->x4 = NULL;
|
||||
node->successors = NULL;
|
||||
node->instr = instr;
|
||||
node->x10 = node->x16 = MI->latency(instr);
|
||||
node->x12 = 0;
|
||||
node->x14 = 0;
|
||||
node->predCount = 0;
|
||||
return node;
|
||||
}
|
||||
|
||||
static DGNode *adddgnode(DGNode *head, DGNode *node) {
|
||||
if (head)
|
||||
head->x4 = node;
|
||||
node->x0 = head;
|
||||
return node;
|
||||
}
|
||||
|
||||
static DGNode *removedgnode(DGNode *head, DGNode *node) {
|
||||
if (node->x4)
|
||||
node->x4->x0 = node->x0;
|
||||
else
|
||||
head = node->x0;
|
||||
|
||||
if (node->x0)
|
||||
node->x0->x4 = node->x4;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
static void addtolist(DGNodeList **list, DGNode *node) {
|
||||
DGNodeList *entry = oalloc(sizeof(DGNodeList));
|
||||
entry->node = node;
|
||||
entry->next = *list;
|
||||
*list = entry;
|
||||
}
|
||||
|
||||
static DGNodeList *makedglistnode(DGNode *node) {
|
||||
DGNodeList *list = oalloc(sizeof(DGNodeList));
|
||||
list->next = NULL;
|
||||
list->node = node;
|
||||
return list;
|
||||
}
|
||||
|
||||
int is_same_operand(PCodeArg *a, PCodeArg *b) {
|
||||
if (a->kind != b->kind)
|
||||
return 0;
|
||||
|
||||
switch (a->kind) {
|
||||
case PCOp_IMMEDIATE:
|
||||
if (a->data.imm.value != b->data.imm.value)
|
||||
return 0;
|
||||
break;
|
||||
case PCOp_REGISTER:
|
||||
if ((char) a->arg != (char) b->arg)
|
||||
return 0;
|
||||
if (a->data.reg.reg != b->data.reg.reg)
|
||||
return 0;
|
||||
break;
|
||||
case PCOp_MEMORY:
|
||||
if (a->data.mem.offset != b->data.mem.offset)
|
||||
return 0;
|
||||
if (a->data.mem.obj != b->data.mem.obj)
|
||||
return 0;
|
||||
break;
|
||||
case PCOp_LABEL:
|
||||
if (a->data.label.label != b->data.label.label)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void addsuccessor(DGNode *a, DGNode *b, Boolean flag) {
|
||||
int v6;
|
||||
int r29;
|
||||
DGSuccessor *succ;
|
||||
|
||||
if (flag)
|
||||
v6 = a->x10;
|
||||
else
|
||||
v6 = 0;
|
||||
|
||||
if (a != b) {
|
||||
r29 = (v6 > 0) ? v6 : 0;
|
||||
for (succ = a->successors; succ; succ = succ->next) {
|
||||
if (succ->node == b) {
|
||||
if (succ->x8 < r29) {
|
||||
succ->x8 = r29;
|
||||
if (b->x16 + succ->x8 > a->x16)
|
||||
a->x16 = b->x16 + succ->x8;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
succ = oalloc(sizeof(DGSuccessor));
|
||||
succ->node = b;
|
||||
succ->next = a->successors;
|
||||
a->successors = succ;
|
||||
succ->x8 = r29;
|
||||
|
||||
if (flag && (succ->node->instr->flags & fIsBranch))
|
||||
succ->x8 += MI->x8;
|
||||
|
||||
b->predCount++;
|
||||
|
||||
if (b->x16 + succ->x8 > a->x16)
|
||||
a->x16 = b->x16 + succ->x8;
|
||||
}
|
||||
}
|
||||
|
||||
static void serializeall(DGNode *nodes, DGNode *node) {
|
||||
DGNode *scan;
|
||||
|
||||
for (scan = nodes; scan; scan = scan->x0)
|
||||
addsuccessor(node, scan, 0);
|
||||
}
|
||||
|
||||
static void serializelist(DGNode *node, DGNodeList *list) {
|
||||
while (list) {
|
||||
if (list->node != node)
|
||||
addsuccessor(node, list->node, 0);
|
||||
list = list->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void serializeregister(int rclass, DGNode *node, DGNodeList **defs, DGNodeList **uses, int isWrite) {
|
||||
DGNodeList *list;
|
||||
|
||||
if (isWrite) {
|
||||
for (list = *uses; list; list = list->next) {
|
||||
if (list->node != node)
|
||||
addsuccessor(node, list->node, 1);
|
||||
}
|
||||
for (list = *defs; list; list = list->next) {
|
||||
if (list->node != node)
|
||||
addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0));
|
||||
}
|
||||
|
||||
list = makedglistnode(node);
|
||||
list->next = *defs;
|
||||
*defs = list;
|
||||
} else {
|
||||
for (list = *defs; list; list = list->next) {
|
||||
if (list->node != node)
|
||||
addsuccessor(node, list->node, ((char) rclass == RegClass_SPR) || (MI->x4 == 0));
|
||||
}
|
||||
|
||||
list = makedglistnode(node);
|
||||
list->next = *uses;
|
||||
*uses = list;
|
||||
}
|
||||
}
|
||||
|
||||
static void serialize_load(DGNode *node) {
|
||||
DGNodeList *list;
|
||||
|
||||
for (list = memory_defs; list; list = list->next) {
|
||||
if (may_alias(node->instr, list->node->instr))
|
||||
addsuccessor(node, list->node, 1);
|
||||
}
|
||||
|
||||
addtolist(&memory_uses, node);
|
||||
}
|
||||
|
||||
static void serialize_store(DGNode *node) {
|
||||
DGNodeList *list;
|
||||
|
||||
for (list = memory_uses; list; list = list->next) {
|
||||
if (may_alias(node->instr, list->node->instr))
|
||||
addsuccessor(node, list->node, 1);
|
||||
}
|
||||
for (list = memory_defs; list; list = list->next) {
|
||||
if (may_alias(node->instr, list->node->instr))
|
||||
addsuccessor(node, list->node, 1);
|
||||
}
|
||||
|
||||
addtolist(&memory_defs, node);
|
||||
if (node->instr->flags & fPCodeFlag40000)
|
||||
addtolist(&memory_uses, node);
|
||||
}
|
||||
|
||||
static void findsuccessors(DGNode *nodes, DGNode *node) {
|
||||
PCode *instr;
|
||||
PCodeArg *op;
|
||||
int i;
|
||||
|
||||
instr = node->instr;
|
||||
for (i = 0, op = instr->args; i < instr->argCount; i++, op++) {
|
||||
switch (op->kind) {
|
||||
case PCOp_IMMEDIATE:
|
||||
case PCOp_MEMORY:
|
||||
break;
|
||||
case PCOp_REGISTER:
|
||||
if (
|
||||
op->data.reg.reg < 0 ||
|
||||
op->data.reg.reg > used_virtual_registers[(char) op->arg]
|
||||
)
|
||||
{
|
||||
CError_FATAL(491);
|
||||
}
|
||||
|
||||
if (op->kind == PCOp_REGISTER && op->arg == RegClass_GPR) {
|
||||
if (op->data.reg.reg == Register2)
|
||||
break;
|
||||
if (op->data.reg.reg == Register0 && !(op->data.reg.effect & (EffectRead | EffectWrite)))
|
||||
break;
|
||||
}
|
||||
|
||||
serializeregister(
|
||||
op->arg,
|
||||
node,
|
||||
®ister_defs[(char) op->arg][op->data.reg.reg],
|
||||
®ister_uses[(char) op->arg][op->data.reg.reg],
|
||||
op->data.reg.effect & EffectWrite
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (instr->flags & (fIsRead | fPCodeFlag20000))
|
||||
serialize_load(node);
|
||||
else if (instr->flags & (fIsWrite | fPCodeFlag40000))
|
||||
serialize_store(node);
|
||||
|
||||
if (instr->flags & fIsVolatile) {
|
||||
serializelist(node, volatile_refs);
|
||||
addtolist(&volatile_refs, node);
|
||||
}
|
||||
|
||||
if (
|
||||
((instr->flags & fIsCall | fIsBranch) && (instr->flags & fLink)) ||
|
||||
(instr->flags & fSideEffects) ||
|
||||
MI->serializes(instr)
|
||||
)
|
||||
{
|
||||
serializeall(nodes, node);
|
||||
addtolist(&side_effects, node);
|
||||
}
|
||||
|
||||
if (side_effects)
|
||||
serializelist(node, side_effects);
|
||||
|
||||
if (!node->successors && defaultsuccessor)
|
||||
addsuccessor(node, defaultsuccessor, 0);
|
||||
|
||||
if (node->x16 > criticalpath)
|
||||
criticalpath = node->x16;
|
||||
}
|
||||
|
||||
static void computedeadlines(DGNode *nodes) {
|
||||
while (nodes) {
|
||||
nodes->x14 = criticalpath - nodes->x16;
|
||||
nodes = nodes->x0;
|
||||
}
|
||||
}
|
||||
|
||||
static int uncovering(DGNode *node) {
|
||||
int counter;
|
||||
DGSuccessor *succ;
|
||||
|
||||
counter = 0;
|
||||
for (succ = node->successors; succ; succ = succ->next) {
|
||||
if (succ->node->predCount == 1)
|
||||
counter++;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
static DGNode *selectinstruction(DGNode *nodes, UInt16 counter) {
|
||||
DGNode *node;
|
||||
DGNode *node2;
|
||||
int a;
|
||||
int b;
|
||||
|
||||
node = nodes;
|
||||
while (node) {
|
||||
if (node->predCount == 0 && node->x12 <= counter && MI->can_issue(node->instr))
|
||||
break;
|
||||
node = node->x0;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
for (node2 = node->x0; node2; node2 = node2->x0) {
|
||||
if (
|
||||
node2->predCount == 0 &&
|
||||
node2->x12 <= counter &&
|
||||
MI->can_issue(node2->instr) &&
|
||||
(node->x14 > counter || node2->x14 <= counter)
|
||||
)
|
||||
{
|
||||
if (node->x14 > counter && node2->x14 <= counter) {
|
||||
node = node2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((a = uncovering(node)) > (b = uncovering(node2)))
|
||||
continue;
|
||||
|
||||
if (a < b) {
|
||||
node = node2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (node->x16 > node2->x16)
|
||||
continue;
|
||||
|
||||
if (node->x16 < node2->x16) {
|
||||
node = node2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coloring) {
|
||||
if (opcodeinfo[node->instr->op].x9 < opcodeinfo[node2->instr->op].x9)
|
||||
continue;
|
||||
|
||||
if (opcodeinfo[node->instr->op].x9 > opcodeinfo[node2->instr->op].x9)
|
||||
node = node2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static void holdoffsuccessors(DGNode *node, UInt16 counter) {
|
||||
DGSuccessor *succ;
|
||||
DGNode *n;
|
||||
|
||||
for (succ = node->successors; succ; succ = succ->next) {
|
||||
n = succ->node;
|
||||
n->predCount--;
|
||||
if (n->x12 < counter + succ->x8)
|
||||
n->x12 = counter + succ->x8;
|
||||
}
|
||||
}
|
||||
|
||||
static void scheduleblock(PCodeBlock *block) {
|
||||
DGNode *node;
|
||||
UInt16 counter;
|
||||
PCode *instr;
|
||||
UInt16 i;
|
||||
DGNode *head;
|
||||
|
||||
initresources();
|
||||
defaultsuccessor = NULL;
|
||||
head = NULL;
|
||||
|
||||
for (instr = block->lastPCode; instr; instr = instr->prevPCode) {
|
||||
DGNode *n = makedgnode(instr);
|
||||
findsuccessors(head, n);
|
||||
if (instr->flags & fIsBranch)
|
||||
defaultsuccessor = n;
|
||||
head = adddgnode(head, n);
|
||||
}
|
||||
|
||||
computedeadlines(head);
|
||||
block->firstPCode = block->lastPCode = NULL;
|
||||
block->pcodeCount = 0;
|
||||
|
||||
MI->initialize();
|
||||
counter = 0;
|
||||
while (head != NULL) {
|
||||
for (i = 0; i < MI->x0; i++) {
|
||||
if (head == NULL)
|
||||
break;
|
||||
|
||||
node = selectinstruction(head, counter);
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
instr = node->instr;
|
||||
if (node->successors)
|
||||
holdoffsuccessors(node, counter);
|
||||
|
||||
appendpcode(block, instr);
|
||||
MI->issue(instr);
|
||||
head = removedgnode(head, node);
|
||||
}
|
||||
|
||||
MI->advance_clock();
|
||||
counter++;
|
||||
}
|
||||
|
||||
freeoheap();
|
||||
}
|
||||
|
||||
void scheduleinstructions(Boolean flag) {
|
||||
PCodeBlock *block;
|
||||
int cpu;
|
||||
|
||||
cpu = copts.scheduling;
|
||||
if (cpu == 10) {
|
||||
MI = &machine7450;
|
||||
} else if (copts.altivec_model != 0 || cpu == 7) {
|
||||
MI = &machine7400;
|
||||
} else if (cpu == 2) {
|
||||
MI = &machine603;
|
||||
} else if (cpu == 5) {
|
||||
MI = &machine603e;
|
||||
} else if (cpu == 3) {
|
||||
MI = &machine604;
|
||||
} else if (cpu == 6) {
|
||||
MI = &machine604;
|
||||
} else if (cpu == 4) {
|
||||
MI = &machine750;
|
||||
} else if (cpu == 1) {
|
||||
MI = &machine601;
|
||||
} else if (cpu == 9) {
|
||||
MI = &machine821;
|
||||
} else {
|
||||
MI = &machine603;
|
||||
}
|
||||
|
||||
gather_alias_info();
|
||||
|
||||
for (block = pcbasicblocks; block; block = block->nextBlock) {
|
||||
if (
|
||||
block->pcodeCount > 2 &&
|
||||
(flag || !(block->flags & (fIsProlog | fIsEpilogue))) &&
|
||||
!(block->flags & fScheduled)
|
||||
)
|
||||
{
|
||||
scheduleblock(block);
|
||||
block->flags |= fScheduled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int is_dependent(PCode *a, PCode *b, char rclass) {
|
||||
int i;
|
||||
int reg;
|
||||
PCodeArg *op;
|
||||
|
||||
if (
|
||||
b &&
|
||||
b->argCount >= 1 &&
|
||||
b->args[0].kind == PCOp_REGISTER &&
|
||||
(char) b->args[0].arg == rclass &&
|
||||
(b->args[0].data.reg.effect & EffectWrite)
|
||||
)
|
||||
{
|
||||
reg = b->args[0].data.reg.reg;
|
||||
for (i = 0; i < a->argCount; i++) {
|
||||
op = &a->args[i];
|
||||
if (
|
||||
op->kind == PCOp_REGISTER &&
|
||||
(char) op->arg == rclass &&
|
||||
(op->data.reg.effect & (EffectRead | EffectWrite)) &&
|
||||
op->data.reg.reg == reg
|
||||
)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uses_vpermute_unit(PCode *instr) {
|
||||
int cpu;
|
||||
|
||||
cpu = copts.scheduling;
|
||||
if (cpu == 10)
|
||||
return machine7450.uses_vpermute_unit(instr);
|
||||
if (copts.altivec_model != 0 || cpu == 7)
|
||||
return machine7400.uses_vpermute_unit(instr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int default_uses_vpermute_unit(PCode *instr) {
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user