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