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