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