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