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