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