xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MipsScheduleI6400.td (revision 700637cbb5e582861067a11aaca4d053546871d2)
1*700637cbSDimitry Andric//==- MipsScheduleI6400.td - I6400 Scheduling Definitions --*- tablegen -*-===//
2*700637cbSDimitry Andric//
3*700637cbSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*700637cbSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*700637cbSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*700637cbSDimitry Andric//
7*700637cbSDimitry Andric//===----------------------------------------------------------------------===//
8*700637cbSDimitry Andric
9*700637cbSDimitry Andricdef MipsI6400Model : SchedMachineModel {
10*700637cbSDimitry Andric  int IssueWidth = 2;         // 2x dispatched per cycle
11*700637cbSDimitry Andric  int MicroOpBufferSize = 0;
12*700637cbSDimitry Andric  int LoadLatency = 3;
13*700637cbSDimitry Andric  int MispredictPenalty = 8;
14*700637cbSDimitry Andric
15*700637cbSDimitry Andric  let CompleteModel = 0;
16*700637cbSDimitry Andric  let FullInstRWOverlapCheck = 1;
17*700637cbSDimitry Andric
18*700637cbSDimitry Andric  list<Predicate> UnsupportedFeatures = [HasMips64r5, HasMips32r5,
19*700637cbSDimitry Andric                                         InMicroMips, InMips16Mode, HasCnMips,
20*700637cbSDimitry Andric					 HasCnMipsP,  HasDSP, HasDSPR2,
21*700637cbSDimitry Andric					 HasMips3D, HasMT, HasCRC,
22*700637cbSDimitry Andric					 NotMips32r6, NotMips64r6, HasEVA];
23*700637cbSDimitry Andric}
24*700637cbSDimitry Andric
25*700637cbSDimitry Andriclet SchedModel = MipsI6400Model in {
26*700637cbSDimitry Andric
27*700637cbSDimitry Andric  // I6400 Resources
28*700637cbSDimitry Andric  // ===============
29*700637cbSDimitry Andric  let BufferSize = 0 in {
30*700637cbSDimitry Andric
31*700637cbSDimitry Andric    def I6400AGEN : ProcResource<1>;
32*700637cbSDimitry Andric    def I6400IssueLSU : ProcResource<1> { let Super = I6400AGEN; }
33*700637cbSDimitry Andric    def I6400IssueALU1 : ProcResource<1> { let Super = I6400AGEN; }
34*700637cbSDimitry Andric    def I6400CTRL : ProcResource<1>;
35*700637cbSDimitry Andric    def I6400IssueCTU : ProcResource<1> { let Super = I6400CTRL; }
36*700637cbSDimitry Andric    def I6400IssueALU0 : ProcResource<1> { let Super = I6400CTRL; }
37*700637cbSDimitry Andric    def I6400MDU : ProcResource<1>;
38*700637cbSDimitry Andric    def I6400FPU : ProcResource<3>;
39*700637cbSDimitry Andric    def I6400FPUShort : ProcResource<1> { let Super = I6400FPU; }
40*700637cbSDimitry Andric    def I6400FPULong : ProcResource<1> { let Super = I6400FPU; }
41*700637cbSDimitry Andric    def I6400FPUApu : ProcResource<1>;
42*700637cbSDimitry Andric    def I6400FPUFloatL : ProcResource<1>;
43*700637cbSDimitry Andric    def I6400Atomic : ProcResource<1>;
44*700637cbSDimitry Andric  }
45*700637cbSDimitry Andric
46*700637cbSDimitry Andric  // AGEN Pipelines
47*700637cbSDimitry Andric  // ==============
48*700637cbSDimitry Andric  def I6400WriteLSUStore : SchedWriteRes<[I6400IssueLSU]>;
49*700637cbSDimitry Andric  def I6400WriteLSUStore2 : SchedWriteRes<[I6400IssueLSU]> {
50*700637cbSDimitry Andric    let Latency = 8;
51*700637cbSDimitry Andric    let ReleaseAtCycles = [5];
52*700637cbSDimitry Andric  }
53*700637cbSDimitry Andric  def I6400WriteLSULoad : SchedWriteRes<[I6400IssueLSU]> { let Latency = 3; }
54*700637cbSDimitry Andric  def I6400WriteLSUPref : SchedWriteRes<[I6400IssueLSU]>;
55*700637cbSDimitry Andric  def I6400WriteLSUOther : SchedWriteRes<[I6400IssueLSU]> {
56*700637cbSDimitry Andric    let Latency = 6;
57*700637cbSDimitry Andric    let ReleaseAtCycles = [5];
58*700637cbSDimitry Andric  }
59*700637cbSDimitry Andric
60*700637cbSDimitry Andric  // LSU pipelines
61*700637cbSDimitry Andric  // =============
62*700637cbSDimitry Andric  def : InstRW<[I6400WriteLSUStore], (instrs SB, SD, SH, SW, SDC1, SDC164, SWC1, SWC2_R6,
63*700637cbSDimitry Andric				      SDC2_R6, SDC3)>;
64*700637cbSDimitry Andric  def : InstRW<[I6400WriteLSUStore2], (instrs SC_R6, SCD_R6, SYNCI, TLBP, TLBR,
65*700637cbSDimitry Andric                                          TLBWI, TLBWR, TLBINV, TLBINVF,
66*700637cbSDimitry Andric                                          CACHE_R6, SC64_R6)>;
67*700637cbSDimitry Andric  def : InstRW<[I6400WriteLSULoad],
68*700637cbSDimitry Andric               (instrs LB, LBu, LBu64, LD, LH, LHu, LHu64, LW, LWu, LDC1,
69*700637cbSDimitry Andric		   LDC164, LWC1, LD_F16, ST_F16, LDC2_R6, LDC3, LWC2_R6,
70*700637cbSDimitry Andric                   LLD_R6, LL_R6, LWPC, LWUPC, LDPC, ST_B, ST_H, ST_W, ST_D,
71*700637cbSDimitry Andric		   LB64, LH64, LW64, LWL64, LWR64, SB64, SH64, SW64, SWL64,
72*700637cbSDimitry Andric		   SWR64, LL64_R6)>;
73*700637cbSDimitry Andric  def : InstRW<[I6400WriteLSUPref], (instrs PREF, PREF_R6, PAUSE)>;
74*700637cbSDimitry Andric  def : InstRW<[I6400WriteLSUOther], (instrs SYNC)>;
75*700637cbSDimitry Andric
76*700637cbSDimitry Andric  // CONTROL Pipelines
77*700637cbSDimitry Andric  // =================
78*700637cbSDimitry Andric
79*700637cbSDimitry Andric  def I6400WriteALU0 : SchedWriteRes<[I6400IssueALU0]>;
80*700637cbSDimitry Andric  def I6400WriteALU1 : SchedWriteRes<[I6400IssueALU1]>;
81*700637cbSDimitry Andric  def I6400WriteCTU : SchedWriteRes<[I6400IssueCTU]>;
82*700637cbSDimitry Andric
83*700637cbSDimitry Andric  // CTU pipelines
84*700637cbSDimitry Andric  // =============
85*700637cbSDimitry Andric  def : InstRW<[I6400WriteCTU],
86*700637cbSDimitry Andric               (instrs J, JAL, JALR, B, BEQ, BNE, BGEZ, BGTZ, BLEZ, BLTZ,
87*700637cbSDimitry Andric                   JALR64, JALR64Pseudo, JIALC, JIALC64, JIC, JIC64, JR64,
88*700637cbSDimitry Andric		   JR_HB_R6,
89*700637cbSDimitry Andric                   JR_HB64_R6, NAL, SDBBP_R6, SYSCALL, BEQC64, BEQZC64, BGEC64,
90*700637cbSDimitry Andric                   BGEUC64, BGTZC64, BLEZC64, BLTC64, BLTUC64, BNEC64, BNEZC64,
91*700637cbSDimitry Andric                   PseudoIndirectBranchR6, BC, BALC, BEQZC, BNEZC, BLEZC, BGEZC,
92*700637cbSDimitry Andric                   BGTZC, BLTZC, BEQZALC, BNEZALC, BLEZALC, BGEZALC, BGTZALC,
93*700637cbSDimitry Andric                   BLTZALC, BEQC, BNEC, BGEC, BLTC, BGEUC, BLTUC, BAL, BOVC,
94*700637cbSDimitry Andric                   BNVC, BC1EQZ, BC1NEZ, BREAK, ERET, ERETNC, BAL_BR, DERET,
95*700637cbSDimitry Andric		   JALRHBPseudo, JALRPseudo, JALR_HB, JALR_HB64, TAILCALL,
96*700637cbSDimitry Andric		   PseudoIndirectBranch64R6, TAILCALL64R6REG,
97*700637cbSDimitry Andric		   TAILCALLR6REG, PseudoIndrectHazardBranch64R6,
98*700637cbSDimitry Andric		   PseudoIndrectHazardBranchR6, TAILCALLHB64R6REG,
99*700637cbSDimitry Andric		   TAILCALLHBR6REG, PseudoReturn, PseudoReturn64, ERet, RetRA,
100*700637cbSDimitry Andric		   BC2EQZ, BC2NEZ, TLT, TLTU, TNE, WAIT, DI, TRAP, EI,
101*700637cbSDimitry Andric		   BEQ64, BGEZ64, BGEZC64, BGTZ64, BGTZ64, BLEZ64, BLTZ64,
102*700637cbSDimitry Andric		   BLTZC64, BNE64, JALRHB64Pseudo)>;
103*700637cbSDimitry Andric
104*700637cbSDimitry Andric  // Either ALU0 or ALU1 pipelines
105*700637cbSDimitry Andric  // =============================
106*700637cbSDimitry Andric  def I6400IssueEitherALU : ProcResGroup<[I6400IssueALU0, I6400IssueALU1]>;
107*700637cbSDimitry Andric  def I6400WriteEitherALU : SchedWriteRes<[I6400IssueEitherALU]>;
108*700637cbSDimitry Andric
109*700637cbSDimitry Andric  def : InstRW<[I6400WriteEitherALU],
110*700637cbSDimitry Andric               (instrs ADD, ADDiu, ADDIUPC, ADDu, ALIGN, ALUIPC, AND, ANDi, AUI,
111*700637cbSDimitry Andric                   AUIPC, BITSWAP, CFC1, CLO_R6, CLZ_R6, CTC1, DADD, DADDiu,
112*700637cbSDimitry Andric                   DADDu, DAHI, DALIGN, DATI, DAUI, DBITSWAP, DCLO_R6, DCLZ_R6,
113*700637cbSDimitry Andric                   DEXT, DEXT64_32, DEXTM, DEXTU, DINS, DINSM, DINSU, DLSA_R6,
114*700637cbSDimitry Andric                   DMFC1, DMTC1, DROTR, DROTR32, DROTRV, DSBH, DSHD, DSLL,
115*700637cbSDimitry Andric                   DSLL32, DSLLV, DSRA, DSRA32, DSRAV, DSRL, DSRL32, DSRLV,
116*700637cbSDimitry Andric                   DSUB, DSUBu, EXT, INS, LSA, LSA_R6, LUi, MFC1, MFC1_D64,
117*700637cbSDimitry Andric		   MFC0, MFC2, MTC0, MTC2,
118*700637cbSDimitry Andric                   MFHC1_D32, MFHC1_D64, MTC1, MTC1_D64, MTHC1_D32, MTHC1_D64,
119*700637cbSDimitry Andric                   NOP, NOR, OR, ORi, ROTR, ROTRV, SEB, SEB64, SEH, SEH64,
120*700637cbSDimitry Andric                   SELEQZ, SELEQZ64, SELNEZ, SELNEZ64, SLL, SLLV, SLT, SLTi, SLTiu, SLTu, SRA, SRAV,
121*700637cbSDimitry Andric                   SRL, SRLV, SSNOP, SUB, SUBu, WSBH, XOR, XORi, SLT64, SLTu64,
122*700637cbSDimitry Andric                   AND64, OR64, XOR64, NOR64, SLTi64, SLTiu64, ANDi64, ORi64,
123*700637cbSDimitry Andric                   XORi64, LUi64, DSLL64_32, SLL64_32, SLL64_64,
124*700637cbSDimitry Andric                   LONG_BRANCH_LUi2Op_64, LONG_BRANCH_DADDiu2Op,
125*700637cbSDimitry Andric                   LONG_BRANCH_DADDiu, DLSA,
126*700637cbSDimitry Andric		   TEQ, TGE, TGEU, COPY,
127*700637cbSDimitry Andric		   BuildPairF64, BuildPairF64_64,
128*700637cbSDimitry Andric		   ExtractElementF64, ExtractElementF64_64,
129*700637cbSDimitry Andric		   SELNEZ_D, SELNEZ_S, SELEQZ_D, SELEQZ_S,
130*700637cbSDimitry Andric		   SEL_D, SEL_S, EHB, RDHWR, RDHWR64, EVP, DVP,
131*700637cbSDimitry Andric		   DMFC0, DMFC2, DMTC0, DMTC2)>;
132*700637cbSDimitry Andric
133*700637cbSDimitry Andric  // MDU pipelines
134*700637cbSDimitry Andric  // =============
135*700637cbSDimitry Andric  def I6400GPMUL : SchedWriteRes<[I6400MDU]> { let Latency = 4; }
136*700637cbSDimitry Andric  def : InstRW<[I6400GPMUL], (instrs MUL_R6, MULU, MUH, MUHU, DMUL_R6, DMUH,
137*700637cbSDimitry Andric                                 DMULU, DMUHU)>;
138*700637cbSDimitry Andric
139*700637cbSDimitry Andric  def I6400GPDIV : SchedWriteRes<[I6400MDU]> { let Latency = 32; }
140*700637cbSDimitry Andric  def : InstRW<[I6400GPDIV], (instrs DIV, DIVU, MOD, MODU, DDIV, DMOD, DDIVU,
141*700637cbSDimitry Andric                                 DMODU)>;
142*700637cbSDimitry Andric  def : InstRW<[I6400GPDIV], (instregex "^MOD_(S|U)_[BHWD]$")>;
143*700637cbSDimitry Andric
144*700637cbSDimitry Andric  // FPU pipelines
145*700637cbSDimitry Andric  // =============
146*700637cbSDimitry Andric
147*700637cbSDimitry Andric  def I6400FPUFabs : SchedWriteRes<[I6400FPUShort]>;
148*700637cbSDimitry Andric  def : InstRW<[I6400FPUFabs], (instrs FABS_S, FNEG_S, FMOV_S,
149*700637cbSDimitry Andric				FMOV_D32, FMOV_D64,
150*700637cbSDimitry Andric				FNEG_D32, FNEG_D64, CLASS_S, CLASS_D)>;
151*700637cbSDimitry Andric
152*700637cbSDimitry Andric  def I6400FPUFadd : SchedWriteRes<[I6400FPULong]> {
153*700637cbSDimitry Andric    let Latency = 4;
154*700637cbSDimitry Andric    let ReleaseAtCycles = [1];
155*700637cbSDimitry Andric  }
156*700637cbSDimitry Andric  def : InstRW<[I6400FPUFadd], (instrs FADD_S, FSUB_S, FSUB_D32, FSUB_D64)>;
157*700637cbSDimitry Andric
158*700637cbSDimitry Andric  def I6400FPUFmul : SchedWriteRes<[I6400FPULong, I6400FPUApu]> {
159*700637cbSDimitry Andric    let Latency = 5;
160*700637cbSDimitry Andric    let ReleaseAtCycles = [1, 4];
161*700637cbSDimitry Andric  }
162*700637cbSDimitry Andric  def : InstRW<[I6400FPUFmul], (instrs FMUL_S, FMUL_D32, FMUL_D64)>;
163*700637cbSDimitry Andric
164*700637cbSDimitry Andric  def I6400FPUFdivS : SchedWriteRes<[I6400FPULong, I6400FPUApu]> {
165*700637cbSDimitry Andric    let Latency = 22;
166*700637cbSDimitry Andric    let ReleaseAtCycles = [1, 21];
167*700637cbSDimitry Andric  }
168*700637cbSDimitry Andric  def : InstRW<[I6400FPUFdivS], (instrs FDIV_S, FSQRT_S, FDIV_D32, FDIV_D64,
169*700637cbSDimitry Andric				 FSQRT_D, FSQRT_D32, FSQRT_D64,
170*700637cbSDimitry Andric				 FSQRT_W, RECIP_S, RECIP_D32, RECIP_D64,
171*700637cbSDimitry Andric				 FRSQRT_D, FRSQRT_W, RSQRT_S, RSQRT_D32,
172*700637cbSDimitry Andric				 RSQRT_D64, FRCP_D, FRCP_W)>;
173*700637cbSDimitry Andric  def : InstRW<[I6400FPUFdivS], (instregex "^DIV_S_(B|D|H|W)$")>;
174*700637cbSDimitry Andric  def : InstRW<[I6400FPUFdivS], (instregex "^DIV_U_(B|D|H|W)$")>;
175*700637cbSDimitry Andric
176*700637cbSDimitry Andric  // MSA pipelines
177*700637cbSDimitry Andric  // =============
178*700637cbSDimitry Andric  // Short pipe
179*700637cbSDimitry Andric  def I6400MSAAdd : SchedWriteRes<[I6400FPUShort]> {
180*700637cbSDimitry Andric    let Latency = 2;
181*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
182*700637cbSDimitry Andric  }
183*700637cbSDimitry Andric  def : InstRW<[I6400MSAAdd], (instrs ADDV_B, ADDV_H, ADDV_W, ADDV_D, ADDVI_B,
184*700637cbSDimitry Andric                                  ADDVI_H, ADDVI_W, ADDVI_D, SUBV_B, SUBV_H,
185*700637cbSDimitry Andric                                  SUBV_W, SUBV_D, SUBVI_B, SUBVI_H, SUBVI_W,
186*700637cbSDimitry Andric                                  SUBVI_D)>;
187*700637cbSDimitry Andric  def : InstRW<[I6400MSAAdd], (instregex "^ASUB_S_(B|D|H|W)$")>;
188*700637cbSDimitry Andric  def : InstRW<[I6400MSAAdd], (instregex "^ASUB_U_(B|D|H|W)$")>;
189*700637cbSDimitry Andric  def : InstRW<[I6400MSAAdd], (instregex "^SUBSUS_U_(B|D|H|W)$")>;
190*700637cbSDimitry Andric
191*700637cbSDimitry Andric  def I6400MSAMaxMin : SchedWriteRes<[I6400FPUShort]> {
192*700637cbSDimitry Andric    let Latency = 2;
193*700637cbSDimitry Andric    let ReleaseAtCycles = [1];
194*700637cbSDimitry Andric  }
195*700637cbSDimitry Andric  def : InstRW<[I6400MSAMaxMin], (instrs MAX_D, MAX_S, MAXA_D, MAXA_S,
196*700637cbSDimitry Andric				  MIN_D, MIN_S, MINA_D, MINA_S)>;
197*700637cbSDimitry Andric
198*700637cbSDimitry Andric  def I6400MSAIntAdd : SchedWriteRes<[I6400FPUShort]> {
199*700637cbSDimitry Andric    let Latency = 2;
200*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
201*700637cbSDimitry Andric  }
202*700637cbSDimitry Andric  def : InstRW<[I6400MSAIntAdd],
203*700637cbSDimitry Andric               (instrs ADD_A_B, ADD_A_H, ADD_A_W, ADD_A_D, ADDS_A_B, ADDS_A_H,
204*700637cbSDimitry Andric                   ADDS_A_W, ADDS_A_D, ADDS_S_B, ADDS_S_H, ADDS_S_W, ADDS_S_D,
205*700637cbSDimitry Andric                   ADDS_U_B, ADDS_U_H, ADDS_U_W, ADDS_U_D, HADD_S_H, HADD_S_W,
206*700637cbSDimitry Andric                   HADD_S_D, HADD_U_H, HADD_U_W, HADD_U_D, SUBS_S_B, SUBS_S_H,
207*700637cbSDimitry Andric                   SUBS_S_W, SUBS_S_D, SUBS_U_B, SUBS_U_H, SUBS_U_W, SUBS_U_D,
208*700637cbSDimitry Andric                   SUBSUU_S_B, SUBSUU_S_H, SUBSUU_S_W, SUBSUU_S_D, HSUB_S_H,
209*700637cbSDimitry Andric                   HSUB_S_W, HSUB_S_D, HSUB_U_H, HSUB_U_W, HSUB_U_D, AVE_S_B,
210*700637cbSDimitry Andric                   AVE_S_H, AVE_S_W, AVE_S_D, AVE_U_B, AVE_U_H, AVE_U_W,
211*700637cbSDimitry Andric                   AVE_U_D, AVER_S_B, AVER_S_H, AVER_S_W, AVER_S_D, AVER_U_B,
212*700637cbSDimitry Andric                   AVER_U_H, AVER_U_W, AVER_U_D, MIN_A_B, MIN_A_H, MIN_A_W,
213*700637cbSDimitry Andric                   MIN_A_D, MIN_S_B, MIN_S_H, MIN_S_W, MIN_S_D, MIN_U_B,
214*700637cbSDimitry Andric                   MIN_U_H, MIN_U_W, MIN_U_D, MINI_S_B, MINI_S_H, MINI_S_W,
215*700637cbSDimitry Andric                   MINI_S_D, MINI_U_B, MINI_U_H, MINI_U_W, MINI_U_D, MAX_A_B,
216*700637cbSDimitry Andric                   MAX_A_H, MAX_A_W, MAX_A_D, MAX_S_B, MAX_S_H, MAX_S_W,
217*700637cbSDimitry Andric                   MAX_S_D, MAX_U_B, MAX_U_H, MAX_U_W, MAX_U_D, MAXI_S_B,
218*700637cbSDimitry Andric                   MAXI_S_H, MAXI_S_W, MAXI_S_D, MAXI_U_B, MAXI_U_H, MAXI_U_W,
219*700637cbSDimitry Andric                   MAXI_U_D, CEQ_B, CEQ_H, CEQ_W, CEQ_D, CEQI_B, CEQI_H, CEQI_W,
220*700637cbSDimitry Andric                   CEQI_D, CLE_S_B, CLE_S_H, CLE_S_W, CLE_S_D, CLE_U_B, CLE_U_H,
221*700637cbSDimitry Andric                   CLE_U_W, CLE_U_D, CLEI_S_B, CLEI_S_H, CLEI_S_W, CLEI_S_D,
222*700637cbSDimitry Andric                   CLEI_U_B, CLEI_U_H, CLEI_U_W, CLEI_U_D, CLT_S_B, CLT_S_H,
223*700637cbSDimitry Andric                   CLT_S_W, CLT_S_D, CLT_U_B, CLT_U_H, CLT_U_W, CLT_U_D,
224*700637cbSDimitry Andric                   CLTI_S_B, CLTI_S_H, CLTI_S_W, CLTI_S_D, CLTI_U_B, CLTI_U_H,
225*700637cbSDimitry Andric                   CLTI_U_W, CLTI_U_D)>;
226*700637cbSDimitry Andric
227*700637cbSDimitry Andric  def I6400MSAShortLogic3 : SchedWriteRes<[I6400FPUShort]> {
228*700637cbSDimitry Andric    let Latency = 3;
229*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
230*700637cbSDimitry Andric  }
231*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic3],
232*700637cbSDimitry Andric               (instrs SAT_S_B, SAT_S_H, SAT_S_W, SAT_S_D, SAT_U_B, SAT_U_H,
233*700637cbSDimitry Andric                   SAT_U_W, SAT_U_D, PCNT_B, PCNT_H, PCNT_W, PCNT_D)>;
234*700637cbSDimitry Andric
235*700637cbSDimitry Andric  def I6400MSAShortLogic2 : SchedWriteRes<[I6400FPUShort]> {
236*700637cbSDimitry Andric    let Latency = 2;
237*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
238*700637cbSDimitry Andric  }
239*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic2],
240*700637cbSDimitry Andric               (instrs SLL_B, SLL_H, SLL_W, SLL_D, SLLI_B, SLLI_H, SLLI_W,
241*700637cbSDimitry Andric                   SLLI_D, SRA_B, SRA_H, SRA_W, SRA_D, SRAI_B, SRAI_H, SRAI_W,
242*700637cbSDimitry Andric                   SRAI_D, SRAR_B, SRAR_H, SRAR_W, SRAR_D, SRARI_B, SRARI_H,
243*700637cbSDimitry Andric                   SRARI_W, SRARI_D, SRL_B, SRL_H, SRL_W, SRL_D, SRLI_B, SRLI_H,
244*700637cbSDimitry Andric                   SRLI_W, SRLI_D, SRLR_B, SRLR_H, SRLR_W, SRLR_D, SRLRI_B,
245*700637cbSDimitry Andric                   SRLRI_H, SRLRI_W, SRLRI_D, NLOC_B, NLOC_H, NLOC_W, NLOC_D,
246*700637cbSDimitry Andric                   NLZC_B, NLZC_H, NLZC_W, NLZC_D, BNEG_B, BNEG_H, BNEG_W,
247*700637cbSDimitry Andric                   BNEG_D, BNEGI_B, BNEGI_H, BNEGI_W, BNEGI_D, BCLR_B, BCLR_H,
248*700637cbSDimitry Andric                   BCLR_W, BCLR_D, BCLRI_B, BCLRI_H, BCLRI_W, BCLRI_D, SHF_B,
249*700637cbSDimitry Andric                   SHF_H, SHF_W)>;
250*700637cbSDimitry Andric
251*700637cbSDimitry Andric  def I6400MSAShortLogic : SchedWriteRes<[I6400FPUShort]> {
252*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
253*700637cbSDimitry Andric  }
254*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic],
255*700637cbSDimitry Andric               (instrs AND_V, ANDI_B, OR_V, ORI_B, XOR_V, XORI_B,
256*700637cbSDimitry Andric		NOR_V, NORI_B)>;
257*700637cbSDimitry Andric
258*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^NOR_V_(H|W|D)_PSEUDO$")>;
259*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^OR_V_(H|W|D)_PSEUDO$")>;
260*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^XOR_V_(H|W|D)_PSEUDO$")>;
261*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^AND_V_(H|W|D)_PSEUDO$")>;
262*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^ILVEV_(B|H|W|D)$")>;
263*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^ILVL_(B|H|W|D)$")>;
264*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^ILVOD_(B|H|W|D)$")>;
265*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^ILVR_(B|H|W|D)$")>;
266*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^PCKEV_(B|H|W|D)$")>;
267*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^PCKOD_(B|H|W|D)$")>;
268*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^FILL_(B|H|W|D)$")>;
269*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^FILL_F(D|W)_PSEUDO$")>;
270*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^INSERT_F(D|W)_PSEUDO$")>;
271*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^SPLAT_(B|H|W|D)$")>;
272*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic], (instregex "^SPLATI_(B|H|W|D)$")>;
273*700637cbSDimitry Andric
274*700637cbSDimitry Andric  def I6400MSAShortLogic4 : SchedWriteRes<[I6400FPUShort]>;
275*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortLogic4],
276*700637cbSDimitry Andric               (instrs CTCMSA, CFCMSA, COPY_S_B, COPY_S_H, COPY_S_W, COPY_S_D,
277*700637cbSDimitry Andric                   COPY_U_B, COPY_U_H, COPY_U_W, BNZ_B, BNZ_H, BNZ_W, BNZ_D,
278*700637cbSDimitry Andric                   BNZ_V, BZ_B, BZ_H, BZ_W, BZ_D, BZ_V)>;
279*700637cbSDimitry Andric
280*700637cbSDimitry Andric  def I6400MSAMove : SchedWriteRes<[I6400FPUShort]> {
281*700637cbSDimitry Andric    let Latency = 3;
282*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
283*700637cbSDimitry Andric  }
284*700637cbSDimitry Andric  def : InstRW<[I6400MSAMove], (instrs LD_B, LD_H, LD_W, LD_D)>;
285*700637cbSDimitry Andric
286*700637cbSDimitry Andric  def I6400MSAMove2 : SchedWriteRes<[I6400FPUShort]> {
287*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
288*700637cbSDimitry Andric  }
289*700637cbSDimitry Andric  def : InstRW<[I6400MSAMove2], (instrs LDI_B, LDI_H, LDI_W, LDI_D, MOVE_V)>;
290*700637cbSDimitry Andric
291*700637cbSDimitry Andric  def I6400MSACmp : SchedWriteRes<[I6400FPUShort]> {
292*700637cbSDimitry Andric    let Latency = 2;
293*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
294*700637cbSDimitry Andric  }
295*700637cbSDimitry Andric  def : InstRW<[I6400MSACmp],
296*700637cbSDimitry Andric               (instrs FCAF_W, FCAF_D, FCUN_W, FCUN_D, FCOR_W, FCOR_D, FCEQ_W,
297*700637cbSDimitry Andric                   FCEQ_D, FCUNE_W, FCUNE_D, FCUEQ_W, FCUEQ_D, FCNE_W, FCNE_D,
298*700637cbSDimitry Andric                   FCLT_W, FCLT_D, FCULT_W, FCULT_D, FCLE_W, FCLE_D, FCULE_W,
299*700637cbSDimitry Andric                   FCULE_D, FSAF_W, FSAF_D, FSUN_W, FSUN_D, FSOR_W, FSOR_D,
300*700637cbSDimitry Andric                   FSEQ_W, FSEQ_D, FSUNE_W, FSUNE_D, FSUEQ_W, FSUEQ_D, FSNE_W,
301*700637cbSDimitry Andric                   FSNE_D, FSLT_W, FSLT_D, FSULT_W, FSULT_D, FSLE_W, FSLE_D,
302*700637cbSDimitry Andric                   FSULE_W, FSULE_D)>;
303*700637cbSDimitry Andric
304*700637cbSDimitry Andric  def I6400MSAShortFloat : SchedWriteRes<[I6400FPUShort]> {
305*700637cbSDimitry Andric    let Latency = 2;
306*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
307*700637cbSDimitry Andric  }
308*700637cbSDimitry Andric  def : InstRW<[I6400MSAShortFloat], (instrs FMAX_W, FMAX_D, FMAX_A_W, FMAX_A_D,
309*700637cbSDimitry Andric                                         FMIN_W, FMIN_D, FMIN_A_W, FMIN_A_D,
310*700637cbSDimitry Andric                                         FCLASS_W, FCLASS_D, FABS_D, FABS_W,
311*700637cbSDimitry Andric					 FABS_D32, FABS_D64)>;
312*700637cbSDimitry Andric  def I6400MSAFloatCompare : SchedWriteRes<[I6400FPUShort]> {
313*700637cbSDimitry Andric    let Latency = 2;
314*700637cbSDimitry Andric    let ReleaseAtCycles = [1];
315*700637cbSDimitry Andric  }
316*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_UN_(S|D)$")>;
317*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_UEQ_(S|D)$")>;
318*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_EQ_(S|D)$")>;
319*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_LT_(S|D)$")>;
320*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_ULT_(S|D)$")>;
321*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_LE_(S|D)$")>;
322*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_ULE_(S|D)$")>;
323*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_F_(D|S)$")>;
324*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SAF_(D|S)$")>;
325*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SEQ_(D|S)$")>;
326*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SLE_(D|S)$")>;
327*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SLT_(D|S)$")>;
328*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SUEQ_(D|S)$")>;
329*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SULE_(D|S)$")>;
330*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SULT_(D|S)$")>;
331*700637cbSDimitry Andric  def : InstRW<[I6400MSAFloatCompare], (instregex "^CMP_SUN_(D|S)$")>;
332*700637cbSDimitry Andric
333*700637cbSDimitry Andric  def I6400FPULongFloat : SchedWriteRes<[I6400FPULong]> { let Latency = 4; }
334*700637cbSDimitry Andric  def : InstRW<[I6400FPULongFloat],
335*700637cbSDimitry Andric               (instrs TRUNC_W_S, TRUNC_L_S, TRUNC_L_D64,
336*700637cbSDimitry Andric		   TRUNC_W_D32, TRUNC_W_D64, PseudoTRUNC_W_D,
337*700637cbSDimitry Andric		   PseudoTRUNC_W_D32, PseudoTRUNC_W_S,
338*700637cbSDimitry Andric		   ROUND_W_S, ROUND_L_S,
339*700637cbSDimitry Andric                   ROUND_L_D64, FLOOR_W_S, FLOOR_L_S, FLOOR_L_D64, CVT_D32_S,
340*700637cbSDimitry Andric                   CVT_D32_W, CVT_D64_W, CVT_D64_S, CVT_D64_L, CVT_L_S,
341*700637cbSDimitry Andric                   CVT_L_D64, CVT_S_W, CVT_S_D32, CVT_S_PU64, CVT_S_PL64,
342*700637cbSDimitry Andric                   CVT_S_L, CVT_S_D64, CVT_W_S, CEIL_W_S, CEIL_L_S,
343*700637cbSDimitry Andric                   CEIL_L_D64, FLOOR_W_D32, FLOOR_W_D64, CVT_W_D64, CVT_W_D32,
344*700637cbSDimitry Andric		   RINT_D, RINT_S, ROUND_W_D32, ROUND_W_D64,
345*700637cbSDimitry Andric		   CEIL_W_D32, CEIL_W_D64)>;
346*700637cbSDimitry Andric
347*700637cbSDimitry Andric  def I6400MSALongLogic1 : SchedWriteRes<[I6400FPULong]> {
348*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
349*700637cbSDimitry Andric  }
350*700637cbSDimitry Andric  def : InstRW<[I6400MSALongLogic1], (instrs BMZ_V, BMZI_B, BMNZ_V, BMNZI_B,
351*700637cbSDimitry Andric                                         INSERT_B, INSERT_H,
352*700637cbSDimitry Andric                                         INSERT_W, INSERT_D, INSVE_B, INSVE_H,
353*700637cbSDimitry Andric                                         INSVE_W, INSVE_D)>;
354*700637cbSDimitry Andric  def : InstRW<[I6400MSALongLogic1], (instregex "^(BSEL_V|BSELI_B)$")>;
355*700637cbSDimitry Andric  def : InstRW<[I6400MSALongLogic1],
356*700637cbSDimitry Andric             (instregex "^BSEL_(H|W|D|FW|FD)_PSEUDO$")>;
357*700637cbSDimitry Andric
358*700637cbSDimitry Andric  def I6400MSALongLogic2 : SchedWriteRes<[I6400FPULong]> {
359*700637cbSDimitry Andric    let Latency = 2;
360*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
361*700637cbSDimitry Andric  }
362*700637cbSDimitry Andric  def : InstRW<[I6400MSALongLogic2],
363*700637cbSDimitry Andric               (instrs BINSL_B, BINSL_H, BINSL_W, BINSL_D, BINSLI_B, BINSLI_H,
364*700637cbSDimitry Andric                   BINSLI_W, BINSLI_D, BINSR_B, BINSR_H, BINSR_W, BINSR_D,
365*700637cbSDimitry Andric                   BINSRI_B, BINSRI_H, BINSRI_W, BINSRI_D, VSHF_B, VSHF_H,
366*700637cbSDimitry Andric                   VSHF_W, VSHF_D, SLD_B, SLD_H, SLD_W, SLD_D, SLDI_B, SLDI_H,
367*700637cbSDimitry Andric                   SLDI_W, SLDI_D, BSET_B, BSET_H, BSET_W, BSET_D, BSETI_B,
368*700637cbSDimitry Andric                   BSETI_H, BSETI_W, BSETI_D)>;
369*700637cbSDimitry Andric
370*700637cbSDimitry Andric  def I6400MSAMult : SchedWriteRes<[I6400FPULong]> {
371*700637cbSDimitry Andric    let Latency = 5;
372*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
373*700637cbSDimitry Andric  }
374*700637cbSDimitry Andric  def : InstRW<[I6400MSAMult],
375*700637cbSDimitry Andric               (instrs MADDV_B, MADDV_H, MADDV_W, MADDV_D, MSUBV_B, MSUBV_H,
376*700637cbSDimitry Andric                   MSUBV_W, MSUBV_D, MULV_B, MULV_H, MULV_W, MULV_D, DOTP_S_H,
377*700637cbSDimitry Andric                   DOTP_S_W, DOTP_S_D, DOTP_U_H, DOTP_U_W, DOTP_U_D, MUL_Q_H,
378*700637cbSDimitry Andric                   MUL_Q_W, MULR_Q_H, MULR_Q_W, MSUB_Q_H, MSUB_Q_W, MSUBR_Q_H,
379*700637cbSDimitry Andric                   MSUBR_Q_W, MADD_Q_H, MADD_Q_W, MADDR_Q_H, MADDR_Q_W)>;
380*700637cbSDimitry Andric
381*700637cbSDimitry Andric  def I6400MSALongFloat2 : SchedWriteRes<[I6400FPULong]> {
382*700637cbSDimitry Andric    let Latency = 2;
383*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
384*700637cbSDimitry Andric  }
385*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloat2], (instrs FLOG2_W, FLOG2_D)>;
386*700637cbSDimitry Andric
387*700637cbSDimitry Andric  def I6400MSALongFloat4 : SchedWriteRes<[I6400FPULong]> {
388*700637cbSDimitry Andric    let Latency = 4;
389*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
390*700637cbSDimitry Andric  }
391*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloat4],
392*700637cbSDimitry Andric               (instrs FADD_W, FADD_D, FSUB_W, FSUB_D, FEXDO_H, FEXDO_W,
393*700637cbSDimitry Andric                   FEXUPL_W, FEXUPL_D, FEXUPR_W, FEXUPR_D, FFINT_S_W, FFINT_S_D,
394*700637cbSDimitry Andric                   FFINT_U_W, FFINT_U_D, FFQL_W, FFQL_D, FFQR_W, FFQR_D,
395*700637cbSDimitry Andric                   FTINT_S_W, FTINT_S_D, FTINT_U_W, FTINT_U_D, FTRUNC_S_W,
396*700637cbSDimitry Andric                   FTRUNC_S_D, FTRUNC_U_W, FTRUNC_U_D, FTQ_H, FTQ_W, FRINT_W,
397*700637cbSDimitry Andric                   FRINT_D, FADD_D32, FADD_D64)>;
398*700637cbSDimitry Andric
399*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloat4], (instregex "^PseudoCVT_(S|D32|D64)_(L|W)$")>;
400*700637cbSDimitry Andric
401*700637cbSDimitry Andric  def I6400MSALongFloat5 : SchedWriteRes<[I6400FPULong]> {
402*700637cbSDimitry Andric    let Latency = 5;
403*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
404*700637cbSDimitry Andric  }
405*700637cbSDimitry Andric
406*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloat5],
407*700637cbSDimitry Andric               (instrs FMUL_W, FMUL_D, FEXP2_W, FEXP2_D, DPADD_S_H, DPADD_S_W,
408*700637cbSDimitry Andric                   DPADD_S_D, DPADD_U_H, DPADD_U_W, DPADD_U_D, DPSUB_S_H,
409*700637cbSDimitry Andric                   DPSUB_S_W, DPSUB_S_D, DPSUB_U_H, DPSUB_U_W, DPSUB_U_D)>;
410*700637cbSDimitry Andric
411*700637cbSDimitry Andric  def I6400MSALongFloat8 : SchedWriteRes<[I6400FPULong]> {
412*700637cbSDimitry Andric    let Latency = 8;
413*700637cbSDimitry Andric    let ReleaseAtCycles = [2];
414*700637cbSDimitry Andric  }
415*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloat8], (instrs FMADD_W, FMADD_D, FMSUB_W,
416*700637cbSDimitry Andric                                         FMSUB_D)>;
417*700637cbSDimitry Andric
418*700637cbSDimitry Andric  def I6400MSALongFloatFuse : SchedWriteRes<[I6400FPULong]> {
419*700637cbSDimitry Andric    let Latency = 8;
420*700637cbSDimitry Andric    let ReleaseAtCycles = [1];
421*700637cbSDimitry Andric  }
422*700637cbSDimitry Andric  def : InstRW<[I6400MSALongFloatFuse], (instrs MSUBF_D, MSUBF_S,
423*700637cbSDimitry Andric					 MADDF_D, MADDF_S)>;
424*700637cbSDimitry Andric
425*700637cbSDimitry Andric  def I6400MSADivD : SchedWriteRes<[I6400FPULong, I6400FPUFloatL]> {
426*700637cbSDimitry Andric    let Latency = 30;
427*700637cbSDimitry Andric    let ReleaseAtCycles = [1, 29];
428*700637cbSDimitry Andric  }
429*700637cbSDimitry Andric  def : InstRW<[I6400MSADivD], (instrs FDIV_D)>;
430*700637cbSDimitry Andric
431*700637cbSDimitry Andric  def I6400MSADivW : SchedWriteRes<[I6400FPULong, I6400FPUFloatL]> {
432*700637cbSDimitry Andric    let Latency = 22;
433*700637cbSDimitry Andric    let ReleaseAtCycles = [1, 21];
434*700637cbSDimitry Andric  }
435*700637cbSDimitry Andric  def : InstRW<[I6400MSADivW], (instrs FDIV_W)>;
436*700637cbSDimitry Andric
437*700637cbSDimitry Andric  // Atomic instructions
438*700637cbSDimitry Andric
439*700637cbSDimitry Andric  // FIXME: Define `WriteAtomic` in the MipsSchedule.td and
440*700637cbSDimitry Andric  // attach it to the Atomic2OpsPostRA, AtomicCmpSwapPostRA, ...
441*700637cbSDimitry Andric  // classes. Then just define resources for the `WriteAtomic` in each
442*700637cbSDimitry Andric  // machine models.
443*700637cbSDimitry Andric  def I6400WriteAtomic : SchedWriteRes<[I6400Atomic]> { let Latency = 2; }
444*700637cbSDimitry Andric
445*700637cbSDimitry Andric  def : InstRW<[I6400WriteAtomic],
446*700637cbSDimitry Andric      (instregex "^ATOMIC_SWAP_I(8|16|32|64)_POSTRA$")>;
447*700637cbSDimitry Andric  def : InstRW<[I6400WriteAtomic],
448*700637cbSDimitry Andric      (instregex "^ATOMIC_CMP_SWAP_I(8|16|32|64)_POSTRA$")>;
449*700637cbSDimitry Andric  def : InstRW<[I6400WriteAtomic],
450*700637cbSDimitry Andric      (instregex "^ATOMIC_LOAD_(ADD|SUB|AND|OR|XOR|NAND|MIN|MAX|UMIN|UMAX)"
451*700637cbSDimitry Andric               "_I(8|16|32|64)_POSTRA$")>;
452*700637cbSDimitry Andric}
453