Home | History | Annotate | Download | only in X86
      1 //===-- X86InstrShiftRotate.td - Shift and Rotate Instrs ---*- 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 describes the shift and rotate instructions.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 // FIXME: Someone needs to smear multipattern goodness all over this file.
     15 
     16 let Defs = [EFLAGS] in {
     17 
     18 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
     19 let Uses = [CL] in {
     20 def SHL8rCL  : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1),
     21                  "shl{b}\t{%cl, $dst|$dst, cl}",
     22                  [(set GR8:$dst, (shl GR8:$src1, CL))], IIC_SR>;
     23 def SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
     24                  "shl{w}\t{%cl, $dst|$dst, cl}",
     25                  [(set GR16:$dst, (shl GR16:$src1, CL))], IIC_SR>, OpSize;
     26 def SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
     27                  "shl{l}\t{%cl, $dst|$dst, cl}",
     28                  [(set GR32:$dst, (shl GR32:$src1, CL))], IIC_SR>;
     29 def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
     30                   "shl{q}\t{%cl, $dst|$dst, cl}",
     31                   [(set GR64:$dst, (shl GR64:$src1, CL))], IIC_SR>;
     32 } // Uses = [CL]
     33 
     34 def SHL8ri   : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
     35                    "shl{b}\t{$src2, $dst|$dst, $src2}",
     36                    [(set GR8:$dst, (shl GR8:$src1, (i8 imm:$src2)))], IIC_SR>;
     37 
     38 let isConvertibleToThreeAddress = 1 in {   // Can transform into LEA.
     39 def SHL16ri  : Ii8<0xC1, MRM4r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
     40                    "shl{w}\t{$src2, $dst|$dst, $src2}",
     41                    [(set GR16:$dst, (shl GR16:$src1, (i8 imm:$src2)))], IIC_SR>,
     42                    OpSize;
     43 def SHL32ri  : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
     44                    "shl{l}\t{$src2, $dst|$dst, $src2}",
     45                    [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))], IIC_SR>;
     46 def SHL64ri  : RIi8<0xC1, MRM4r, (outs GR64:$dst),
     47                     (ins GR64:$src1, i8imm:$src2),
     48                     "shl{q}\t{$src2, $dst|$dst, $src2}",
     49                     [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))],
     50                     IIC_SR>;
     51 
     52 // NOTE: We don't include patterns for shifts of a register by one, because
     53 // 'add reg,reg' is cheaper (and we have a Pat pattern for shift-by-one).
     54 let hasSideEffects = 0 in {
     55 def SHL8r1   : I<0xD0, MRM4r, (outs GR8:$dst), (ins GR8:$src1),
     56                  "shl{b}\t$dst", [], IIC_SR>;
     57 def SHL16r1  : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
     58                  "shl{w}\t$dst", [], IIC_SR>, OpSize;
     59 def SHL32r1  : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
     60                  "shl{l}\t$dst", [], IIC_SR>;
     61 def SHL64r1  : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
     62                  "shl{q}\t$dst", [], IIC_SR>;
     63 } // hasSideEffects = 0
     64 } // isConvertibleToThreeAddress = 1
     65 } // Constraints = "$src = $dst", SchedRW
     66 
     67 
     68 let SchedRW = [WriteShiftLd, WriteRMW] in {
     69 // FIXME: Why do we need an explicit "Uses = [CL]" when the instr has a pattern
     70 // using CL?
     71 let Uses = [CL] in {
     72 def SHL8mCL  : I<0xD2, MRM4m, (outs), (ins i8mem :$dst),
     73                  "shl{b}\t{%cl, $dst|$dst, cl}",
     74                  [(store (shl (loadi8 addr:$dst), CL), addr:$dst)], IIC_SR>;
     75 def SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst),
     76                  "shl{w}\t{%cl, $dst|$dst, cl}",
     77                  [(store (shl (loadi16 addr:$dst), CL), addr:$dst)], IIC_SR>,
     78                  OpSize;
     79 def SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst),
     80                  "shl{l}\t{%cl, $dst|$dst, cl}",
     81                  [(store (shl (loadi32 addr:$dst), CL), addr:$dst)], IIC_SR>;
     82 def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
     83                   "shl{q}\t{%cl, $dst|$dst, cl}",
     84                   [(store (shl (loadi64 addr:$dst), CL), addr:$dst)], IIC_SR>;
     85 }
     86 def SHL8mi   : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, i8imm:$src),
     87                    "shl{b}\t{$src, $dst|$dst, $src}",
     88                 [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)],
     89                 IIC_SR>;
     90 def SHL16mi  : Ii8<0xC1, MRM4m, (outs), (ins i16mem:$dst, i8imm:$src),
     91                    "shl{w}\t{$src, $dst|$dst, $src}",
     92                [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)],
     93                IIC_SR>,
     94                    OpSize;
     95 def SHL32mi  : Ii8<0xC1, MRM4m, (outs), (ins i32mem:$dst, i8imm:$src),
     96                    "shl{l}\t{$src, $dst|$dst, $src}",
     97                [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)],
     98                IIC_SR>;
     99 def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, i8imm:$src),
    100                   "shl{q}\t{$src, $dst|$dst, $src}",
    101                  [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
    102                  IIC_SR>;
    103 
    104 // Shift by 1
    105 def SHL8m1   : I<0xD0, MRM4m, (outs), (ins i8mem :$dst),
    106                  "shl{b}\t$dst",
    107                 [(store (shl (loadi8 addr:$dst), (i8 1)), addr:$dst)],
    108                 IIC_SR>;
    109 def SHL16m1  : I<0xD1, MRM4m, (outs), (ins i16mem:$dst),
    110                  "shl{w}\t$dst",
    111                [(store (shl (loadi16 addr:$dst), (i8 1)), addr:$dst)],
    112                IIC_SR>,
    113                    OpSize;
    114 def SHL32m1  : I<0xD1, MRM4m, (outs), (ins i32mem:$dst),
    115                  "shl{l}\t$dst",
    116                [(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)],
    117                IIC_SR>;
    118 def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
    119                   "shl{q}\t$dst",
    120                  [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)],
    121                  IIC_SR>;
    122 } // SchedRW
    123 
    124 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    125 let Uses = [CL] in {
    126 def SHR8rCL  : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src1),
    127                  "shr{b}\t{%cl, $dst|$dst, cl}",
    128                  [(set GR8:$dst, (srl GR8:$src1, CL))], IIC_SR>;
    129 def SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
    130                  "shr{w}\t{%cl, $dst|$dst, cl}",
    131                  [(set GR16:$dst, (srl GR16:$src1, CL))], IIC_SR>, OpSize;
    132 def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
    133                  "shr{l}\t{%cl, $dst|$dst, cl}",
    134                  [(set GR32:$dst, (srl GR32:$src1, CL))], IIC_SR>;
    135 def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
    136                   "shr{q}\t{%cl, $dst|$dst, cl}",
    137                   [(set GR64:$dst, (srl GR64:$src1, CL))], IIC_SR>;
    138 }
    139 
    140 def SHR8ri   : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$src2),
    141                    "shr{b}\t{$src2, $dst|$dst, $src2}",
    142                    [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))], IIC_SR>;
    143 def SHR16ri  : Ii8<0xC1, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
    144                    "shr{w}\t{$src2, $dst|$dst, $src2}",
    145                    [(set GR16:$dst, (srl GR16:$src1, (i8 imm:$src2)))],
    146                    IIC_SR>, OpSize;
    147 def SHR32ri  : Ii8<0xC1, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
    148                    "shr{l}\t{$src2, $dst|$dst, $src2}",
    149                    [(set GR32:$dst, (srl GR32:$src1, (i8 imm:$src2)))],
    150                    IIC_SR>;
    151 def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$src2),
    152                   "shr{q}\t{$src2, $dst|$dst, $src2}",
    153                   [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))], IIC_SR>;
    154 
    155 // Shift right by 1
    156 def SHR8r1   : I<0xD0, MRM5r, (outs GR8:$dst), (ins GR8:$src1),
    157                  "shr{b}\t$dst",
    158                  [(set GR8:$dst, (srl GR8:$src1, (i8 1)))], IIC_SR>;
    159 def SHR16r1  : I<0xD1, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
    160                  "shr{w}\t$dst",
    161                  [(set GR16:$dst, (srl GR16:$src1, (i8 1)))], IIC_SR>, OpSize;
    162 def SHR32r1  : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
    163                  "shr{l}\t$dst",
    164                  [(set GR32:$dst, (srl GR32:$src1, (i8 1)))], IIC_SR>;
    165 def SHR64r1  : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
    166                  "shr{q}\t$dst",
    167                  [(set GR64:$dst, (srl GR64:$src1, (i8 1)))], IIC_SR>;
    168 } // Constraints = "$src = $dst", SchedRW
    169 
    170 
    171 let SchedRW = [WriteShiftLd, WriteRMW] in {
    172 let Uses = [CL] in {
    173 def SHR8mCL  : I<0xD2, MRM5m, (outs), (ins i8mem :$dst),
    174                  "shr{b}\t{%cl, $dst|$dst, cl}",
    175                  [(store (srl (loadi8 addr:$dst), CL), addr:$dst)], IIC_SR>;
    176 def SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst),
    177                  "shr{w}\t{%cl, $dst|$dst, cl}",
    178                  [(store (srl (loadi16 addr:$dst), CL), addr:$dst)], IIC_SR>,
    179                  OpSize;
    180 def SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst),
    181                  "shr{l}\t{%cl, $dst|$dst, cl}",
    182                  [(store (srl (loadi32 addr:$dst), CL), addr:$dst)], IIC_SR>;
    183 def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
    184                   "shr{q}\t{%cl, $dst|$dst, cl}",
    185                   [(store (srl (loadi64 addr:$dst), CL), addr:$dst)], IIC_SR>;
    186 }
    187 def SHR8mi   : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, i8imm:$src),
    188                    "shr{b}\t{$src, $dst|$dst, $src}",
    189                 [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)],
    190                 IIC_SR>;
    191 def SHR16mi  : Ii8<0xC1, MRM5m, (outs), (ins i16mem:$dst, i8imm:$src),
    192                    "shr{w}\t{$src, $dst|$dst, $src}",
    193                [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)],
    194                IIC_SR>,
    195                    OpSize;
    196 def SHR32mi  : Ii8<0xC1, MRM5m, (outs), (ins i32mem:$dst, i8imm:$src),
    197                    "shr{l}\t{$src, $dst|$dst, $src}",
    198                [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)],
    199                IIC_SR>;
    200 def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, i8imm:$src),
    201                   "shr{q}\t{$src, $dst|$dst, $src}",
    202                  [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
    203                  IIC_SR>;
    204 
    205 // Shift by 1
    206 def SHR8m1   : I<0xD0, MRM5m, (outs), (ins i8mem :$dst),
    207                  "shr{b}\t$dst",
    208                 [(store (srl (loadi8 addr:$dst), (i8 1)), addr:$dst)],
    209                 IIC_SR>;
    210 def SHR16m1  : I<0xD1, MRM5m, (outs), (ins i16mem:$dst),
    211                  "shr{w}\t$dst",
    212                [(store (srl (loadi16 addr:$dst), (i8 1)), addr:$dst)],
    213                IIC_SR>,OpSize;
    214 def SHR32m1  : I<0xD1, MRM5m, (outs), (ins i32mem:$dst),
    215                  "shr{l}\t$dst",
    216                [(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)],
    217                IIC_SR>;
    218 def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
    219                   "shr{q}\t$dst",
    220                  [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)],
    221                  IIC_SR>;
    222 } // SchedRW
    223 
    224 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    225 let Uses = [CL] in {
    226 def SAR8rCL  : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
    227                  "sar{b}\t{%cl, $dst|$dst, cl}",
    228                  [(set GR8:$dst, (sra GR8:$src1, CL))],
    229                  IIC_SR>;
    230 def SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
    231                  "sar{w}\t{%cl, $dst|$dst, cl}",
    232                  [(set GR16:$dst, (sra GR16:$src1, CL))],
    233                  IIC_SR>, OpSize;
    234 def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
    235                  "sar{l}\t{%cl, $dst|$dst, cl}",
    236                  [(set GR32:$dst, (sra GR32:$src1, CL))],
    237                  IIC_SR>;
    238 def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
    239                  "sar{q}\t{%cl, $dst|$dst, cl}",
    240                  [(set GR64:$dst, (sra GR64:$src1, CL))],
    241                  IIC_SR>;
    242 }
    243 
    244 def SAR8ri   : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
    245                    "sar{b}\t{$src2, $dst|$dst, $src2}",
    246                    [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))],
    247                    IIC_SR>;
    248 def SAR16ri  : Ii8<0xC1, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
    249                    "sar{w}\t{$src2, $dst|$dst, $src2}",
    250                    [(set GR16:$dst, (sra GR16:$src1, (i8 imm:$src2)))],
    251                    IIC_SR>,
    252                    OpSize;
    253 def SAR32ri  : Ii8<0xC1, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
    254                    "sar{l}\t{$src2, $dst|$dst, $src2}",
    255                    [(set GR32:$dst, (sra GR32:$src1, (i8 imm:$src2)))],
    256                    IIC_SR>;
    257 def SAR64ri  : RIi8<0xC1, MRM7r, (outs GR64:$dst),
    258                     (ins GR64:$src1, i8imm:$src2),
    259                     "sar{q}\t{$src2, $dst|$dst, $src2}",
    260                     [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))],
    261                     IIC_SR>;
    262 
    263 // Shift by 1
    264 def SAR8r1   : I<0xD0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
    265                  "sar{b}\t$dst",
    266                  [(set GR8:$dst, (sra GR8:$src1, (i8 1)))],
    267                  IIC_SR>;
    268 def SAR16r1  : I<0xD1, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
    269                  "sar{w}\t$dst",
    270                  [(set GR16:$dst, (sra GR16:$src1, (i8 1)))],
    271                  IIC_SR>, OpSize;
    272 def SAR32r1  : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
    273                  "sar{l}\t$dst",
    274                  [(set GR32:$dst, (sra GR32:$src1, (i8 1)))],
    275                  IIC_SR>;
    276 def SAR64r1  : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
    277                  "sar{q}\t$dst",
    278                  [(set GR64:$dst, (sra GR64:$src1, (i8 1)))],
    279                  IIC_SR>;
    280 } // Constraints = "$src = $dst", SchedRW
    281 
    282 
    283 let SchedRW = [WriteShiftLd, WriteRMW] in {
    284 let Uses = [CL] in {
    285 def SAR8mCL  : I<0xD2, MRM7m, (outs), (ins i8mem :$dst),
    286                  "sar{b}\t{%cl, $dst|$dst, cl}",
    287                  [(store (sra (loadi8 addr:$dst), CL), addr:$dst)],
    288                  IIC_SR>;
    289 def SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst),
    290                  "sar{w}\t{%cl, $dst|$dst, cl}",
    291                  [(store (sra (loadi16 addr:$dst), CL), addr:$dst)],
    292                  IIC_SR>, OpSize;
    293 def SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst), 
    294                  "sar{l}\t{%cl, $dst|$dst, cl}",
    295                  [(store (sra (loadi32 addr:$dst), CL), addr:$dst)],
    296                  IIC_SR>;
    297 def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst), 
    298                  "sar{q}\t{%cl, $dst|$dst, cl}",
    299                  [(store (sra (loadi64 addr:$dst), CL), addr:$dst)],
    300                  IIC_SR>;
    301 }
    302 def SAR8mi   : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, i8imm:$src),
    303                    "sar{b}\t{$src, $dst|$dst, $src}",
    304                 [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)],
    305                 IIC_SR>;
    306 def SAR16mi  : Ii8<0xC1, MRM7m, (outs), (ins i16mem:$dst, i8imm:$src),
    307                    "sar{w}\t{$src, $dst|$dst, $src}",
    308                [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)],
    309                IIC_SR>,
    310                    OpSize;
    311 def SAR32mi  : Ii8<0xC1, MRM7m, (outs), (ins i32mem:$dst, i8imm:$src),
    312                    "sar{l}\t{$src, $dst|$dst, $src}",
    313                [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)],
    314                IIC_SR>;
    315 def SAR64mi  : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, i8imm:$src),
    316                     "sar{q}\t{$src, $dst|$dst, $src}",
    317                  [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
    318                  IIC_SR>;
    319 
    320 // Shift by 1
    321 def SAR8m1   : I<0xD0, MRM7m, (outs), (ins i8mem :$dst),
    322                  "sar{b}\t$dst",
    323                 [(store (sra (loadi8 addr:$dst), (i8 1)), addr:$dst)],
    324                 IIC_SR>;
    325 def SAR16m1  : I<0xD1, MRM7m, (outs), (ins i16mem:$dst),
    326                  "sar{w}\t$dst",
    327                [(store (sra (loadi16 addr:$dst), (i8 1)), addr:$dst)],
    328                IIC_SR>,
    329                    OpSize;
    330 def SAR32m1  : I<0xD1, MRM7m, (outs), (ins i32mem:$dst),
    331                  "sar{l}\t$dst",
    332                [(store (sra (loadi32 addr:$dst), (i8 1)), addr:$dst)],
    333                IIC_SR>;
    334 def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
    335                   "sar{q}\t$dst",
    336                  [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)],
    337                  IIC_SR>;
    338 } // SchedRW
    339 
    340 //===----------------------------------------------------------------------===//
    341 // Rotate instructions
    342 //===----------------------------------------------------------------------===//
    343 
    344 let hasSideEffects = 0 in {
    345 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    346 def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
    347                "rcl{b}\t$dst", [], IIC_SR>;
    348 def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$cnt),
    349                  "rcl{b}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    350 let Uses = [CL] in
    351 def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
    352                 "rcl{b}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    353   
    354 def RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
    355                 "rcl{w}\t$dst", [], IIC_SR>, OpSize;
    356 def RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$cnt),
    357                   "rcl{w}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>, OpSize;
    358 let Uses = [CL] in
    359 def RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
    360                  "rcl{w}\t{%cl, $dst|$dst, cl}", [], IIC_SR>, OpSize;
    361 
    362 def RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
    363                 "rcl{l}\t$dst", [], IIC_SR>;
    364 def RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$cnt),
    365                   "rcl{l}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    366 let Uses = [CL] in
    367 def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
    368                  "rcl{l}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    369 
    370 
    371 def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
    372                  "rcl{q}\t$dst", [], IIC_SR>;
    373 def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$cnt),
    374                    "rcl{q}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    375 let Uses = [CL] in
    376 def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
    377                   "rcl{q}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    378 
    379 
    380 def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
    381                "rcr{b}\t$dst", [], IIC_SR>;
    382 def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src1, i8imm:$cnt),
    383                  "rcr{b}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    384 let Uses = [CL] in
    385 def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
    386                 "rcr{b}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    387   
    388 def RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
    389                 "rcr{w}\t$dst", [], IIC_SR>, OpSize;
    390 def RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$cnt),
    391                   "rcr{w}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>, OpSize;
    392 let Uses = [CL] in
    393 def RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
    394                  "rcr{w}\t{%cl, $dst|$dst, cl}", [], IIC_SR>, OpSize;
    395 
    396 def RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
    397                 "rcr{l}\t$dst", [], IIC_SR>;
    398 def RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$cnt),
    399                   "rcr{l}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    400 let Uses = [CL] in
    401 def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
    402                  "rcr{l}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    403                  
    404 def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
    405                  "rcr{q}\t$dst", [], IIC_SR>;
    406 def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, i8imm:$cnt),
    407                    "rcr{q}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    408 let Uses = [CL] in
    409 def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
    410                   "rcr{q}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    411 
    412 } // Constraints = "$src = $dst"
    413 
    414 let SchedRW = [WriteShiftLd, WriteRMW] in {
    415 def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst),
    416                "rcl{b}\t$dst", [], IIC_SR>;
    417 def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, i8imm:$cnt),
    418                  "rcl{b}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    419 def RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst),
    420                 "rcl{w}\t$dst", [], IIC_SR>, OpSize;
    421 def RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, i8imm:$cnt),
    422                   "rcl{w}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>, OpSize;
    423 def RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst),
    424                 "rcl{l}\t$dst", [], IIC_SR>;
    425 def RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, i8imm:$cnt),
    426                   "rcl{l}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    427 def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
    428                  "rcl{q}\t$dst", [], IIC_SR>;
    429 def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, i8imm:$cnt),
    430                    "rcl{q}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    431 
    432 def RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst),
    433                "rcr{b}\t$dst", [], IIC_SR>;
    434 def RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, i8imm:$cnt),
    435                  "rcr{b}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    436 def RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst),
    437                 "rcr{w}\t$dst", [], IIC_SR>, OpSize;
    438 def RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, i8imm:$cnt),
    439                   "rcr{w}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>, OpSize;
    440 def RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst),
    441                 "rcr{l}\t$dst", [], IIC_SR>;
    442 def RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, i8imm:$cnt),
    443                   "rcr{l}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    444 def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
    445                  "rcr{q}\t$dst", [], IIC_SR>;
    446 def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, i8imm:$cnt),
    447                    "rcr{q}\t{$cnt, $dst|$dst, $cnt}", [], IIC_SR>;
    448 
    449 let Uses = [CL] in {
    450 def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst),
    451                 "rcl{b}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    452 def RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst),
    453                  "rcl{w}\t{%cl, $dst|$dst, cl}", [], IIC_SR>, OpSize;
    454 def RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst),
    455                  "rcl{l}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    456 def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
    457                   "rcl{q}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    458 
    459 def RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst),
    460                 "rcr{b}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    461 def RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst),
    462                  "rcr{w}\t{%cl, $dst|$dst, cl}", [], IIC_SR>, OpSize;
    463 def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst),
    464                  "rcr{l}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    465 def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
    466                   "rcr{q}\t{%cl, $dst|$dst, cl}", [], IIC_SR>;
    467 }
    468 } // SchedRW
    469 } // hasSideEffects = 0
    470 
    471 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    472 // FIXME: provide shorter instructions when imm8 == 1
    473 let Uses = [CL] in {
    474 def ROL8rCL  : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
    475                  "rol{b}\t{%cl, $dst|$dst, cl}",
    476                  [(set GR8:$dst, (rotl GR8:$src1, CL))], IIC_SR>;
    477 def ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
    478                  "rol{w}\t{%cl, $dst|$dst, cl}",
    479                  [(set GR16:$dst, (rotl GR16:$src1, CL))], IIC_SR>, OpSize;
    480 def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
    481                  "rol{l}\t{%cl, $dst|$dst, cl}",
    482                  [(set GR32:$dst, (rotl GR32:$src1, CL))], IIC_SR>;
    483 def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
    484                   "rol{q}\t{%cl, $dst|$dst, cl}",
    485                   [(set GR64:$dst, (rotl GR64:$src1, CL))], IIC_SR>;
    486 }
    487 
    488 def ROL8ri   : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
    489                    "rol{b}\t{$src2, $dst|$dst, $src2}",
    490                    [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))], IIC_SR>;
    491 def ROL16ri  : Ii8<0xC1, MRM0r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
    492                    "rol{w}\t{$src2, $dst|$dst, $src2}",
    493                    [(set GR16:$dst, (rotl GR16:$src1, (i8 imm:$src2)))],
    494                    IIC_SR>, 
    495                    OpSize;
    496 def ROL32ri  : Ii8<0xC1, MRM0r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
    497                    "rol{l}\t{$src2, $dst|$dst, $src2}",
    498                    [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$src2)))],
    499                    IIC_SR>;
    500 def ROL64ri  : RIi8<0xC1, MRM0r, (outs GR64:$dst), 
    501                     (ins GR64:$src1, i8imm:$src2),
    502                     "rol{q}\t{$src2, $dst|$dst, $src2}",
    503                     [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))],
    504                     IIC_SR>;
    505 
    506 // Rotate by 1
    507 def ROL8r1   : I<0xD0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
    508                  "rol{b}\t$dst",
    509                  [(set GR8:$dst, (rotl GR8:$src1, (i8 1)))],
    510                  IIC_SR>;
    511 def ROL16r1  : I<0xD1, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
    512                  "rol{w}\t$dst",
    513                  [(set GR16:$dst, (rotl GR16:$src1, (i8 1)))],
    514                  IIC_SR>, OpSize;
    515 def ROL32r1  : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
    516                  "rol{l}\t$dst",
    517                  [(set GR32:$dst, (rotl GR32:$src1, (i8 1)))],
    518                  IIC_SR>;
    519 def ROL64r1  : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
    520                   "rol{q}\t$dst",
    521                   [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))],
    522                   IIC_SR>;
    523 } // Constraints = "$src = $dst", SchedRW
    524 
    525 let SchedRW = [WriteShiftLd, WriteRMW] in {
    526 let Uses = [CL] in {
    527 def ROL8mCL  : I<0xD2, MRM0m, (outs), (ins i8mem :$dst),
    528                  "rol{b}\t{%cl, $dst|$dst, cl}",
    529                  [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)],
    530                  IIC_SR>;
    531 def ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst),
    532                  "rol{w}\t{%cl, $dst|$dst, cl}",
    533                  [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)],
    534                  IIC_SR>, OpSize;
    535 def ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst),
    536                  "rol{l}\t{%cl, $dst|$dst, cl}",
    537                  [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)],
    538                  IIC_SR>;
    539 def ROL64mCL :  RI<0xD3, MRM0m, (outs), (ins i64mem:$dst),
    540                    "rol{q}\t{%cl, $dst|$dst, cl}",
    541                    [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)],
    542                    IIC_SR>;
    543 }
    544 def ROL8mi   : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, i8imm:$src1),
    545                    "rol{b}\t{$src1, $dst|$dst, $src1}",
    546                [(store (rotl (loadi8 addr:$dst), (i8 imm:$src1)), addr:$dst)],
    547                IIC_SR>;
    548 def ROL16mi  : Ii8<0xC1, MRM0m, (outs), (ins i16mem:$dst, i8imm:$src1),
    549                    "rol{w}\t{$src1, $dst|$dst, $src1}",
    550               [(store (rotl (loadi16 addr:$dst), (i8 imm:$src1)), addr:$dst)],
    551               IIC_SR>,
    552                    OpSize;
    553 def ROL32mi  : Ii8<0xC1, MRM0m, (outs), (ins i32mem:$dst, i8imm:$src1),
    554                    "rol{l}\t{$src1, $dst|$dst, $src1}",
    555               [(store (rotl (loadi32 addr:$dst), (i8 imm:$src1)), addr:$dst)],
    556               IIC_SR>;
    557 def ROL64mi  : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, i8imm:$src1),
    558                     "rol{q}\t{$src1, $dst|$dst, $src1}",
    559                 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src1)), addr:$dst)],
    560                 IIC_SR>;
    561 
    562 // Rotate by 1
    563 def ROL8m1   : I<0xD0, MRM0m, (outs), (ins i8mem :$dst),
    564                  "rol{b}\t$dst",
    565                [(store (rotl (loadi8 addr:$dst), (i8 1)), addr:$dst)],
    566                IIC_SR>;
    567 def ROL16m1  : I<0xD1, MRM0m, (outs), (ins i16mem:$dst),
    568                  "rol{w}\t$dst",
    569               [(store (rotl (loadi16 addr:$dst), (i8 1)), addr:$dst)],
    570               IIC_SR>,
    571                    OpSize;
    572 def ROL32m1  : I<0xD1, MRM0m, (outs), (ins i32mem:$dst),
    573                  "rol{l}\t$dst",
    574               [(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)],
    575               IIC_SR>;
    576 def ROL64m1  : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
    577                  "rol{q}\t$dst",
    578                [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)],
    579                IIC_SR>;
    580 } // SchedRW
    581 
    582 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    583 let Uses = [CL] in {
    584 def ROR8rCL  : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
    585                  "ror{b}\t{%cl, $dst|$dst, cl}",
    586                  [(set GR8:$dst, (rotr GR8:$src1, CL))], IIC_SR>;
    587 def ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
    588                  "ror{w}\t{%cl, $dst|$dst, cl}",
    589                  [(set GR16:$dst, (rotr GR16:$src1, CL))], IIC_SR>, OpSize;
    590 def ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
    591                  "ror{l}\t{%cl, $dst|$dst, cl}",
    592                  [(set GR32:$dst, (rotr GR32:$src1, CL))], IIC_SR>;
    593 def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
    594                   "ror{q}\t{%cl, $dst|$dst, cl}",
    595                   [(set GR64:$dst, (rotr GR64:$src1, CL))], IIC_SR>;
    596 }
    597 
    598 def ROR8ri   : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm:$src2),
    599                    "ror{b}\t{$src2, $dst|$dst, $src2}",
    600                    [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))], IIC_SR>;
    601 def ROR16ri  : Ii8<0xC1, MRM1r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
    602                    "ror{w}\t{$src2, $dst|$dst, $src2}",
    603                    [(set GR16:$dst, (rotr GR16:$src1, (i8 imm:$src2)))],
    604                    IIC_SR>, 
    605                    OpSize;
    606 def ROR32ri  : Ii8<0xC1, MRM1r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
    607                    "ror{l}\t{$src2, $dst|$dst, $src2}",
    608                    [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$src2)))],
    609                    IIC_SR>;
    610 def ROR64ri  : RIi8<0xC1, MRM1r, (outs GR64:$dst), 
    611                     (ins GR64:$src1, i8imm:$src2),
    612                     "ror{q}\t{$src2, $dst|$dst, $src2}",
    613                     [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))],
    614                     IIC_SR>;
    615 
    616 // Rotate by 1
    617 def ROR8r1   : I<0xD0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
    618                  "ror{b}\t$dst",
    619                  [(set GR8:$dst, (rotr GR8:$src1, (i8 1)))],
    620                  IIC_SR>;
    621 def ROR16r1  : I<0xD1, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
    622                  "ror{w}\t$dst",
    623                  [(set GR16:$dst, (rotr GR16:$src1, (i8 1)))],
    624                  IIC_SR>, OpSize;
    625 def ROR32r1  : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
    626                  "ror{l}\t$dst",
    627                  [(set GR32:$dst, (rotr GR32:$src1, (i8 1)))],
    628                  IIC_SR>;
    629 def ROR64r1  : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
    630                   "ror{q}\t$dst",
    631                   [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))],
    632                   IIC_SR>;
    633 } // Constraints = "$src = $dst", SchedRW
    634 
    635 let SchedRW = [WriteShiftLd, WriteRMW] in {
    636 let Uses = [CL] in {
    637 def ROR8mCL  : I<0xD2, MRM1m, (outs), (ins i8mem :$dst),
    638                  "ror{b}\t{%cl, $dst|$dst, cl}",
    639                  [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)],
    640                  IIC_SR>;
    641 def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst),
    642                  "ror{w}\t{%cl, $dst|$dst, cl}",
    643                  [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)],
    644                  IIC_SR>, OpSize;
    645 def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst), 
    646                  "ror{l}\t{%cl, $dst|$dst, cl}",
    647                  [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)],
    648                  IIC_SR>;
    649 def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), 
    650                   "ror{q}\t{%cl, $dst|$dst, cl}",
    651                   [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)],
    652                   IIC_SR>;
    653 }
    654 def ROR8mi   : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, i8imm:$src),
    655                    "ror{b}\t{$src, $dst|$dst, $src}",
    656                [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)],
    657                IIC_SR>;
    658 def ROR16mi  : Ii8<0xC1, MRM1m, (outs), (ins i16mem:$dst, i8imm:$src),
    659                    "ror{w}\t{$src, $dst|$dst, $src}",
    660               [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)],
    661               IIC_SR>,
    662                    OpSize;
    663 def ROR32mi  : Ii8<0xC1, MRM1m, (outs), (ins i32mem:$dst, i8imm:$src),
    664                    "ror{l}\t{$src, $dst|$dst, $src}",
    665               [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)],
    666               IIC_SR>;
    667 def ROR64mi  : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
    668                     "ror{q}\t{$src, $dst|$dst, $src}",
    669                 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
    670                 IIC_SR>;
    671 
    672 // Rotate by 1
    673 def ROR8m1   : I<0xD0, MRM1m, (outs), (ins i8mem :$dst),
    674                  "ror{b}\t$dst",
    675                [(store (rotr (loadi8 addr:$dst), (i8 1)), addr:$dst)],
    676                IIC_SR>;
    677 def ROR16m1  : I<0xD1, MRM1m, (outs), (ins i16mem:$dst),
    678                  "ror{w}\t$dst",
    679               [(store (rotr (loadi16 addr:$dst), (i8 1)), addr:$dst)],
    680               IIC_SR>,
    681                    OpSize;
    682 def ROR32m1  : I<0xD1, MRM1m, (outs), (ins i32mem:$dst),
    683                  "ror{l}\t$dst",
    684               [(store (rotr (loadi32 addr:$dst), (i8 1)), addr:$dst)],
    685               IIC_SR>;
    686 def ROR64m1  : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
    687                  "ror{q}\t$dst",
    688                [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)],
    689                IIC_SR>;
    690 } // SchedRW
    691 
    692 
    693 //===----------------------------------------------------------------------===//
    694 // Double shift instructions (generalizations of rotate)
    695 //===----------------------------------------------------------------------===//
    696 
    697 let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
    698 
    699 let Uses = [CL] in {
    700 def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst), 
    701                    (ins GR16:$src1, GR16:$src2),
    702                    "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    703                    [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))],
    704                     IIC_SHD16_REG_CL>,
    705                    TB, OpSize;
    706 def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst), 
    707                    (ins GR16:$src1, GR16:$src2),
    708                    "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    709                    [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))],
    710                     IIC_SHD16_REG_CL>,
    711                    TB, OpSize;
    712 def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst), 
    713                    (ins GR32:$src1, GR32:$src2),
    714                    "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    715                    [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))],
    716                     IIC_SHD32_REG_CL>, TB;
    717 def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst),
    718                    (ins GR32:$src1, GR32:$src2),
    719                    "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    720                    [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))],
    721                    IIC_SHD32_REG_CL>, TB;
    722 def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), 
    723                     (ins GR64:$src1, GR64:$src2),
    724                     "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    725                     [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))],
    726                     IIC_SHD64_REG_CL>, 
    727                     TB;
    728 def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), 
    729                     (ins GR64:$src1, GR64:$src2),
    730                     "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    731                     [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))],
    732                     IIC_SHD64_REG_CL>, 
    733                     TB;
    734 }
    735 
    736 let isCommutable = 1 in {  // These instructions commute to each other.
    737 def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
    738                      (outs GR16:$dst), 
    739                      (ins GR16:$src1, GR16:$src2, i8imm:$src3),
    740                      "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    741                      [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2,
    742                                       (i8 imm:$src3)))], IIC_SHD16_REG_IM>,
    743                      TB, OpSize;
    744 def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
    745                      (outs GR16:$dst), 
    746                      (ins GR16:$src1, GR16:$src2, i8imm:$src3),
    747                      "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    748                      [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2,
    749                                       (i8 imm:$src3)))], IIC_SHD16_REG_IM>,
    750                      TB, OpSize;
    751 def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
    752                      (outs GR32:$dst), 
    753                      (ins GR32:$src1, GR32:$src2, i8imm:$src3),
    754                      "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    755                      [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2,
    756                                       (i8 imm:$src3)))], IIC_SHD32_REG_IM>,
    757                  TB;
    758 def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
    759                      (outs GR32:$dst), 
    760                      (ins GR32:$src1, GR32:$src2, i8imm:$src3),
    761                      "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    762                      [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2,
    763                                       (i8 imm:$src3)))], IIC_SHD32_REG_IM>,
    764                  TB;
    765 def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
    766                       (outs GR64:$dst), 
    767                       (ins GR64:$src1, GR64:$src2, i8imm:$src3),
    768                       "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    769                       [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
    770                                        (i8 imm:$src3)))], IIC_SHD64_REG_IM>,
    771                  TB;
    772 def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
    773                       (outs GR64:$dst), 
    774                       (ins GR64:$src1, GR64:$src2, i8imm:$src3),
    775                       "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    776                       [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
    777                                        (i8 imm:$src3)))], IIC_SHD64_REG_IM>,
    778                  TB;
    779 }
    780 } // Constraints = "$src = $dst", SchedRW
    781 
    782 let SchedRW = [WriteShiftLd, WriteRMW] in {
    783 let Uses = [CL] in {
    784 def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
    785                    "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    786                    [(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL),
    787                      addr:$dst)], IIC_SHD16_MEM_CL>, TB, OpSize;
    788 def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
    789                   "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    790                   [(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL),
    791                     addr:$dst)], IIC_SHD16_MEM_CL>, TB, OpSize;
    792 
    793 def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
    794                    "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    795                    [(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL),
    796                      addr:$dst)], IIC_SHD32_MEM_CL>, TB;
    797 def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
    798                   "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    799                   [(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL),
    800                     addr:$dst)], IIC_SHD32_MEM_CL>, TB;
    801                     
    802 def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
    803                     "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    804                     [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
    805                       addr:$dst)], IIC_SHD64_MEM_CL>, TB;
    806 def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
    807                     "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
    808                     [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
    809                       addr:$dst)], IIC_SHD64_MEM_CL>, TB;
    810 }
    811 
    812 def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
    813                     (outs), (ins i16mem:$dst, GR16:$src2, i8imm:$src3),
    814                     "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    815                     [(store (X86shld (loadi16 addr:$dst), GR16:$src2,
    816                                       (i8 imm:$src3)), addr:$dst)],
    817                                       IIC_SHD16_MEM_IM>,
    818                     TB, OpSize;
    819 def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
    820                      (outs), (ins i16mem:$dst, GR16:$src2, i8imm:$src3),
    821                      "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    822                     [(store (X86shrd (loadi16 addr:$dst), GR16:$src2,
    823                                       (i8 imm:$src3)), addr:$dst)],
    824                                       IIC_SHD16_MEM_IM>,
    825                      TB, OpSize;
    826 
    827 def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
    828                     (outs), (ins i32mem:$dst, GR32:$src2, i8imm:$src3),
    829                     "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    830                     [(store (X86shld (loadi32 addr:$dst), GR32:$src2,
    831                                       (i8 imm:$src3)), addr:$dst)],
    832                                       IIC_SHD32_MEM_IM>,
    833                     TB;
    834 def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
    835                      (outs), (ins i32mem:$dst, GR32:$src2, i8imm:$src3),
    836                      "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    837                      [(store (X86shrd (loadi32 addr:$dst), GR32:$src2,
    838                                        (i8 imm:$src3)), addr:$dst)],
    839                                        IIC_SHD32_MEM_IM>,
    840                      TB;
    841 
    842 def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
    843                       (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
    844                       "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    845                       [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
    846                                        (i8 imm:$src3)), addr:$dst)],
    847                                        IIC_SHD64_MEM_IM>,
    848                  TB;
    849 def SHRD64mri8 : RIi8<0xAC, MRMDestMem, 
    850                       (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
    851                       "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
    852                       [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
    853                                        (i8 imm:$src3)), addr:$dst)],
    854                                        IIC_SHD64_MEM_IM>,
    855                  TB;
    856 } // SchedRW
    857 
    858 } // Defs = [EFLAGS]
    859 
    860 def ROT32L2R_imm8  : SDNodeXForm<imm, [{
    861   // Convert a ROTL shamt to a ROTR shamt on 32-bit integer.
    862   return getI8Imm(32 - N->getZExtValue());
    863 }]>;
    864 
    865 def ROT64L2R_imm8  : SDNodeXForm<imm, [{
    866   // Convert a ROTL shamt to a ROTR shamt on 64-bit integer.
    867   return getI8Imm(64 - N->getZExtValue());
    868 }]>;
    869 
    870 multiclass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop> {
    871 let neverHasSideEffects = 1 in {
    872   def ri : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, i8imm:$src2),
    873                !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
    874                []>, TAXD, VEX, Sched<[WriteShift]>;
    875   let mayLoad = 1 in
    876   def mi : Ii8<0xF0, MRMSrcMem, (outs RC:$dst),
    877                (ins x86memop:$src1, i8imm:$src2),
    878                !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
    879                []>, TAXD, VEX, Sched<[WriteShiftLd]>;
    880 }
    881 }
    882 
    883 multiclass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop> {
    884 let neverHasSideEffects = 1 in {
    885   def rr : I<0xF7, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
    886              !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
    887              VEX_4VOp3, Sched<[WriteShift]>;
    888   let mayLoad = 1 in
    889   def rm : I<0xF7, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
    890              !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
    891              VEX_4VOp3,
    892              Sched<[WriteShiftLd,
    893                     // x86memop:$src1
    894                     ReadDefault, ReadDefault, ReadDefault, ReadDefault,
    895                     ReadDefault,
    896                     // RC:$src1
    897                     ReadAfterLd]>;
    898 }
    899 }
    900 
    901 let Predicates = [HasBMI2] in {
    902   defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>;
    903   defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, VEX_W;
    904   defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8XS;
    905   defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8XS, VEX_W;
    906   defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8XD;
    907   defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8XD, VEX_W;
    908   defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8, OpSize;
    909   defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8, OpSize, VEX_W;
    910 
    911   // Prefer RORX which is non-destructive and doesn't update EFLAGS.
    912   let AddedComplexity = 10 in {
    913     def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),
    914               (RORX32ri GR32:$src, (ROT32L2R_imm8 imm:$shamt))>;
    915     def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),
    916               (RORX64ri GR64:$src, (ROT64L2R_imm8 imm:$shamt))>;
    917   }
    918 
    919   def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)),
    920             (RORX32mi addr:$src, (ROT32L2R_imm8 imm:$shamt))>;
    921   def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)),
    922             (RORX64mi addr:$src, (ROT64L2R_imm8 imm:$shamt))>;
    923 
    924   // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not
    925   // immedidate shift, i.e. the following code is considered better
    926   //
    927   //  mov %edi, %esi
    928   //  shl $imm, %esi
    929   //  ... %edi, ...
    930   //
    931   // than
    932   //
    933   //  movb $imm, %sil
    934   //  shlx %sil, %edi, %esi
    935   //  ... %edi, ...
    936   //
    937   let AddedComplexity = 1 in {
    938     def : Pat<(sra GR32:$src1, GR8:$src2),
    939               (SARX32rr GR32:$src1,
    940                         (INSERT_SUBREG
    941                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    942     def : Pat<(sra GR64:$src1, GR8:$src2),
    943               (SARX64rr GR64:$src1,
    944                         (INSERT_SUBREG
    945                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    946 
    947     def : Pat<(srl GR32:$src1, GR8:$src2),
    948               (SHRX32rr GR32:$src1,
    949                         (INSERT_SUBREG
    950                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    951     def : Pat<(srl GR64:$src1, GR8:$src2),
    952               (SHRX64rr GR64:$src1,
    953                         (INSERT_SUBREG
    954                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    955 
    956     def : Pat<(shl GR32:$src1, GR8:$src2),
    957               (SHLX32rr GR32:$src1,
    958                         (INSERT_SUBREG
    959                           (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    960     def : Pat<(shl GR64:$src1, GR8:$src2),
    961               (SHLX64rr GR64:$src1,
    962                         (INSERT_SUBREG
    963                           (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
    964   }
    965 
    966   // Patterns on SARXrm/SHRXrm/SHLXrm are explicitly omitted to favor
    967   //
    968   //  mov (%ecx), %esi
    969   //  shl $imm, $esi
    970   //
    971   // over
    972   //
    973   //  movb $imm %al
    974   //  shlx %al, (%ecx), %esi
    975   //
    976   // As SARXrr/SHRXrr/SHLXrr is favored on variable shift, the peephole
    977   // optimization will fold them into SARXrm/SHRXrm/SHLXrm if possible.
    978 }
    979