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