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