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