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