MWCC/compiler_and_linker/unsorted/MachineSimulation821.c

616 lines
25 KiB
C

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