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