xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64SchedThunderX2T99.td (revision 7877fdebeeb35fad1cbbafce22598b1bdf97c786)
1//=- AArch64SchedThunderX2T99.td - Cavium ThunderX T99 ---*- 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//
9// This file defines the scheduling model for Cavium ThunderX2T99
10// processors.
11// Based on Broadcom Vulcan.
12//
13//===----------------------------------------------------------------------===//
14
15//===----------------------------------------------------------------------===//
16// 2. Pipeline Description.
17
18def ThunderX2T99Model : SchedMachineModel {
19  let IssueWidth            =   4; // 4 micro-ops dispatched at a time.
20  let MicroOpBufferSize     = 180; // 180 entries in micro-op re-order buffer.
21  let LoadLatency           =   4; // Optimistic load latency.
22  let MispredictPenalty     =  12; // Extra cycles for mispredicted branch.
23  // Determined via a mix of micro-arch details and experimentation.
24  let LoopMicroOpBufferSize = 128;
25  let PostRAScheduler       =   1; // Using PostRA sched.
26  let CompleteModel         =   1;
27
28  list<Predicate> UnsupportedFeatures = !listconcat(SVEUnsupported.F,
29                                                    PAUnsupported.F);
30  // FIXME: Remove when all errors have been fixed.
31  let FullInstRWOverlapCheck = 0;
32}
33
34let SchedModel = ThunderX2T99Model in {
35
36// Define the issue ports.
37
38// Port 0: ALU, FP/SIMD.
39def THX2T99P0 : ProcResource<1>;
40
41// Port 1: ALU, FP/SIMD, integer mul/div.
42def THX2T99P1 : ProcResource<1>;
43
44// Port 2: ALU, Branch.
45def THX2T99P2 : ProcResource<1>;
46
47// Port 3: Store data.
48def THX2T99P3 : ProcResource<1>;
49
50// Port 4: Load/store.
51def THX2T99P4 : ProcResource<1>;
52
53// Port 5: Load/store.
54def THX2T99P5 : ProcResource<1>;
55
56// Define groups for the functional units on each issue port.  Each group
57// created will be used by a WriteRes later on.
58//
59// NOTE: Some groups only contain one member.  This is a way to create names for
60// the various functional units that share a single issue port.  For example,
61// "THX2T99I1" for ALU ops on port 1 and "THX2T99F1" for FP ops on port 1.
62
63// Integer divide and multiply micro-ops only on port 1.
64def THX2T99I1 : ProcResGroup<[THX2T99P1]>;
65
66// Branch micro-ops only on port 2.
67def THX2T99I2 : ProcResGroup<[THX2T99P2]>;
68
69// ALU micro-ops on ports 0, 1, and 2.
70def THX2T99I012 : ProcResGroup<[THX2T99P0, THX2T99P1, THX2T99P2]>;
71
72// Crypto FP/SIMD micro-ops only on port 1.
73def THX2T99F1 : ProcResGroup<[THX2T99P1]>;
74
75// FP/SIMD micro-ops on ports 0 and 1.
76def THX2T99F01 : ProcResGroup<[THX2T99P0, THX2T99P1]>;
77
78// Store data micro-ops only on port 3.
79def THX2T99SD : ProcResGroup<[THX2T99P3]>;
80
81// Load/store micro-ops on ports 4 and 5.
82def THX2T99LS01 : ProcResGroup<[THX2T99P4, THX2T99P5]>;
83
84// 60 entry unified scheduler.
85def THX2T99Any : ProcResGroup<[THX2T99P0, THX2T99P1, THX2T99P2,
86                               THX2T99P3, THX2T99P4, THX2T99P5]> {
87  let BufferSize = 60;
88}
89
90// Define commonly used write types for InstRW specializations.
91// All definitions follow the format: THX2T99Write_<NumCycles>Cyc_<Resources>.
92
93// 3 cycles on I1.
94def THX2T99Write_3Cyc_I1 : SchedWriteRes<[THX2T99I1]> {
95  let Latency = 3;
96  let NumMicroOps = 2;
97}
98
99// 1 cycles on I2.
100def THX2T99Write_1Cyc_I2 : SchedWriteRes<[THX2T99I2]> {
101  let Latency = 1;
102  let NumMicroOps = 2;
103}
104
105// 4 cycles on I1.
106def THX2T99Write_4Cyc_I1 : SchedWriteRes<[THX2T99I1]> {
107  let Latency = 4;
108  let NumMicroOps = 2;
109}
110
111// 23 cycles on I1.
112def THX2T99Write_23Cyc_I1 : SchedWriteRes<[THX2T99I1]> {
113  let Latency = 23;
114  let ResourceCycles = [13, 23];
115  let NumMicroOps = 4;
116}
117
118// 39 cycles on I1.
119def THX2T99Write_39Cyc_I1 : SchedWriteRes<[THX2T99I1]> {
120  let Latency = 39;
121  let ResourceCycles = [13, 39];
122  let NumMicroOps = 4;
123}
124
125// 1 cycle on I0, I1, or I2.
126def THX2T99Write_1Cyc_I012 : SchedWriteRes<[THX2T99I012]> {
127  let Latency = 1;
128  let NumMicroOps = 2;
129}
130
131// 2 cycles on I0, I1, or I2.
132def THX2T99Write_2Cyc_I012 : SchedWriteRes<[THX2T99I012]> {
133  let Latency = 2;
134  let NumMicroOps = 2;
135}
136
137// 4 cycles on I0, I1, or I2.
138def THX2T99Write_4Cyc_I012 : SchedWriteRes<[THX2T99I012]> {
139  let Latency = 2;
140  let NumMicroOps = 3;
141}
142
143// 5 cycles on I0, I1, or I2.
144def THX2T99Write_5Cyc_I012 : SchedWriteRes<[THX2T99I012]> {
145  let Latency = 2;
146  let NumMicroOps = 3;
147}
148
149// 5 cycles on F1.
150def THX2T99Write_5Cyc_F1 : SchedWriteRes<[THX2T99F1]> {
151  let Latency = 5;
152  let NumMicroOps = 2;
153}
154
155// 7 cycles on F1.
156def THX2T99Write_7Cyc_F1 : SchedWriteRes<[THX2T99F1]> {
157  let Latency = 7;
158  let NumMicroOps = 2;
159}
160
161// 4 cycles on F0 or F1.
162def THX2T99Write_4Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
163  let Latency = 4;
164  let NumMicroOps = 2;
165}
166
167// 5 cycles on F0 or F1.
168def THX2T99Write_5Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
169  let Latency = 5;
170  let NumMicroOps = 2;
171}
172
173// 6 cycles on F0 or F1.
174def THX2T99Write_6Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
175  let Latency = 6;
176  let NumMicroOps = 3;
177}
178
179// 7 cycles on F0 or F1.
180def THX2T99Write_7Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
181  let Latency = 7;
182  let NumMicroOps = 3;
183}
184
185// 8 cycles on F0 or F1.
186def THX2T99Write_8Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
187  let Latency = 8;
188  let NumMicroOps = 3;
189}
190
191// 10 cycles on F0 or F1.
192def THX2T99Write_10Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
193  let Latency = 10;
194  let NumMicroOps = 3;
195}
196
197// 16 cycles on F0 or F1.
198def THX2T99Write_16Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
199  let Latency = 16;
200  let NumMicroOps = 3;
201  let ResourceCycles = [8];
202}
203
204// 23 cycles on F0 or F1.
205def THX2T99Write_23Cyc_F01 : SchedWriteRes<[THX2T99F01]> {
206  let Latency = 23;
207  let NumMicroOps = 3;
208  let ResourceCycles = [11];
209}
210
211// 1 cycles on LS0 or LS1.
212def THX2T99Write_1Cyc_LS01 : SchedWriteRes<[THX2T99LS01]> {
213  let Latency = 0;
214}
215
216// 1 cycles on LS0 or LS1 and I0, I1, or I2.
217def THX2T99Write_1Cyc_LS01_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
218  let Latency = 0;
219  let NumMicroOps = 2;
220}
221
222// 1 cycles on LS0 or LS1 and 2 of I0, I1, or I2.
223def THX2T99Write_1Cyc_LS01_I012_I012 :
224  SchedWriteRes<[THX2T99LS01, THX2T99I012, THX2T99I012]> {
225  let Latency = 0;
226  let NumMicroOps = 3;
227}
228
229// 2 cycles on LS0 or LS1.
230def THX2T99Write_2Cyc_LS01 : SchedWriteRes<[THX2T99LS01]> {
231  let Latency = 1;
232  let NumMicroOps = 2;
233}
234
235// 4 cycles on LS0 or LS1.
236def THX2T99Write_4Cyc_LS01 : SchedWriteRes<[THX2T99LS01]> {
237  let Latency = 4;
238  let NumMicroOps = 4;
239}
240
241// 5 cycles on LS0 or LS1.
242def THX2T99Write_5Cyc_LS01 : SchedWriteRes<[THX2T99LS01]> {
243  let Latency = 5;
244  let NumMicroOps = 3;
245}
246
247// 6 cycles on LS0 or LS1.
248def THX2T99Write_6Cyc_LS01 : SchedWriteRes<[THX2T99LS01]> {
249  let Latency = 6;
250  let NumMicroOps = 3;
251}
252
253// 4 cycles on LS0 or LS1 and I0, I1, or I2.
254def THX2T99Write_4Cyc_LS01_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
255  let Latency = 4;
256  let NumMicroOps = 3;
257}
258
259// 4 cycles on LS0 or LS1 and 2 of I0, I1, or I2.
260def THX2T99Write_4Cyc_LS01_I012_I012 :
261  SchedWriteRes<[THX2T99LS01, THX2T99I012, THX2T99I012]> {
262  let Latency = 4;
263  let NumMicroOps = 3;
264}
265
266// 5 cycles on LS0 or LS1 and I0, I1, or I2.
267def THX2T99Write_5Cyc_LS01_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
268  let Latency = 5;
269  let NumMicroOps = 3;
270}
271
272// 5 cycles on LS0 or LS1 and 2 of I0, I1, or I2.
273def THX2T99Write_5Cyc_LS01_I012_I012 :
274  SchedWriteRes<[THX2T99LS01, THX2T99I012, THX2T99I012]> {
275  let Latency = 5;
276  let NumMicroOps = 3;
277}
278
279// 6 cycles on LS0 or LS1 and I0, I1, or I2.
280def THX2T99Write_6Cyc_LS01_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
281  let Latency = 6;
282  let NumMicroOps = 4;
283}
284
285// 6 cycles on LS0 or LS1 and 2 of I0, I1, or I2.
286def THX2T99Write_6Cyc_LS01_I012_I012 :
287  SchedWriteRes<[THX2T99LS01, THX2T99I012, THX2T99I012]> {
288  let Latency = 6;
289  let NumMicroOps = 3;
290}
291
292// 1 cycles on LS0 or LS1 and F0 or F1.
293def THX2T99Write_1Cyc_LS01_F01 : SchedWriteRes<[THX2T99LS01, THX2T99F01]> {
294  let Latency = 1;
295  let NumMicroOps = 2;
296}
297
298// 5 cycles on LS0 or LS1 and F0 or F1.
299def THX2T99Write_5Cyc_LS01_F01 : SchedWriteRes<[THX2T99LS01, THX2T99F01]> {
300  let Latency = 5;
301  let NumMicroOps = 3;
302}
303
304// 6 cycles on LS0 or LS1 and F0 or F1.
305def THX2T99Write_6Cyc_LS01_F01 : SchedWriteRes<[THX2T99LS01, THX2T99F01]> {
306  let Latency = 6;
307  let NumMicroOps = 3;
308}
309
310// 7 cycles on LS0 or LS1 and F0 or F1.
311def THX2T99Write_7Cyc_LS01_F01 : SchedWriteRes<[THX2T99LS01, THX2T99F01]> {
312  let Latency = 7;
313  let NumMicroOps = 3;
314}
315
316// 8 cycles on LS0 or LS1 and F0 or F1.
317def THX2T99Write_8Cyc_LS01_F01 : SchedWriteRes<[THX2T99LS01, THX2T99F01]> {
318  let Latency = 8;
319  let NumMicroOps = 3;
320}
321
322// 8 cycles on LS0 or LS1 and I0, I1, or I2.
323def THX2T99Write_8Cyc_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
324  let Latency = 8;
325  let NumMicroOps = 4;
326}
327
328// 12 cycles on LS0 or LS1 and I0, I1, or I2.
329def THX2T99Write_12Cyc_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
330  let Latency = 12;
331  let NumMicroOps = 6;
332}
333
334// 16 cycles on LS0 or LS1 and I0, I1, or I2.
335def THX2T99Write_16Cyc_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
336  let Latency = 16;
337  let NumMicroOps = 8;
338}
339
340// 24 cycles on LS0 or LS1 and I0, I1, or I2.
341def THX2T99Write_24Cyc_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
342  let Latency = 24;
343  let NumMicroOps = 12;
344}
345
346// 32 cycles on LS0 or LS1 and I0, I1, or I2.
347def THX2T99Write_32Cyc_I012 : SchedWriteRes<[THX2T99LS01, THX2T99I012]> {
348  let Latency = 32;
349  let NumMicroOps = 16;
350}
351
352// Define commonly used read types.
353
354// No forwarding is provided for these types.
355def : ReadAdvance<ReadI,       0>;
356def : ReadAdvance<ReadISReg,   0>;
357def : ReadAdvance<ReadIEReg,   0>;
358def : ReadAdvance<ReadIM,      0>;
359def : ReadAdvance<ReadIMA,     0>;
360def : ReadAdvance<ReadID,      0>;
361def : ReadAdvance<ReadExtrHi,  0>;
362def : ReadAdvance<ReadAdrBase, 0>;
363def : ReadAdvance<ReadVLD,     0>;
364
365//===----------------------------------------------------------------------===//
366// 3. Instruction Tables.
367
368//---
369// 3.1 Branch Instructions
370//---
371
372// Branch, immed
373// Branch and link, immed
374// Compare and branch
375def : WriteRes<WriteBr,      [THX2T99I2]> {
376  let Latency = 1;
377  let NumMicroOps = 2;
378}
379
380// Branch, register
381// Branch and link, register != LR
382// Branch and link, register = LR
383def : WriteRes<WriteBrReg,   [THX2T99I2]> {
384  let Latency = 1;
385  let NumMicroOps = 2;
386}
387
388def : WriteRes<WriteSys,     []> { let Latency = 1; }
389def : WriteRes<WriteBarrier, []> { let Latency = 1; }
390def : WriteRes<WriteHint,    []> { let Latency = 1; }
391
392def : WriteRes<WriteAtomic,  []> {
393  let Latency = 4;
394  let NumMicroOps = 2;
395}
396
397//---
398// Branch
399//---
400def : InstRW<[THX2T99Write_1Cyc_I2], (instrs B, BL, BR, BLR)>;
401def : InstRW<[THX2T99Write_1Cyc_I2], (instrs RET)>;
402def : InstRW<[THX2T99Write_1Cyc_I2], (instregex "^B..$")>;
403def : InstRW<[THX2T99Write_1Cyc_I2],
404            (instregex "^CBZ", "^CBNZ", "^TBZ", "^TBNZ")>;
405
406//---
407// 3.2 Arithmetic and Logical Instructions
408// 3.3 Move and Shift Instructions
409//---
410
411
412// ALU, basic
413// Conditional compare
414// Conditional select
415// Address generation
416def : WriteRes<WriteI,       [THX2T99I012]> {
417  let Latency = 1;
418  let ResourceCycles = [1];
419  let NumMicroOps = 2;
420}
421
422def : InstRW<[WriteI],
423            (instregex "ADD?(W|X)r(i|r|s|x)",   "ADDS?(W|X)r(i|r|s|x)(64)?",
424                       "AND?(W|X)r(i|r|s|x)",   "ANDS?(W|X)r(i|r|s|x)",
425                       "ADC(W|X)r",
426                       "BIC?(W|X)r(i|r|s|x)",   "BICS?(W|X)r(i|r|s|x)",
427                       "EON?(W|X)r(i|r|s|x)",   "ORN?(W|X)r(i|r|s|x)",
428                       "ORR?(W|X)r(i|r|s|x)",   "SUB?(W|X)r(i|r|s|x)",
429                       "SUBS?(W|X)r(i|r|s|x)",  "SBC(W|X)r",
430                       "SBCS(W|X)r",            "CCMN(W|X)(i|r)",
431                       "CCMP(W|X)(i|r)",        "CSEL(W|X)r",
432                       "CSINC(W|X)r",           "CSINV(W|X)r",
433                       "CSNEG(W|X)r")>;
434
435def : InstRW<[WriteI], (instrs COPY)>;
436
437// ALU, extend and/or shift
438def : WriteRes<WriteISReg,   [THX2T99I012]> {
439  let Latency = 2;
440  let ResourceCycles = [2];
441  let NumMicroOps = 2;
442}
443
444def : InstRW<[WriteISReg],
445            (instregex "ADD?(W|X)r(i|r|s|x)",   "ADDS?(W|X)r(i|r|s|x)(64)?",
446                       "AND?(W|X)r(i|r|s|x)",   "ANDS?(W|X)r(i|r|s|x)",
447                       "ADC(W|X)r",
448                       "BIC?(W|X)r(i|r|s|x)",   "BICS?(W|X)r(i|r|s|x)",
449                       "EON?(W|X)r(i|r|s|x)",   "ORN?(W|X)r(i|r|s|x)",
450                       "ORR?(W|X)r(i|r|s|x)",   "SUB?(W|X)r(i|r|s|x)",
451                       "SUBS?(W|X)r(i|r|s|x)",  "SBC(W|X)r",
452                       "SBCS(W|X)r",            "CCMN(W|X)(i|r)",
453                       "CCMP(W|X)(i|r)",        "CSEL(W|X)r",
454                       "CSINC(W|X)r",           "CSINV(W|X)r",
455                       "CSNEG(W|X)r")>;
456
457def : WriteRes<WriteIEReg,   [THX2T99I012]> {
458  let Latency = 1;
459  let ResourceCycles = [1];
460  let NumMicroOps = 2;
461}
462
463def : InstRW<[WriteIEReg],
464            (instregex "ADD?(W|X)r(i|r|s|x)",   "ADDS?(W|X)r(i|r|s|x)(64)?",
465                       "AND?(W|X)r(i|r|s|x)",   "ANDS?(W|X)r(i|r|s|x)",
466                       "ADC(W|X)r",
467                       "BIC?(W|X)r(i|r|s|x)",   "BICS?(W|X)r(i|r|s|x)",
468                       "EON?(W|X)r(i|r|s|x)",   "ORN?(W|X)r(i|r|s|x)",
469                       "ORR?(W|X)r(i|r|s|x)",   "SUB?(W|X)r(i|r|s|x)",
470                       "SUBS?(W|X)r(i|r|s|x)",  "SBC(W|X)r",
471                       "SBCS(W|X)r",            "CCMN(W|X)(i|r)",
472                       "CCMP(W|X)(i|r)",        "CSEL(W|X)r",
473                       "CSINC(W|X)r",           "CSINV(W|X)r",
474                       "CSNEG(W|X)r")>;
475
476// Move immed
477def : WriteRes<WriteImm,     [THX2T99I012]> {
478  let Latency = 1;
479  let NumMicroOps = 2;
480}
481
482def : InstRW<[THX2T99Write_1Cyc_I012],
483            (instrs MOVKWi, MOVKXi, MOVNWi, MOVNXi, MOVZWi, MOVZXi)>;
484
485def : InstRW<[THX2T99Write_1Cyc_I012],
486            (instrs ASRVWr, ASRVXr, LSLVWr, LSLVXr, RORVWr, RORVXr)>;
487
488// Variable shift
489def : WriteRes<WriteIS,      [THX2T99I012]> {
490  let Latency = 1;
491  let NumMicroOps = 2;
492}
493
494//---
495// 3.4 Divide and Multiply Instructions
496//---
497
498// Divide, W-form
499// Latency range of 13-23/13-39.
500def : WriteRes<WriteID32,    [THX2T99I1]> {
501  let Latency = 39;
502  let ResourceCycles = [39];
503  let NumMicroOps = 4;
504}
505
506// Divide, X-form
507def : WriteRes<WriteID64,    [THX2T99I1]> {
508  let Latency = 23;
509  let ResourceCycles = [23];
510  let NumMicroOps = 4;
511}
512
513// Multiply accumulate, W-form
514def : WriteRes<WriteIM32,    [THX2T99I012]> {
515  let Latency = 5;
516  let NumMicroOps = 3;
517}
518
519// Multiply accumulate, X-form
520def : WriteRes<WriteIM64,    [THX2T99I012]> {
521  let Latency = 5;
522  let NumMicroOps = 3;
523}
524
525//def : InstRW<[WriteIM32, ReadIM, ReadIM, ReadIMA, THX2T99Write_5Cyc_I012],
526//             (instrs MADDWrrr, MSUBWrrr)>;
527def : InstRW<[WriteIM32], (instrs MADDWrrr, MSUBWrrr)>;
528def : InstRW<[WriteIM32], (instrs MADDXrrr, MSUBXrrr)>;
529def : InstRW<[THX2T99Write_5Cyc_I012],
530            (instregex "(S|U)(MADDL|MSUBL)rrr")>;
531
532def : InstRW<[WriteID32], (instrs SDIVWr, UDIVWr)>;
533def : InstRW<[WriteID64], (instrs SDIVXr, UDIVXr)>;
534
535// Bitfield extract, two reg
536def : WriteRes<WriteExtr,    [THX2T99I012]> {
537  let Latency = 1;
538  let NumMicroOps = 2;
539}
540
541// Multiply high
542def : InstRW<[THX2T99Write_4Cyc_I1], (instrs SMULHrr, UMULHrr)>;
543
544// Miscellaneous Data-Processing Instructions
545// Bitfield extract
546def : InstRW<[THX2T99Write_1Cyc_I012], (instrs EXTRWrri, EXTRXrri)>;
547
548// Bitifield move - basic
549def : InstRW<[THX2T99Write_1Cyc_I012],
550            (instrs SBFMWri, SBFMXri, UBFMWri, UBFMXri)>;
551
552// Bitfield move, insert
553def : InstRW<[THX2T99Write_1Cyc_I012], (instregex "^BFM")>;
554def : InstRW<[THX2T99Write_1Cyc_I012], (instregex "(S|U)?BFM.*")>;
555
556// Count leading
557def : InstRW<[THX2T99Write_3Cyc_I1], (instregex "^CLS(W|X)r$",
558                                                "^CLZ(W|X)r$")>;
559
560// Reverse bits
561def : InstRW<[THX2T99Write_1Cyc_I012], (instrs RBITWr, RBITXr)>;
562
563// Cryptography Extensions
564def : InstRW<[THX2T99Write_5Cyc_F1], (instregex "^AES[DE]")>;
565def : InstRW<[THX2T99Write_5Cyc_F1], (instregex "^AESI?MC")>;
566def : InstRW<[THX2T99Write_5Cyc_F1], (instregex "^PMULL")>;
567def : InstRW<[THX2T99Write_7Cyc_F1], (instregex "^SHA1SU0")>;
568def : InstRW<[THX2T99Write_7Cyc_F1], (instregex "^SHA1(H|SU1)")>;
569def : InstRW<[THX2T99Write_7Cyc_F1], (instregex "^SHA1[CMP]")>;
570def : InstRW<[THX2T99Write_7Cyc_F1], (instregex "^SHA256SU0")>;
571def : InstRW<[THX2T99Write_7Cyc_F1], (instregex "^SHA256(H|H2|SU1)")>;
572
573// CRC Instructions
574// def : InstRW<[THX2T99Write_4Cyc_I1], (instregex "^CRC32", "^CRC32C")>;
575def : InstRW<[THX2T99Write_4Cyc_I1],
576            (instrs CRC32Brr, CRC32Hrr, CRC32Wrr, CRC32Xrr)>;
577
578def : InstRW<[THX2T99Write_4Cyc_I1],
579            (instrs CRC32CBrr, CRC32CHrr, CRC32CWrr, CRC32CXrr)>;
580
581// Reverse bits/bytes
582// NOTE: Handled by WriteI.
583
584//---
585// 3.6 Load Instructions
586// 3.10 FP Load Instructions
587//---
588
589// Load register, literal
590// Load register, unscaled immed
591// Load register, immed unprivileged
592// Load register, unsigned immed
593def : WriteRes<WriteLD,      [THX2T99LS01]> {
594  let Latency = 4;
595  let NumMicroOps = 4;
596}
597
598// Load register, immed post-index
599// NOTE: Handled by WriteLD, WriteI.
600// Load register, immed pre-index
601// NOTE: Handled by WriteLD, WriteAdr.
602def : WriteRes<WriteAdr,     [THX2T99I012]> {
603  let Latency = 1;
604  let NumMicroOps = 2;
605}
606
607// Load pair, immed offset, normal
608// Load pair, immed offset, signed words, base != SP
609// Load pair, immed offset signed words, base = SP
610// LDP only breaks into *one* LS micro-op.  Thus
611// the resources are handled by WriteLD.
612def : WriteRes<WriteLDHi,    []> {
613  let Latency = 5;
614  let NumMicroOps = 5;
615}
616
617// Load register offset, basic
618// Load register, register offset, scale by 4/8
619// Load register, register offset, scale by 2
620// Load register offset, extend
621// Load register, register offset, extend, scale by 4/8
622// Load register, register offset, extend, scale by 2
623def THX2T99WriteLDIdx : SchedWriteVariant<[
624  SchedVar<ScaledIdxPred, [THX2T99Write_6Cyc_LS01_I012_I012]>,
625  SchedVar<NoSchedPred,   [THX2T99Write_5Cyc_LS01_I012]>]>;
626def : SchedAlias<WriteLDIdx, THX2T99WriteLDIdx>;
627
628def THX2T99ReadAdrBase : SchedReadVariant<[
629  SchedVar<ScaledIdxPred, [ReadDefault]>,
630  SchedVar<NoSchedPred,   [ReadDefault]>]>;
631def : SchedAlias<ReadAdrBase, THX2T99ReadAdrBase>;
632
633// Load pair, immed pre-index, normal
634// Load pair, immed pre-index, signed words
635// Load pair, immed post-index, normal
636// Load pair, immed post-index, signed words
637// NOTE: Handled by WriteLD, WriteLDHi, WriteAdr.
638
639def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDNPDi)>;
640def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDNPQi)>;
641def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDNPSi)>;
642def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDNPWi)>;
643def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDNPXi)>;
644
645def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPDi)>;
646def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPQi)>;
647def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPSi)>;
648def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPSWi)>;
649def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPWi)>;
650def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi], (instrs LDPXi)>;
651
652def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRBui)>;
653def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRDui)>;
654def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRHui)>;
655def : InstRW<[THX2T99Write_5Cyc_LS01], (instrs LDRQui)>;
656def : InstRW<[THX2T99Write_5Cyc_LS01], (instrs LDRSui)>;
657
658def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRDl)>;
659def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRQl)>;
660def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRWl)>;
661def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDRXl)>;
662
663def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRBi)>;
664def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRHi)>;
665def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRWi)>;
666def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRXi)>;
667
668def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRSBWi)>;
669def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRSBXi)>;
670def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRSHWi)>;
671def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRSHXi)>;
672def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDTRSWi)>;
673
674def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
675            (instrs LDPDpre)>;
676def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
677            (instrs LDPQpre)>;
678def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
679            (instrs LDPSpre)>;
680def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
681            (instrs LDPWpre)>;
682def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
683            (instrs LDPWpre)>;
684
685def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRBpre)>;
686def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRDpre)>;
687def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRHpre)>;
688def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRQpre)>;
689def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRSpre)>;
690def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRWpre)>;
691def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteAdr], (instrs LDRXpre)>;
692
693def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSBWpre)>;
694def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSBXpre)>;
695def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSBWpost)>;
696def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSBXpost)>;
697
698def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSHWpre)>;
699def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSHXpre)>;
700def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSHWpost)>;
701def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRSHXpost)>;
702
703def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRBBpre)>;
704def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRBBpost)>;
705
706def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRHHpre)>;
707def : InstRW<[THX2T99Write_4Cyc_LS01_I012, WriteAdr], (instrs LDRHHpost)>;
708
709def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
710            (instrs LDPDpost)>;
711def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
712            (instrs LDPQpost)>;
713def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
714            (instrs LDPSpost)>;
715def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
716            (instrs LDPWpost)>;
717def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteLDHi, WriteAdr],
718            (instrs LDPXpost)>;
719
720def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRBpost)>;
721def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRDpost)>;
722def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRHpost)>;
723def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRQpost)>;
724def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRSpost)>;
725def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRWpost)>;
726def : InstRW<[THX2T99Write_5Cyc_LS01_I012, WriteI], (instrs LDRXpost)>;
727
728def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
729            (instrs LDPDpre)>;
730def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
731            (instrs LDPQpre)>;
732def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
733            (instrs LDPSpre)>;
734def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
735            (instrs LDPWpre)>;
736def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
737            (instrs LDPXpre)>;
738
739def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRBpre)>;
740def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRDpre)>;
741def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRHpre)>;
742def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRQpre)>;
743def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRSpre)>;
744def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRWpre)>;
745def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteAdr], (instrs LDRXpre)>;
746
747def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
748            (instrs LDPDpost)>;
749def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
750            (instrs LDPQpost)>;
751def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
752            (instrs LDPSpost)>;
753def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
754            (instrs LDPWpost)>;
755def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteLDHi, WriteAdr],
756            (instrs LDPXpost)>;
757
758def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRBpost)>;
759def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRDpost)>;
760def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRHpost)>;
761def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRQpost)>;
762def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRSpost)>;
763def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRWpost)>;
764def : InstRW<[THX2T99Write_5Cyc_LS01_I012_I012, WriteI], (instrs LDRXpost)>;
765
766def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRBroW)>;
767def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRDroW)>;
768def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRHroW)>;
769def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRHHroW)>;
770def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRQroW)>;
771def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSroW)>;
772def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSHWroW)>;
773def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSHXroW)>;
774def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRWroW)>;
775def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRXroW)>;
776
777def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRBroX)>;
778def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRDroX)>;
779def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRHHroX)>;
780def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRHroX)>;
781def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRQroX)>;
782def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSroX)>;
783def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSHWroX)>;
784def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRSHXroX)>;
785def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRWroX)>;
786def : InstRW<[THX2T99Write_4Cyc_LS01_I012, ReadAdrBase], (instrs LDRXroX)>;
787
788def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
789            (instrs LDRBroW)>;
790def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
791            (instrs LDRBroW)>;
792def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
793             (instrs LDRDroW)>;
794def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
795            (instrs LDRHroW)>;
796def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
797            (instrs LDRHHroW)>;
798def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
799            (instrs LDRQroW)>;
800def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
801            (instrs LDRSroW)>;
802def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
803            (instrs LDRSHWroW)>;
804def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
805            (instrs LDRSHXroW)>;
806def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
807            (instrs LDRWroW)>;
808def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
809            (instrs LDRXroW)>;
810def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
811            (instrs LDRBroX)>;
812def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
813            (instrs LDRDroX)>;
814def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
815            (instrs LDRHroX)>;
816def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
817            (instrs LDRHHroX)>;
818def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
819            (instrs LDRQroX)>;
820def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
821            (instrs LDRSroX)>;
822def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
823            (instrs LDRSHWroX)>;
824def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
825            (instrs LDRSHXroX)>;
826def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
827            (instrs LDRWroX)>;
828def : InstRW<[THX2T99Write_4Cyc_LS01_I012_I012, ReadAdrBase],
829            (instrs LDRXroX)>;
830
831def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURBi)>;
832def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURBBi)>;
833def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURDi)>;
834def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURHi)>;
835def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURHHi)>;
836def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURQi)>;
837def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSi)>;
838def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURXi)>;
839def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSBWi)>;
840def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSBXi)>;
841def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSHWi)>;
842def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSHXi)>;
843def : InstRW<[THX2T99Write_4Cyc_LS01], (instrs LDURSWi)>;
844
845//---
846// Prefetch
847//---
848def : InstRW<[THX2T99Write_6Cyc_LS01_I012], (instrs PRFMl)>;
849def : InstRW<[THX2T99Write_6Cyc_LS01_I012], (instrs PRFUMi)>;
850def : InstRW<[THX2T99Write_6Cyc_LS01_I012], (instrs PRFMui)>;
851def : InstRW<[THX2T99Write_6Cyc_LS01_I012], (instrs PRFMroW)>;
852def : InstRW<[THX2T99Write_6Cyc_LS01_I012], (instrs PRFMroX)>;
853
854//--
855// 3.7 Store Instructions
856// 3.11 FP Store Instructions
857//--
858
859// Store register, unscaled immed
860// Store register, immed unprivileged
861// Store register, unsigned immed
862def : WriteRes<WriteST,      [THX2T99LS01, THX2T99SD]> {
863  let Latency = 1;
864  let NumMicroOps = 2;
865}
866
867// Store register, immed post-index
868// NOTE: Handled by WriteAdr, WriteST, ReadAdrBase
869
870// Store register, immed pre-index
871// NOTE: Handled by WriteAdr, WriteST
872
873// Store register, register offset, basic
874// Store register, register offset, scaled by 4/8
875// Store register, register offset, scaled by 2
876// Store register, register offset, extend
877// Store register, register offset, extend, scale by 4/8
878// Store register, register offset, extend, scale by 1
879def : WriteRes<WriteSTIdx, [THX2T99LS01, THX2T99SD, THX2T99I012]> {
880  let Latency = 1;
881  let NumMicroOps = 3;
882}
883
884// Store pair, immed offset, W-form
885// Store pair, immed offset, X-form
886def : WriteRes<WriteSTP,     [THX2T99LS01, THX2T99SD]> {
887  let Latency = 1;
888  let NumMicroOps = 2;
889}
890
891// Store pair, immed post-index, W-form
892// Store pair, immed post-index, X-form
893// Store pair, immed pre-index, W-form
894// Store pair, immed pre-index, X-form
895// NOTE: Handled by WriteAdr, WriteSTP.
896
897def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURBi)>;
898def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURBBi)>;
899def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURDi)>;
900def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURHi)>;
901def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURHHi)>;
902def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURQi)>;
903def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURSi)>;
904def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURWi)>;
905def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STURXi)>;
906
907def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01], (instrs STTRBi)>;
908def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01], (instrs STTRHi)>;
909def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01], (instrs STTRWi)>;
910def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01], (instrs STTRXi)>;
911
912def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STNPDi)>;
913def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STNPQi)>;
914def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STNPXi)>;
915def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STNPWi)>;
916
917def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STPDi)>;
918def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STPQi)>;
919def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STPXi)>;
920def : InstRW<[THX2T99Write_1Cyc_LS01], (instrs STPWi)>;
921
922def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRBui)>;
923def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRBui)>;
924def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRDui)>;
925def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRDui)>;
926def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRHui)>;
927def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRHui)>;
928def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRQui)>;
929def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRQui)>;
930def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRXui)>;
931def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRXui)>;
932def : InstRW<[THX2T99Write_1Cyc_LS01_I012_I012], (instrs STRWui)>;
933def : InstRW<[THX2T99Write_1Cyc_LS01_I012], (instrs STRWui)>;
934
935def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
936            (instrs STPDpre, STPDpost)>;
937def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
938            (instrs STPDpre, STPDpost)>;
939def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
940            (instrs STPDpre, STPDpost)>;
941def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
942            (instrs STPDpre, STPDpost)>;
943def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
944            (instrs STPQpre, STPQpost)>;
945def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
946            (instrs STPQpre, STPQpost)>;
947def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
948            (instrs STPQpre, STPQpost)>;
949def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
950            (instrs STPQpre, STPQpost)>;
951def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
952            (instrs STPSpre, STPSpost)>;
953def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
954            (instrs STPSpre, STPSpost)>;
955def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
956            (instrs STPSpre, STPSpost)>;
957def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
958            (instrs STPSpre, STPSpost)>;
959def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
960            (instrs STPWpre, STPWpost)>;
961def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
962            (instrs STPWpre, STPWpost)>;
963def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
964            (instrs STPWpre, STPWpost)>;
965def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
966            (instrs STPWpre, STPWpost)>;
967def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
968            (instrs STPXpre, STPXpost)>;
969def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
970            (instrs STPXpre, STPXpost)>;
971def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
972            (instrs STPXpre, STPXpost)>;
973def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
974            (instrs STPXpre, STPXpost)>;
975
976def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
977            (instrs STRBpre, STRBpost)>;
978def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
979            (instrs STRBpre, STRBpost)>;
980def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
981            (instrs STRBpre, STRBpost)>;
982def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
983            (instrs STRBpre, STRBpost)>;
984def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
985            (instrs STRBBpre, STRBBpost)>;
986def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
987            (instrs STRBBpre, STRBBpost)>;
988def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
989            (instrs STRBBpre, STRBBpost)>;
990def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
991            (instrs STRBBpre, STRBBpost)>;
992def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
993            (instrs STRDpre, STRDpost)>;
994def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
995            (instrs STRDpre, STRDpost)>;
996def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
997            (instrs STRDpre, STRDpost)>;
998def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
999            (instrs STRDpre, STRDpost)>;
1000def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1001            (instrs STRHpre, STRHpost)>;
1002def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1003            (instrs STRHpre, STRHpost)>;
1004def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1005            (instrs STRHpre, STRHpost)>;
1006def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1007            (instrs STRHpre, STRHpost)>;
1008def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1009            (instrs STRHHpre, STRHHpost)>;
1010def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1011            (instrs STRHHpre, STRHHpost)>;
1012def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1013            (instrs STRHHpre, STRHHpost)>;
1014def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1015            (instrs STRHHpre, STRHHpost)>;
1016def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1017            (instrs STRQpre, STRQpost)>;
1018def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1019            (instrs STRQpre, STRQpost)>;
1020def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1021            (instrs STRQpre, STRQpost)>;
1022def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1023            (instrs STRQpre, STRQpost)>;
1024def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1025            (instrs STRSpre, STRSpost)>;
1026def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1027            (instrs STRSpre, STRSpost)>;
1028def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1029            (instrs STRSpre, STRSpost)>;
1030def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1031            (instrs STRSpre, STRSpost)>;
1032def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1033            (instrs STRWpre, STRWpost)>;
1034def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1035            (instrs STRWpre, STRWpost)>;
1036def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1037            (instrs STRWpre, STRWpost)>;
1038def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1039            (instrs STRWpre, STRWpost)>;
1040def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012],
1041            (instrs STRXpre, STRXpost)>;
1042def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1043            (instrs STRXpre, STRXpost)>;
1044def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012],
1045            (instrs STRXpre, STRXpost)>;
1046def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1047            (instrs STRXpre, STRXpost)>;
1048
1049def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1050            (instrs STRBroW, STRBroX)>;
1051def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1052            (instrs STRBroW, STRBroX)>;
1053def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1054            (instrs STRBBroW, STRBBroX)>;
1055def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1056            (instrs STRBBroW, STRBBroX)>;
1057def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1058            (instrs STRDroW, STRDroX)>;
1059def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1060            (instrs STRDroW, STRDroX)>;
1061def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1062            (instrs STRHroW, STRHroX)>;
1063def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1064            (instrs STRHroW, STRHroX)>;
1065def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1066            (instrs STRHHroW, STRHHroX)>;
1067def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1068            (instrs STRHHroW, STRHHroX)>;
1069def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1070            (instrs STRQroW, STRQroX)>;
1071def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1072            (instrs STRQroW, STRQroX)>;
1073def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1074            (instrs STRSroW, STRSroX)>;
1075def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1076            (instrs STRSroW, STRSroX)>;
1077def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1078            (instrs STRWroW, STRWroX)>;
1079def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1080            (instrs STRWroW, STRWroX)>;
1081def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012, ReadAdrBase],
1082            (instrs STRXroW, STRXroX)>;
1083def : InstRW<[WriteAdr, THX2T99Write_1Cyc_LS01_I012_I012, ReadAdrBase],
1084            (instrs STRXroW, STRXroX)>;
1085
1086//---
1087// 3.8 FP Data Processing Instructions
1088//---
1089
1090// FP absolute value
1091// FP min/max
1092// FP negate
1093def : WriteRes<WriteF,       [THX2T99F01]> {
1094  let Latency = 5;
1095  let NumMicroOps = 2;
1096}
1097
1098// FP arithmetic
1099def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "^FADD", "^FSUB")>;
1100
1101// FP compare
1102def : WriteRes<WriteFCmp,    [THX2T99F01]> {
1103  let Latency = 5;
1104  let NumMicroOps = 2;
1105}
1106
1107// FP Mul, Div, Sqrt
1108def : WriteRes<WriteFDiv, [THX2T99F01]> {
1109  let Latency = 22;
1110  let ResourceCycles = [19];
1111}
1112
1113def THX2T99XWriteFDiv : SchedWriteRes<[THX2T99F01]> {
1114  let Latency = 16;
1115  let ResourceCycles = [8];
1116  let NumMicroOps = 4;
1117}
1118
1119def THX2T99XWriteFDivSP : SchedWriteRes<[THX2T99F01]> {
1120  let Latency = 16;
1121  let ResourceCycles = [8];
1122  let NumMicroOps = 4;
1123}
1124
1125def THX2T99XWriteFDivDP : SchedWriteRes<[THX2T99F01]> {
1126  let Latency = 23;
1127  let ResourceCycles = [12];
1128  let NumMicroOps = 4;
1129}
1130
1131def THX2T99XWriteFSqrtSP : SchedWriteRes<[THX2T99F01]> {
1132  let Latency = 16;
1133  let ResourceCycles = [8];
1134  let NumMicroOps = 4;
1135}
1136
1137def THX2T99XWriteFSqrtDP : SchedWriteRes<[THX2T99F01]> {
1138  let Latency = 23;
1139  let ResourceCycles = [12];
1140  let NumMicroOps = 4;
1141}
1142
1143// FP divide, S-form
1144// FP square root, S-form
1145def : InstRW<[THX2T99XWriteFDivSP], (instrs FDIVSrr)>;
1146def : InstRW<[THX2T99XWriteFSqrtSP], (instrs FSQRTSr)>;
1147def : InstRW<[THX2T99XWriteFDivSP], (instregex "^FDIVv.*32$")>;
1148def : InstRW<[THX2T99XWriteFSqrtSP], (instregex "^.*SQRT.*32$")>;
1149def : InstRW<[THX2T99Write_16Cyc_F01], (instregex "^FDIVSrr", "^FSQRTSr")>;
1150
1151// FP divide, D-form
1152// FP square root, D-form
1153def : InstRW<[THX2T99XWriteFDivDP], (instrs FDIVDrr)>;
1154def : InstRW<[THX2T99XWriteFSqrtDP], (instrs FSQRTDr)>;
1155def : InstRW<[THX2T99XWriteFDivDP], (instregex "^FDIVv.*64$")>;
1156def : InstRW<[THX2T99XWriteFSqrtDP], (instregex "^.*SQRT.*64$")>;
1157def : InstRW<[THX2T99Write_23Cyc_F01], (instregex "^FDIVDrr", "^FSQRTDr")>;
1158
1159// FP multiply
1160// FP multiply accumulate
1161def : WriteRes<WriteFMul, [THX2T99F01]> {
1162  let Latency = 6;
1163  let ResourceCycles = [2];
1164  let NumMicroOps = 3;
1165}
1166
1167def THX2T99XWriteFMul : SchedWriteRes<[THX2T99F01]> {
1168  let Latency = 6;
1169  let ResourceCycles = [2];
1170  let NumMicroOps = 3;
1171}
1172
1173def THX2T99XWriteFMulAcc : SchedWriteRes<[THX2T99F01]> {
1174  let Latency = 6;
1175  let ResourceCycles = [2];
1176  let NumMicroOps = 3;
1177}
1178
1179def : InstRW<[THX2T99XWriteFMul], (instregex "^FMUL", "^FNMUL")>;
1180def : InstRW<[THX2T99XWriteFMulAcc],
1181            (instregex "^FMADD", "^FMSUB", "^FNMADD", "^FNMSUB")>;
1182
1183// FP round to integral
1184def : InstRW<[THX2T99Write_7Cyc_F01],
1185            (instregex "^FRINT(A|I|M|N|P|X|Z)(Sr|Dr)")>;
1186
1187// FP select
1188def : InstRW<[THX2T99Write_4Cyc_F01], (instregex "^FCSEL")>;
1189
1190//---
1191// 3.9 FP Miscellaneous Instructions
1192//---
1193
1194// FP convert, from vec to vec reg
1195// FP convert, from gen to vec reg
1196// FP convert, from vec to gen reg
1197def : WriteRes<WriteFCvt, [THX2T99F01]> {
1198  let Latency = 7;
1199  let NumMicroOps = 3;
1200}
1201
1202// FP move, immed
1203// FP move, register
1204def : WriteRes<WriteFImm, [THX2T99F01]> {
1205  let Latency = 4;
1206  let NumMicroOps = 2;
1207}
1208
1209// FP transfer, from gen to vec reg
1210// FP transfer, from vec to gen reg
1211def : WriteRes<WriteFCopy, [THX2T99F01]> {
1212  let Latency = 4;
1213  let NumMicroOps = 2;
1214}
1215
1216def : InstRW<[THX2T99Write_5Cyc_F01], (instrs FMOVXDHighr, FMOVDXHighr)>;
1217
1218//---
1219// 3.12 ASIMD Integer Instructions
1220//---
1221
1222// ASIMD absolute diff, D-form
1223// ASIMD absolute diff, Q-form
1224// ASIMD absolute diff accum, D-form
1225// ASIMD absolute diff accum, Q-form
1226// ASIMD absolute diff accum long
1227// ASIMD absolute diff long
1228// ASIMD arith, basic
1229// ASIMD arith, complex
1230// ASIMD compare
1231// ASIMD logical (AND, BIC, EOR)
1232// ASIMD max/min, basic
1233// ASIMD max/min, reduce, 4H/4S
1234// ASIMD max/min, reduce, 8B/8H
1235// ASIMD max/min, reduce, 16B
1236// ASIMD multiply, D-form
1237// ASIMD multiply, Q-form
1238// ASIMD multiply accumulate long
1239// ASIMD multiply accumulate saturating long
1240// ASIMD multiply long
1241// ASIMD pairwise add and accumulate
1242// ASIMD shift accumulate
1243// ASIMD shift by immed, basic
1244// ASIMD shift by immed and insert, basic, D-form
1245// ASIMD shift by immed and insert, basic, Q-form
1246// ASIMD shift by immed, complex
1247// ASIMD shift by register, basic, D-form
1248// ASIMD shift by register, basic, Q-form
1249// ASIMD shift by register, complex, D-form
1250// ASIMD shift by register, complex, Q-form
1251def : WriteRes<WriteV, [THX2T99F01]> {
1252  let Latency = 7;
1253  let NumMicroOps = 4;
1254  let ResourceCycles = [4];
1255}
1256
1257// ASIMD arith, reduce, 4H/4S
1258// ASIMD arith, reduce, 8B/8H
1259// ASIMD arith, reduce, 16B
1260
1261// ASIMD logical (MVN (alias for NOT), ORN, ORR)
1262def : InstRW<[THX2T99Write_5Cyc_F01],
1263            (instregex "^ANDv", "^BICv", "^EORv", "^ORRv", "^ORNv", "^NOTv")>;
1264
1265// ASIMD arith, reduce
1266def : InstRW<[THX2T99Write_10Cyc_F01],
1267            (instregex "^ADDVv", "^SADDLVv", "^UADDLVv")>;
1268
1269// ASIMD polynomial (8x8) multiply long
1270def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^(S|U|SQD)MULL")>;
1271def : InstRW<[THX2T99Write_7Cyc_F01],
1272            (instregex "(S|U|SQD)(MLAL|MLSL|MULL)v.*")>;
1273def : InstRW<[THX2T99Write_5Cyc_F1], (instregex "^PMULL(v8i8|v16i8)")>;
1274def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^PMULL(v1i64|v2i64)")>;
1275
1276// ASIMD absolute diff accum, D-form
1277def : InstRW<[THX2T99Write_7Cyc_F01],
1278            (instregex "^[SU]ABA(v8i8|v4i16|v2i32)$")>;
1279// ASIMD absolute diff accum, Q-form
1280def : InstRW<[THX2T99Write_7Cyc_F01],
1281            (instregex "^[SU]ABA(v16i8|v8i16|v4i32)$")>;
1282// ASIMD absolute diff accum long
1283def : InstRW<[THX2T99Write_7Cyc_F01],
1284            (instregex "^[SU]ABAL")>;
1285// ASIMD arith, reduce, 4H/4S
1286def : InstRW<[THX2T99Write_5Cyc_F01],
1287            (instregex "^[SU]?ADDL?V(v8i8|v4i16|v2i32)v$")>;
1288// ASIMD arith, reduce, 8B
1289def : InstRW<[THX2T99Write_5Cyc_F01],
1290            (instregex "^[SU]?ADDL?V(v8i16|v4i32)v$")>;
1291// ASIMD arith, reduce, 16B/16H
1292def : InstRW<[THX2T99Write_10Cyc_F01],
1293            (instregex "^[SU]?ADDL?Vv16i8v$")>;
1294// ASIMD max/min, reduce, 4H/4S
1295def : InstRW<[THX2T99Write_10Cyc_F01],
1296            (instregex "^[SU](MIN|MAX)V(v4i16|v4i32)v$")>;
1297// ASIMD max/min, reduce, 8B/8H
1298def : InstRW<[THX2T99Write_7Cyc_F01],
1299            (instregex "^[SU](MIN|MAX)V(v8i8|v8i16)v$")>;
1300// ASIMD max/min, reduce, 16B/16H
1301def : InstRW<[THX2T99Write_10Cyc_F01],
1302            (instregex "^[SU](MIN|MAX)Vv16i8v$")>;
1303// ASIMD multiply, D-form
1304def : InstRW<[THX2T99Write_7Cyc_F01],
1305            (instregex "^(P?MUL|SQR?DMULH)" #
1306                       "(v8i8|v4i16|v2i32|v1i8|v1i16|v1i32|v1i64)" #
1307                       "(_indexed)?$")>;
1308// ASIMD multiply, Q-form
1309def : InstRW<[THX2T99Write_7Cyc_F01],
1310            (instregex "^(P?MUL|SQR?DMULH)(v16i8|v8i16|v4i32)(_indexed)?$")>;
1311// ASIMD multiply accumulate, D-form
1312def : InstRW<[THX2T99Write_7Cyc_F01],
1313            (instregex "^ML[AS](v8i8|v4i16|v2i32)(_indexed)?$")>;
1314// ASIMD multiply accumulate, Q-form
1315def : InstRW<[THX2T99Write_7Cyc_F01],
1316            (instregex "^ML[AS](v16i8|v8i16|v4i32)(_indexed)?$")>;
1317// ASIMD shift accumulate
1318def : InstRW<[THX2T99Write_7Cyc_F01],
1319            (instregex "SRSRAv","SSRAv","URSRAv","USRAv")>;
1320
1321// ASIMD shift by immed, basic
1322def : InstRW<[THX2T99Write_7Cyc_F01],
1323            (instregex "RSHRNv","SHRNv", "SQRSHRNv","SQRSHRUNv",
1324                       "SQSHRNv","SQSHRUNv", "UQRSHRNv",
1325                       "UQSHRNv","SQXTNv","SQXTUNv","UQXTNv")>;
1326// ASIMD shift by immed, complex
1327def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^[SU]?(Q|R){1,2}SHR")>;
1328def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^SQSHLU")>;
1329// ASIMD shift by register, basic, Q-form
1330def : InstRW<[THX2T99Write_7Cyc_F01],
1331            (instregex "^[SU]SHL(v16i8|v8i16|v4i32|v2i64)")>;
1332// ASIMD shift by register, complex, D-form
1333def : InstRW<[THX2T99Write_7Cyc_F01],
1334            (instregex "^[SU][QR]{1,2}SHL" #
1335                       "(v1i8|v1i16|v1i32|v1i64|v8i8|v4i16|v2i32|b|d|h|s)")>;
1336// ASIMD shift by register, complex, Q-form
1337def : InstRW<[THX2T99Write_7Cyc_F01],
1338            (instregex "^[SU][QR]{1,2}SHL(v16i8|v8i16|v4i32|v2i64)")>;
1339
1340// ASIMD Arithmetic
1341def : InstRW<[THX2T99Write_7Cyc_F01],
1342            (instregex "(ADD|SUB)(v8i8|v4i16|v2i32|v1i64)")>;
1343def : InstRW<[THX2T99Write_7Cyc_F01],
1344            (instregex "(ADD|SUB)(v16i8|v8i16|v4i32|v2i64)")>;
1345def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "(ADD|SUB)HNv.*")>;
1346def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "(RADD|RSUB)HNv.*")>;
1347def : InstRW<[THX2T99Write_7Cyc_F01],
1348            (instregex "^SQADD", "^SQNEG", "^SQSUB", "^SRHADD",
1349                       "^SUQADD", "^UQADD", "^UQSUB", "^URHADD", "^USQADD")>;
1350def : InstRW<[THX2T99Write_7Cyc_F01],
1351            (instregex "ADDP(v16i8|v8i16|v4i32|v2i64)")>;
1352def : InstRW<[THX2T99Write_5Cyc_F01],
1353            (instregex "((AND|ORN|EOR|EON)S?(Xr[rsi]|v16i8|v8i16|v4i32)|" #
1354                       "(ORR|BIC)S?(Xr[rs]|v16i8|v8i16|v4i32))")>;
1355def : InstRW<[THX2T99Write_5Cyc_F01],
1356            (instregex "(CLS|CLZ|CNT)(v4i32|v8i16|v16i8)")>;
1357def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^SADALP","^UADALP")>;
1358def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^SADDLPv","^UADDLPv")>;
1359def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^SADDLV","^UADDLV")>;
1360def : InstRW<[THX2T99Write_7Cyc_F01],
1361             (instregex "^ADDVv","^SMAXVv","^UMAXVv","^SMINVv","^UMINVv")>;
1362def : InstRW<[THX2T99Write_7Cyc_F01],
1363             (instregex "^SABAv","^UABAv","^SABALv","^UABALv")>;
1364def : InstRW<[THX2T99Write_7Cyc_F01],
1365            (instregex "^SQADDv","^SQSUBv","^UQADDv","^UQSUBv")>;
1366def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^SUQADDv","^USQADDv")>;
1367def : InstRW<[THX2T99Write_7Cyc_F01],
1368            (instregex "^ADDHNv","^RADDHNv", "^RSUBHNv",
1369                       "^SQABS", "^SQADD", "^SQNEG", "^SQSUB",
1370                       "^SRHADD", "^SUBHNv", "^SUQADD",
1371                       "^UQADD", "^UQSUB", "^URHADD", "^USQADD")>;
1372def : InstRW<[THX2T99Write_7Cyc_F01],
1373            (instregex "^CMEQv","^CMGEv","^CMGTv",
1374                       "^CMLEv","^CMLTv", "^CMHIv","^CMHSv")>;
1375def : InstRW<[THX2T99Write_7Cyc_F01],
1376            (instregex "^SMAXv","^SMINv","^UMAXv","^UMINv",
1377                       "^SMAXPv","^SMINPv","^UMAXPv","^UMINPv")>;
1378def : InstRW<[THX2T99Write_7Cyc_F01],
1379            (instregex "^SABDv","^UABDv", "^SABDLv","^UABDLv")>;
1380
1381//---
1382// 3.13 ASIMD Floating-point Instructions
1383//---
1384
1385// ASIMD FP absolute value
1386def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FABSv")>;
1387
1388// ASIMD FP arith, normal, D-form
1389// ASIMD FP arith, normal, Q-form
1390def : InstRW<[THX2T99Write_6Cyc_F01],
1391            (instregex "^FABDv", "^FADDv", "^FSUBv")>;
1392
1393// ASIMD FP arith,pairwise, D-form
1394// ASIMD FP arith, pairwise, Q-form
1395def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "^FADDPv")>;
1396
1397// ASIMD FP compare, D-form
1398// ASIMD FP compare, Q-form
1399def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FACGEv", "^FACGTv")>;
1400def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FCMEQv", "^FCMGEv",
1401                                                 "^FCMGTv", "^FCMLEv",
1402                                                 "^FCMLTv")>;
1403
1404// ASIMD FP round, D-form
1405def : InstRW<[THX2T99Write_7Cyc_F01],
1406            (instregex "^FRINT[AIMNPXZ](v2f32)")>;
1407// ASIMD FP round, Q-form
1408def : InstRW<[THX2T99Write_7Cyc_F01],
1409            (instregex "^FRINT[AIMNPXZ](v4f32|v2f64)")>;
1410
1411// ASIMD FP convert, long
1412// ASIMD FP convert, narrow
1413// ASIMD FP convert, other, D-form
1414// ASIMD FP convert, other, Q-form
1415// NOTE: Handled by WriteV.
1416
1417// ASIMD FP convert, long and narrow
1418def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^FCVT(L|N|XN)v")>;
1419// ASIMD FP convert, other, D-form
1420def : InstRW<[THX2T99Write_7Cyc_F01],
1421      (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v2f32|v1i32|v2i32|v1i64)")>;
1422// ASIMD FP convert, other, Q-form
1423def : InstRW<[THX2T99Write_7Cyc_F01],
1424      (instregex "^[FVSU]CVT([AMNPZ][SU])?(_Int)?(v4f32|v2f64|v4i32|v2i64)")>;
1425
1426// ASIMD FP divide, D-form, F32
1427def : InstRW<[THX2T99Write_16Cyc_F01], (instrs FDIVv2f32)>;
1428def : InstRW<[THX2T99Write_16Cyc_F01], (instregex "FDIVv2f32")>;
1429
1430// ASIMD FP divide, Q-form, F32
1431def : InstRW<[THX2T99Write_16Cyc_F01], (instrs FDIVv4f32)>;
1432def : InstRW<[THX2T99Write_16Cyc_F01], (instregex "FDIVv4f32")>;
1433
1434// ASIMD FP divide, Q-form, F64
1435def : InstRW<[THX2T99Write_23Cyc_F01], (instrs FDIVv2f64)>;
1436def : InstRW<[THX2T99Write_23Cyc_F01], (instregex "FDIVv2f64")>;
1437
1438// ASIMD FP max/min, normal, D-form
1439// ASIMD FP max/min, normal, Q-form
1440def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FMAXv", "^FMAXNMv",
1441                                                "^FMINv", "^FMINNMv")>;
1442
1443// ASIMD FP max/min, pairwise, D-form
1444// ASIMD FP max/min, pairwise, Q-form
1445def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FMAXPv", "^FMAXNMPv",
1446                                                "^FMINPv", "^FMINNMPv")>;
1447
1448// ASIMD FP max/min, reduce
1449def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FMAXVv", "^FMAXNMVv",
1450                                                "^FMINVv", "^FMINNMVv")>;
1451
1452// ASIMD FP multiply, D-form, FZ
1453// ASIMD FP multiply, D-form, no FZ
1454// ASIMD FP multiply, Q-form, FZ
1455// ASIMD FP multiply, Q-form, no FZ
1456def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "^FMULv", "^FMULXv")>;
1457def : InstRW<[THX2T99Write_6Cyc_F01],
1458            (instregex "^FMULX?(v2f32|v1i32|v2i32|v1i64|32|64)")>;
1459def : InstRW<[THX2T99Write_6Cyc_F01],
1460            (instregex "^FMULX?(v4f32|v2f64|v4i32|v2i64)")>;
1461
1462// ASIMD FP multiply accumulate, Dform, FZ
1463// ASIMD FP multiply accumulate, Dform, no FZ
1464// ASIMD FP multiply accumulate, Qform, FZ
1465// ASIMD FP multiply accumulate, Qform, no FZ
1466def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "^FMLAv", "^FMLSv")>;
1467def : InstRW<[THX2T99Write_6Cyc_F01],
1468            (instregex "^FML[AS](v2f32|v1i32|v2i32|v1i64)")>;
1469def : InstRW<[THX2T99Write_6Cyc_F01],
1470            (instregex "^FML[AS](v4f32|v2f64|v4i32|v2i64)")>;
1471
1472// ASIMD FP negate
1473def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FNEGv")>;
1474
1475//--
1476// 3.14 ASIMD Miscellaneous Instructions
1477//--
1478
1479// ASIMD bit reverse
1480def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^RBITv")>;
1481
1482// ASIMD bitwise insert, D-form
1483// ASIMD bitwise insert, Q-form
1484def : InstRW<[THX2T99Write_5Cyc_F01],
1485            (instregex "^BIFv", "^BITv", "^BSLv", "^BSPv")>;
1486
1487// ASIMD count, D-form
1488// ASIMD count, Q-form
1489def : InstRW<[THX2T99Write_5Cyc_F01],
1490            (instregex "^CLSv", "^CLZv", "^CNTv")>;
1491
1492// ASIMD duplicate, gen reg
1493// ASIMD duplicate, element
1494def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^DUPv")>;
1495def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^CPY")>;
1496def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^DUPv.+gpr")>;
1497
1498// ASIMD extract
1499def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^EXTv")>;
1500
1501// ASIMD extract narrow
1502def : InstRW<[THX2T99Write_7Cyc_F01], (instregex "^XTNv")>;
1503
1504// ASIMD extract narrow, saturating
1505def : InstRW<[THX2T99Write_7Cyc_F01],
1506            (instregex "^SQXTNv", "^SQXTUNv", "^UQXTNv")>;
1507
1508// ASIMD insert, element to element
1509def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^INSv")>;
1510
1511// ASIMD transfer, element to gen reg
1512def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^[SU]MOVv")>;
1513
1514// ASIMD move, integer immed
1515def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^MOVIv")>;
1516
1517// ASIMD move, FP immed
1518def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^FMOVv")>;
1519
1520// ASIMD reciprocal estimate, D-form
1521// ASIMD reciprocal estimate, Q-form
1522def : InstRW<[THX2T99Write_5Cyc_F01],
1523            (instregex "^FRECPEv", "^FRECPXv", "^URECPEv",
1524                       "^FRSQRTEv", "^URSQRTEv")>;
1525
1526// ASIMD reciprocal step, D-form, FZ
1527// ASIMD reciprocal step, D-form, no FZ
1528// ASIMD reciprocal step, Q-form, FZ
1529// ASIMD reciprocal step, Q-form, no FZ
1530def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "^FRECPSv", "^FRSQRTSv")>;
1531
1532// ASIMD reverse
1533def : InstRW<[THX2T99Write_5Cyc_F01],
1534            (instregex "^REV16v", "^REV32v", "^REV64v")>;
1535
1536// ASIMD table lookup, D-form
1537// ASIMD table lookup, Q-form
1538def : InstRW<[THX2T99Write_8Cyc_F01], (instregex "^TBLv", "^TBXv")>;
1539
1540// ASIMD transfer, element to word or word
1541def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^[SU]MOVv")>;
1542
1543// ASIMD transfer, element to gen reg
1544def : InstRW<[THX2T99Write_6Cyc_F01], (instregex "(S|U)MOVv.*")>;
1545
1546// ASIMD transfer gen reg to element
1547def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^INSv")>;
1548
1549// ASIMD transpose
1550def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^TRN1v", "^TRN2v",
1551                                                 "^UZP1v", "^UZP2v")>;
1552
1553// ASIMD unzip/zip
1554def : InstRW<[THX2T99Write_5Cyc_F01], (instregex "^ZIP1v", "^ZIP2v")>;
1555
1556//--
1557// 3.15 ASIMD Load Instructions
1558//--
1559
1560// ASIMD load, 1 element, multiple, 1 reg, D-form
1561// ASIMD load, 1 element, multiple, 1 reg, Q-form
1562def : InstRW<[THX2T99Write_4Cyc_LS01],
1563            (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1564def : InstRW<[THX2T99Write_4Cyc_LS01, WriteAdr],
1565            (instregex "^LD1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1566
1567// ASIMD load, 1 element, multiple, 2 reg, D-form
1568// ASIMD load, 1 element, multiple, 2 reg, Q-form
1569def : InstRW<[THX2T99Write_4Cyc_LS01],
1570            (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1571def : InstRW<[THX2T99Write_4Cyc_LS01, WriteAdr],
1572            (instregex "^LD1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1573
1574// ASIMD load, 1 element, multiple, 3 reg, D-form
1575// ASIMD load, 1 element, multiple, 3 reg, Q-form
1576def : InstRW<[THX2T99Write_5Cyc_LS01],
1577            (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1578def : InstRW<[THX2T99Write_5Cyc_LS01, WriteAdr],
1579            (instregex "^LD1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1580
1581// ASIMD load, 1 element, multiple, 4 reg, D-form
1582// ASIMD load, 1 element, multiple, 4 reg, Q-form
1583def : InstRW<[THX2T99Write_6Cyc_LS01],
1584            (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1585def : InstRW<[THX2T99Write_6Cyc_LS01, WriteAdr],
1586            (instregex "^LD1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1587
1588// ASIMD load, 1 element, one lane, B/H/S
1589// ASIMD load, 1 element, one lane, D
1590def : InstRW<[THX2T99Write_5Cyc_LS01_F01], (instregex "^LD1i(8|16|32|64)$")>;
1591def : InstRW<[THX2T99Write_5Cyc_LS01_F01, WriteAdr],
1592            (instregex "^LD1i(8|16|32|64)_POST$")>;
1593
1594// ASIMD load, 1 element, all lanes, D-form, B/H/S
1595// ASIMD load, 1 element, all lanes, D-form, D
1596// ASIMD load, 1 element, all lanes, Q-form
1597def : InstRW<[THX2T99Write_5Cyc_LS01_F01],
1598            (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1599def : InstRW<[THX2T99Write_5Cyc_LS01_F01, WriteAdr],
1600            (instregex "^LD1Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1601
1602// ASIMD load, 2 element, multiple, D-form, B/H/S
1603// ASIMD load, 2 element, multiple, Q-form, D
1604def : InstRW<[THX2T99Write_5Cyc_LS01_F01],
1605            (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
1606def : InstRW<[THX2T99Write_5Cyc_LS01_F01, WriteAdr],
1607            (instregex "^LD2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1608
1609// ASIMD load, 2 element, one lane, B/H
1610// ASIMD load, 2 element, one lane, S
1611// ASIMD load, 2 element, one lane, D
1612def : InstRW<[THX2T99Write_5Cyc_LS01_F01], (instregex "^LD2i(8|16|32|64)$")>;
1613def : InstRW<[THX2T99Write_5Cyc_LS01_F01, WriteAdr],
1614            (instregex "^LD2i(8|16|32|64)_POST$")>;
1615
1616// ASIMD load, 2 element, all lanes, D-form, B/H/S
1617// ASIMD load, 2 element, all lanes, D-form, D
1618// ASIMD load, 2 element, all lanes, Q-form
1619def : InstRW<[THX2T99Write_5Cyc_LS01_F01],
1620            (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1621def : InstRW<[THX2T99Write_5Cyc_LS01_F01, WriteAdr],
1622            (instregex "^LD2Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1623
1624// ASIMD load, 3 element, multiple, D-form, B/H/S
1625// ASIMD load, 3 element, multiple, Q-form, B/H/S
1626// ASIMD load, 3 element, multiple, Q-form, D
1627def : InstRW<[THX2T99Write_8Cyc_LS01_F01],
1628            (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
1629def : InstRW<[THX2T99Write_8Cyc_LS01_F01, WriteAdr],
1630            (instregex "^LD3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1631
1632// ASIMD load, 3 element, one lone, B/H
1633// ASIMD load, 3 element, one lane, S
1634// ASIMD load, 3 element, one lane, D
1635def : InstRW<[THX2T99Write_7Cyc_LS01_F01], (instregex "^LD3i(8|16|32|64)$")>;
1636def : InstRW<[THX2T99Write_7Cyc_LS01_F01, WriteAdr],
1637            (instregex "^LD3i(8|16|32|64)_POST$")>;
1638
1639// ASIMD load, 3 element, all lanes, D-form, B/H/S
1640// ASIMD load, 3 element, all lanes, D-form, D
1641// ASIMD load, 3 element, all lanes, Q-form, B/H/S
1642// ASIMD load, 3 element, all lanes, Q-form, D
1643def : InstRW<[THX2T99Write_7Cyc_LS01_F01],
1644            (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1645def : InstRW<[THX2T99Write_7Cyc_LS01_F01, WriteAdr],
1646            (instregex "^LD3Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1647
1648// ASIMD load, 4 element, multiple, D-form, B/H/S
1649// ASIMD load, 4 element, multiple, Q-form, B/H/S
1650// ASIMD load, 4 element, multiple, Q-form, D
1651def : InstRW<[THX2T99Write_8Cyc_LS01_F01],
1652            (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
1653def : InstRW<[THX2T99Write_8Cyc_LS01_F01, WriteAdr],
1654            (instregex "^LD4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1655
1656// ASIMD load, 4 element, one lane, B/H
1657// ASIMD load, 4 element, one lane, S
1658// ASIMD load, 4 element, one lane, D
1659def : InstRW<[THX2T99Write_6Cyc_LS01_F01], (instregex "^LD4i(8|16|32|64)$")>;
1660def : InstRW<[THX2T99Write_6Cyc_LS01_F01, WriteAdr],
1661            (instregex "^LD4i(8|16|32|64)_POST$")>;
1662
1663// ASIMD load, 4 element, all lanes, D-form, B/H/S
1664// ASIMD load, 4 element, all lanes, D-form, D
1665// ASIMD load, 4 element, all lanes, Q-form, B/H/S
1666// ASIMD load, 4 element, all lanes, Q-form, D
1667def : InstRW<[THX2T99Write_6Cyc_LS01_F01],
1668            (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1669def : InstRW<[THX2T99Write_6Cyc_LS01_F01, WriteAdr],
1670            (instregex "^LD4Rv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1671
1672//--
1673// 3.16 ASIMD Store Instructions
1674//--
1675
1676// ASIMD store, 1 element, multiple, 1 reg, D-form
1677// ASIMD store, 1 element, multiple, 1 reg, Q-form
1678def : InstRW<[THX2T99Write_1Cyc_LS01],
1679            (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1680def : InstRW<[THX2T99Write_1Cyc_LS01, WriteAdr],
1681            (instregex "^ST1Onev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1682
1683// ASIMD store, 1 element, multiple, 2 reg, D-form
1684// ASIMD store, 1 element, multiple, 2 reg, Q-form
1685def : InstRW<[THX2T99Write_1Cyc_LS01],
1686            (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1687def : InstRW<[THX2T99Write_1Cyc_LS01, WriteAdr],
1688            (instregex "^ST1Twov(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1689
1690// ASIMD store, 1 element, multiple, 3 reg, D-form
1691// ASIMD store, 1 element, multiple, 3 reg, Q-form
1692def : InstRW<[THX2T99Write_1Cyc_LS01],
1693            (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1694def : InstRW<[THX2T99Write_1Cyc_LS01, WriteAdr],
1695            (instregex "^ST1Threev(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1696
1697// ASIMD store, 1 element, multiple, 4 reg, D-form
1698// ASIMD store, 1 element, multiple, 4 reg, Q-form
1699def : InstRW<[THX2T99Write_1Cyc_LS01],
1700            (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)$")>;
1701def : InstRW<[THX2T99Write_1Cyc_LS01, WriteAdr],
1702            (instregex "^ST1Fourv(8b|4h|2s|1d|16b|8h|4s|2d)_POST$")>;
1703
1704// ASIMD store, 1 element, one lane, B/H/S
1705// ASIMD store, 1 element, one lane, D
1706def : InstRW<[THX2T99Write_1Cyc_LS01_F01],
1707            (instregex "^ST1i(8|16|32|64)$")>;
1708def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1709            (instregex "^ST1i(8|16|32|64)_POST$")>;
1710
1711// ASIMD store, 2 element, multiple, D-form, B/H/S
1712// ASIMD store, 2 element, multiple, Q-form, B/H/S
1713// ASIMD store, 2 element, multiple, Q-form, D
1714def : InstRW<[THX2T99Write_1Cyc_LS01_F01],
1715            (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)$")>;
1716def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1717            (instregex "^ST2Twov(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1718
1719// ASIMD store, 2 element, one lane, B/H/S
1720// ASIMD store, 2 element, one lane, D
1721def : InstRW<[THX2T99Write_1Cyc_LS01_F01],
1722            (instregex "^ST2i(8|16|32|64)$")>;
1723def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1724            (instregex "^ST2i(8|16|32|64)_POST$")>;
1725
1726// ASIMD store, 3 element, multiple, D-form, B/H/S
1727// ASIMD store, 3 element, multiple, Q-form, B/H/S
1728// ASIMD store, 3 element, multiple, Q-form, D
1729def : InstRW<[THX2T99Write_1Cyc_LS01_F01],
1730            (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)$")>;
1731def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1732            (instregex "^ST3Threev(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1733
1734// ASIMD store, 3 element, one lane, B/H
1735// ASIMD store, 3 element, one lane, S
1736// ASIMD store, 3 element, one lane, D
1737def : InstRW<[THX2T99Write_1Cyc_LS01_F01], (instregex "^ST3i(8|16|32|64)$")>;
1738def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1739            (instregex "^ST3i(8|16|32|64)_POST$")>;
1740
1741// ASIMD store, 4 element, multiple, D-form, B/H/S
1742// ASIMD store, 4 element, multiple, Q-form, B/H/S
1743// ASIMD store, 4 element, multiple, Q-form, D
1744def : InstRW<[THX2T99Write_1Cyc_LS01_F01],
1745            (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)$")>;
1746def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1747            (instregex "^ST4Fourv(8b|4h|2s|16b|8h|4s|2d)_POST$")>;
1748
1749// ASIMD store, 4 element, one lane, B/H
1750// ASIMD store, 4 element, one lane, S
1751// ASIMD store, 4 element, one lane, D
1752def : InstRW<[THX2T99Write_1Cyc_LS01_F01], (instregex "^ST4i(8|16|32|64)$")>;
1753def : InstRW<[THX2T99Write_1Cyc_LS01_F01, WriteAdr],
1754            (instregex "^ST4i(8|16|32|64)_POST$")>;
1755
1756// V8.1a Atomics (LSE)
1757def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1758            (instrs CASB, CASH, CASW, CASX)>;
1759
1760def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1761            (instrs CASAB, CASAH, CASAW, CASAX)>;
1762
1763def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1764            (instrs CASLB, CASLH, CASLW, CASLX)>;
1765
1766def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1767            (instrs CASALB, CASALH, CASALW, CASALX)>;
1768
1769def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1770            (instrs LDLARB, LDLARH, LDLARW, LDLARX)>;
1771
1772def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1773            (instrs LDADDB, LDADDH, LDADDW, LDADDX)>;
1774
1775def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1776            (instrs LDADDAB, LDADDAH, LDADDAW, LDADDAX)>;
1777
1778def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1779            (instrs LDADDLB, LDADDLH, LDADDLW, LDADDLX)>;
1780
1781def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1782            (instrs LDADDALB, LDADDALH, LDADDALW, LDADDALX)>;
1783
1784def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1785            (instrs LDCLRB, LDCLRH, LDCLRW, LDCLRX)>;
1786
1787def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1788            (instrs LDCLRAB, LDCLRAH, LDCLRAW, LDCLRAX)>;
1789
1790def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1791            (instrs LDCLRLB, LDCLRLH, LDCLRLW, LDCLRLX)>;
1792
1793def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1794            (instrs LDCLRALB, LDCLRALH, LDCLRALW, LDCLRALX)>;
1795
1796def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1797            (instrs LDEORB, LDEORH, LDEORW, LDEORX)>;
1798
1799def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1800            (instrs LDEORAB, LDEORAH, LDEORAW, LDEORAX)>;
1801
1802def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1803            (instrs LDEORLB, LDEORLH, LDEORLW, LDEORLX)>;
1804
1805def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1806            (instrs LDEORALB, LDEORALH, LDEORALW, LDEORALX)>;
1807
1808def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1809            (instrs LDSETB, LDSETH, LDSETW, LDSETX)>;
1810
1811def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1812            (instrs LDSETAB, LDSETAH, LDSETAW, LDSETAX)>;
1813
1814def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1815            (instrs LDSETLB, LDSETLH, LDSETLW, LDSETLX)>;
1816
1817def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1818            (instrs LDSETALB, LDSETALH, LDSETALW, LDSETALX)>;
1819
1820def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1821            (instrs LDSMAXB, LDSMAXH, LDSMAXW, LDSMAXX,
1822             LDSMAXAB, LDSMAXAH, LDSMAXAW, LDSMAXAX,
1823             LDSMAXLB, LDSMAXLH, LDSMAXLW, LDSMAXLX,
1824             LDSMAXALB, LDSMAXALH, LDSMAXALW, LDSMAXALX)>;
1825
1826def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1827            (instrs LDSMINB, LDSMINH, LDSMINW, LDSMINX,
1828             LDSMINAB, LDSMINAH, LDSMINAW, LDSMINAX,
1829             LDSMINLB, LDSMINLH, LDSMINLW, LDSMINLX,
1830             LDSMINALB, LDSMINALH, LDSMINALW, LDSMINALX)>;
1831
1832def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1833            (instrs LDUMAXB, LDUMAXH, LDUMAXW, LDUMAXX,
1834             LDUMAXAB, LDUMAXAH, LDUMAXAW, LDUMAXAX,
1835             LDUMAXLB, LDUMAXLH, LDUMAXLW, LDUMAXLX,
1836             LDUMAXALB, LDUMAXALH, LDUMAXALW, LDUMAXALX)>;
1837
1838def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1839            (instrs LDUMINB, LDUMINH, LDUMINW, LDUMINX,
1840             LDUMINAB, LDUMINAH, LDUMINAW, LDUMINAX,
1841             LDUMINLB, LDUMINLH, LDUMINLW, LDUMINLX,
1842             LDUMINALB, LDUMINALH, LDUMINALW, LDUMINALX)>;
1843
1844def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1845            (instrs SWPB, SWPH, SWPW, SWPX)>;
1846
1847def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1848            (instrs SWPAB, SWPAH, SWPAW, SWPAX)>;
1849
1850def : InstRW<[THX2T99Write_12Cyc_I012, WriteAtomic],
1851            (instrs SWPLB, SWPLH, SWPLW, SWPLX)>;
1852
1853def : InstRW<[THX2T99Write_16Cyc_I012, WriteAtomic],
1854            (instrs SWPALB, SWPALH, SWPALW, SWPALX)>;
1855
1856def : InstRW<[THX2T99Write_8Cyc_I012, WriteAtomic],
1857            (instrs STLLRB, STLLRH, STLLRW, STLLRX)>;
1858
1859} // SchedModel = ThunderX2T99Model
1860
1861