Home | History | Annotate | Download | only in AArch64
      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 
   1881