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