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