diff options
Diffstat (limited to 'compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c')
-rw-r--r-- | compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c | 615 |
1 files changed, 615 insertions, 0 deletions
diff --git a/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c new file mode 100644 index 0000000..bbf0509 --- /dev/null +++ b/compiler_and_linker/BackEnd/PowerPC/Scheduler/MachineSimulation821.c @@ -0,0 +1,615 @@ +#include "compiler/Scheduler.h" +#include "compiler/PCode.h" +#include "compiler/PCodeInfo.h" + +// https://www.nxp.com/docs/en/user-guide/MPC821UM.pdf + +typedef enum Stage { + BranchUnit, + Stage1, + Stage2, + LSU1, + LSU2, + CRUnit, + NumStages, + Stage7 +} Stage; + +static struct { + // the instruction currently in this pipeline stage + PCode *instr; + + // how many cycles are left for this instruction to finish + int remaining; +} pipeline[NumStages]; + +enum { + MaxEntries = 6 +}; + +static struct { + // how many entries remain unused in the queue + unsigned int free; + + // how many entries are currently used in the queue + unsigned int used; + + // the index of the next instruction that will be retired + unsigned int nextToRetire; + + // the index of the next free slot that will be used when an instruction is dispatched + unsigned int nextFreeSlot; + + // circular array of entries in the completion queue + struct { + PCode *instr; + int completed; + } entries[MaxEntries]; +} completionbuffers; + +static struct { + // the initial stage for this instruction + Stage stage; + + // the total amount of cycles required by this instruction + char latency; + + // how long it takes to finish each stage + char cycles[3]; + + // does this instruction serialise? + char serializes; +} instruction_timing[OPCODE_MAX] = { + BranchUnit, 0, 0, 0, 0, 0, // PC_B + BranchUnit, 0, 0, 0, 0, 0, // PC_BL + BranchUnit, 0, 0, 0, 0, 0, // PC_BC + BranchUnit, 0, 0, 0, 0, 0, // PC_BCLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BT + BranchUnit, 0, 0, 0, 0, 0, // PC_BTLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BTCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BF + BranchUnit, 0, 0, 0, 0, 0, // PC_BFLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BFCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZ + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZT + BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZF + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZ + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZT + BranchUnit, 0, 0, 0, 0, 0, // PC_BDZF + BranchUnit, 0, 0, 0, 0, 0, // PC_BLR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCTR + BranchUnit, 0, 0, 0, 0, 0, // PC_BCTRL + BranchUnit, 0, 0, 0, 0, 0, // PC_BLRL + BranchUnit, 0, 0, 0, 0, 0, // PC_LBZ + LSU1, 2, 1, 1, 0, 0, // PC_LBZU + LSU1, 2, 1, 1, 0, 0, // PC_LBZX + LSU1, 2, 1, 1, 0, 0, // PC_LBZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHZ + LSU1, 2, 1, 1, 0, 0, // PC_LHZU + LSU1, 2, 1, 1, 0, 0, // PC_LHZX + LSU1, 2, 1, 1, 0, 0, // PC_LHZUX + LSU1, 2, 1, 1, 0, 0, // PC_LHA + LSU1, 2, 1, 1, 0, 0, // PC_LHAU + LSU1, 2, 1, 1, 0, 0, // PC_LHAX + LSU1, 2, 1, 1, 0, 0, // PC_LHAUX + LSU1, 2, 1, 1, 0, 0, // PC_LHBRX + LSU1, 2, 1, 1, 0, 0, // PC_LWZ + LSU1, 2, 1, 1, 0, 0, // PC_LWZU + LSU1, 2, 1, 1, 0, 0, // PC_LWZX + LSU1, 2, 1, 1, 0, 0, // PC_LWZUX + LSU1, 2, 1, 1, 0, 0, // PC_LWBRX + LSU1, 2, 1, 1, 0, 0, // PC_LMW + LSU1, 2, 1, 1, 0, 0, // PC_STB + LSU1, 2, 1, 1, 0, 0, // PC_STBU + LSU1, 2, 1, 1, 0, 0, // PC_STBX + LSU1, 2, 1, 1, 0, 0, // PC_STBUX + LSU1, 2, 1, 1, 0, 0, // PC_STH + LSU1, 2, 1, 1, 0, 0, // PC_STHU + LSU1, 2, 1, 1, 0, 0, // PC_STHX + LSU1, 2, 1, 1, 0, 0, // PC_STHUX + LSU1, 2, 1, 1, 0, 0, // PC_STHBRX + LSU1, 2, 1, 1, 0, 0, // PC_STW + LSU1, 2, 1, 1, 0, 0, // PC_STWU + LSU1, 2, 1, 1, 0, 0, // PC_STWX + LSU1, 2, 1, 1, 0, 0, // PC_STWUX + LSU1, 2, 1, 1, 0, 0, // PC_STWBRX + LSU1, 2, 1, 1, 0, 0, // PC_STMW + LSU1, 2, 1, 1, 0, 0, // PC_DCBF + LSU1, 2, 1, 1, 0, 0, // PC_DCBST + LSU1, 2, 1, 1, 0, 0, // PC_DCBT + LSU1, 2, 1, 1, 0, 0, // PC_DCBTST + LSU1, 2, 1, 1, 0, 0, // PC_DCBZ + LSU1, 2, 1, 1, 0, 0, // PC_ADD + Stage1, 1, 1, 0, 0, 0, // PC_ADDC + Stage1, 1, 1, 0, 0, 0, // PC_ADDE + Stage1, 1, 1, 0, 0, 0, // PC_ADDI + Stage1, 1, 1, 0, 0, 0, // PC_ADDIC + Stage1, 1, 1, 0, 0, 0, // PC_ADDICR + Stage1, 1, 1, 0, 0, 0, // PC_ADDIS + Stage1, 1, 1, 0, 0, 0, // PC_ADDME + Stage1, 1, 1, 0, 0, 0, // PC_ADDZE + Stage1, 1, 1, 0, 0, 0, // PC_DIVW + Stage1, 37, 37, 0, 0, 0, // PC_DIVWU + Stage1, 37, 37, 0, 0, 0, // PC_MULHW + Stage1, 5, 5, 0, 0, 0, // PC_MULHWU + Stage1, 5, 5, 0, 0, 0, // PC_MULLI + Stage1, 3, 3, 0, 0, 0, // PC_MULLW + Stage1, 5, 5, 0, 0, 0, // PC_NEG + Stage1, 1, 1, 0, 0, 0, // PC_SUBF + Stage1, 1, 1, 0, 0, 0, // PC_SUBFC + Stage1, 1, 1, 0, 0, 0, // PC_SUBFE + Stage1, 1, 1, 0, 0, 0, // PC_SUBFIC + Stage1, 1, 1, 0, 0, 0, // PC_SUBFME + Stage1, 1, 1, 0, 0, 0, // PC_SUBFZE + Stage1, 1, 1, 0, 0, 0, // PC_CMPI + Stage1, 3, 1, 0, 0, 0, // PC_CMP + Stage1, 3, 1, 0, 0, 0, // PC_CMPLI + Stage1, 3, 1, 0, 0, 0, // PC_CMPL + Stage1, 3, 1, 0, 0, 0, // PC_ANDI + Stage1, 1, 1, 0, 0, 0, // PC_ANDIS + Stage1, 1, 1, 0, 0, 0, // PC_ORI + Stage1, 1, 1, 0, 0, 0, // PC_ORIS + Stage1, 1, 1, 0, 0, 0, // PC_XORI + Stage1, 1, 1, 0, 0, 0, // PC_XORIS + Stage1, 1, 1, 0, 0, 0, // PC_AND + Stage1, 1, 1, 0, 0, 0, // PC_OR + Stage1, 1, 1, 0, 0, 0, // PC_XOR + Stage1, 1, 1, 0, 0, 0, // PC_NAND + Stage1, 1, 1, 0, 0, 0, // PC_NOR + Stage1, 1, 1, 0, 0, 0, // PC_EQV + Stage1, 1, 1, 0, 0, 0, // PC_ANDC + Stage1, 1, 1, 0, 0, 0, // PC_ORC + Stage1, 1, 1, 0, 0, 0, // PC_EXTSB + Stage1, 1, 1, 0, 0, 0, // PC_EXTSH + Stage1, 1, 1, 0, 0, 0, // PC_CNTLZW + Stage1, 1, 1, 0, 0, 0, // PC_RLWINM + Stage1, 1, 1, 0, 0, 0, // PC_RLWNM + Stage1, 1, 1, 0, 0, 0, // PC_RLWIMI + Stage1, 1, 1, 0, 0, 0, // PC_SLW + Stage1, 1, 1, 0, 0, 0, // PC_SRW + Stage1, 1, 1, 0, 0, 0, // PC_SRAWI + Stage1, 1, 1, 0, 0, 0, // PC_SRAW + Stage1, 1, 1, 0, 0, 0, // PC_CRAND + CRUnit, 1, 1, 0, 0, 0, // PC_CRANDC + CRUnit, 1, 1, 0, 0, 0, // PC_CREQV + CRUnit, 1, 1, 0, 0, 0, // PC_CRNAND + CRUnit, 1, 1, 0, 0, 0, // PC_CRNOR + CRUnit, 1, 1, 0, 0, 0, // PC_CROR + CRUnit, 1, 1, 0, 0, 0, // PC_CRORC + CRUnit, 1, 1, 0, 0, 0, // PC_CRXOR + CRUnit, 1, 1, 0, 0, 0, // PC_MCRF + CRUnit, 1, 1, 0, 0, 0, // PC_MTXER + Stage1, 1, 1, 0, 0, 0, // PC_MTCTR + BranchUnit, 2, 2, 0, 0, 0, // PC_MTLR + BranchUnit, 2, 2, 0, 0, 0, // PC_MTCRF + Stage1, 1, 1, 0, 0, 0, // PC_MTMSR + Stage1, 1, 1, 0, 0, 0, // PC_MTSPR + Stage1, 1, 1, 0, 0, 0, // PC_MFMSR + Stage1, 1, 1, 0, 0, 0, // PC_MFSPR + Stage1, 1, 1, 0, 0, 0, // PC_MFXER + Stage7, 3, 1, 1, 1, 0, // PC_MFCTR + Stage7, 3, 1, 1, 1, 0, // PC_MFLR + Stage1, 1, 1, 0, 0, 0, // PC_MFCR + Stage1, 1, 1, 0, 0, 0, // PC_MFFS + Stage1, 1, 1, 0, 0, 0, // PC_MTFSF + Stage1, 1, 1, 0, 0, 0, // PC_EIEIO + Stage1, 1, 1, 0, 0, 0, // PC_ISYNC + Stage1, 1, 1, 0, 0, 0, // PC_SYNC + Stage1, 1, 1, 0, 0, 0, // PC_RFI + Stage1, 1, 1, 0, 0, 0, // PC_LI + LSU1, 2, 1, 1, 0, 0, // PC_LIS + LSU1, 2, 1, 1, 0, 0, // PC_MR + LSU1, 2, 1, 1, 0, 0, // PC_NOP + LSU1, 2, 1, 1, 0, 0, // PC_NOT + LSU1, 2, 1, 1, 0, 0, // PC_LFS + LSU1, 2, 1, 1, 0, 0, // PC_LFSU + LSU1, 2, 1, 1, 0, 0, // PC_LFSX + LSU1, 2, 1, 1, 0, 0, // PC_LFSUX + LSU1, 2, 1, 1, 0, 0, // PC_LFD + LSU1, 2, 1, 1, 0, 0, // PC_LFDU + LSU1, 2, 1, 1, 0, 0, // PC_LFDX + LSU1, 2, 1, 1, 0, 0, // PC_LFDUX + LSU1, 2, 1, 1, 0, 0, // PC_STFS + LSU1, 2, 1, 1, 0, 0, // PC_STFSU + LSU1, 2, 1, 1, 0, 0, // PC_STFSX + LSU1, 2, 1, 1, 0, 0, // PC_STFSUX + Stage7, 3, 1, 1, 1, 0, // PC_STFD + Stage7, 3, 1, 1, 1, 0, // PC_STFDU + Stage7, 3, 1, 1, 1, 0, // PC_STFDX + Stage7, 3, 1, 1, 1, 0, // PC_STFDUX + Stage7, 3, 1, 1, 1, 0, // PC_FMR + Stage7, 3, 1, 1, 1, 0, // PC_FABS + Stage7, 3, 1, 1, 1, 0, // PC_FNEG + Stage7, 3, 1, 1, 1, 0, // PC_FNABS + Stage7, 4, 2, 1, 1, 0, // PC_FADD + Stage7, 3, 1, 1, 1, 0, // PC_FADDS + Stage7, 33, 33, 0, 0, 0, // PC_FSUB + Stage7, 18, 18, 0, 0, 0, // PC_FSUBS + Stage7, 4, 2, 1, 1, 0, // PC_FMUL + Stage7, 3, 1, 1, 1, 0, // PC_FMULS + Stage7, 4, 2, 1, 1, 0, // PC_FDIV + Stage7, 3, 1, 1, 1, 0, // PC_FDIVS + Stage7, 4, 2, 1, 1, 0, // PC_FMADD + Stage7, 3, 1, 1, 1, 0, // PC_FMADDS + Stage7, 4, 2, 1, 1, 0, // PC_FMSUB + Stage7, 3, 1, 1, 1, 0, // PC_FMSUBS + Stage7, 18, 18, 0, 0, 0, // PC_FNMADD + Stage7, 3, 1, 1, 1, 0, // PC_FNMADDS + Stage7, 3, 1, 1, 1, 0, // PC_FNMSUB + Stage7, 3, 1, 1, 1, 0, // PC_FNMSUBS + Stage7, 3, 1, 1, 1, 0, // PC_FRES + Stage7, 3, 1, 1, 1, 0, // PC_FRSQRTE + Stage7, 5, 1, 1, 1, 0, // PC_FSEL + Stage7, 5, 1, 1, 1, 0, // PC_FRSP + LSU1, 1, 0, 0, 0, 0, // PC_FCTIW + LSU1, 1, 0, 0, 0, 0, // PC_FCTIWZ + LSU1, 1, 0, 0, 0, 0, // PC_FCMPU + LSU1, 1, 0, 0, 0, 0, // PC_FCMPO + LSU1, 1, 0, 0, 0, 0, // PC_LWARX + LSU1, 1, 0, 0, 0, 0, // PC_LSWI + LSU1, 1, 0, 0, 0, 0, // PC_LSWX + Stage1, 1, 0, 0, 0, 0, // PC_STFIWX + Stage1, 1, 0, 0, 0, 0, // PC_STSWI + Stage1, 1, 0, 0, 0, 0, // PC_STSWX + Stage1, 1, 0, 0, 0, 0, // PC_STWCX + Stage1, 1, 0, 0, 0, 0, // PC_ECIWX + Stage1, 1, 0, 0, 0, 0, // PC_ECOWX + Stage1, 1, 0, 0, 0, 0, // PC_DCBI + Stage1, 1, 0, 0, 0, 0, // PC_ICBI + Stage1, 1, 0, 0, 0, 0, // PC_MCRFS + Stage1, 1, 0, 0, 0, 0, // PC_MCRXR + Stage1, 1, 0, 0, 0, 0, // PC_MFTB + Stage1, 1, 0, 0, 0, 0, // PC_MFSR + Stage1, 1, 0, 0, 0, 0, // PC_MTSR + Stage1, 1, 0, 0, 0, 0, // PC_MFSRIN + Stage1, 1, 0, 0, 0, 0, // PC_MTSRIN + Stage1, 1, 0, 0, 0, 0, // PC_MTFSB0 + Stage1, 1, 0, 0, 0, 0, // PC_MTFSB1 + Stage1, 1, 0, 0, 0, 0, // PC_MTFSFI + Stage1, 1, 0, 0, 0, 1, // PC_SC + Stage1, 1, 0, 0, 0, 1, // PC_FSQRT + Stage1, 1, 0, 0, 0, 0, // PC_FSQRTS + Stage1, 1, 0, 0, 0, 0, // PC_TLBIA + Stage1, 1, 0, 0, 0, 0, // PC_TLBIE + Stage1, 1, 0, 0, 0, 0, // PC_TLBLD + Stage1, 1, 0, 0, 0, 0, // PC_TLBLI + Stage1, 1, 0, 0, 0, 0, // PC_TLBSYNC + Stage1, 1, 0, 0, 0, 0, // PC_TW + Stage1, 1, 0, 0, 0, 1, // PC_TRAP + Stage1, 1, 0, 0, 0, 1, // PC_TWI + Stage1, 1, 0, 0, 0, 1, // PC_OPWORD + Stage1, 1, 0, 0, 0, 1, // PC_MFROM + Stage1, 1, 0, 0, 0, 0, // PC_DSA + Stage1, 1, 0, 0, 0, 0, // PC_ESA + Stage1, 1, 0, 0, 0, 0, // PC_DCCCI + Stage1, 0, 0, 0, 0, 0, // PC_DCREAD + Stage1, 0, 0, 0, 0, 0, // PC_ICBT + Stage1, 0, 0, 0, 0, 0, // PC_ICCCI + Stage1, 0, 0, 0, 0, 0, // PC_ICREAD + Stage1, 0, 0, 0, 0, 0, // PC_RFCI + Stage1, 0, 0, 0, 0, 0, // PC_TLBRE + Stage1, 0, 0, 0, 0, 0, // PC_TLBSX + Stage1, 0, 0, 0, 0, 0, // PC_TLBWE + Stage1, 0, 0, 0, 0, 0, // PC_WRTEE + Stage1, 0, 0, 0, 0, 0, // PC_WRTEEI + Stage1, 0, 0, 0, 0, 0, // PC_MFDCR + Stage1, 0, 0, 0, 0, 0, // PC_MTDCR + Stage1, 0, 0, 0, 0, 0, // PC_DCBA + Stage1, 0, 0, 0, 0, 0, // PC_DSS + BranchUnit, 0, 0, 0, 0, 0, // PC_DSSALL + BranchUnit, 0, 0, 0, 0, 0, // PC_DST + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTT + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTST + BranchUnit, 0, 0, 0, 0, 0, // PC_DSTSTT + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEBX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEHX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVEWX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVSL + BranchUnit, 0, 0, 0, 0, 0, // PC_LVSR + BranchUnit, 0, 0, 0, 0, 0, // PC_LVX + BranchUnit, 0, 0, 0, 0, 0, // PC_LVXL + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEBX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEHX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVEWX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVX + BranchUnit, 0, 0, 0, 0, 0, // PC_STVXL + BranchUnit, 0, 0, 0, 0, 0, // PC_MFVSCR + BranchUnit, 0, 0, 0, 0, 0, // PC_MTVSCR + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDCUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWM + BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VAND + BranchUnit, 0, 0, 0, 0, 0, // PC_VANDC + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCFSX + BranchUnit, 0, 0, 0, 0, 0, // PC_VCFUX + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VCTSXS + BranchUnit, 0, 0, 0, 0, 0, // PC_VCTUXS + BranchUnit, 0, 0, 0, 0, 0, // PC_VEXPTEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VLOGEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUB + BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUH + BranchUnit, 0, 0, 0, 0, 0, // PC_VNOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHSS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWSS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUM + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUM + BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUS + BranchUnit, 0, 0, 0, 0, 0, // PC_VREFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIM + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIN + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIP + BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIZ + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VRLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VRSQRTEFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VSL + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLO + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSR + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRB + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRH + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRO + BranchUnit, 0, 0, 0, 0, 0, // PC_VSRW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBCUW + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUMSWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM2SWS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4UBS + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLPX + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSB + BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSH + BranchUnit, 0, 0, 0, 0, 0, // PC_VXOR + BranchUnit, 0, 0, 0, 0, 0, // PC_VMADDFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VMHADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMHRADDSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMLADDUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMMBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUBM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHM + BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHS + BranchUnit, 0, 0, 0, 0, 0, // PC_VNMSUBFP + BranchUnit, 0, 0, 0, 0, 0, // PC_VPERM + BranchUnit, 0, 0, 0, 0, 0, // PC_VSEL + BranchUnit, 0, 0, 0, 0, 0, // PC_VSLDOI + BranchUnit, 0, 0, 0, 0, 0, // PC_VMR + BranchUnit, 0, 0, 0, 0, 0, // PC_VMRP + BranchUnit, 0, 0, 0, 0, 0, // PC_SLE + BranchUnit, 0, 0, 0, 0, 0, // PC_SLEQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRAIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRAQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRE + BranchUnit, 0, 0, 0, 0, 0, // PC_SREA + BranchUnit, 0, 0, 0, 0, 0, // PC_SREQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRLIQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRLQ + BranchUnit, 0, 0, 0, 0, 0, // PC_SRQ + BranchUnit, 0, 0, 0, 0, 0, // PC_MASKG + BranchUnit, 0, 0, 0, 0, 0, // PC_MASKIR + BranchUnit, 0, 0, 0, 0, 0, // PC_LSCBX + BranchUnit, 0, 0, 0, 0, 0, // PC_DIV + BranchUnit, 0, 0, 0, 0, 0, // PC_DIVS + BranchUnit, 0, 0, 0, 0, 0, // PC_DOZ + BranchUnit, 0, 0, 0, 0, 0, // PC_MUL + BranchUnit, 0, 0, 0, 0, 0, // PC_NABS + BranchUnit, 0, 0, 0, 0, 0, // PC_ABS + BranchUnit, 0, 0, 0, 0, 0, // PC_CLCS + BranchUnit, 0, 0, 0, 0, 0, // PC_DOZI + BranchUnit, 0, 0, 0, 0, 0, // PC_RLMI + BranchUnit, 0, 0, 0, 0, 0, // PC_RRIB +}; + +static void advance(int firstStage, int oldStage, int newStage) { + PCode *instr = pipeline[oldStage].instr; + int cycles = instruction_timing[instr->op].cycles[newStage - firstStage]; + pipeline[newStage].instr = instr; + pipeline[newStage].remaining = cycles; + pipeline[oldStage].instr = NULL; +} + +static void assign_completion_buffer(PCode *instr) { + completionbuffers.used++; + completionbuffers.free--; + completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr; + completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0; + completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries; +} + +static void complete_instruction(int stage) { + PCode *instr = pipeline[stage].instr; + int buf = 0; + while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr) + buf++; + + completionbuffers.entries[buf].completed = 1; + pipeline[stage].instr = NULL; +} + +static void retire_instruction(void) { + completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL; + completionbuffers.used--; + completionbuffers.free++; + completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries; +} + +static int latency(PCode *instr) { + int cycles = instruction_timing[instr->op].latency; + if (PCODE_FLAG_SET_F(instr) & fRecordBit) + cycles += 2; + if (instr->op == PC_LMW || instr->op == PC_STMW) + cycles += instr->argCount - 2; + return cycles; +} + +static void initialize(void) { + int stage; + int i; + + for (stage = 0; stage < NumStages; stage++) + pipeline[stage].instr = NULL; + + completionbuffers.free = MaxEntries; + completionbuffers.used = 0; + completionbuffers.nextToRetire = 0; + completionbuffers.nextFreeSlot = 0; + for (i = 0; i < MaxEntries; i++) + completionbuffers.entries[i].instr = NULL; +} + +static int can_issue(PCode *instr) { + int stage; + + if (completionbuffers.free == 0) + return 0; + + stage = instruction_timing[instr->op].stage; + if (pipeline[stage].instr) + return 0; + + if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite)) + return 0; + + return 1; +} + +static void issue(PCode *instr) { + int stage = instruction_timing[instr->op].stage; + int cycles = instruction_timing[instr->op].cycles[0]; + assign_completion_buffer(instr); + pipeline[stage].instr = instr; + pipeline[stage].remaining = cycles; +} + +static void advance_clock(void) { + int stage; + + for (stage = 0; stage < NumStages; stage++) { + if (pipeline[stage].instr && pipeline[stage].remaining) + --pipeline[stage].remaining; + } + + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) { + retire_instruction(); + } + } + + if (pipeline[Stage1].instr && pipeline[Stage1].remaining == 0) + complete_instruction(Stage1); + if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0) + complete_instruction(LSU2); + if (pipeline[BranchUnit].instr && pipeline[BranchUnit].remaining == 0) + complete_instruction(BranchUnit); + + if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr) + advance(LSU1, LSU1, LSU2); +} + +static int serializes(PCode *instr) { + return instruction_timing[instr->op].serializes; +} + +MachineInfo machine821 = { + 1, + 0, + 0, + &latency, + &initialize, + &can_issue, + &issue, + &advance_clock, + &serializes, + &default_uses_vpermute_unit +}; |