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