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