MWCC/compiler_and_linker/unsorted/MachineSimulation7400.c

745 lines
30 KiB
C

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