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