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