xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMScheduleM55.td (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1*bdd1243dSDimitry Andric//==- ARMScheduleM55.td - Arm Cortex-M55 Scheduling Definitions -*- tablegen -*-=//
2*bdd1243dSDimitry Andric//
3*bdd1243dSDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bdd1243dSDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*bdd1243dSDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bdd1243dSDimitry Andric//
7*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
8*bdd1243dSDimitry Andric//
9*bdd1243dSDimitry Andric// This file defines the scheduling model for the Arm Cortex-M55 processors.
10*bdd1243dSDimitry Andric//
11*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
12*bdd1243dSDimitry Andric
13*bdd1243dSDimitry Andric// ===---------------------------------------------------------------------===//
14*bdd1243dSDimitry Andric// Cortex-M55 is a lot like the M4/M33 in terms of scheduling. It technically
15*bdd1243dSDimitry Andric// has an extra pipeline stage but that is unimportant for scheduling, just
16*bdd1243dSDimitry Andric// starting our model a stage later. The main points of interest over an
17*bdd1243dSDimitry Andric// Cortex-M4 are MVE instructions and the ability to dual issue thumb1
18*bdd1243dSDimitry Andric// instructions.
19*bdd1243dSDimitry Andric//
20*bdd1243dSDimitry Andric//
21*bdd1243dSDimitry Andric// MVE
22*bdd1243dSDimitry Andric//
23*bdd1243dSDimitry Andric// The EPU pipelines now include both MVE and FP instructions. It has four
24*bdd1243dSDimitry Andric// pipelines across 4 stages (E1-E4). These pipelines are "control",
25*bdd1243dSDimitry Andric// "load/store", "integer" and "float/mul". We start the schedule at E2 to line
26*bdd1243dSDimitry Andric// up with the rest of the pipeline we model, and take the latency as the time
27*bdd1243dSDimitry Andric// between reading registers (almost always in E2) and register write (or
28*bdd1243dSDimitry Andric// forward, if it allows it). This mean that a lot of instructions (including
29*bdd1243dSDimitry Andric// loads) actually take 1 cycle (amazingly).
30*bdd1243dSDimitry Andric//
31*bdd1243dSDimitry Andric// Each MVE instruction needs to take 2 beats, each performing 64bits of the
32*bdd1243dSDimitry Andric// 128bit vector operation. So long as the beats are to different pipelines,
33*bdd1243dSDimitry Andric// the execution of the first-beat-of-the-second-instruction can overlap with
34*bdd1243dSDimitry Andric// the second-beat-of-the-first. For example a sequence of VLDR;VADD;VMUL;VSTR
35*bdd1243dSDimitry Andric// can look like this is a pipeline:
36*bdd1243dSDimitry Andric//          1    2    3    4    5
37*bdd1243dSDimitry Andric// LD/ST  : VLDR VLDR      VSTR VSTR
38*bdd1243dSDimitry Andric// INTEGER:      VADD VADD
39*bdd1243dSDimitry Andric// FP/MUL :           VMUL VMUL
40*bdd1243dSDimitry Andric//
41*bdd1243dSDimitry Andric// But a sequence of VLDR;VLDRB;VADD;VSTR because the loads cannot overlap,
42*bdd1243dSDimitry Andric// looks like:
43*bdd1243dSDimitry Andric//          1     2     3     4     5    6
44*bdd1243dSDimitry Andric// LD/ST  : VLDR  VLDR  VLDRB VLDRB VSTR VSTR
45*bdd1243dSDimitry Andric// INTEGER:                   VADD  VADD
46*bdd1243dSDimitry Andric//
47*bdd1243dSDimitry Andric// For this schedule, we currently model latencies and pipelines well for each
48*bdd1243dSDimitry Andric// instruction. MVE instruction take two beats, modelled using
49*bdd1243dSDimitry Andric// ResourceCycles=[2].
50*bdd1243dSDimitry Andric//
51*bdd1243dSDimitry Andric//
52*bdd1243dSDimitry Andric// Dual Issue
53*bdd1243dSDimitry Andric//
54*bdd1243dSDimitry Andric// Cortex-M55 can dual issue two 16-bit T1 instructions providing one is one of
55*bdd1243dSDimitry Andric// NOPs, ITs, Brs, ADDri/SUBri, UXTB/H, SXTB/H and MOVri's. NOPs and IT's are
56*bdd1243dSDimitry Andric// not relevant (they will not appear when scheduling), Brs are only at the end
57*bdd1243dSDimitry Andric// of the block. The others are more useful, and where the problems arise.
58*bdd1243dSDimitry Andric//
59*bdd1243dSDimitry Andric// The first problem comes from the fact that we will only be seeing Thumb2
60*bdd1243dSDimitry Andric// instructions at the point in the pipeline where we do the scheduling. The
61*bdd1243dSDimitry Andric// Thumb2SizeReductionPass has not been run yet. Especially pre-ra scheduling
62*bdd1243dSDimitry Andric// (where the scheduler has the most freedom) we can only really guess at which
63*bdd1243dSDimitry Andric// instructions will become thumb1 instructions. We are quite optimistic, and
64*bdd1243dSDimitry Andric// may get some things wrong as a result.
65*bdd1243dSDimitry Andric//
66*bdd1243dSDimitry Andric// The other problem is one of telling llvm what to do exactly. The way we
67*bdd1243dSDimitry Andric// attempt to meld this is:
68*bdd1243dSDimitry Andric//  Set IssueWidth to 2 to allow 2 instructions per cycle.
69*bdd1243dSDimitry Andric//  All instructions we cannot dual issue are "SingleIssue=1" (MVE/FP and T2
70*bdd1243dSDimitry Andric//    instructions)
71*bdd1243dSDimitry Andric//  We guess at another set of instructions that will become T1 instruction.
72*bdd1243dSDimitry Andric//    These become the primary instruction in a dual issue pair (the normal
73*bdd1243dSDimitry Andric//    one). These use normal resources and latencies, but set SingleIssue = 0.
74*bdd1243dSDimitry Andric//  We guess at another set of instructions that will be shrank down into T1 DI
75*bdd1243dSDimitry Andric//    instructions (add, sub, mov's, etc), which become the secondary. These
76*bdd1243dSDimitry Andric//    don't use a resource, and set SingleIssue = 0.
77*bdd1243dSDimitry Andric//
78*bdd1243dSDimitry Andric// So our guessing is a bit rough. It may be possible to improve this by moving
79*bdd1243dSDimitry Andric// T2SizeReduction pass earlier in the pipeline, for example, so that at least
80*bdd1243dSDimitry Andric// Post-RA scheduling sees what is T1/T2. It may also be possible to write a
81*bdd1243dSDimitry Andric// custom instruction matcher for more accurately guess at T1 instructions.
82*bdd1243dSDimitry Andric
83*bdd1243dSDimitry Andric
84*bdd1243dSDimitry Andricdef CortexM55Model : SchedMachineModel {
85*bdd1243dSDimitry Andric  let MicroOpBufferSize = 0;      // Explicitly set to zero since M55 is in-order.
86*bdd1243dSDimitry Andric  let IssueWidth = 2;             // There is some dual-issue support in M55.
87*bdd1243dSDimitry Andric  let MispredictPenalty = 3;      // Default is 10
88*bdd1243dSDimitry Andric  let LoadLatency = 4;            // Default is 4
89*bdd1243dSDimitry Andric  let PostRAScheduler = 1;
90*bdd1243dSDimitry Andric  let FullInstRWOverlapCheck = 1;
91*bdd1243dSDimitry Andric
92*bdd1243dSDimitry Andric  let CompleteModel = 0;
93*bdd1243dSDimitry Andric  let UnsupportedFeatures = [IsARM, HasNEON, HasDotProd, HasMatMulInt8, HasZCZ,
94*bdd1243dSDimitry Andric                             IsNotMClass, HasV8, HasV8_3a, HasTrustZone, HasDFB,
95*bdd1243dSDimitry Andric                             IsWindows];
96*bdd1243dSDimitry Andric}
97*bdd1243dSDimitry Andric
98*bdd1243dSDimitry Andric
99*bdd1243dSDimitry Andriclet SchedModel = CortexM55Model in {
100*bdd1243dSDimitry Andric
101*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
102*bdd1243dSDimitry Andric// Define each kind of processor resource and number available.
103*bdd1243dSDimitry Andric
104*bdd1243dSDimitry Andric// Modeling each pipeline as a ProcResource using the BufferSize = 0 since
105*bdd1243dSDimitry Andric// M55 is in-order.
106*bdd1243dSDimitry Andricdef M55UnitALU : ProcResource<1> { let BufferSize = 0; } // Int ALU
107*bdd1243dSDimitry Andricdef M55UnitVecALU : ProcResource<1> { let BufferSize = 0; } // MVE integer pipe
108*bdd1243dSDimitry Andricdef M55UnitVecFPALU : ProcResource<1> { let BufferSize = 0; } // MVE float pipe
109*bdd1243dSDimitry Andricdef M55UnitLoadStore : ProcResource<1> { let BufferSize = 0; } // MVE load/store pipe
110*bdd1243dSDimitry Andricdef M55UnitVecSys : ProcResource<1> { let BufferSize = 0; } // MVE control/sys pipe
111*bdd1243dSDimitry Andric
112*bdd1243dSDimitry Andric// Some VMOV's can go down either pipeline. FIXME: This M55Write2IntFPE2 is
113*bdd1243dSDimitry Andric// intended to model the VMOV taking either Int or FP for 2 cycles. It is not
114*bdd1243dSDimitry Andric// clear if the llvm scheduler is using it like we want though.
115*bdd1243dSDimitry Andricdef M55UnitVecIntFP: ProcResGroup<[M55UnitVecALU, M55UnitVecFPALU]>;
116*bdd1243dSDimitry Andric
117*bdd1243dSDimitry Andric
118*bdd1243dSDimitry Andric//===----------------------------------------------------------------------===//
119*bdd1243dSDimitry Andric// Subtarget-specific SchedWrite types which both map the ProcResources and
120*bdd1243dSDimitry Andric// set the latency.
121*bdd1243dSDimitry Andric
122*bdd1243dSDimitry Andric//=====//
123*bdd1243dSDimitry Andric// ALU //
124*bdd1243dSDimitry Andric//=====//
125*bdd1243dSDimitry Andric
126*bdd1243dSDimitry Andric// Generic writes for Flags, GRPs and other extra operands (eg post-inc, vadc flags, vaddlv etc)
127*bdd1243dSDimitry Andricdef M55WriteLat0  : SchedWriteRes<[]>  { let Latency = 0; let NumMicroOps = 0; }
128*bdd1243dSDimitry Andricdef M55WriteLat1  : SchedWriteRes<[]>  { let Latency = 1; let NumMicroOps = 0; }
129*bdd1243dSDimitry Andricdef M55WriteLat2  : SchedWriteRes<[]>  { let Latency = 2; let NumMicroOps = 0; }
130*bdd1243dSDimitry Andric
131*bdd1243dSDimitry Andric// DX instructions are ALU instructions that take a single cycle. The
132*bdd1243dSDimitry Andric// instructions that may be shrank to T1 (and can be dual issued) are
133*bdd1243dSDimitry Andric// SingleIssue = 0. The others are SingleIssue = 1.
134*bdd1243dSDimitry Andriclet SingleIssue = 0, Latency = 1 in {
135*bdd1243dSDimitry Andric    def : WriteRes<WriteALU, [M55UnitALU]>;
136*bdd1243dSDimitry Andric    def : WriteRes<WriteCMP, [M55UnitALU]>;
137*bdd1243dSDimitry Andric    def : WriteRes<WriteBr, [M55UnitALU]>;
138*bdd1243dSDimitry Andric    def : WriteRes<WriteBrL, [M55UnitALU]>;
139*bdd1243dSDimitry Andric    def : WriteRes<WriteBrTbl, [M55UnitALU]>;
140*bdd1243dSDimitry Andric    def : WriteRes<WriteST, [M55UnitALU]>;
141*bdd1243dSDimitry Andric    def M55WriteDX_DI : SchedWriteRes<[M55UnitALU]>;
142*bdd1243dSDimitry Andric}
143*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 1 in {
144*bdd1243dSDimitry Andric    def : WriteRes<WritePreLd, [M55UnitALU]>;
145*bdd1243dSDimitry Andric    def M55WriteDX_SI : SchedWriteRes<[M55UnitALU]>;
146*bdd1243dSDimitry Andric}
147*bdd1243dSDimitry Andric
148*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_SI], (instregex "t2BF[CI]", "t2CPS", "t2DBG",
149*bdd1243dSDimitry Andric          "t2MRS", "t2MSR", "t2SEL", "t2SG", "t2TT")>;
150*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_SI], (instregex "t2SUBS_PC_LR", "COPY")>;
151*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_SI], (instregex "t2CS(EL|INC|INV|NEG)")>;
152*bdd1243dSDimitry Andric// Thumb 2 instructions that could be reduced to a thumb 1 instruction and can
153*bdd1243dSDimitry Andric// be dual issued with one of the above. This list is optimistic.
154*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_DI], (instregex "t2ADDC?rr$", "t2ADDrr$",
155*bdd1243dSDimitry Andric           "t2ADDSrr$", "t2ANDrr$", "t2ASRr[ir]$", "t2BICrr$", "t2CMNzrr$",
156*bdd1243dSDimitry Andric           "t2CMPr[ir]$", "t2EORrr$", "t2LSLr[ir]$", "t2LSRr[ir]$", "t2MVNr$",
157*bdd1243dSDimitry Andric           "t2ORRrr$", "t2REV(16|SH)?$", "t2RORrr$", "t2RSBr[ir]$", "t2RSBSri$",
158*bdd1243dSDimitry Andric           "t2SBCrr$", "t2SUBS?rr$", "t2TEQrr$", "t2TSTrr$", "t2STRi12$",
159*bdd1243dSDimitry Andric           "t2STRs$", "t2STRBi12$", "t2STRBs$", "t2STRHi12$", "t2STRHs$",
160*bdd1243dSDimitry Andric           "t2STR_POST$", "t2STMIA$", "t2STMIA_UPD$", "t2STMDB$", "t2STMDB_UPD$")>;
161*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_DI], (instregex "t2SETPAN$", "tADC$", "tADDhirr$",
162*bdd1243dSDimitry Andric           "tADDrSP$", "tADDrSPi$", "tADDrr$", "tADDspi$", "tADDspr$", "tADR$",
163*bdd1243dSDimitry Andric           "tAND$", "tASRri$", "tASRrr$", "tBIC$", "tBKPT$", "tCBNZ$", "tCBZ$",
164*bdd1243dSDimitry Andric           "tCMNz$", "tCMPhir$", "tCMPi8$", "tCMPr$", "tCPS$", "tEOR$", "tHINT$",
165*bdd1243dSDimitry Andric           "tHLT$", "tLSLri$", "tLSLrr$", "tLSRri$", "tLSRrr$", "tMOVSr$",
166*bdd1243dSDimitry Andric           "tMUL$", "tMVN$", "tORR$", "tPICADD$", "tPOP$", "tPUSH$", "tREV$",
167*bdd1243dSDimitry Andric           "tREV16$", "tREVSH$", "tROR$", "tRSB$", "tSBC$", "tSETEND$",
168*bdd1243dSDimitry Andric           "tSTMIA_UPD$", "tSTRBi$", "tSTRBr$", "tSTRHi$", "tSTRHr$", "tSTRi$",
169*bdd1243dSDimitry Andric           "tSTRr$", "tSTRspi$", "tSUBrr$", "tSUBspi$", "tSVC$", "tTRAP$",
170*bdd1243dSDimitry Andric           "tTST$", "tUDF$")>;
171*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDX_DI], (instregex "tB$", "tBLXNSr$", "tBLXr$", "tBX$",
172*bdd1243dSDimitry Andric           "tBXNS$", "tBcc$")>;
173*bdd1243dSDimitry Andric
174*bdd1243dSDimitry Andric
175*bdd1243dSDimitry Andric// CX instructions take 2 (or more) cycles. Again T1 instructions may be dual
176*bdd1243dSDimitry Andric// issues (SingleIssue = 0)
177*bdd1243dSDimitry Andriclet SingleIssue = 0, Latency = 2 in {
178*bdd1243dSDimitry Andric    def : WriteRes<WriteLd, [M55UnitALU]>;
179*bdd1243dSDimitry Andric    def M55WriteCX_DI  : SchedWriteRes<[M55UnitALU]>;
180*bdd1243dSDimitry Andric}
181*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 2 in {
182*bdd1243dSDimitry Andric    def : WriteRes<WriteALUsi, [M55UnitALU]>;
183*bdd1243dSDimitry Andric    def : WriteRes<WriteALUsr, [M55UnitALU]>;
184*bdd1243dSDimitry Andric    def : WriteRes<WriteALUSsr, [M55UnitALU]>;
185*bdd1243dSDimitry Andric    def : WriteRes<WriteCMPsi, [M55UnitALU]>;
186*bdd1243dSDimitry Andric    def : WriteRes<WriteCMPsr, [M55UnitALU]>;
187*bdd1243dSDimitry Andric    def : WriteRes<WriteDIV, [M55UnitALU]>;
188*bdd1243dSDimitry Andric    def M55WriteCX_SI  : SchedWriteRes<[M55UnitALU]>;
189*bdd1243dSDimitry Andric}
190*bdd1243dSDimitry Andric
191*bdd1243dSDimitry Andricdef : SchedAlias<WriteMUL16, M55WriteCX_SI>;
192*bdd1243dSDimitry Andricdef : SchedAlias<WriteMUL32, M55WriteCX_SI>;
193*bdd1243dSDimitry Andricdef : SchedAlias<WriteMUL64Lo, M55WriteCX_SI>;
194*bdd1243dSDimitry Andricdef : WriteRes<WriteMUL64Hi, []> { let Latency = 2; }
195*bdd1243dSDimitry Andricdef : SchedAlias<WriteMAC16, M55WriteCX_SI>;
196*bdd1243dSDimitry Andricdef : SchedAlias<WriteMAC32, M55WriteCX_SI>;
197*bdd1243dSDimitry Andricdef : SchedAlias<WriteMAC64Lo, M55WriteCX_SI>;
198*bdd1243dSDimitry Andricdef : WriteRes<WriteMAC64Hi, []> { let Latency = 2; }
199*bdd1243dSDimitry Andric
200*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI], (instregex "t2CDP", "t2CLREX", "t2[DI][MS]B",
201*bdd1243dSDimitry Andric           "t2MCR", "t2MOVSs[ir]", "t2MRC", "t2MUL", "t2STC")>;
202*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI], (instregex "t2Q", "t2[SU](ADD|ASX|BFX|DIV)",
203*bdd1243dSDimitry Andric           "t2[SU]H(ADD|ASX|SUB|SAX)", "t2SM[LM]", "t2S(SAT|SUB|SAX)", "t2UQ",
204*bdd1243dSDimitry Andric           "t2USA", "t2USUB", "t2UXTA[BH]")>;
205*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI], (instregex "t2LD[AC]", "t2STL", "t2STRD")>;
206*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI], (instregex "MVE_[SU]Q?R?SH[LR]$")>;
207*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI, M55WriteLat2], (instregex "MVE_ASRL", "MVE_LSLL",
208*bdd1243dSDimitry Andric            "MVE_LSRL", "MVE_[SU]Q?R?SH[LR]L")>;
209*bdd1243dSDimitry Andric// This may be higher in practice, but that likely doesn't make a difference
210*bdd1243dSDimitry Andric// for scheduling
211*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_SI], (instregex "t2CLRM")>;
212*bdd1243dSDimitry Andric
213*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_DI], (instregex "t2LDR[BH]?i12$", "t2LDRS?[BH]?s$",
214*bdd1243dSDimitry Andric           "t2LDM")>;
215*bdd1243dSDimitry Andricdef : InstRW<[M55WriteCX_DI], (instregex "tLDM", "tLDRBi$", "tLDRBr$",
216*bdd1243dSDimitry Andric           "tLDRHi$", "tLDRHr$", "tLDRSB$", "tLDRSH$", "tLDRi$", "tLDRpci$",
217*bdd1243dSDimitry Andric           "tLDRr$", "tLDRspi$")>;
218*bdd1243dSDimitry Andric
219*bdd1243dSDimitry Andric// Dual Issue instructions
220*bdd1243dSDimitry Andriclet Latency = 1, SingleIssue = 0 in {
221*bdd1243dSDimitry Andric    def : WriteRes<WriteNoop, []>;
222*bdd1243dSDimitry Andric    def M55WriteDI : SchedWriteRes<[]>;
223*bdd1243dSDimitry Andric}
224*bdd1243dSDimitry Andric
225*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDI], (instregex "tADDi[38]$", "tSUBi[38]$", "tMOVi8$",
226*bdd1243dSDimitry Andric           "tMOVr$", "tUXT[BH]$", "tSXT[BH]$")>;
227*bdd1243dSDimitry Andric// Thumb 2 instructions that could be reduced to a dual issuable Thumb 1
228*bdd1243dSDimitry Andric// instruction above.
229*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDI], (instregex "t2ADDS?ri$", "t2MOV[ir]$", "t2MOVi16$",
230*bdd1243dSDimitry Andric           "t2MOVr$", "t2SUBS?ri$", "t2[US]XT[BH]$")>;
231*bdd1243dSDimitry Andricdef : InstRW<[M55WriteDI], (instregex "t2IT", "IT")>;
232*bdd1243dSDimitry Andric
233*bdd1243dSDimitry Andric
234*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLat0], (instregex "t2LoopDec")>;
235*bdd1243dSDimitry Andric
236*bdd1243dSDimitry Andric// Forwarding
237*bdd1243dSDimitry Andric
238*bdd1243dSDimitry Andric// No forwarding in the ALU normally
239*bdd1243dSDimitry Andricdef : ReadAdvance<ReadALU, 0>;
240*bdd1243dSDimitry Andricdef : ReadAdvance<ReadALUsr, 0>;
241*bdd1243dSDimitry Andricdef : ReadAdvance<ReadMUL, 0>;
242*bdd1243dSDimitry Andricdef : ReadAdvance<ReadMAC, 0>;
243*bdd1243dSDimitry Andric
244*bdd1243dSDimitry Andric//=============//
245*bdd1243dSDimitry Andric// MVE and VFP //
246*bdd1243dSDimitry Andric//=============//
247*bdd1243dSDimitry Andric
248*bdd1243dSDimitry Andric// The Writes that take ResourceCycles=[2] are MVE instruction, the others VFP.
249*bdd1243dSDimitry Andric
250*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 1 in {
251*bdd1243dSDimitry Andric  def M55WriteLSE2 : SchedWriteRes<[M55UnitLoadStore]>;
252*bdd1243dSDimitry Andric  def M55WriteIntE2 : SchedWriteRes<[M55UnitVecALU]>;
253*bdd1243dSDimitry Andric  def M55WriteFloatE2 : SchedWriteRes<[M55UnitVecFPALU]>;
254*bdd1243dSDimitry Andric  def M55WriteSysE2 : SchedWriteRes<[M55UnitVecSys]>;
255*bdd1243dSDimitry Andric
256*bdd1243dSDimitry Andric  def M55Write2LSE2 : SchedWriteRes<[M55UnitLoadStore]> { let ResourceCycles=[2]; }
257*bdd1243dSDimitry Andric  def M55Write2IntE2 : SchedWriteRes<[M55UnitVecALU]> { let ResourceCycles=[2]; }
258*bdd1243dSDimitry Andric  def M55Write2FloatE2 : SchedWriteRes<[M55UnitVecFPALU]> { let ResourceCycles=[2]; }
259*bdd1243dSDimitry Andric  def M55Write2IntFPE2 : SchedWriteRes<[M55UnitVecIntFP]> { let ResourceCycles=[2]; }
260*bdd1243dSDimitry Andric}
261*bdd1243dSDimitry Andric
262*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 2 in {
263*bdd1243dSDimitry Andric  def M55WriteLSE3 : SchedWriteRes<[M55UnitLoadStore]>;
264*bdd1243dSDimitry Andric  def M55WriteIntE3 : SchedWriteRes<[M55UnitVecALU]>;
265*bdd1243dSDimitry Andric  def M55WriteFloatE3 : SchedWriteRes<[M55UnitVecFPALU]>;
266*bdd1243dSDimitry Andric
267*bdd1243dSDimitry Andric  def M55Write2LSE3 : SchedWriteRes<[M55UnitLoadStore]> { let ResourceCycles=[2]; }
268*bdd1243dSDimitry Andric  def M55Write2IntE3 : SchedWriteRes<[M55UnitVecALU]> { let ResourceCycles=[2]; }
269*bdd1243dSDimitry Andric  def M55Write2FloatE3 : SchedWriteRes<[M55UnitVecFPALU]> { let ResourceCycles=[2]; }
270*bdd1243dSDimitry Andric}
271*bdd1243dSDimitry Andric
272*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 3 in {
273*bdd1243dSDimitry Andric  def M55Write2IntE3Plus1 : SchedWriteRes<[M55UnitVecALU]> { let ResourceCycles=[2]; }
274*bdd1243dSDimitry Andric
275*bdd1243dSDimitry Andric  // Same as M55Write2IntE3/M55Write2FloatE3 above, but longer latency and no forwarding into stores
276*bdd1243dSDimitry Andric  def M55Write2IntE4NoFwd : SchedWriteRes<[M55UnitVecALU]> { let ResourceCycles=[2]; }
277*bdd1243dSDimitry Andric  def M55Write2FloatE4NoFwd : SchedWriteRes<[M55UnitVecFPALU]> { let ResourceCycles=[2]; }
278*bdd1243dSDimitry Andric}
279*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 4 in {
280*bdd1243dSDimitry Andric  def M55Write2IntE3Plus2 : SchedWriteRes<[M55UnitVecALU]> { let ResourceCycles=[2]; }
281*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus2 : SchedWriteRes<[M55UnitVecFPALU]>;
282*bdd1243dSDimitry Andric}
283*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 9 in {
284*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus7 : SchedWriteRes<[M55UnitVecFPALU]>;
285*bdd1243dSDimitry Andric}
286*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 15 in {
287*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus13 : SchedWriteRes<[M55UnitVecFPALU]>;
288*bdd1243dSDimitry Andric}
289*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 16 in {
290*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus14 : SchedWriteRes<[M55UnitVecFPALU]>;
291*bdd1243dSDimitry Andric}
292*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 21 in {
293*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus19 : SchedWriteRes<[M55UnitVecFPALU]>;
294*bdd1243dSDimitry Andric}
295*bdd1243dSDimitry Andric// VMUL (Double precision) + VADD (Double precision)
296*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 24 in {
297*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus22 : SchedWriteRes<[M55UnitVecFPALU]>;
298*bdd1243dSDimitry Andric}
299*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 30 in {
300*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus28 : SchedWriteRes<[M55UnitVecFPALU]>;
301*bdd1243dSDimitry Andric}
302*bdd1243dSDimitry Andriclet SingleIssue = 1, Latency = 36 in {
303*bdd1243dSDimitry Andric  def M55WriteFloatE3Plus34 : SchedWriteRes<[M55UnitVecFPALU]>;
304*bdd1243dSDimitry Andric}
305*bdd1243dSDimitry Andric
306*bdd1243dSDimitry Andricdef M55Read0 : SchedReadAdvance<0>;
307*bdd1243dSDimitry Andricdef M55Read1 : SchedReadAdvance<1, [M55Write2LSE3, M55Write2IntE3, M55Write2FloatE3]>;
308*bdd1243dSDimitry Andricdef M55GatherQRead : SchedReadAdvance<-4>;
309*bdd1243dSDimitry Andric
310*bdd1243dSDimitry Andric// MVE instructions
311*bdd1243dSDimitry Andric
312*bdd1243dSDimitry Andric// Loads and Stores of different kinds
313*bdd1243dSDimitry Andric
314*bdd1243dSDimitry Andric// Normal loads
315*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2], (instregex "MVE_VLDR(B|H|W)(S|U)(8|16|32)$")>;
316*bdd1243dSDimitry Andric// Pre/post inc loads
317*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLat1, M55Write2LSE2], (instregex "MVE_VLDR(B|H|W)(S|U)(8|16|32)_(post|pre)$")>;
318*bdd1243dSDimitry Andric// Gather loads
319*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE3, M55Read0, M55GatherQRead], (instregex "MVE_VLDR(B|H|W|D)(S|U)(8|16|32|64)_rq")>;
320*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE3, M55GatherQRead], (instregex "MVE_VLDR(B|H|W|D)(S|U)(8|16|32|64)_qi$")>;
321*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLat1, M55Write2LSE3, M55GatherQRead], (instregex "MVE_VLDR(W|D)U(32|64)_qi_pre$")>;
322*bdd1243dSDimitry Andric// Interleaving loads
323*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2], (instregex "MVE_VLD[24][0-3]_(8|16|32)$")>;
324*bdd1243dSDimitry Andric// Interleaving loads with wb
325*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2, M55WriteLat1], (instregex "MVE_VLD[24][0-3]_(8|16|32)_wb$")>;
326*bdd1243dSDimitry Andric
327*bdd1243dSDimitry Andric// Normal stores
328*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2, M55Read1], (instregex "MVE_VSTR(B|H|W)U?(8|16|32)$")>;
329*bdd1243dSDimitry Andric// Pre/post inc stores
330*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2, M55Read1], (instregex "MVE_VSTR(B|H|W)U?(8|16|32)_(post|pre)$")>;
331*bdd1243dSDimitry Andric// Scatter stores
332*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2, M55Read0, M55Read0, M55GatherQRead], (instregex "MVE_VSTR(B|H|W|D)(8|16|32|64)_rq")>;
333*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2, M55Read0, M55GatherQRead], (instregex "MVE_VSTR(B|H|W|D)(8|16|32|64)_qi")>;
334*bdd1243dSDimitry Andric// Interleaving stores
335*bdd1243dSDimitry Andricdef : InstRW<[M55Write2LSE2], (instregex "MVE_VST(2|4)")>;
336*bdd1243dSDimitry Andric
337*bdd1243dSDimitry Andric// Integer pipe operations
338*bdd1243dSDimitry Andric
339*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3Plus1], (instregex "MVE_VABAV")>;
340*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VABD(u|s)")>;
341*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VABS(u|s)")>;
342*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_VADC")>;
343*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VADD(_qr_)?i")>;
344*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VAND")>;
345*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VBIC")>;
346*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VBRSR")>;
347*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VCADDi")>;
348*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VCLS")>;
349*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VCLZ")>;
350*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_V(D|I)?W?DUP")>;
351*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VEOR")>;
352*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VHADD")>;
353*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VHCADD")>;
354*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VHSUB")>;
355*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_V(MAX|MIN)A?(s|u)")>;
356*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_V(MAX|MIN)A?V(s|u)8")>;
357*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3Plus1], (instregex "MVE_V(MAX|MIN)A?V(s|u)16")>;
358*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3Plus2], (instregex "MVE_V(MAX|MIN)A?V(s|u)32")>;
359*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE4NoFwd], (instregex "MVE_VMOVN")>;
360*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VMOVL")>;
361*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_VMULL[BT]p")>;
362*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VMVN")>;
363*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VNEG(u|s)")>;
364*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VORN")>;
365*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VORR")>;
366*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VPSEL")>;
367*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MQPRCopy")>;
368*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VQABS")>;
369*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VQADD")>;
370*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE4NoFwd], (instregex "MVE_VQMOV")>;
371*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VQNEG")>;
372*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VSHL")>;
373*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_V[QR]SHL")>;
374*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_VQRSHL")>;
375*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE4NoFwd], (instregex "MVE_VQ?R?SHRU?N")>;
376*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VSHR_")>;
377*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_VRSHR_")>;
378*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VQSUB")>;
379*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VREV")>;
380*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VRHADD")>;
381*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE3], (instregex "MVE_VSBC")>;
382*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VSLI")>;
383*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VSRI")>;
384*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntE2], (instregex "MVE_VSUB(_qr_)?i")>;
385*bdd1243dSDimitry Andric
386*bdd1243dSDimitry Andric// FP/Mul pipe operations.
387*bdd1243dSDimitry Andric
388*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VABDf")>;
389*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VABSf")>;
390*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VADDf")>;
391*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VADD_qr_f")>;
392*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3, M55WriteLat1], (instregex "MVE_VADDLV")>;
393*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VADDV")>;
394*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VCADDf")>;
395*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCMLA")>;
396*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCMUL")>;
397*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VCMP(i|s|u)", "MVE_VPTv(4|8|16)(i|s|u)")>;
398*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VCMPf", "MVE_VPTv(4|8)f")>;
399*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCVTf16(u|s)16")>;
400*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCVTf32(u|s)32")>;
401*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCVT(u|s)16f16")>;
402*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCVT(u|s)32f32")>;
403*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE4NoFwd], (instregex "MVE_VCVTf16f32")>;
404*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VCVTf32f16")>;
405*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VFM(A|S)")>;
406*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_V(MIN|MAX)NM")>;
407*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VMOV_from_lane")>;
408*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VMOV_rr_q")>;
409*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VMOVi")>;
410*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VMUL(_qr_)?[if]")>;
411*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VQ?R?D?MULH")>;
412*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VQ?D?MULL[TB]?[su]")>;
413*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VQDMULL_qr_")>;
414*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VQ?R?D?ML(A|S)[^L]")>;
415*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3, M55WriteLat1], (instregex "MVE_VR?ML(A|S)L")>;
416*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VNEGf")>;
417*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VRINTf")>;
418*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE2], (instregex "MVE_VSUBf")>;
419*bdd1243dSDimitry Andricdef : InstRW<[M55Write2FloatE3], (instregex "MVE_VSUB_qr_f")>;
420*bdd1243dSDimitry Andric
421*bdd1243dSDimitry Andric// Some VMOV's can go down either pipeline.
422*bdd1243dSDimitry Andricdef : InstRW<[M55Write2IntFPE2], (instregex "MVE_VMOV_to_lane", "MVE_VMOV_q_rr")>;
423*bdd1243dSDimitry Andric
424*bdd1243dSDimitry Andricdef : InstRW<[M55WriteSysE2], (instregex "MVE_VCTP")>;
425*bdd1243dSDimitry Andricdef : InstRW<[M55WriteSysE2], (instregex "MVE_VPNOT")>;
426*bdd1243dSDimitry Andricdef : InstRW<[M55WriteSysE2], (instregex "MVE_VPST")>;
427*bdd1243dSDimitry Andric
428*bdd1243dSDimitry Andric
429*bdd1243dSDimitry Andric// VFP instructions
430*bdd1243dSDimitry Andric
431*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPCVT, M55WriteFloatE3>;
432*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPMOV, M55WriteFloatE3>;
433*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPALU32, M55WriteFloatE3>;
434*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPALU64, M55WriteFloatE3Plus13>;
435*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPMUL32, M55WriteFloatE3>;
436*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPMUL64, M55WriteFloatE3Plus19>;
437*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPMAC32, M55WriteFloatE3Plus2>;
438*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPMAC64, M55WriteFloatE3Plus34>;
439*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPDIV32, M55WriteFloatE3Plus14>;
440*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPDIV64, M55WriteFloatE3Plus28>;
441*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPSQRT32, M55WriteFloatE3Plus14>;
442*bdd1243dSDimitry Andricdef : SchedAlias<WriteFPSQRT64, M55WriteFloatE3Plus28>;
443*bdd1243dSDimitry Andricdef : ReadAdvance<ReadFPMUL, 0>;
444*bdd1243dSDimitry Andricdef : ReadAdvance<ReadFPMAC, 0>;
445*bdd1243dSDimitry Andric
446*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLSE3], (instregex "VLD")>;
447*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLSE2], (instregex "VST")>;
448*bdd1243dSDimitry Andricdef : InstRW<[M55WriteLSE3], (instregex "VLLD", "VLST")>;
449*bdd1243dSDimitry Andric
450*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VABS(H|S|D)")>;
451*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VCVT(A|M|N|P|R|X|Z)(S|U)(H|S|D)")>;
452*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VCVT(B|T)(DH|HD)")>;
453*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE2], (instregex "VCMPZ?(E|H|S|D)")>;
454*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3Plus7], (instregex "VDIVH")>;
455*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VFN?M(A|S)(H|S)")>; // VFMA
456*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3Plus22], (instregex "VFN?M(A|S)D")>; // VFMA
457*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VFP_V(MAX|MIN)NM")>;
458*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VINSH$", "VMOVH$", "VMOVHR$", "VMOVSR$", "VMOVDRR$")>; // VINS, VMOVX, to-FP reg movs
459*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE2], (instregex "VMOVD$", "VMOVS$", "VMOVR")>; // Other VMOV's
460*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE2], (instregex "FCONSTH", "FCONSTS", "FCONSTD")>;
461*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE2], (instregex "VGETLNi32", "VSETLNi32")>;
462*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE2], (instregex "VMSR", "VMRS")>;
463*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3Plus2], (instregex "VN?ML(A|S)H")>; // VMLA
464*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VNEG(H|S|D)")>;
465*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VRINT(A|M|N|P|R|X|Z)(H|S|D)")>;
466*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3], (instregex "VSEL..(H|S|D)")>;
467*bdd1243dSDimitry Andricdef : InstRW<[M55WriteFloatE3Plus7], (instregex "VSQRTH")>;
468*bdd1243dSDimitry Andric
469*bdd1243dSDimitry Andricdef : WriteRes<WriteVLD1, []>;
470*bdd1243dSDimitry Andricdef : WriteRes<WriteVLD2, []>;
471*bdd1243dSDimitry Andricdef : WriteRes<WriteVLD3, []>;
472*bdd1243dSDimitry Andricdef : WriteRes<WriteVLD4, []>;
473*bdd1243dSDimitry Andricdef : WriteRes<WriteVST1, []>;
474*bdd1243dSDimitry Andricdef : WriteRes<WriteVST2, []>;
475*bdd1243dSDimitry Andricdef : WriteRes<WriteVST3, []>;
476*bdd1243dSDimitry Andricdef : WriteRes<WriteVST4, []>;
477*bdd1243dSDimitry Andric
478*bdd1243dSDimitry Andric}
479