Home | History | Annotate | Download | only in AArch64
      1 //=- AArch64SchedExynosM1.td - Samsung Exynos M1 Sched Defs --*- 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 machine model for the Samsung Exynos M1 to support
     11 // instruction scheduling and other instruction cost heuristics.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 //===----------------------------------------------------------------------===//
     16 // The Exynos-M1 is a traditional superscalar microprocessor with a
     17 // 4-wide in-order stage for decode and dispatch and a wider issue stage.
     18 // The execution units and loads and stores are out-of-order.
     19 
     20 def ExynosM1Model : SchedMachineModel {
     21   let IssueWidth            =  4; // Up to 4 uops per cycle.
     22   let MicroOpBufferSize     = 96; // ROB size.
     23   let LoopMicroOpBufferSize = 24; // Based on the instruction queue size.
     24   let LoadLatency           =  4; // Optimistic load cases.
     25   let MispredictPenalty     = 14; // Minimum branch misprediction penalty.
     26   let CompleteModel         =  1; // Use the default model otherwise.
     27 
     28   list<Predicate> UnsupportedFeatures = [HasSVE];
     29 }
     30 
     31 //===----------------------------------------------------------------------===//
     32 // Define each kind of processor resource and number available on the Exynos-M1,
     33 // which has 9 pipelines, each with its own queue with out-of-order dispatch.
     34 
     35 let SchedModel = ExynosM1Model in {
     36 
     37 def M1UnitA  : ProcResource<2>; // Simple integer
     38 def M1UnitC  : ProcResource<1>; // Simple and complex integer
     39 def M1UnitD  : ProcResource<1>; // Integer division (inside C, serialized)
     40 def M1UnitB  : ProcResource<2>; // Branch
     41 def M1UnitL  : ProcResource<1>; // Load
     42 def M1UnitS  : ProcResource<1>; // Store
     43 def M1PipeF0 : ProcResource<1>; // FP #0
     44 let Super = M1PipeF0 in {
     45   def M1UnitFMAC   : ProcResource<1>; // FP multiplication
     46   def M1UnitNAL0   : ProcResource<1>; // Simple vector
     47   def M1UnitNMISC  : ProcResource<1>; // Miscellanea
     48   def M1UnitFCVT   : ProcResource<1>; // FP conversion
     49   def M1UnitNCRYPT : ProcResource<1>; // Cryptographic
     50 }
     51 def M1PipeF1 : ProcResource<1>; // FP #1
     52 let Super = M1PipeF1 in {
     53   def M1UnitFADD : ProcResource<1>; // Simple FP
     54   def M1UnitNAL1 : ProcResource<1>; // Simple vector
     55   def M1UnitFVAR : ProcResource<1>; // FP division & square root (serialized)
     56   def M1UnitFST  : ProcResource<1>; // FP store
     57 }
     58 
     59 def M1UnitALU  : ProcResGroup<[M1UnitA,
     60                                M1UnitC]>;    // All integer
     61 def M1UnitNALU : ProcResGroup<[M1UnitNAL0,
     62                                M1UnitNAL1]>; // All simple vector
     63 
     64 //===----------------------------------------------------------------------===//
     65 // Predicates.
     66 
     67 def M1BranchLinkFastPred : SchedPredicate<[{MI->getOpcode() == AArch64::BLR &&
     68                                             MI->getOperand(0).getReg() != AArch64::LR}]>;
     69 def M1ShiftLeftFastPred  : SchedPredicate<[{TII->isExynosShiftLeftFast(*MI)}]>;
     70 
     71 //===----------------------------------------------------------------------===//
     72 // Coarse scheduling model.
     73 
     74 def M1WriteA1 : SchedWriteRes<[M1UnitALU]> { let Latency = 1; }
     75 def M1WriteA2 : SchedWriteRes<[M1UnitALU]> { let Latency = 2; }
     76 def M1WriteAA : SchedWriteRes<[M1UnitALU]> { let Latency = 2;
     77                                              let ResourceCycles = [2]; }
     78 def M1WriteAB : SchedWriteRes<[M1UnitALU,
     79                                M1UnitC]>   { let Latency = 1;
     80                                              let NumMicroOps = 2; }
     81 def M1WriteAC : SchedWriteRes<[M1UnitALU,
     82                                M1UnitALU,
     83                                M1UnitC]>   { let Latency = 2;
     84                                              let NumMicroOps = 3; }
     85 def M1WriteAD : SchedWriteRes<[M1UnitALU,
     86                                M1UnitC]>   { let Latency = 2;
     87                                              let NumMicroOps = 2; }
     88 def M1WriteAX : SchedWriteVariant<[SchedVar<M1ShiftLeftFastPred, [M1WriteA1]>,
     89                                    SchedVar<NoSchedPred,         [M1WriteAA]>]>;
     90 def M1WriteC1 : SchedWriteRes<[M1UnitC]>   { let Latency = 1; }
     91 def M1WriteC2 : SchedWriteRes<[M1UnitC]>   { let Latency = 2; }
     92 
     93 def M1WriteB1 : SchedWriteRes<[M1UnitB]> { let Latency = 1; }
     94 def M1WriteBX : SchedWriteVariant<[SchedVar<M1BranchLinkFastPred, [M1WriteAB]>,
     95                                    SchedVar<NoSchedPred,          [M1WriteAC]>]>;
     96 
     97 def M1WriteL5 : SchedWriteRes<[M1UnitL]> { let Latency = 5; }
     98 def M1WriteL6 : SchedWriteRes<[M1UnitL]> { let Latency = 6; }
     99 def M1WriteLA : SchedWriteRes<[M1UnitL]> { let Latency = 6;
    100                                            let ResourceCycles = [2]; }
    101 def M1WriteLB : SchedWriteRes<[M1UnitL,
    102                                M1UnitA]> { let Latency = 4;
    103                                            let NumMicroOps = 2; }
    104 def M1WriteLC : SchedWriteRes<[M1UnitL,
    105                                M1UnitA]> { let Latency = 5;
    106                                            let NumMicroOps = 2; }
    107 def M1WriteLD : SchedWriteRes<[M1UnitL,
    108                                M1UnitA]> { let Latency = 6;
    109                                            let NumMicroOps = 2;
    110                                            let ResourceCycles = [2, 1]; }
    111 def M1WriteLH : SchedWriteRes<[]>        { let Latency = 5;
    112                                            let NumMicroOps = 0; }
    113 def M1WriteLX : SchedWriteVariant<[SchedVar<M1ShiftLeftFastPred, [M1WriteL5]>,
    114                                    SchedVar<NoSchedPred,         [M1WriteLC]>]>;
    115 def M1WriteLY : SchedWriteVariant<[SchedVar<M1ShiftLeftFastPred, [M1WriteL5]>,
    116                                    SchedVar<NoSchedPred,         [M1WriteLD]>]>;
    117 
    118 def M1WriteS1 : SchedWriteRes<[M1UnitS]>   { let Latency = 1; }
    119 def M1WriteS3 : SchedWriteRes<[M1UnitS]>   { let Latency = 3; }
    120 def M1WriteS4 : SchedWriteRes<[M1UnitS]>   { let Latency = 4; }
    121 def M1WriteSA : SchedWriteRes<[M1UnitS,
    122                                M1UnitFST,
    123                                M1UnitS,
    124                                M1UnitFST]> { let Latency = 1;
    125                                              let NumMicroOps = 2; }
    126 def M1WriteSB : SchedWriteRes<[M1UnitS,
    127                                M1UnitFST,
    128                                M1UnitA]>   { let Latency = 3;
    129                                              let NumMicroOps = 2; }
    130 def M1WriteSC : SchedWriteRes<[M1UnitS,
    131                                M1UnitFST,
    132                                M1UnitS,
    133                                M1UnitFST,
    134                                M1UnitA]>   { let Latency = 3;
    135                                              let NumMicroOps = 3; }
    136 def M1WriteSD : SchedWriteRes<[M1UnitS,
    137                                M1UnitFST,
    138                                M1UnitA]>   { let Latency = 1;
    139                                              let NumMicroOps = 2; }
    140 def M1WriteSE : SchedWriteRes<[M1UnitS,
    141                                M1UnitA]>   { let Latency = 2;
    142                                              let NumMicroOps = 2; }
    143 def M1WriteSX : SchedWriteVariant<[SchedVar<M1ShiftLeftFastPred, [M1WriteS1]>,
    144                                    SchedVar<NoSchedPred,         [M1WriteSE]>]>;
    145 def M1WriteSY : SchedWriteVariant<[SchedVar<M1ShiftLeftFastPred, [M1WriteS1]>,
    146                                    SchedVar<NoSchedPred,         [M1WriteSB]>]>;
    147 
    148 def M1ReadAdrBase : SchedReadVariant<[SchedVar<ScaledIdxPred, [ReadDefault]>,
    149                                       SchedVar<NoSchedPred,   [ReadDefault]>]>;
    150 
    151 // Branch instructions.
    152 def : WriteRes<WriteBr,    []>        { let Latency = 0; }
    153 def : WriteRes<WriteBrReg, [M1UnitC]> { let Latency = 1; }
    154 
    155 // Arithmetic and logical integer instructions.
    156 def : WriteRes<WriteI,     [M1UnitALU]> { let Latency = 1; }
    157 def : WriteRes<WriteISReg, [M1UnitALU]> { let Latency = 1; }
    158 def : WriteRes<WriteIEReg, [M1UnitALU]> { let Latency = 1; }
    159 def : WriteRes<WriteIS,    [M1UnitALU]> { let Latency = 1; }
    160 
    161 // Move instructions.
    162 def : WriteRes<WriteImm, [M1UnitALU]> { let Latency = 1; }
    163 
    164 // Divide and multiply instructions.
    165 def : WriteRes<WriteID32, [M1UnitC,
    166                            M1UnitD]> { let Latency = 13;
    167                                        let ResourceCycles = [1, 13]; }
    168 def : WriteRes<WriteID64, [M1UnitC,
    169                            M1UnitD]> { let Latency = 21;
    170                                        let ResourceCycles = [1, 21]; }
    171 // TODO: Long multiplication take 5 cycles and also the ALU.
    172 def : WriteRes<WriteIM32, [M1UnitC]> { let Latency = 3; }
    173 def : WriteRes<WriteIM64, [M1UnitC]> { let Latency = 4;
    174                                        let ResourceCycles = [2]; }
    175 
    176 // Miscellaneous instructions.
    177 def : WriteRes<WriteExtr, [M1UnitALU,
    178                            M1UnitALU]> { let Latency = 2;
    179                                          let NumMicroOps = 2; }
    180 
    181 // Addressing modes.
    182 def : WriteRes<WriteAdr, []> { let Latency = 1;
    183                                let NumMicroOps = 0; }
    184 def : SchedAlias<ReadAdrBase, M1ReadAdrBase>;
    185 
    186 // Load instructions.
    187 def : WriteRes<WriteLD,    [M1UnitL]>   { let Latency = 4; }
    188 def : WriteRes<WriteLDHi,  []>          { let Latency = 4;
    189                                           let NumMicroOps = 0; }
    190 def : SchedAlias<WriteLDIdx, M1WriteLX>;
    191 
    192 // Store instructions.
    193 def : WriteRes<WriteST,    [M1UnitS]> { let Latency = 1; }
    194 def : WriteRes<WriteSTP,   [M1UnitS]> { let Latency = 1; }
    195 def : WriteRes<WriteSTX,   [M1UnitS]> { let Latency = 1; }
    196 def : SchedAlias<WriteSTIdx, M1WriteSX>;
    197 
    198 // FP data instructions.
    199 def : WriteRes<WriteF,    [M1UnitFADD]>  { let Latency = 3; }
    200 def : WriteRes<WriteFCmp, [M1UnitNMISC]> { let Latency = 4; }
    201 def : WriteRes<WriteFDiv, [M1UnitFVAR]>  { let Latency = 15;
    202                                            let ResourceCycles = [15]; }
    203 def : WriteRes<WriteFMul, [M1UnitFMAC]>  { let Latency = 4; }
    204 
    205 // FP miscellaneous instructions.
    206 def : WriteRes<WriteFCvt,  [M1UnitFCVT]> { let Latency = 3; }
    207 def : WriteRes<WriteFImm,  [M1UnitNALU]> { let Latency = 1; }
    208 def : WriteRes<WriteFCopy, [M1UnitS]>    { let Latency = 4; }
    209 
    210 // FP load instructions.
    211 def : WriteRes<WriteVLD,   [M1UnitL]> { let Latency = 5; }
    212 
    213 // FP store instructions.
    214 def : WriteRes<WriteVST, [M1UnitS,
    215                           M1UnitFST]> { let Latency = 1;
    216                                         let NumMicroOps = 1; }
    217 
    218 // ASIMD FP instructions.
    219 def : WriteRes<WriteV, [M1UnitFADD]> { let Latency = 3; }
    220 
    221 // Other miscellaneous instructions.
    222 def : WriteRes<WriteAtomic,  []> { let Unsupported = 1; }
    223 def : WriteRes<WriteBarrier, []> { let Latency = 1; }
    224 def : WriteRes<WriteHint,    []> { let Latency = 1; }
    225 def : WriteRes<WriteSys,     []> { let Latency = 1; }
    226 
    227 //===----------------------------------------------------------------------===//
    228 // Fast forwarding.
    229 
    230 // TODO: Add FP register forwarding rules.
    231 def : ReadAdvance<ReadI,       0>;
    232 def : ReadAdvance<ReadISReg,   0>;
    233 def : ReadAdvance<ReadIEReg,   0>;
    234 def : ReadAdvance<ReadIM,      0>;
    235 // TODO: The forwarding for WriteIM32 saves actually 2 cycles.
    236 def : ReadAdvance<ReadIMA,     3, [WriteIM32, WriteIM64]>;
    237 def : ReadAdvance<ReadID,      0>;
    238 def : ReadAdvance<ReadExtrHi,  0>;
    239 def : ReadAdvance<ReadAdrBase, 0>;
    240 def : ReadAdvance<ReadVLD,     0>;
    241 
    242 //===----------------------------------------------------------------------===//
    243 // Finer scheduling model.
    244 
    245 def M1WriteNEONA   : SchedWriteRes<[M1UnitNALU,
    246                                     M1UnitNALU,
    247                                     M1UnitFADD]>   { let Latency = 9;
    248                                                      let NumMicroOps = 3; }
    249 def M1WriteNEONB   : SchedWriteRes<[M1UnitNALU,
    250                                     M1UnitFST]>    { let Latency = 5;
    251                                                      let NumMicroOps = 2;}
    252 def M1WriteNEONC   : SchedWriteRes<[M1UnitNALU,
    253                                     M1UnitFST]>    { let Latency = 6;
    254                                                      let NumMicroOps = 2; }
    255 def M1WriteNEOND   : SchedWriteRes<[M1UnitNALU,
    256                                     M1UnitFST,
    257                                     M1UnitL]>      { let Latency = 10;
    258                                                      let NumMicroOps = 3; }
    259 def M1WriteNEONE   : SchedWriteRes<[M1UnitFCVT,
    260                                     M1UnitFST]>    { let Latency = 8;
    261                                                      let NumMicroOps = 2; }
    262 def M1WriteNEONF   : SchedWriteRes<[M1UnitFCVT,
    263                                     M1UnitFST,
    264                                     M1UnitL]>      { let Latency = 13;
    265                                                      let NumMicroOps = 3; }
    266 def M1WriteNEONG   : SchedWriteRes<[M1UnitNMISC,
    267                                     M1UnitFST]>    { let Latency = 6;
    268                                                      let NumMicroOps = 2; }
    269 def M1WriteNEONH   : SchedWriteRes<[M1UnitNALU,
    270                                     M1UnitFST]>    { let Latency = 3;
    271                                                      let NumMicroOps = 2; }
    272 def M1WriteNEONI   : SchedWriteRes<[M1UnitFST,
    273                                     M1UnitL]>      { let Latency = 9;
    274                                                      let NumMicroOps = 2; }
    275 def M1WriteNEONJ   : SchedWriteRes<[M1UnitNMISC,
    276                                     M1UnitFMAC]>   { let Latency = 6;
    277                                                      let NumMicroOps = 2; }
    278 def M1WriteNEONK   : SchedWriteRes<[M1UnitNMISC,
    279                                     M1UnitFMAC]>   { let Latency = 7;
    280                                                      let NumMicroOps = 2; }
    281 def M1WriteNEONL   : SchedWriteRes<[M1UnitNALU]>   { let Latency = 2;
    282                                                      let ResourceCycles = [2]; }
    283 def M1WriteFADD3   : SchedWriteRes<[M1UnitFADD]>   { let Latency = 3; }
    284 def M1WriteFCVT3   : SchedWriteRes<[M1UnitFCVT]>   { let Latency = 3; }
    285 def M1WriteFCVT4   : SchedWriteRes<[M1UnitFCVT]>   { let Latency = 4; }
    286 def M1WriteFMAC4   : SchedWriteRes<[M1UnitFMAC]>   { let Latency = 4; }
    287 def M1WriteFMAC5   : SchedWriteRes<[M1UnitFMAC]>   { let Latency = 5; }
    288 // TODO
    289 def M1WriteFVAR15  : SchedWriteRes<[M1UnitFVAR]>   { let Latency = 15;
    290                                                      let ResourceCycles = [15]; }
    291 def M1WriteFVAR23  : SchedWriteRes<[M1UnitFVAR]>   { let Latency = 23;
    292                                                      let ResourceCycles = [23]; }
    293 def M1WriteNALU1   : SchedWriteRes<[M1UnitNALU]>   { let Latency = 1; }
    294 def M1WriteNALU2   : SchedWriteRes<[M1UnitNALU]>   { let Latency = 2; }
    295 def M1WriteNAL11   : SchedWriteRes<[M1UnitNAL1]>   { let Latency = 1; }
    296 def M1WriteNAL12   : SchedWriteRes<[M1UnitNAL1]>   { let Latency = 2; }
    297 def M1WriteNAL13   : SchedWriteRes<[M1UnitNAL1]>   { let Latency = 3; }
    298 def M1WriteNCRYPT1 : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 1; }
    299 def M1WriteNCRYPT5 : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 5; }
    300 def M1WriteNMISC1  : SchedWriteRes<[M1UnitNMISC]>  { let Latency = 1; }
    301 def M1WriteNMISC2  : SchedWriteRes<[M1UnitNMISC]>  { let Latency = 2; }
    302 def M1WriteNMISC3  : SchedWriteRes<[M1UnitNMISC]>  { let Latency = 3; }
    303 def M1WriteNMISC4  : SchedWriteRes<[M1UnitNMISC]>  { let Latency = 4; }
    304 def M1WriteTB      : SchedWriteRes<[M1UnitC,
    305                                     M1UnitALU]>    { let Latency = 2;
    306                                                      let NumMicroOps = 2; }
    307 def M1WriteVLDA    : SchedWriteRes<[M1UnitL,
    308                                     M1UnitL]>      { let Latency = 6;
    309                                                      let NumMicroOps = 2; }
    310 def M1WriteVLDB    : SchedWriteRes<[M1UnitL,
    311                                     M1UnitL,
    312                                     M1UnitL]>      { let Latency = 7;
    313                                                      let NumMicroOps = 3; }
    314 def M1WriteVLDC    : SchedWriteRes<[M1UnitL,
    315                                     M1UnitL,
    316                                     M1UnitL,
    317                                     M1UnitL]>      { let Latency = 8;
    318                                                      let NumMicroOps = 4; }
    319 def M1WriteVLDD    : SchedWriteRes<[M1UnitL,
    320                                     M1UnitNALU]>   { let Latency = 7;
    321                                                      let NumMicroOps = 2;
    322                                                      let ResourceCycles = [2, 1]; }
    323 def M1WriteVLDE    : SchedWriteRes<[M1UnitL,
    324                                     M1UnitNALU]>   { let Latency = 6;
    325                                                      let NumMicroOps = 2; }
    326 def M1WriteVLDF    : SchedWriteRes<[M1UnitL,
    327                                     M1UnitL]>      { let Latency = 10;
    328                                                      let NumMicroOps = 2;
    329                                                      let ResourceCycles = [1, 1]; }
    330 def M1WriteVLDG    : SchedWriteRes<[M1UnitL,
    331                                     M1UnitNALU,
    332                                     M1UnitNALU]>   { let Latency = 7;
    333                                                      let NumMicroOps = 3;
    334                                                      let ResourceCycles = [2, 1, 1]; }
    335 def M1WriteVLDH    : SchedWriteRes<[M1UnitL,
    336                                     M1UnitNALU,
    337                                     M1UnitNALU]>   { let Latency = 6;
    338                                                      let NumMicroOps = 3; }
    339 def M1WriteVLDI    : SchedWriteRes<[M1UnitL,
    340                                     M1UnitL,
    341                                     M1UnitL]>      { let Latency = 12;
    342                                                      let NumMicroOps = 3;
    343                                                      let ResourceCycles = [2, 2, 2]; }
    344 def M1WriteVLDJ    : SchedWriteRes<[M1UnitL,
    345                                     M1UnitNALU,
    346                                     M1UnitNALU,
    347                                     M1UnitNALU]>   { let Latency = 9;
    348                                                      let NumMicroOps = 4;
    349                                                      let ResourceCycles = [2, 1, 1, 1]; }
    350 def M1WriteVLDK    : SchedWriteRes<[M1UnitL,
    351                                     M1UnitNALU,
    352                                     M1UnitNALU,
    353                                     M1UnitNALU,
    354                                     M1UnitNALU]>   { let Latency = 9;
    355                                                      let NumMicroOps = 5;
    356                                                      let ResourceCycles = [2, 1, 1, 1, 1]; }
    357 def M1WriteVLDL    : SchedWriteRes<[M1UnitL,
    358                                     M1UnitNALU,
    359                                     M1UnitNALU,
    360                                     M1UnitL,
    361                                     M1UnitNALU]>   { let Latency = 7;
    362                                                      let NumMicroOps = 5;
    363                                                      let ResourceCycles = [1, 1, 1, 1, 1]; }
    364 def M1WriteVLDM    : SchedWriteRes<[M1UnitL,
    365                                     M1UnitNALU,
    366                                     M1UnitNALU,
    367                                     M1UnitL,
    368                                     M1UnitNALU,
    369                                     M1UnitNALU]>   { let Latency = 7;
    370                                                      let NumMicroOps = 6;
    371                                                      let ResourceCycles = [1, 1, 1, 1, 1, 1]; }
    372 def M1WriteVLDN    : SchedWriteRes<[M1UnitL,
    373                                     M1UnitL,
    374                                     M1UnitL,
    375                                     M1UnitL]>      { let Latency = 14;
    376                                                      let NumMicroOps = 4;
    377                                                      let ResourceCycles = [2, 1, 2, 1]; }
    378 def M1WriteVSTA    : WriteSequence<[WriteVST], 2>;
    379 def M1WriteVSTB    : WriteSequence<[WriteVST], 3>;
    380 def M1WriteVSTC    : WriteSequence<[WriteVST], 4>;
    381 def M1WriteVSTD    : SchedWriteRes<[M1UnitS,
    382                                     M1UnitFST,
    383                                     M1UnitFST]>    { let Latency = 7;
    384                                                      let NumMicroOps = 2;
    385                                                      let ResourceCycles = [7, 1, 1]; }
    386 def M1WriteVSTE    : SchedWriteRes<[M1UnitS,
    387                                     M1UnitFST,
    388                                     M1UnitS,
    389                                     M1UnitFST,
    390                                     M1UnitFST]>    { let Latency = 8;
    391                                                      let NumMicroOps = 3;
    392                                                      let ResourceCycles = [7, 1, 1, 1, 1]; }
    393 def M1WriteVSTF    : SchedWriteRes<[M1UnitNALU,
    394                                     M1UnitS,
    395                                     M1UnitFST,
    396                                     M1UnitS,
    397                                     M1UnitFST,
    398                                     M1UnitFST,
    399                                     M1UnitFST]>     { let Latency = 15;
    400                                                       let NumMicroOps = 5;
    401                                                       let ResourceCycles = [1, 7, 1, 7, 1, 1, 1]; }
    402 def M1WriteVSTG    : SchedWriteRes<[M1UnitNALU,
    403                                     M1UnitS,
    404                                     M1UnitFST,
    405                                     M1UnitS,
    406                                     M1UnitFST,
    407                                     M1UnitS,
    408                                     M1UnitFST,
    409                                     M1UnitFST,
    410                                     M1UnitFST]>     { let Latency = 16;
    411                                                       let NumMicroOps = 6;
    412                                                       let ResourceCycles = [1, 7, 1, 7, 1, 1, 1, 1, 1]; }
    413 def M1WriteVSTH    : SchedWriteRes<[M1UnitNALU,
    414                                     M1UnitS,
    415                                     M1UnitFST,
    416                                     M1UnitFST,
    417                                     M1UnitFST]>      { let Latency = 14;
    418                                                        let NumMicroOps = 4;
    419                                                        let ResourceCycles = [1, 7, 1, 7, 1]; }
    420 def M1WriteVSTI    : SchedWriteRes<[M1UnitNALU,
    421                                     M1UnitS,
    422                                     M1UnitFST,
    423                                     M1UnitS,
    424                                     M1UnitFST,
    425                                     M1UnitS,
    426                                     M1UnitFST,
    427                                     M1UnitS,
    428                                     M1UnitFST,
    429                                     M1UnitFST,
    430                                     M1UnitFST]>      { let Latency = 17;
    431                                                        let NumMicroOps = 7;
    432                                                        let ResourceCycles = [1, 7, 1, 7, 1, 1, 1, 1, 1, 1, 1]; }
    433 
    434 // Branch instructions
    435 def : InstRW<[M1WriteB1], (instrs Bcc)>;
    436 def : InstRW<[M1WriteA1], (instrs BL)>;
    437 def : InstRW<[M1WriteBX], (instrs BLR)>;
    438 def : InstRW<[M1WriteC1], (instregex "^CBN?Z[WX]")>;
    439 def : InstRW<[M1WriteAD], (instregex "^TBN?Z[WX]")>;
    440 
    441 // Arithmetic and logical integer instructions.
    442 def : InstRW<[M1WriteA1], (instrs COPY)>;
    443 def : InstRW<[M1WriteAX], (instregex ".+r[sx](64)?$")>;
    444 
    445 // Divide and multiply instructions.
    446 
    447 // Miscellaneous instructions.
    448 
    449 // Load instructions.
    450 def : InstRW<[M1WriteLB,
    451               WriteLDHi,
    452               WriteAdr],    (instregex "^LDP(SW|W|X)(post|pre)")>;
    453 def : InstRW<[M1WriteLX,
    454               ReadAdrBase], (instregex "^PRFMro[WX]")>;
    455 
    456 // Store instructions.
    457 
    458 // FP data instructions.
    459 def : InstRW<[M1WriteNALU1],  (instregex "^F(ABS|NEG)[DS]r")>;
    460 def : InstRW<[M1WriteFADD3],  (instregex "^F(ADD|SUB)[DS]rr")>;
    461 def : InstRW<[M1WriteNEONG],  (instregex "^FCCMPE?[DS]rr")>;
    462 def : InstRW<[M1WriteNMISC4], (instregex "^FCMPE?[DS]r")>;
    463 def : InstRW<[M1WriteFVAR15], (instrs FDIVSrr)>;
    464 def : InstRW<[M1WriteFVAR23], (instrs FDIVDrr)>;
    465 def : InstRW<[M1WriteNMISC2], (instregex "^F(MAX|MIN).+rr")>;
    466 def : InstRW<[M1WriteFMAC4],  (instregex "^FN?MUL[DS]rr")>;
    467 def : InstRW<[M1WriteFMAC5],  (instregex "^FN?M(ADD|SUB)[DS]rrr")>;
    468 def : InstRW<[M1WriteFCVT3],  (instregex "^FRINT.+r")>;
    469 def : InstRW<[M1WriteNEONH],  (instregex "^FCSEL[DS]rrr")>;
    470 def : InstRW<[M1WriteFVAR15], (instrs FSQRTSr)>;
    471 def : InstRW<[M1WriteFVAR23], (instrs FSQRTDr)>;
    472 
    473 // FP miscellaneous instructions.
    474 def : InstRW<[M1WriteFCVT3],  (instregex "^FCVT[DS][DS]r")>;
    475 def : InstRW<[M1WriteNEONF],  (instregex "^[FSU]CVT[AMNPZ][SU](_Int)?[SU]?[XW]?[DS]?[rds]i?")>;
    476 def : InstRW<[M1WriteNEONE],  (instregex "^[SU]CVTF[SU]")>;
    477 def : InstRW<[M1WriteNALU1],  (instregex "^FMOV[DS][ir]")>;
    478 def : InstRW<[M1WriteFCVT4],  (instregex "^[FU](RECP|RSQRT)Ev1")>;
    479 def : InstRW<[M1WriteNMISC1], (instregex "^FRECPXv1")>;
    480 def : InstRW<[M1WriteFMAC5],  (instregex "^F(RECP|RSQRT)S(16|32|64)")>;
    481 def : InstRW<[M1WriteS4],     (instregex "^FMOV[WX][DS](High)?r")>;
    482 def : InstRW<[M1WriteNEONI],  (instregex "^FMOV[DS][WX](High)?r")>;
    483 
    484 // FP load instructions.
    485 def : InstRW<[WriteVLD],    (instregex "^LDR[DSQ]l")>;
    486 def : InstRW<[WriteVLD],    (instregex "^LDUR[BDHSQ]i")>;
    487 def : InstRW<[WriteVLD,
    488               WriteAdr],    (instregex "^LDR[BDHSQ](post|pre)")>;
    489 def : InstRW<[WriteVLD],    (instregex "^LDR[BDHSQ]ui")>;
    490 def : InstRW<[M1WriteLY,
    491               ReadAdrBase], (instregex "^LDR[BDHS]ro[WX]")>;
    492 def : InstRW<[M1WriteLD,
    493               ReadAdrBase], (instregex "^LDRQro[WX]")>;
    494 def : InstRW<[WriteVLD,
    495               M1WriteLH],   (instregex "^LDN?P[DS]i")>;
    496 def : InstRW<[M1WriteLA,
    497               M1WriteLH],   (instregex "^LDN?PQi")>;
    498 def : InstRW<[M1WriteLC,
    499               M1WriteLH,
    500               WriteAdr],    (instregex "^LDP[DS](post|pre)")>;
    501 def : InstRW<[M1WriteLD,
    502               M1WriteLH,
    503               WriteAdr],    (instregex "^LDPQ(post|pre)")>;
    504 
    505 // FP store instructions.
    506 def : InstRW<[WriteVST],    (instregex "^STUR[BDHSQ]i")>;
    507 def : InstRW<[WriteVST,
    508               WriteAdr],    (instregex "^STR[BDHSQ](post|pre)")>;
    509 def : InstRW<[WriteVST],    (instregex "^STR[BDHSQ]ui")>;
    510 def : InstRW<[M1WriteSY,
    511               ReadAdrBase], (instregex "^STR[BDHS]ro[WX]")>;
    512 def : InstRW<[M1WriteSB,
    513               ReadAdrBase], (instregex "^STRQro[WX]")>;
    514 def : InstRW<[WriteVST],    (instregex "^STN?P[DSQ]i")>;
    515 def : InstRW<[WriteVST,
    516               WriteAdr],    (instregex "^STP[DS](post|pre)")>;
    517 def : InstRW<[M1WriteSC,
    518               WriteAdr],    (instregex "^STPQ(post|pre)")>;
    519 
    520 // ASIMD instructions.
    521 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]ABAL?v")>;
    522 def : InstRW<[M1WriteNMISC1], (instregex "^[SU]ABDL?v")>;
    523 def : InstRW<[M1WriteNMISC1], (instregex "^(SQ)?ABSv")>;
    524 def : InstRW<[M1WriteNMISC1], (instregex "^SQNEGv")>;
    525 def : InstRW<[M1WriteNALU1],  (instregex "^(ADD|NEG|SUB)v")>;
    526 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?H(ADD|SUB)v")>;
    527 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?AD[AD](L|LP|P|W)V?2?v")>;
    528 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]?SUB[LW]2?v")>;
    529 def : InstRW<[M1WriteNMISC3], (instregex "^R?(ADD|SUB)HN?2?v")>;
    530 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]+Q(ADD|SUB)v")>;
    531 def : InstRW<[M1WriteNMISC3], (instregex "^[SU]RHADDv")>;
    532 def : InstRW<[M1WriteNMISC1], (instregex "^CM(EQ|GE|GT|HI|HS|LE|LT)v")>;
    533 def : InstRW<[M1WriteNALU1],  (instregex "^CMTSTv")>;
    534 def : InstRW<[M1WriteNALU1],  (instregex "^(AND|BIC|EOR|MVNI|NOT|ORN|ORR)v")>;
    535 def : InstRW<[M1WriteNMISC1], (instregex "^[SU](MIN|MAX)v")>;
    536 def : InstRW<[M1WriteNMISC2], (instregex "^[SU](MIN|MAX)Pv")>;
    537 def : InstRW<[M1WriteNMISC3], (instregex "^[SU](MIN|MAX)Vv")>;
    538 def : InstRW<[M1WriteNMISC4], (instregex "^(MUL|SQR?DMULH)v")>;
    539 def : InstRW<[M1WriteNMISC4], (instregex "^ML[AS]v")>;
    540 def : InstRW<[M1WriteNMISC4], (instregex "^(S|U|SQD|SQRD)ML[AS][HL]v")>;
    541 def : InstRW<[M1WriteNMISC4], (instregex "^(S|U|SQD)MULLv")>;
    542 def : InstRW<[M1WriteNAL13],  (instregex "^(S|SR|U|UR)SRAv")>;
    543 def : InstRW<[M1WriteNALU1],  (instregex "^SHL[dv]")>;
    544 def : InstRW<[M1WriteNALU1],  (instregex "^[SU]SH[LR][dv]")>;
    545 def : InstRW<[M1WriteNALU1],  (instregex "^S[RS]I[dv]")>;
    546 def : InstRW<[M1WriteNAL13],  (instregex "^(([SU]Q)?R)?SHRU?N[bhsv]")>;
    547 def : InstRW<[M1WriteNAL13],  (instregex "^[SU]RSH[LR][dv]")>;
    548 def : InstRW<[M1WriteNAL13],  (instregex "^[SU]QR?SHLU?[bdhsv]")>;
    549 
    550 // ASIMD FP instructions.
    551 def : InstRW<[M1WriteNALU1],  (instregex "^F(ABS|NEG)v")>;
    552 def : InstRW<[M1WriteNMISC3], (instregex "^F(ABD|ADD|SUB)v")>;
    553 def : InstRW<[M1WriteNEONA],  (instregex "^FADDP")>;
    554 def : InstRW<[M1WriteNMISC1], (instregex "^F(AC|CM)(EQ|GE|GT|LE|LT)v[^1]")>;
    555 def : InstRW<[M1WriteFCVT3],  (instregex "^[FVSU]CVTX?[AFLMNPZ][SU]?(_Int)?v")>;
    556 def : InstRW<[M1WriteFVAR15], (instregex "FDIVv.f32")>;
    557 def : InstRW<[M1WriteFVAR23], (instregex "FDIVv2f64")>;
    558 def : InstRW<[M1WriteFVAR15], (instregex "FSQRTv.f32")>;
    559 def : InstRW<[M1WriteFVAR23], (instregex "FSQRTv2f64")>;
    560 def : InstRW<[M1WriteNMISC1], (instregex "^F(MAX|MIN)(NM)?V?v")>;
    561 def : InstRW<[M1WriteNMISC2], (instregex "^F(MAX|MIN)(NM)?Pv")>;
    562 def : InstRW<[M1WriteNEONJ],  (instregex "^FMULX?v.i")>;
    563 def : InstRW<[M1WriteFMAC4],  (instregex "^FMULX?v.f")>;
    564 def : InstRW<[M1WriteNEONK],  (instregex "^FML[AS]v.i")>;
    565 def : InstRW<[M1WriteFMAC5],  (instregex "^FML[AS]v.f")>;
    566 def : InstRW<[M1WriteFCVT3],  (instregex "^FRINT[AIMNPXZ]v")>;
    567 
    568 // ASIMD miscellaneous instructions.
    569 def : InstRW<[M1WriteNALU1],  (instregex "^RBITv")>;
    570 def : InstRW<[M1WriteNAL11],  (instregex "^(BIF|BIT|BSL)v")>;
    571 def : InstRW<[M1WriteNEONB],  (instregex "^DUPv.+gpr")>;
    572 def : InstRW<[M1WriteNALU1],  (instregex "^DUPv.+lane")>;
    573 def : InstRW<[M1WriteNALU1],  (instregex "^EXTv8")>;
    574 def : InstRW<[M1WriteNEONL],  (instregex "^EXTv16")>;
    575 def : InstRW<[M1WriteNAL13],  (instregex "^[SU]?Q?XTU?Nv")>;
    576 def : InstRW<[M1WriteNALU1],  (instregex "^CPY")>;
    577 def : InstRW<[M1WriteNALU1],  (instregex "^INSv.+lane")>;
    578 def : InstRW<[M1WriteNALU1],  (instregex "^MOVI[Dv]")>;
    579 def : InstRW<[M1WriteNALU1],  (instregex "^FMOVv")>;
    580 def : InstRW<[M1WriteFCVT4],  (instregex "^[FU](RECP|RSQRT)Ev[248]")>;
    581 def : InstRW<[M1WriteFMAC5],  (instregex "^F(RECP|RSQRT)Sv")>;
    582 def : InstRW<[M1WriteNALU1],  (instregex "^REV(16|32|64)v")>;
    583 def : InstRW<[M1WriteNAL11],  (instregex "^TB[LX]v8i8One")>;
    584 def : InstRW<[WriteSequence<[M1WriteNAL11], 2>],
    585                               (instregex "^TB[LX]v8i8Two")>;
    586 def : InstRW<[WriteSequence<[M1WriteNAL11], 3>],
    587                               (instregex "^TB[LX]v8i8Three")>;
    588 def : InstRW<[WriteSequence<[M1WriteNAL11], 4>],
    589                               (instregex "^TB[LX]v8i8Four")>;
    590 def : InstRW<[M1WriteNAL12],  (instregex "^TB[LX]v16i8One")>;
    591 def : InstRW<[WriteSequence<[M1WriteNAL12], 2>],
    592                               (instregex "^TB[LX]v16i8Two")>;
    593 def : InstRW<[WriteSequence<[M1WriteNAL12], 3>],
    594                               (instregex "^TB[LX]v16i8Three")>;
    595 def : InstRW<[WriteSequence<[M1WriteNAL12], 4>],
    596                               (instregex "^TB[LX]v16i8Four")>;
    597 def : InstRW<[M1WriteNEOND],  (instregex "^[SU]MOVv")>;
    598 def : InstRW<[M1WriteNEONC],  (instregex "^INSv.+gpr")>;
    599 def : InstRW<[M1WriteNALU1],  (instregex "^(TRN|UZP)[12](v8i8|v4i16|v2i32)")>;
    600 def : InstRW<[M1WriteNALU2],  (instregex "^(TRN|UZP)[12](v16i8|v8i16|v4i32|v2i64)")>;
    601 def : InstRW<[M1WriteNALU1],  (instregex "^ZIP[12]v")>;
    602 
    603 // ASIMD load instructions.
    604 def : InstRW<[M1WriteVLDD],   (instregex "LD1i(8|16|32)$")>;
    605 def : InstRW<[M1WriteVLDD,
    606               WriteAdr],      (instregex "LD1i(8|16|32)_POST$")>;
    607 def : InstRW<[M1WriteVLDE],   (instregex "LD1i(64)$")>;
    608 def : InstRW<[M1WriteVLDE,
    609               WriteAdr],      (instregex "LD1i(64)_POST$")>;
    610 
    611 def : InstRW<[M1WriteL5],     (instregex "LD1Rv(8b|4h|2s)$")>;
    612 def : InstRW<[M1WriteL5,
    613               WriteAdr],      (instregex "LD1Rv(8b|4h|2s)_POST$")>;
    614 def : InstRW<[M1WriteL5],     (instregex "LD1Rv(1d)$")>;
    615 def : InstRW<[M1WriteL5,
    616               WriteAdr],      (instregex "LD1Rv(1d)_POST$")>;
    617 def : InstRW<[M1WriteL5],     (instregex "LD1Rv(16b|8h|4s|2d)$")>;
    618 def : InstRW<[M1WriteL5,
    619               WriteAdr],      (instregex "LD1Rv(16b|8h|4s|2d)_POST$")>;
    620 
    621 def : InstRW<[M1WriteL5],     (instregex "LD1Onev(8b|4h|2s|1d)$")>;
    622 def : InstRW<[M1WriteL5,
    623               WriteAdr],      (instregex "LD1Onev(8b|4h|2s|1d)_POST$")>;
    624 def : InstRW<[M1WriteL5],     (instregex "LD1Onev(16b|8h|4s|2d)$")>;
    625 def : InstRW<[M1WriteL5,
    626               WriteAdr],      (instregex "LD1Onev(16b|8h|4s|2d)_POST$")>;
    627 def : InstRW<[M1WriteVLDA],   (instregex "LD1Twov(8b|4h|2s|1d)$")>;
    628 def : InstRW<[M1WriteVLDA,
    629               WriteAdr],      (instregex "LD1Twov(8b|4h|2s|1d)_POST$")>;
    630 def : InstRW<[M1WriteVLDA],   (instregex "LD1Twov(16b|8h|4s|2d)$")>;
    631 def : InstRW<[M1WriteVLDA,
    632               WriteAdr],      (instregex "LD1Twov(16b|8h|4s|2d)_POST$")>;
    633 def : InstRW<[M1WriteVLDB],   (instregex "LD1Threev(8b|4h|2s|1d)$")>;
    634 def : InstRW<[M1WriteVLDB,
    635               WriteAdr],      (instregex "LD1Threev(8b|4h|2s|1d)_POST$")>;
    636 def : InstRW<[M1WriteVLDB],   (instregex "LD1Threev(16b|8h|4s|2d)$")>;
    637 def : InstRW<[M1WriteVLDB,
    638               WriteAdr],      (instregex "LD1Threev(16b|8h|4s|2d)_POST$")>;
    639 def : InstRW<[M1WriteVLDC],   (instregex "LD1Fourv(8b|4h|2s|1d)$")>;
    640 def : InstRW<[M1WriteVLDC,
    641               WriteAdr],      (instregex "LD1Fourv(8b|4h|2s|1d)_POST$")>;
    642 def : InstRW<[M1WriteVLDC],   (instregex "LD1Fourv(16b|8h|4s|2d)$")>;
    643 def : InstRW<[M1WriteVLDC,
    644               WriteAdr],      (instregex "LD1Fourv(16b|8h|4s|2d)_POST$")>;
    645 
    646 def : InstRW<[M1WriteVLDG],   (instregex "LD2i(8|16)$")>;
    647 def : InstRW<[M1WriteVLDG,
    648               WriteAdr],      (instregex "LD2i(8|16)_POST$")>;
    649 def : InstRW<[M1WriteVLDG],   (instregex "LD2i(32)$")>;
    650 def : InstRW<[M1WriteVLDG,
    651               WriteAdr],      (instregex "LD2i(32)_POST$")>;
    652 def : InstRW<[M1WriteVLDH],   (instregex "LD2i(64)$")>;
    653 def : InstRW<[M1WriteVLDH,
    654               WriteAdr],      (instregex "LD2i(64)_POST$")>;
    655 
    656 def : InstRW<[M1WriteVLDA],   (instregex "LD2Rv(8b|4h|2s)$")>;
    657 def : InstRW<[M1WriteVLDA,
    658               WriteAdr],      (instregex "LD2Rv(8b|4h|2s)_POST$")>;
    659 def : InstRW<[M1WriteVLDA],   (instregex "LD2Rv(1d)$")>;
    660 def : InstRW<[M1WriteVLDA,
    661               WriteAdr],      (instregex "LD2Rv(1d)_POST$")>;
    662 def : InstRW<[M1WriteVLDA],   (instregex "LD2Rv(16b|8h|4s|2d)$")>;
    663 def : InstRW<[M1WriteVLDA,
    664               WriteAdr],      (instregex "LD2Rv(16b|8h|4s|2d)_POST$")>;
    665 
    666 def : InstRW<[M1WriteVLDF],   (instregex "LD2Twov(8b|4h|2s)$")>;
    667 def : InstRW<[M1WriteVLDF,
    668               WriteAdr],      (instregex "LD2Twov(8b|4h|2s)_POST$")>;
    669 def : InstRW<[M1WriteVLDF],   (instregex "LD2Twov(16b|8h|4s)$")>;
    670 def : InstRW<[M1WriteVLDF,
    671               WriteAdr],      (instregex "LD2Twov(16b|8h|4s)_POST$")>;
    672 def : InstRW<[M1WriteVLDF],   (instregex "LD2Twov(2d)$")>;
    673 def : InstRW<[M1WriteVLDF,
    674               WriteAdr],      (instregex "LD2Twov(2d)_POST$")>;
    675 
    676 def : InstRW<[M1WriteVLDJ],   (instregex "LD3i(8|16)$")>;
    677 def : InstRW<[M1WriteVLDJ,
    678               WriteAdr],      (instregex "LD3i(8|16)_POST$")>;
    679 def : InstRW<[M1WriteVLDJ],   (instregex "LD3i(32)$")>;
    680 def : InstRW<[M1WriteVLDJ,
    681               WriteAdr],      (instregex "LD3i(32)_POST$")>;
    682 def : InstRW<[M1WriteVLDL],   (instregex "LD3i(64)$")>;
    683 def : InstRW<[M1WriteVLDL,
    684               WriteAdr],      (instregex "LD3i(64)_POST$")>;
    685 
    686 def : InstRW<[M1WriteVLDB],   (instregex "LD3Rv(8b|4h|2s)$")>;
    687 def : InstRW<[M1WriteVLDB,
    688               WriteAdr],      (instregex "LD3Rv(8b|4h|2s)_POST$")>;
    689 def : InstRW<[M1WriteVLDB],   (instregex "LD3Rv(1d)$")>;
    690 def : InstRW<[M1WriteVLDB,
    691               WriteAdr],      (instregex "LD3Rv(1d)_POST$")>;
    692 def : InstRW<[M1WriteVLDB],   (instregex "LD3Rv(16b|8h|4s)$")>;
    693 def : InstRW<[M1WriteVLDB,
    694               WriteAdr],      (instregex "LD3Rv(16b|8h|4s)_POST$")>;
    695 def : InstRW<[M1WriteVLDB],   (instregex "LD3Rv(2d)$")>;
    696 def : InstRW<[M1WriteVLDB,
    697               WriteAdr],      (instregex "LD3Rv(2d)_POST$")>;
    698 
    699 def : InstRW<[M1WriteVLDI],   (instregex "LD3Threev(8b|4h|2s)$")>;
    700 def : InstRW<[M1WriteVLDI,
    701               WriteAdr],      (instregex "LD3Threev(8b|4h|2s)_POST$")>;
    702 def : InstRW<[M1WriteVLDI],   (instregex "LD3Threev(16b|8h|4s)$")>;
    703 def : InstRW<[M1WriteVLDI,
    704               WriteAdr],      (instregex "LD3Threev(16b|8h|4s)_POST$")>;
    705 def : InstRW<[M1WriteVLDI],   (instregex "LD3Threev(2d)$")>;
    706 def : InstRW<[M1WriteVLDI,
    707               WriteAdr],      (instregex "LD3Threev(2d)_POST$")>;
    708 
    709 def : InstRW<[M1WriteVLDK],   (instregex "LD4i(8|16)$")>;
    710 def : InstRW<[M1WriteVLDK,
    711               WriteAdr],      (instregex "LD4i(8|16)_POST$")>;
    712 def : InstRW<[M1WriteVLDK],   (instregex "LD4i(32)$")>;
    713 def : InstRW<[M1WriteVLDK,
    714               WriteAdr],      (instregex "LD4i(32)_POST$")>;
    715 def : InstRW<[M1WriteVLDM],   (instregex "LD4i(64)$")>;
    716 def : InstRW<[M1WriteVLDM,
    717               WriteAdr],      (instregex "LD4i(64)_POST$")>;
    718 
    719 def : InstRW<[M1WriteVLDC],   (instregex "LD4Rv(8b|4h|2s)$")>;
    720 def : InstRW<[M1WriteVLDC,
    721               WriteAdr],      (instregex "LD4Rv(8b|4h|2s)_POST$")>;
    722 def : InstRW<[M1WriteVLDC],   (instregex "LD4Rv(1d)$")>;
    723 def : InstRW<[M1WriteVLDC,
    724               WriteAdr],      (instregex "LD4Rv(1d)_POST$")>;
    725 def : InstRW<[M1WriteVLDC],   (instregex "LD4Rv(16b|8h|4s)$")>;
    726 def : InstRW<[M1WriteVLDC,
    727               WriteAdr],      (instregex "LD4Rv(16b|8h|4s)_POST$")>;
    728 def : InstRW<[M1WriteVLDC],   (instregex "LD4Rv(2d)$")>;
    729 def : InstRW<[M1WriteVLDC,
    730               WriteAdr],      (instregex "LD4Rv(2d)_POST$")>;
    731 
    732 def : InstRW<[M1WriteVLDN],   (instregex "LD4Fourv(8b|4h|2s)$")>;
    733 def : InstRW<[M1WriteVLDN,
    734               WriteAdr],      (instregex "LD4Fourv(8b|4h|2s)_POST$")>;
    735 def : InstRW<[M1WriteVLDN],   (instregex "LD4Fourv(16b|8h|4s)$")>;
    736 def : InstRW<[M1WriteVLDN,
    737               WriteAdr],      (instregex "LD4Fourv(16b|8h|4s)_POST$")>;
    738 def : InstRW<[M1WriteVLDN],   (instregex "LD4Fourv(2d)$")>;
    739 def : InstRW<[M1WriteVLDN,
    740               WriteAdr],      (instregex "LD4Fourv(2d)_POST$")>;
    741 
    742 // ASIMD store instructions.
    743 def : InstRW<[M1WriteVSTD],   (instregex "ST1i(8|16|32)$")>;
    744 def : InstRW<[M1WriteVSTD,
    745               WriteAdr],      (instregex "ST1i(8|16|32)_POST$")>;
    746 def : InstRW<[M1WriteVSTD],   (instregex "ST1i(64)$")>;
    747 def : InstRW<[M1WriteVSTD,
    748               WriteAdr],      (instregex "ST1i(64)_POST$")>;
    749 
    750 def : InstRW<[WriteVST],      (instregex "ST1Onev(8b|4h|2s|1d)$")>;
    751 def : InstRW<[WriteVST,
    752               WriteAdr],      (instregex "ST1Onev(8b|4h|2s|1d)_POST$")>;
    753 def : InstRW<[WriteVST],      (instregex "ST1Onev(16b|8h|4s|2d)$")>;
    754 def : InstRW<[WriteVST,
    755               WriteAdr],      (instregex "ST1Onev(16b|8h|4s|2d)_POST$")>;
    756 def : InstRW<[M1WriteVSTA],   (instregex "ST1Twov(8b|4h|2s|1d)$")>;
    757 def : InstRW<[M1WriteVSTA,
    758               WriteAdr],      (instregex "ST1Twov(8b|4h|2s|1d)_POST$")>;
    759 def : InstRW<[M1WriteVSTA],   (instregex "ST1Twov(16b|8h|4s|2d)$")>;
    760 def : InstRW<[M1WriteVSTA,
    761               WriteAdr],      (instregex "ST1Twov(16b|8h|4s|2d)_POST$")>;
    762 def : InstRW<[M1WriteVSTB],   (instregex "ST1Threev(8b|4h|2s|1d)$")>;
    763 def : InstRW<[M1WriteVSTB,
    764               WriteAdr],      (instregex "ST1Threev(8b|4h|2s|1d)_POST$")>;
    765 def : InstRW<[M1WriteVSTB],   (instregex "ST1Threev(16b|8h|4s|2d)$")>;
    766 def : InstRW<[M1WriteVSTB,
    767               WriteAdr],      (instregex "ST1Threev(16b|8h|4s|2d)_POST$")>;
    768 def : InstRW<[M1WriteVSTC],   (instregex "ST1Fourv(8b|4h|2s|1d)$")>;
    769 def : InstRW<[M1WriteVSTC,
    770               WriteAdr],      (instregex "ST1Fourv(8b|4h|2s|1d)_POST$")>;
    771 def : InstRW<[M1WriteVSTC],   (instregex "ST1Fourv(16b|8h|4s|2d)$")>;
    772 def : InstRW<[M1WriteVSTC,
    773               WriteAdr], (instregex "ST1Fourv(16b|8h|4s|2d)_POST$")>;
    774 
    775 def : InstRW<[M1WriteVSTD],   (instregex "ST2i(8|16|32)$")>;
    776 def : InstRW<[M1WriteVSTD,
    777               WriteAdr],      (instregex "ST2i(8|16|32)_POST$")>;
    778 def : InstRW<[M1WriteVSTD],   (instregex "ST2i(64)$")>;
    779 def : InstRW<[M1WriteVSTD,
    780               WriteAdr],      (instregex "ST2i(64)_POST$")>;
    781 
    782 def : InstRW<[M1WriteVSTD],   (instregex "ST2Twov(8b|4h|2s)$")>;
    783 def : InstRW<[M1WriteVSTD,
    784               WriteAdr],      (instregex "ST2Twov(8b|4h|2s)_POST$")>;
    785 def : InstRW<[M1WriteVSTE],   (instregex "ST2Twov(16b|8h|4s)$")>;
    786 def : InstRW<[M1WriteVSTE,
    787               WriteAdr],      (instregex "ST2Twov(16b|8h|4s)_POST$")>;
    788 def : InstRW<[M1WriteVSTE],   (instregex "ST2Twov(2d)$")>;
    789 def : InstRW<[M1WriteVSTE,
    790               WriteAdr],      (instregex "ST2Twov(2d)_POST$")>;
    791 
    792 def : InstRW<[M1WriteVSTH],   (instregex "ST3i(8|16)$")>;
    793 def : InstRW<[M1WriteVSTH,
    794               WriteAdr],      (instregex "ST3i(8|16)_POST$")>;
    795 def : InstRW<[M1WriteVSTH],   (instregex "ST3i(32)$")>;
    796 def : InstRW<[M1WriteVSTH,
    797               WriteAdr],      (instregex "ST3i(32)_POST$")>;
    798 def : InstRW<[M1WriteVSTF],   (instregex "ST3i(64)$")>;
    799 def : InstRW<[M1WriteVSTF,
    800               WriteAdr],      (instregex "ST3i(64)_POST$")>;
    801 
    802 def : InstRW<[M1WriteVSTF],   (instregex "ST3Threev(8b|4h|2s)$")>;
    803 def : InstRW<[M1WriteVSTF,
    804               WriteAdr],      (instregex "ST3Threev(8b|4h|2s)_POST$")>;
    805 def : InstRW<[M1WriteVSTG],   (instregex "ST3Threev(16b|8h|4s)$")>;
    806 def : InstRW<[M1WriteVSTG,
    807               WriteAdr],      (instregex "ST3Threev(16b|8h|4s)_POST$")>;
    808 def : InstRW<[M1WriteVSTG],   (instregex "ST3Threev(2d)$")>;
    809 def : InstRW<[M1WriteVSTG,
    810               WriteAdr],      (instregex "ST3Threev(2d)_POST$")>;
    811 
    812 def : InstRW<[M1WriteVSTH],   (instregex "ST4i(8|16)$")>;
    813 def : InstRW<[M1WriteVSTH,
    814               WriteAdr],      (instregex "ST4i(8|16)_POST$")>;
    815 def : InstRW<[M1WriteVSTH],   (instregex "ST4i(32)$")>;
    816 def : InstRW<[M1WriteVSTH,
    817               WriteAdr],      (instregex "ST4i(32)_POST$")>;
    818 def : InstRW<[M1WriteVSTF],   (instregex "ST4i(64)$")>;
    819 def : InstRW<[M1WriteVSTF,
    820               WriteAdr],      (instregex "ST4i(64)_POST$")>;
    821 
    822 def : InstRW<[M1WriteVSTF],   (instregex "ST4Fourv(8b|4h|2s)$")>;
    823 def : InstRW<[M1WriteVSTF,
    824               WriteAdr],      (instregex "ST4Fourv(8b|4h|2s)_POST$")>;
    825 def : InstRW<[M1WriteVSTI],   (instregex "ST4Fourv(16b|8h|4s)$")>;
    826 def : InstRW<[M1WriteVSTI,
    827               WriteAdr],      (instregex "ST4Fourv(16b|8h|4s)_POST$")>;
    828 def : InstRW<[M1WriteVSTI],   (instregex "ST4Fourv(2d)$")>;
    829 def : InstRW<[M1WriteVSTI,
    830               WriteAdr],      (instregex "ST4Fourv(2d)_POST$")>;
    831 
    832 // Cryptography instructions.
    833 def M1WriteAES : SchedWriteRes<[M1UnitNCRYPT]> { let Latency = 1; }
    834 def M1ReadAES  : SchedReadAdvance<1, [M1WriteAES]>;
    835 def : InstRW<[M1WriteAES], (instregex "^AES[DE]")>;
    836 def : InstRW<[M1WriteAES, M1ReadAES], (instregex "^AESI?MC")>;
    837 
    838 def : InstRW<[M1WriteNCRYPT1], (instregex "^PMUL")>;
    839 def : InstRW<[M1WriteNCRYPT1], (instregex "^SHA1(H|SU)")>;
    840 def : InstRW<[M1WriteNCRYPT5], (instregex "^SHA1[CMP]")>;
    841 def : InstRW<[M1WriteNCRYPT1], (instregex "^SHA256SU0")>;
    842 def : InstRW<[M1WriteNCRYPT5], (instregex "^SHA256(H|SU1)")>;
    843 
    844 // CRC instructions.
    845 def : InstRW<[M1WriteC2], (instregex "^CRC32")>;
    846 
    847 } // SchedModel = ExynosM1Model
    848