10b57cec5SDimitry Andric//==- MipsScheduleP5600.td - P5600 Scheduling Definitions --*- tablegen -*-===// 20b57cec5SDimitry Andric// 30b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric// 70b57cec5SDimitry Andric//===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andricdef MipsP5600Model : SchedMachineModel { 100b57cec5SDimitry Andric int IssueWidth = 2; // 2x dispatched per cycle 110b57cec5SDimitry Andric int MicroOpBufferSize = 48; // min(48, 48, 64) 120b57cec5SDimitry Andric int LoadLatency = 4; 130b57cec5SDimitry Andric int MispredictPenalty = 8; // TODO: Estimated 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric let CompleteModel = 1; 160b57cec5SDimitry Andric let FullInstRWOverlapCheck = 1; 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric list<Predicate> UnsupportedFeatures = [HasMips3, HasMips32r6, HasMips64, 190b57cec5SDimitry Andric HasMips64r2, HasMips64r5, HasMips64r6, 200b57cec5SDimitry Andric IsGP64bit, IsPTR64bit, 210b57cec5SDimitry Andric InMicroMips, InMips16Mode, 220b57cec5SDimitry Andric HasCnMips, HasCnMipsP, 235ffd83dbSDimitry Andric HasDSP, HasDSPR2, HasMips3D, HasMT, 245ffd83dbSDimitry Andric HasCRC]; 250b57cec5SDimitry Andric} 260b57cec5SDimitry Andric 270b57cec5SDimitry Andriclet SchedModel = MipsP5600Model in { 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric// ALQ Pipelines 300b57cec5SDimitry Andric// ============= 310b57cec5SDimitry Andric 320b57cec5SDimitry Andricdef P5600ALQ : ProcResource<1> { let BufferSize = 16; } 330b57cec5SDimitry Andricdef P5600IssueALU : ProcResource<1> { let Super = P5600ALQ; } 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric// ALU Pipeline 360b57cec5SDimitry Andric// ------------ 370b57cec5SDimitry Andric 380b57cec5SDimitry Andricdef P5600WriteALU : SchedWriteRes<[P5600IssueALU]>; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric// and, lui, nor, or, slti, sltiu, sub, subu, xor 410b57cec5SDimitry Andricdef : InstRW<[P5600WriteALU], (instrs AND, LUi, NOR, OR, SLTi, SLTiu, SUB, 420b57cec5SDimitry Andric SUBu, XOR)>; 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric// AGQ Pipelines 450b57cec5SDimitry Andric// ============= 460b57cec5SDimitry Andric 470b57cec5SDimitry Andricdef P5600AGQ : ProcResource<3> { let BufferSize = 16; } 480b57cec5SDimitry Andricdef P5600IssueAL2 : ProcResource<1> { let Super = P5600AGQ; } 490b57cec5SDimitry Andricdef P5600IssueCTISTD : ProcResource<1> { let Super = P5600AGQ; } 500b57cec5SDimitry Andricdef P5600IssueLDST : ProcResource<1> { let Super = P5600AGQ; } 510b57cec5SDimitry Andric 520b57cec5SDimitry Andricdef P5600AL2Div : ProcResource<1>; 530b57cec5SDimitry Andric// Pseudo-resource used to block CTISTD when handling multi-pipeline splits. 540b57cec5SDimitry Andricdef P5600CTISTD : ProcResource<1>; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric// CTISTD Pipeline 570b57cec5SDimitry Andric// --------------- 580b57cec5SDimitry Andric 590b57cec5SDimitry Andricdef P5600WriteJump : SchedWriteRes<[P5600IssueCTISTD, P5600CTISTD]>; 600b57cec5SDimitry Andricdef P5600WriteJumpAndLink : SchedWriteRes<[P5600IssueCTISTD, P5600CTISTD]> { 610b57cec5SDimitry Andric let Latency = 2; 620b57cec5SDimitry Andric} 630b57cec5SDimitry Andric 640b57cec5SDimitry Andricdef P5600Nop : SchedWriteRes<[P5600IssueCTISTD]> { 650b57cec5SDimitry Andric let Latency = 0; 660b57cec5SDimitry Andric} 670b57cec5SDimitry Andric 680b57cec5SDimitry Andricdef : InstRW<[P5600Nop], (instrs SSNOP, NOP)>; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric// b, beq, beql, bg[et]z, bl[et]z, bne, bnel, j, syscall, jal, bltzal, 710b57cec5SDimitry Andric// jalr, jr.hb, jr 720b57cec5SDimitry Andricdef : InstRW<[P5600WriteJump], (instrs B, BAL, BAL_BR, BEQ, BEQL, BGEZ, BGEZAL, 730b57cec5SDimitry Andric BGEZALL, BGEZL, BGTZ, BGTZL, BLEZ, BLEZL, BLTZ, 740b57cec5SDimitry Andric BLTZAL, BLTZALL, BLTZL, BNE, BNEL, BREAK, 750b57cec5SDimitry Andric DERET, ERET, ERet, ERETNC, J, JR, JR_HB, 760b57cec5SDimitry Andric PseudoIndirectBranch, 770b57cec5SDimitry Andric PseudoIndirectHazardBranch, PseudoReturn, 780b57cec5SDimitry Andric SDBBP, SYSCALL, RetRA, TAILCALL, TAILCALLREG, 790b57cec5SDimitry Andric TAILCALLREGHB, TEQ, TEQI, TGE, TGEI, TGEIU, 800b57cec5SDimitry Andric TGEU, TLT, TLTI, TLTU, TNE, TNEI, TRAP, 810b57cec5SDimitry Andric TTLTIU, WAIT, PAUSE)>; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andricdef : InstRW<[P5600WriteJumpAndLink], (instrs JAL, JALR, JALRHBPseudo, 840b57cec5SDimitry Andric JALRPseudo, JALR_HB)>; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andricdef : InstRW<[P5600WriteJumpAndLink], (instrs JALX)> { 870b57cec5SDimitry Andric let Unsupported = 1; 880b57cec5SDimitry Andric} 890b57cec5SDimitry Andric 900b57cec5SDimitry Andricdef P5600COP0 : SchedWriteRes<[P5600IssueCTISTD, P5600CTISTD]>; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andricdef : InstRW<[P5600COP0], (instrs TLBINV, TLBINVF, TLBP, TLBR, TLBWI, TLBWR, 930b57cec5SDimitry Andric MFC0, MTC0)>; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andricdef P5600COP2 : SchedWriteRes<[P5600IssueCTISTD, P5600CTISTD]>; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andricdef : InstRW<[P5600COP2], (instrs MFC2, MTC2)> { 980b57cec5SDimitry Andric let Unsupported = 1; 990b57cec5SDimitry Andric} 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric// MIPS Virtualization ASE 1020b57cec5SDimitry Andric// ======================= 1030b57cec5SDimitry Andricdef : InstRW<[P5600COP0], (instrs HYPCALL, MFGC0, MFHGC0, MTGC0, MTHGC0, 1040b57cec5SDimitry Andric TLBGINV, TLBGINVF, TLBGP, TLBGR, TLBGWI, TLBGWR)>; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric// LDST Pipeline 1070b57cec5SDimitry Andric// ------------- 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andricdef P5600WriteLoad : SchedWriteRes<[P5600IssueLDST]> { 1100b57cec5SDimitry Andric let Latency = 4; 1110b57cec5SDimitry Andric} 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andricdef P5600WriteLoadShifted : SchedWriteRes<[P5600IssueLDST, P5600CTISTD]> { 1140b57cec5SDimitry Andric let Latency = 4; 1150b57cec5SDimitry Andric} 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andricdef P5600WriteCache : SchedWriteRes<[P5600IssueLDST]>; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andricdef P5600WriteStore : SchedWriteRes<[P5600IssueLDST, P5600CTISTD]> { 1200b57cec5SDimitry Andric // FIXME: This is a bit pessimistic. P5600CTISTD is only used during cycle 2 1210b57cec5SDimitry Andric // not during 0, 1, and 2. 122*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 3 ]; 1230b57cec5SDimitry Andric} 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andricdef P5600WriteGPRFromBypass : SchedWriteRes<[P5600IssueLDST]> { 1260b57cec5SDimitry Andric let Latency = 2; 1270b57cec5SDimitry Andric} 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andricdef P5600WriteStoreFromOtherUnits : SchedWriteRes<[P5600IssueLDST]>; 1300b57cec5SDimitry Andricdef P5600WriteLoadToOtherUnits : SchedWriteRes<[P5600IssueLDST]> { 1310b57cec5SDimitry Andric let Latency = 0; 1320b57cec5SDimitry Andric} 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric// l[bhw], l[bh]u, ll 1350b57cec5SDimitry Andricdef : InstRW<[P5600WriteLoad], (instrs LB, LBu, LH, LHu, LW, LL, LWC2, LWC3, 1360b57cec5SDimitry Andric LDC2, LDC3, LBE, LBuE, LHE, LHuE, LWE, LLE, 1370b57cec5SDimitry Andric LWPC)>; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric// lw[lr] 1400b57cec5SDimitry Andricdef : InstRW<[P5600WriteLoadShifted], (instrs LWL, LWR, LWLE, LWRE)>; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric// s[bhw], sw[lr] 1430b57cec5SDimitry Andricdef : InstRW<[P5600WriteStore], (instrs SB, SH, SW, SWC2, SWC3, SDC2, SDC3, SC, 1440b57cec5SDimitry Andric SBE, SHE, SWE, SCE, SWL, SWR, SWLE, SWRE)>; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric// pref, cache, sync, synci 1470b57cec5SDimitry Andricdef : InstRW<[P5600WriteCache], (instrs PREF, PREFE, CACHE, CACHEE, SYNC, 1480b57cec5SDimitry Andric SYNCI)>; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric// LDST is also used in moves from general purpose registers to floating point 1510b57cec5SDimitry Andric// and MSA. 1520b57cec5SDimitry Andricdef P5600WriteMoveGPRToOtherUnits : SchedWriteRes<[P5600IssueLDST]> { 1530b57cec5SDimitry Andric let Latency = 0; 1540b57cec5SDimitry Andric} 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric// AL2 Pipeline 1570b57cec5SDimitry Andric// ------------ 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andricdef P5600WriteAL2 : SchedWriteRes<[P5600IssueAL2]>; 1600b57cec5SDimitry Andricdef P5600WriteAL2BitExt : SchedWriteRes<[P5600IssueAL2]> { let Latency = 2; } 1610b57cec5SDimitry Andricdef P5600WriteAL2ShadowMov : SchedWriteRes<[P5600IssueAL2]> { let Latency = 2; } 1620b57cec5SDimitry Andricdef P5600WriteAL2CondMov : SchedWriteRes<[P5600IssueAL2, P5600CTISTD]> { 1630b57cec5SDimitry Andric let Latency = 2; 1640b57cec5SDimitry Andric} 1650b57cec5SDimitry Andricdef P5600WriteAL2Div : SchedWriteRes<[P5600IssueAL2, P5600AL2Div]> { 1660b57cec5SDimitry Andric // Estimated worst case 1670b57cec5SDimitry Andric let Latency = 34; 168*5f757f3fSDimitry Andric let ReleaseAtCycles = [1, 34]; 1690b57cec5SDimitry Andric} 1700b57cec5SDimitry Andricdef P5600WriteAL2DivU : SchedWriteRes<[P5600IssueAL2, P5600AL2Div]> { 1710b57cec5SDimitry Andric // Estimated worst case 1720b57cec5SDimitry Andric let Latency = 34; 173*5f757f3fSDimitry Andric let ReleaseAtCycles = [1, 34]; 1740b57cec5SDimitry Andric} 1750b57cec5SDimitry Andricdef P5600WriteAL2Mul : SchedWriteRes<[P5600IssueAL2]> { let Latency = 3; } 1760b57cec5SDimitry Andricdef P5600WriteAL2Mult: SchedWriteRes<[P5600IssueAL2]> { let Latency = 5; } 1770b57cec5SDimitry Andricdef P5600WriteAL2MAdd: SchedWriteRes<[P5600IssueAL2, P5600CTISTD]> { 1780b57cec5SDimitry Andric let Latency = 5; 1790b57cec5SDimitry Andric} 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric// clo, clz, di, ei, mfhi, mflo 1820b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2], (instrs CLO, CLZ, DI, EI, MFHI, MFLO, 1830b57cec5SDimitry Andric PseudoMFHI, PseudoMFLO)>; 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric// ehb, rdhwr, rdpgpr, wrpgpr, wsbh 1860b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2ShadowMov], (instrs EHB, RDHWR, WSBH)>; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric// mov[nz] 1890b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2CondMov], (instrs MOVN_I_I, MOVZ_I_I)>; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric// divu? 1920b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2Div], (instrs DIV, PseudoSDIV, SDIV)>; 1930b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2DivU], (instrs DIVU, PseudoUDIV, UDIV)>; 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric// mul 1960b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2Mul], (instrs MUL)>; 1970b57cec5SDimitry Andric// multu?, multu? 1980b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2Mult], (instrs MULT, MULTu, PseudoMULT, 1990b57cec5SDimitry Andric PseudoMULTu)>; 2000b57cec5SDimitry Andric// maddu?, msubu?, mthi, mtlo 2010b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2MAdd], (instrs MADD, MADDU, MSUB, MSUBU, 2020b57cec5SDimitry Andric MTHI, MTLO, PseudoMADD, PseudoMADDU, 2030b57cec5SDimitry Andric PseudoMSUB, PseudoMSUBU, PseudoMTLOHI)>; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric// ext, ins 2060b57cec5SDimitry Andricdef : InstRW<[P5600WriteAL2BitExt], (instrs EXT, INS)>; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric// Either ALU or AL2 Pipelines 2090b57cec5SDimitry Andric// --------------------------- 2100b57cec5SDimitry Andric// 2110b57cec5SDimitry Andric// Some instructions can choose between ALU and AL2, but once dispatched to 2120b57cec5SDimitry Andric// ALQ or AGQ respectively they are committed to that path. 2130b57cec5SDimitry Andric// The decision is based on the outcome of the most recent selection when the 2140b57cec5SDimitry Andric// choice was last available. For now, we assume ALU is always chosen. 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andricdef P5600WriteEitherALU : SchedWriteVariant< 2170b57cec5SDimitry Andric // FIXME: Implement selection predicate 2180b57cec5SDimitry Andric [SchedVar<SchedPredicate<[{1}]>, [P5600WriteALU]>, 2190b57cec5SDimitry Andric SchedVar<SchedPredicate<[{0}]>, [P5600WriteAL2]> 2200b57cec5SDimitry Andric ]>; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric// add, addi, addiu, addu, andi, ori, rotr, se[bh], sllv?, sr[al]v?, slt, sltu, 2230b57cec5SDimitry Andric// xori 2240b57cec5SDimitry Andricdef : InstRW<[P5600WriteEitherALU], (instrs ADD, ADDi, ADDiu, ANDi, ORi, ROTR, 2250b57cec5SDimitry Andric SEB, SEH, SLT, SLTu, SLL, SRA, SRL, XORi, 2260b57cec5SDimitry Andric ADDu, SLLV, SRAV, SRLV, LSA, COPY)>; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric// FPU Pipelines 2290b57cec5SDimitry Andric// ============= 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andricdef P5600FPQ : ProcResource<3> { let BufferSize = 16; } 2320b57cec5SDimitry Andricdef P5600IssueFPUS : ProcResource<1> { let Super = P5600FPQ; } 2330b57cec5SDimitry Andricdef P5600IssueFPUL : ProcResource<1> { let Super = P5600FPQ; } 2340b57cec5SDimitry Andricdef P5600IssueFPULoad : ProcResource<1> { let Super = P5600FPQ; } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andricdef P5600FPUDivSqrt : ProcResource<2>; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andricdef P5600WriteFPUS : SchedWriteRes<[P5600IssueFPUS]>; 2390b57cec5SDimitry Andricdef P5600WriteFPUL : SchedWriteRes<[P5600IssueFPUL]> { let Latency = 4; } 2400b57cec5SDimitry Andricdef P5600WriteFPUL_MADDSUB : SchedWriteRes<[P5600IssueFPUL]> { let Latency = 6; } 2410b57cec5SDimitry Andricdef P5600WriteFPUDivI : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2420b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 23 / 27 2430b57cec5SDimitry Andric let Latency = 23; // Using common case 244*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 23 ]; 2450b57cec5SDimitry Andric} 2460b57cec5SDimitry Andricdef P5600WriteFPUDivS : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2470b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 23 / 27 2480b57cec5SDimitry Andric let Latency = 23; // Using common case 249*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 23 ]; 2500b57cec5SDimitry Andric} 2510b57cec5SDimitry Andricdef P5600WriteFPUDivD : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2520b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 31 / 35 2530b57cec5SDimitry Andric let Latency = 31; // Using common case 254*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 31 ]; 2550b57cec5SDimitry Andric} 2560b57cec5SDimitry Andricdef P5600WriteFPURcpS : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2570b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 19 / 23 2580b57cec5SDimitry Andric let Latency = 19; // Using common case 259*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 19 ]; 2600b57cec5SDimitry Andric} 2610b57cec5SDimitry Andricdef P5600WriteFPURcpD : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2620b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 27 / 31 2630b57cec5SDimitry Andric let Latency = 27; // Using common case 264*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 27 ]; 2650b57cec5SDimitry Andric} 2660b57cec5SDimitry Andricdef P5600WriteFPURsqrtS : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2670b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 27 / 27 2680b57cec5SDimitry Andric let Latency = 27; // Using common case 269*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 27 ]; 2700b57cec5SDimitry Andric} 2710b57cec5SDimitry Andricdef P5600WriteFPURsqrtD : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2720b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 27 / 31 2730b57cec5SDimitry Andric let Latency = 27; // Using common case 274*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 27 ]; 2750b57cec5SDimitry Andric} 2760b57cec5SDimitry Andricdef P5600WriteFPUSqrtS : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2770b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 27 / 31 2780b57cec5SDimitry Andric let Latency = 27; // Using common case 279*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 27 ]; 2800b57cec5SDimitry Andric} 2810b57cec5SDimitry Andricdef P5600WriteFPUSqrtD : SchedWriteRes<[P5600IssueFPUL, P5600FPUDivSqrt]> { 2820b57cec5SDimitry Andric // Best/Common/Worst case = 7 / 35 / 39 2830b57cec5SDimitry Andric let Latency = 35; // Using common case 284*5f757f3fSDimitry Andric let ReleaseAtCycles = [ 1, 35 ]; 2850b57cec5SDimitry Andric} 2860b57cec5SDimitry Andricdef P5600WriteMSAShortLogic : SchedWriteRes<[P5600IssueFPUS]>; 2870b57cec5SDimitry Andricdef P5600WriteMSAShortInt : SchedWriteRes<[P5600IssueFPUS]> { let Latency = 2; } 2880b57cec5SDimitry Andricdef P5600WriteMoveOtherUnitsToFPU : SchedWriteRes<[P5600IssueFPUS]>; 2890b57cec5SDimitry Andricdef P5600WriteMSAOther3 : SchedWriteRes<[P5600IssueFPUS]> { let Latency = 3; } 2900b57cec5SDimitry Andricdef P5600WriteMSALongInt : SchedWriteRes<[P5600IssueFPUS]> { let Latency = 5; } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric// vshf.[bhwd], binsl.[bhwd], binsr.[bhwd], insert.[bhwd], sld?.[bhwd], 2930b57cec5SDimitry Andric// bset.[bhwd], bclr.[bhwd], bneg.[bhwd], bsel_v, bseli_b 2940b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^VSHF_[BHWD]$")>; 2950b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BINSL|BINSLI)_[BHWD]$")>; 2960b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BINSR|BINSRI)_[BHWD]$")>; 2970b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^INSERT_[BHWD]$")>; 2980b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(SLD|SLDI)_[BHWD]$")>; 2990b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSET|BSETI)_[BHWD]$")>; 3000b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BCLR|BCLRI)_[BHWD]$")>; 3010b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BNEG|BNEGI)_[BHWD]$")>; 3020b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(BSEL_V|BSELI_B)$")>; 3030b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^BMN*Z.*$")>; 3040b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], 3050b57cec5SDimitry Andric (instregex "^BSEL_(H|W|D|FW|FD)_PSEUDO$")>; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric// pcnt.[bhwd], sat_s.[bhwd], sat_u.bhwd] 3080b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAOther3], (instregex "^PCNT_[BHWD]$")>; 3090b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAOther3], (instregex "^SAT_(S|U)_[BHWD]$")>; 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric// bnz.[bhwdv], cfcmsa, ctcmsa 3120b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(BNZ|BZ)_[BHWDV]$")>; 3130b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^C(F|T)CMSA$")>; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric// FPUS is also used in moves from floating point and MSA registers to general 3160b57cec5SDimitry Andric// purpose registers. 3170b57cec5SDimitry Andricdef P5600WriteMoveFPUSToOtherUnits : SchedWriteRes<[P5600IssueFPUS]> { 3180b57cec5SDimitry Andric let Latency = 0; 3190b57cec5SDimitry Andric} 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric// FPUL is also used in moves from floating point and MSA registers to general 3220b57cec5SDimitry Andric// purpose registers. 3230b57cec5SDimitry Andricdef P5600WriteMoveFPULToOtherUnits : SchedWriteRes<[P5600IssueFPUL]>; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric// Short Pipe 3260b57cec5SDimitry Andric// ---------- 3270b57cec5SDimitry Andric// 3280b57cec5SDimitry Andric// abs.[ds], abs.ps, bc1[tf]l?, mov[tf].[ds], mov[tf], mov.[ds], [cm][ft]c1, 3290b57cec5SDimitry Andric// m[ft]hc1, neg.[ds], neg.ps, nor.v, nori.b, or.v, ori.b, xor.v, xori.b, 3300b57cec5SDimitry Andric// sdxc1, sdc1, st.[bhwd], swc1, swxc1 3310b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instrs FABS_S, FABS_D32, FABS_D64, MOVF_D32, 3320b57cec5SDimitry Andric MOVF_D64, MOVF_S, MOVT_D32, MOVT_D64, 3330b57cec5SDimitry Andric MOVT_S, FMOV_D32, FMOV_D64, FMOV_S, FNEG_S, 3340b57cec5SDimitry Andric FNEG_D32, FNEG_D64)>; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric// adds_a.[bhwd], adds_[asu].[bhwd], addvi?.[bhwd], asub_[us].[bhwd], 3370b57cec5SDimitry Andric// aver?_[us].[bhwd], shf.[bhw], fill[bhwd], splat?.[bhwd] 3380b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^ADD_A_[BHWD]$")>; 3390b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^ADDS_[ASU]_[BHWD]$")>; 3400b57cec5SDimitry Andric// TODO: ADDVI_[BHW] might be 1 cycle latency rather than 2. Need to confirm it. 3410b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^ADDVI?_[BHWD]$")>; 3420b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^ASUB_[US].[BHWD]$")>; 3430b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^AVER?_[US].[BHWD]$")>; 3440b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SHF_[BHW]$")>; 3450b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^FILL_[BHWD]$")>; 3460b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^(SPLAT|SPLATI)_[BHWD]$")>; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric// and.v, andi.b, move.v, ldi.[bhwd] 3490b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^MOVE_V$")>; 3500b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^LDI_[BHWD]$")>; 3510b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(AND|OR|[XN]OR)_V$")>; 3520b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(AND|OR|[XN]OR)I_B$")>; 3530b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], 3540b57cec5SDimitry Andric (instregex "^(AND|OR|[XN]OR)_V_[DHW]_PSEUDO$")>; 3550b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^FILL_F(D|W)_PSEUDO$")>; 3560b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^INSERT_F(D|W)_PSEUDO$")>; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric// fexp2_w, fexp2_d 3590b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FEXP2_(W|D)$")>; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric// compare, converts, round to int, floating point truncate. 3620b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^(CLT|CLTI)_(S|U)_[BHWD]$")>; 3630b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^(CLE|CLEI)_(S|U)_[BHWD]$")>; 3640b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^(CEQ|CEQI)_[BHWD]$")>; 3650b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_UN_(S|D)$")>; 3660b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_UEQ_(S|D)$")>; 3670b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_EQ_(S|D)$")>; 3680b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_LT_(S|D)$")>; 3690b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_ULT_(S|D)$")>; 3700b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_LE_(S|D)$")>; 3710b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^CMP_ULE_(S|D)$")>; 3720b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FS(AF|EQ|LT|LE|NE|OR)_(W|D)$")>; 3730b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FSUEQ_(W|D)$")>; 3740b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FSULE_(W|D)$")>; 3750b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FSULT_(W|D)$")>; 3760b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FSUNE_(W|D)$")>; 3770b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FSUN_(W|D)$")>; 3780b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCAF_(W|D)$")>; 3790b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCEQ_(W|D)$")>; 3800b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCLE_(W|D)$")>; 3810b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCLT_(W|D)$")>; 3820b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCNE_(W|D)$")>; 3830b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCOR_(W|D)$")>; 3840b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCUEQ_(W|D)$")>; 3850b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCULE_(W|D)$")>; 3860b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCULT_(W|D)$")>; 3870b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCUNE_(W|D)$")>; 3880b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCUN_(W|D)$")>; 3890b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FABS_(W|D)$")>; 3900b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FFINT_(U|S)_(W|D)$")>; 3910b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FFQL_(W|D)$")>; 3920b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FFQR_(W|D)$")>; 3930b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FTINT_(U|S)_(W|D)$")>; 3940b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FRINT_(W|D)$")>; 3950b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FTQ_(H|W)$")>; 3960b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FTRUNC_(U|S)_(W|D)$")>; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric// fexdo.[hw], fexupl.[wd], fexupr.[wd] 3990b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FEXDO_(H|W)$")>; 4000b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FEXUPL_(W|D)$")>; 4010b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FEXUPR_(W|D)$")>; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric// fclass.[wd], fmax.[wd], fmax_a.[wd], fmin.[wd], fmin_a.[wd], flog2.[wd] 4040b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FCLASS_(W|D)$")>; 4050b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FMAX_A_(W|D)$")>; 4060b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FMAX_(W|D)$")>; 4070b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FMIN_A_(W|D)$")>; 4080b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FMIN_(W|D)$")>; 4090b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUS], (instregex "^FLOG2_(W|D)$")>; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric// interleave right/left, interleave even/odd, insert 4120b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(ILVR|ILVL)_[BHWD]$")>; 4130b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(ILVEV|ILVOD)_[BHWD]$")>; 4140b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^INSVE_[BHWD]$")>; 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric// subs_?.[bhwd], subsus_?.[bhwd], subsuu_?.[bhwd], subvi.[bhwd], subv.[bhwd], 4170b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SUBS_(S|U)_[BHWD]$")>; 4180b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SUBSUS_(S|U)_[BHWD]$")>; 4190b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SUBSUU_(S|U)_[BHWD]$")>; 4200b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SUBVI_[BHWD]$")>; 4210b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortInt], (instregex "^SUBV_[BHWD]$")>; 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric// mod_[su].[bhwd], div_[su].[bhwd] 4240b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivI], (instregex "^MOD_(S|U)_[BHWD]$")>; 4250b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivI], (instregex "^DIV_(S|U)_[BHWD]$")>; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric// hadd_[su].[bhwd], hsub_[su].[bhwd], max_[sua].[bhwd], min_[sua].[bhwd], 4280b57cec5SDimitry Andric// maxi_[su].[bhwd], mini_[su].[bhwd], sra?.[bhwd], srar?.[bhwd], srlr.[bhwd], 4290b57cec5SDimitry Andric// sll?.[bhwd], pckev.[bhwd], pckod.[bhwd], nloc.[bhwd], nlzc.[bhwd], 4300b57cec5SDimitry Andric// insve.[bhwd] 4310b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^HADD_(S|U)_[BHWD]$")>; 4320b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^HSUB_(S|U)_[BHWD]$")>; 4330b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(MAX|MIN)_S_[BHWD]$")>; 4340b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(MAX|MIN)_U_[BHWD]$")>; 4350b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(MAX|MIN)_A_[BHWD]$")>; 4360b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(MAXI|MINI)_(S|U)_[BHWD]$")>; 4370b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(SRA|SRAI)_[BHWD]$")>; 4380b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(SRL|SRLI)_[BHWD]$")>; 4390b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(SRAR|SRARI)_[BHWD]$")>; 4400b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(SRLR|SRLRI)_[BHWD]$")>; 4410b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(SLL|SLLI)_[BHWD]$")>; 4420b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(PCKEV|PCKOD)_[BHWD]$")>; 4430b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSAShortLogic], (instregex "^(NLOC|NLZC)_[BHWD]$")>; 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric// Long Pipe 4460b57cec5SDimitry Andric// ---------- 4470b57cec5SDimitry Andric// 4480b57cec5SDimitry Andric// add.[ds], add.ps, cvt.d.[sw], cvt.s.[dw], cvt.w.[sd], cvt.[sw].ps, 4490b57cec5SDimitry Andric// cvt.ps.[sw], cvt.s.(pl|pu), c.<cc>.[ds], c.<cc>.ps, mul.[ds], mul.ps, 4500b57cec5SDimitry Andric// pl[lu].ps, sub.[ds], sub.ps, trunc.w.[ds], trunc.w.ps 4510b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], 452e8d8bef9SDimitry Andric (instrs FADD_D32, FADD_D64, FADD_PS64, FADD_S, FMUL_D32, FMUL_D64, 453e8d8bef9SDimitry Andric FMUL_PS64, FMUL_S, FSUB_D32, FSUB_D64, FSUB_PS64, FSUB_S)>; 4540b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^TRUNC_(L|W)_(S|D32|D64)$")>; 4550b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], 4560b57cec5SDimitry Andric (instregex "^CVT_(S|D32|D64|L|W)_(S|D32|D64|L|W)$")>; 4570b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instrs CVT_PS_S64, CVT_S_PL64, CVT_S_PU64)>; 4580b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^C_[A-Z]+_(S|D32|D64)$")>; 4590b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^FCMP_(S32|D32|D64)$")>; 4600b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^PseudoCVT_(S|D32|D64)_(L|W)$")>; 4615ffd83dbSDimitry Andricdef : InstRW<[P5600WriteFPUL], (instrs PLL_PS64, PLU_PS64, PUL_PS64, PUU_PS64)>; 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric// div.[ds], div.ps 4640b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivS], (instrs FDIV_S)>; 4650b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivD], (instrs FDIV_D32, FDIV_D64)>; 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric// sqrt.[ds], sqrt.ps 4680b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUSqrtS], (instrs FSQRT_S)>; 4690b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUSqrtD], (instrs FSQRT_D32, FSQRT_D64)>; 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric// frcp.[wd], frsqrt.[wd] 4720b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPURsqrtD], (instregex "^FRCP_(W|D)$")>; 4730b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPURsqrtD], (instregex "^FRSQRT_(W|D)$")>; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPURsqrtD], (instrs RECIP_D32, RECIP_D64, RSQRT_D32, 4760b57cec5SDimitry Andric RSQRT_D64)>; 4770b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPURsqrtS], (instrs RECIP_S, RSQRT_S)>; 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric// fmadd.[wd], fmsubb.[wd], fdiv.[wd], fsqrt.[wd], fmul.[wd], fadd.[wd], 4800b57cec5SDimitry Andric// fsub.[wd] 4810b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL_MADDSUB], (instregex "^FMADD_(W|D)$")>; 4820b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL_MADDSUB], (instregex "^FMSUB_(W|D)$")>; 4830b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivS], (instregex "^FDIV_W$")>; 4840b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUDivD], (instregex "^FDIV_D$")>; 4850b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUSqrtS], (instregex "^FSQRT_W$")>; 4860b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUSqrtD], (instregex "^FSQRT_D$")>; 4870b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^FMUL_(W|D)$")>; 4880b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^FADD_(W|D)$")>; 4890b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^FSUB_(W|D)$")>; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric// dpadd_?.[bhwd], dpsub_?.[bhwd], dotp_?.[bhwd], msubv.[bhwd], maddv.[bhwd] 4920b57cec5SDimitry Andric// mulv.[bhwd]. 4930b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^DPADD_(S|U)_[HWD]$")>; 4940b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^DPSUB_(S|U)_[HWD]$")>; 4950b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^DOTP_(S|U)_[HWD]$")>; 4960b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MSUBV_[BHWD]$")>; 4970b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MADDV_[BHWD]$")>; 4980b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MULV_[BHWD]$")>; 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MADDR_Q_[HW]$")>; 5010b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MADD_Q_[HW]$")>; 5020b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MSUBR_Q_[HW]$")>; 5030b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MSUB_Q_[HW]$")>; 5040b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MULR_Q_[HW]$")>; 5050b57cec5SDimitry Andricdef : InstRW<[P5600WriteMSALongInt], (instregex "^MUL_Q_[HW]$")>; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric// madd.[ds], msub.[ds], nmadd.[ds], nmsub.[ds], 5080b57cec5SDimitry Andric// Operand 0 is read on cycle 5. All other operands are read on operand 0. 5090b57cec5SDimitry Andricdef : InstRW<[SchedReadAdvance<5>, P5600WriteFPUL_MADDSUB], 5100b57cec5SDimitry Andric (instrs MADD_D32, MADD_D64, MADD_S, MSUB_D32, MSUB_D64, MSUB_S, 5110b57cec5SDimitry Andric NMADD_D32, NMADD_D64, NMADD_S, NMSUB_D32, NMSUB_D64, NMSUB_S)>; 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric// madd.ps, msub.ps, nmadd.ps, nmsub.ps 5140b57cec5SDimitry Andric// Operand 0 and 1 are read on cycle 5. All others are read on operand 0. 5150b57cec5SDimitry Andric// (none of these instructions exist in the backend yet) 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric// Load Pipe 5180b57cec5SDimitry Andric// --------- 5190b57cec5SDimitry Andric// 5200b57cec5SDimitry Andric// This is typically used in conjunction with the load pipeline under the AGQ 5210b57cec5SDimitry Andric// All the instructions are in the 'Tricky Instructions' section. 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andricdef P5600WriteLoadOtherUnitsToFPU : SchedWriteRes<[P5600IssueFPULoad]> { 5240b57cec5SDimitry Andric let Latency = 4; 5250b57cec5SDimitry Andric} 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric// Tricky Instructions 5280b57cec5SDimitry Andric// =================== 5290b57cec5SDimitry Andric// 5300b57cec5SDimitry Andric// These instructions are split across multiple uops (in different pipelines) 5310b57cec5SDimitry Andric// that must cooperate to complete the operation 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric// FIXME: This isn't quite right since the implementation of WriteSequence 5340b57cec5SDimitry Andric// current aggregates the resources and ignores the exact cycle they are 5350b57cec5SDimitry Andric// used. 5360b57cec5SDimitry Andricdef P5600WriteMoveGPRToFPU : WriteSequence<[P5600WriteMoveGPRToOtherUnits, 5370b57cec5SDimitry Andric P5600WriteMoveOtherUnitsToFPU]>; 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andric// FIXME: This isn't quite right since the implementation of WriteSequence 5400b57cec5SDimitry Andric// current aggregates the resources and ignores the exact cycle they are 5410b57cec5SDimitry Andric// used. 5420b57cec5SDimitry Andricdef P5600WriteMoveFPUToGPR : WriteSequence<[P5600WriteMoveFPUSToOtherUnits, 5430b57cec5SDimitry Andric P5600WriteGPRFromBypass]>; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric// FIXME: This isn't quite right since the implementation of WriteSequence 5460b57cec5SDimitry Andric// current aggregates the resources and ignores the exact cycle they are 5470b57cec5SDimitry Andric// used. 5480b57cec5SDimitry Andricdef P5600WriteStoreFPUS : WriteSequence<[P5600WriteMoveFPUSToOtherUnits, 5490b57cec5SDimitry Andric P5600WriteStoreFromOtherUnits]>; 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric// FIXME: This isn't quite right since the implementation of WriteSequence 5520b57cec5SDimitry Andric// current aggregates the resources and ignores the exact cycle they are 5530b57cec5SDimitry Andric// used. 5540b57cec5SDimitry Andricdef P5600WriteStoreFPUL : WriteSequence<[P5600WriteMoveFPULToOtherUnits, 5550b57cec5SDimitry Andric P5600WriteStoreFromOtherUnits]>; 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric// FIXME: This isn't quite right since the implementation of WriteSequence 5580b57cec5SDimitry Andric// current aggregates the resources and ignores the exact cycle they are 5590b57cec5SDimitry Andric// used. 5600b57cec5SDimitry Andricdef P5600WriteLoadFPU : WriteSequence<[P5600WriteLoadToOtherUnits, 5610b57cec5SDimitry Andric P5600WriteLoadOtherUnitsToFPU]>; 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric// ctc1, mtc1, mthc1 5640b57cec5SDimitry Andricdef : InstRW<[P5600WriteMoveGPRToFPU], (instrs CTC1, MTC1, MTC1_D64, MTHC1_D32, 5650b57cec5SDimitry Andric MTHC1_D64, BuildPairF64, 5660b57cec5SDimitry Andric BuildPairF64_64)>; 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric// copy.[su]_[bhwd] 5690b57cec5SDimitry Andricdef : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_U_[BHW]$")>; 5700b57cec5SDimitry Andricdef : InstRW<[P5600WriteMoveFPUToGPR], (instregex "^COPY_S_[BHWD]$")>; 5710b57cec5SDimitry Andric 5720b57cec5SDimitry Andric// bc1[ft], cfc1, mfc1, mfhc1, movf, movt 5730b57cec5SDimitry Andricdef : InstRW<[P5600WriteMoveFPUToGPR], (instrs BC1F, BC1FL, BC1T, BC1TL, CFC1, 5740b57cec5SDimitry Andric MFC1, MFC1_D64, MFHC1_D32, MFHC1_D64, 5750b57cec5SDimitry Andric MOVF_I, MOVT_I, ExtractElementF64, 5760b57cec5SDimitry Andric ExtractElementF64_64)>; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric// swc1, swxc1, st.[bhwd] 5790b57cec5SDimitry Andricdef : InstRW<[P5600WriteStoreFPUS], (instrs SDC1, SDC164, SDXC1, SDXC164, 5800b57cec5SDimitry Andric SWC1, SWXC1, SUXC1, SUXC164)>; 5810b57cec5SDimitry Andricdef : InstRW<[P5600WriteStoreFPUS], (instregex "^ST_[BHWD]$")>; 5820b57cec5SDimitry Andricdef : InstRW<[P5600WriteStoreFPUS], (instrs ST_F16)>; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric// movn.[ds], movz.[ds] 5850b57cec5SDimitry Andricdef : InstRW<[P5600WriteStoreFPUL], (instrs MOVN_I_D32, MOVN_I_D64, MOVN_I_S, 5860b57cec5SDimitry Andric MOVZ_I_D32, MOVZ_I_D64, MOVZ_I_S)>; 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric// l[dw]x?c1, ld.[bhwd] 5890b57cec5SDimitry Andricdef : InstRW<[P5600WriteLoadFPU], (instrs LDC1, LDC164, LDXC1, LDXC164, 5900b57cec5SDimitry Andric LWC1, LWXC1, LUXC1, LUXC164)>; 5910b57cec5SDimitry Andricdef : InstRW<[P5600WriteLoadFPU], (instregex "LD_[BHWD]")>; 5920b57cec5SDimitry Andricdef : InstRW<[P5600WriteLoadFPU], (instrs LD_F16)>; 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric// Unsupported Instructions 5950b57cec5SDimitry Andric// ======================== 5960b57cec5SDimitry Andric// 5970b57cec5SDimitry Andric// The following instruction classes are never valid on P5600. 5980b57cec5SDimitry Andric// II_DADDIU, II_DADDU, II_DMFC1, II_DMTC1, II_DMULT, II_DMULTU, II_DROTR, 5990b57cec5SDimitry Andric// II_DROTR32, II_DROTRV, II_DDIV, II_DSLL, II_DSLL32, II_DSLLV, II_DSRA, 6000b57cec5SDimitry Andric// II_DSRA32, II_DSRAV, II_DSRL, II_DSRL32, II_DSRLV, II_DSUBU, II_DDIVU, 6010b57cec5SDimitry Andric// II_JALRC, II_LD, II_LD[LR], II_RESTORE, II_SAVE, II_SD, II_SDC1, II_SD[LR] 6020b57cec5SDimitry Andric// 6030b57cec5SDimitry Andric// The following instructions are never valid on P5600. 6040b57cec5SDimitry Andric// addq.ph, repl.ph, repl.qb, subq.ph, subu_s.qb 6050b57cec5SDimitry Andric// 6060b57cec5SDimitry Andric// Guesswork 6070b57cec5SDimitry Andric// ========= 6080b57cec5SDimitry Andric// 6090b57cec5SDimitry Andric// This section is largely temporary guesswork. 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric// ceil.[lw].[ds], floor.[lw].[ds] 6120b57cec5SDimitry Andric// Reason behind guess: trunc.[lw].ds and the various cvt's are in FPUL 6130b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^CEIL_(L|W)_(S|D32|D64)$")>; 6140b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^FLOOR_(L|W)_(S|D32|D64)$")>; 6150b57cec5SDimitry Andricdef : InstRW<[P5600WriteFPUL], (instregex "^ROUND_(L|W)_(S|D32|D64)$")>; 6160b57cec5SDimitry Andric 6170b57cec5SDimitry Andric// rotrv 6180b57cec5SDimitry Andric// Reason behind guess: rotr is in the same category and the two register forms 6190b57cec5SDimitry Andric// generally follow the immediate forms in this category 6200b57cec5SDimitry Andricdef : InstRW<[P5600WriteEitherALU], (instrs ROTRV)>; 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric// Atomic instructions 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric// FIXME: Define `WriteAtomic` in the MipsSchedule.td and 6250b57cec5SDimitry Andric// attach it to the Atomic2OpsPostRA, AtomicCmpSwapPostRA, ... 6260b57cec5SDimitry Andric// classes. Then just define resources for the `WriteAtomic` in each 6270b57cec5SDimitry Andric// machine models. 6280b57cec5SDimitry Andricdef P5600Atomic : ProcResource<1> { let BufferSize = 1; } 6290b57cec5SDimitry Andricdef P5600WriteAtomic : SchedWriteRes<[P5600Atomic]> { let Latency = 2; } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andricdef : InstRW<[P5600WriteAtomic], 6320b57cec5SDimitry Andric (instregex "^ATOMIC_SWAP_I(8|16|32|64)_POSTRA$")>; 6330b57cec5SDimitry Andricdef : InstRW<[P5600WriteAtomic], 6340b57cec5SDimitry Andric (instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>; 6350b57cec5SDimitry Andricdef : InstRW<[P5600WriteAtomic], 636480093f4SDimitry Andric (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)" 637480093f4SDimitry Andric "_I(8|16|32|64)_POSTRA$")>; 6380b57cec5SDimitry Andric} 639