X86InstrShiftRotate.td revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$src2),
49                    "shl{q}\t{$src2, $dst|$dst, $src2}",
50                    [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))],
51                    IIC_SR>;
52
53// NOTE: We don't include patterns for shifts of a register by one, because
54// 'add reg,reg' is cheaper (and we have a Pat pattern for shift-by-one).
55let hasSideEffects = 0 in {
56def SHL8r1   : I<0xD0, MRM4r, (outs GR8:$dst), (ins GR8:$src1),
57                 "shl{b}\t$dst", [], IIC_SR>;
58def SHL16r1  : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
59                 "shl{w}\t$dst", [], IIC_SR>, OpSize16;
60def SHL32r1  : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
61                 "shl{l}\t$dst", [], IIC_SR>, OpSize32;
62def SHL64r1  : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
63                 "shl{q}\t$dst", [], IIC_SR>;
64} // hasSideEffects = 0
65} // isConvertibleToThreeAddress = 1
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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$src2),
152                  "shr{q}\t{$src2, $dst|$dst, $src2}",
153                  [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))], IIC_SR>;
154
155// Shift right by 1
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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$src),
201                  "shr{q}\t{$src, $dst|$dst, $src}",
202                 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
203                 IIC_SR>;
204
205// Shift by 1
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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$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, i8imm:$src2),
593                   "ror{b}\t{$src2, $dst|$dst, $src2}",
594                   [(set GR8:$dst, (rotr GR8:$src1, (i8 imm:$src2)))], IIC_SR>;
595def ROR16ri  : Ii8<0xC1, MRM1r, (outs GR16:$dst), (ins GR16:$src1, i8imm:$src2),
596                   "ror{w}\t{$src2, $dst|$dst, $src2}",
597                   [(set GR16:$dst, (rotr GR16:$src1, (i8 imm:$src2)))],
598                   IIC_SR>, OpSize16;
599def ROR32ri  : Ii8<0xC1, MRM1r, (outs GR32:$dst), (ins GR32:$src1, i8imm:$src2),
600                   "ror{l}\t{$src2, $dst|$dst, $src2}",
601                   [(set GR32:$dst, (rotr GR32:$src1, (i8 imm:$src2)))],
602                   IIC_SR>, OpSize32;
603def ROR64ri  : RIi8<0xC1, MRM1r, (outs GR64:$dst), 
604                    (ins GR64:$src1, i8imm:$src2),
605                    "ror{q}\t{$src2, $dst|$dst, $src2}",
606                    [(set GR64:$dst, (rotr GR64:$src1, (i8 imm:$src2)))],
607                    IIC_SR>;
608
609// Rotate by 1
610def ROR8r1   : I<0xD0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
611                 "ror{b}\t$dst",
612                 [(set GR8:$dst, (rotr GR8:$src1, (i8 1)))],
613                 IIC_SR>;
614def ROR16r1  : I<0xD1, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
615                 "ror{w}\t$dst",
616                 [(set GR16:$dst, (rotr GR16:$src1, (i8 1)))],
617                 IIC_SR>, OpSize16;
618def ROR32r1  : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
619                 "ror{l}\t$dst",
620                 [(set GR32:$dst, (rotr GR32:$src1, (i8 1)))],
621                 IIC_SR>, OpSize32;
622def ROR64r1  : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
623                  "ror{q}\t$dst",
624                  [(set GR64:$dst, (rotr GR64:$src1, (i8 1)))],
625                  IIC_SR>;
626} // Constraints = "$src = $dst", SchedRW
627
628let SchedRW = [WriteShiftLd, WriteRMW] in {
629let Uses = [CL] in {
630def ROR8mCL  : I<0xD2, MRM1m, (outs), (ins i8mem :$dst),
631                 "ror{b}\t{%cl, $dst|$dst, cl}",
632                 [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)],
633                 IIC_SR>;
634def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst),
635                 "ror{w}\t{%cl, $dst|$dst, cl}",
636                 [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)],
637                 IIC_SR>, OpSize16;
638def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst), 
639                 "ror{l}\t{%cl, $dst|$dst, cl}",
640                 [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)],
641                 IIC_SR>, OpSize32;
642def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst), 
643                  "ror{q}\t{%cl, $dst|$dst, cl}",
644                  [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)],
645                  IIC_SR>;
646}
647def ROR8mi   : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, i8imm:$src),
648                   "ror{b}\t{$src, $dst|$dst, $src}",
649               [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)],
650               IIC_SR>;
651def ROR16mi  : Ii8<0xC1, MRM1m, (outs), (ins i16mem:$dst, i8imm:$src),
652                   "ror{w}\t{$src, $dst|$dst, $src}",
653              [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)],
654              IIC_SR>, OpSize16;
655def ROR32mi  : Ii8<0xC1, MRM1m, (outs), (ins i32mem:$dst, i8imm:$src),
656                   "ror{l}\t{$src, $dst|$dst, $src}",
657              [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)],
658              IIC_SR>, OpSize32;
659def ROR64mi  : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, i8imm:$src),
660                    "ror{q}\t{$src, $dst|$dst, $src}",
661                [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)],
662                IIC_SR>;
663
664// Rotate by 1
665def ROR8m1   : I<0xD0, MRM1m, (outs), (ins i8mem :$dst),
666                 "ror{b}\t$dst",
667               [(store (rotr (loadi8 addr:$dst), (i8 1)), addr:$dst)],
668               IIC_SR>;
669def ROR16m1  : I<0xD1, MRM1m, (outs), (ins i16mem:$dst),
670                 "ror{w}\t$dst",
671              [(store (rotr (loadi16 addr:$dst), (i8 1)), addr:$dst)],
672              IIC_SR>, OpSize16;
673def ROR32m1  : I<0xD1, MRM1m, (outs), (ins i32mem:$dst),
674                 "ror{l}\t$dst",
675              [(store (rotr (loadi32 addr:$dst), (i8 1)), addr:$dst)],
676              IIC_SR>, OpSize32;
677def ROR64m1  : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
678                 "ror{q}\t$dst",
679               [(store (rotr (loadi64 addr:$dst), (i8 1)), addr:$dst)],
680               IIC_SR>;
681} // SchedRW
682
683
684//===----------------------------------------------------------------------===//
685// Double shift instructions (generalizations of rotate)
686//===----------------------------------------------------------------------===//
687
688let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
689
690let Uses = [CL] in {
691def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst), 
692                   (ins GR16:$src1, GR16:$src2),
693                   "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
694                   [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))],
695                    IIC_SHD16_REG_CL>,
696                   TB, OpSize16;
697def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst), 
698                   (ins GR16:$src1, GR16:$src2),
699                   "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
700                   [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))],
701                    IIC_SHD16_REG_CL>,
702                   TB, OpSize16;
703def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst), 
704                   (ins GR32:$src1, GR32:$src2),
705                   "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
706                   [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))],
707                    IIC_SHD32_REG_CL>, TB, OpSize32;
708def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst),
709                   (ins GR32:$src1, GR32:$src2),
710                   "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
711                   [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))],
712                   IIC_SHD32_REG_CL>, TB, OpSize32;
713def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst), 
714                    (ins GR64:$src1, GR64:$src2),
715                    "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
716                    [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))],
717                    IIC_SHD64_REG_CL>, 
718                    TB;
719def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst), 
720                    (ins GR64:$src1, GR64:$src2),
721                    "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
722                    [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))],
723                    IIC_SHD64_REG_CL>, 
724                    TB;
725}
726
727let isCommutable = 1 in {  // These instructions commute to each other.
728def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
729                     (outs GR16:$dst), 
730                     (ins GR16:$src1, GR16:$src2, i8imm:$src3),
731                     "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
732                     [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2,
733                                      (i8 imm:$src3)))], IIC_SHD16_REG_IM>,
734                     TB, OpSize16;
735def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
736                     (outs GR16:$dst), 
737                     (ins GR16:$src1, GR16:$src2, i8imm:$src3),
738                     "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
739                     [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2,
740                                      (i8 imm:$src3)))], IIC_SHD16_REG_IM>,
741                     TB, OpSize16;
742def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
743                     (outs GR32:$dst), 
744                     (ins GR32:$src1, GR32:$src2, i8imm:$src3),
745                     "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
746                     [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2,
747                                      (i8 imm:$src3)))], IIC_SHD32_REG_IM>,
748                 TB, OpSize32;
749def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
750                     (outs GR32:$dst), 
751                     (ins GR32:$src1, GR32:$src2, i8imm:$src3),
752                     "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
753                     [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2,
754                                      (i8 imm:$src3)))], IIC_SHD32_REG_IM>,
755                 TB, OpSize32;
756def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
757                      (outs GR64:$dst), 
758                      (ins GR64:$src1, GR64:$src2, i8imm:$src3),
759                      "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
760                      [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
761                                       (i8 imm:$src3)))], IIC_SHD64_REG_IM>,
762                 TB;
763def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
764                      (outs GR64:$dst), 
765                      (ins GR64:$src1, GR64:$src2, i8imm:$src3),
766                      "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
767                      [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
768                                       (i8 imm:$src3)))], IIC_SHD64_REG_IM>,
769                 TB;
770}
771} // Constraints = "$src = $dst", SchedRW
772
773let SchedRW = [WriteShiftLd, WriteRMW] in {
774let Uses = [CL] in {
775def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
776                   "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
777                   [(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL),
778                     addr:$dst)], IIC_SHD16_MEM_CL>, TB, OpSize16;
779def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
780                  "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
781                  [(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL),
782                    addr:$dst)], IIC_SHD16_MEM_CL>, TB, OpSize16;
783
784def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
785                   "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
786                   [(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL),
787                     addr:$dst)], IIC_SHD32_MEM_CL>, TB, OpSize32;
788def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
789                  "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
790                  [(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL),
791                    addr:$dst)], IIC_SHD32_MEM_CL>, TB, OpSize32;
792                    
793def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
794                    "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
795                    [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
796                      addr:$dst)], IIC_SHD64_MEM_CL>, TB;
797def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
798                    "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
799                    [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
800                      addr:$dst)], IIC_SHD64_MEM_CL>, TB;
801}
802
803def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
804                    (outs), (ins i16mem:$dst, GR16:$src2, i8imm:$src3),
805                    "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
806                    [(store (X86shld (loadi16 addr:$dst), GR16:$src2,
807                                      (i8 imm:$src3)), addr:$dst)],
808                                      IIC_SHD16_MEM_IM>,
809                    TB, OpSize16;
810def SHRD16mri8 : Ii8<0xAC, MRMDestMem, 
811                     (outs), (ins i16mem:$dst, GR16:$src2, i8imm:$src3),
812                     "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
813                    [(store (X86shrd (loadi16 addr:$dst), GR16:$src2,
814                                      (i8 imm:$src3)), addr:$dst)],
815                                      IIC_SHD16_MEM_IM>,
816                     TB, OpSize16;
817
818def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
819                    (outs), (ins i32mem:$dst, GR32:$src2, i8imm:$src3),
820                    "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
821                    [(store (X86shld (loadi32 addr:$dst), GR32:$src2,
822                                      (i8 imm:$src3)), addr:$dst)],
823                                      IIC_SHD32_MEM_IM>,
824                    TB, OpSize32;
825def SHRD32mri8 : Ii8<0xAC, MRMDestMem, 
826                     (outs), (ins i32mem:$dst, GR32:$src2, i8imm:$src3),
827                     "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
828                     [(store (X86shrd (loadi32 addr:$dst), GR32:$src2,
829                                       (i8 imm:$src3)), addr:$dst)],
830                                       IIC_SHD32_MEM_IM>,
831                     TB, OpSize32;
832
833def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
834                      (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
835                      "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
836                      [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
837                                       (i8 imm:$src3)), addr:$dst)],
838                                       IIC_SHD64_MEM_IM>,
839                 TB;
840def SHRD64mri8 : RIi8<0xAC, MRMDestMem, 
841                      (outs), (ins i64mem:$dst, GR64:$src2, i8imm:$src3),
842                      "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
843                      [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
844                                       (i8 imm:$src3)), addr:$dst)],
845                                       IIC_SHD64_MEM_IM>,
846                 TB;
847} // SchedRW
848
849} // Defs = [EFLAGS]
850
851def ROT32L2R_imm8  : SDNodeXForm<imm, [{
852  // Convert a ROTL shamt to a ROTR shamt on 32-bit integer.
853  return getI8Imm(32 - N->getZExtValue());
854}]>;
855
856def ROT64L2R_imm8  : SDNodeXForm<imm, [{
857  // Convert a ROTL shamt to a ROTR shamt on 64-bit integer.
858  return getI8Imm(64 - N->getZExtValue());
859}]>;
860
861multiclass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop> {
862let neverHasSideEffects = 1 in {
863  def ri : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, i8imm:$src2),
864               !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
865               []>, TAXD, VEX, Sched<[WriteShift]>;
866  let mayLoad = 1 in
867  def mi : Ii8<0xF0, MRMSrcMem, (outs RC:$dst),
868               (ins x86memop:$src1, i8imm:$src2),
869               !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
870               []>, TAXD, VEX, Sched<[WriteShiftLd]>;
871}
872}
873
874multiclass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop> {
875let neverHasSideEffects = 1 in {
876  def rr : I<0xF7, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
877             !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
878             VEX_4VOp3, Sched<[WriteShift]>;
879  let mayLoad = 1 in
880  def rm : I<0xF7, MRMSrcMem, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
881             !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
882             VEX_4VOp3,
883             Sched<[WriteShiftLd,
884                    // x86memop:$src1
885                    ReadDefault, ReadDefault, ReadDefault, ReadDefault,
886                    ReadDefault,
887                    // RC:$src1
888                    ReadAfterLd]>;
889}
890}
891
892let Predicates = [HasBMI2] in {
893  defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>;
894  defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, VEX_W;
895  defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8XS;
896  defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8XS, VEX_W;
897  defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8XD;
898  defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8XD, VEX_W;
899  defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8PD;
900  defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8PD, VEX_W;
901
902  // Prefer RORX which is non-destructive and doesn't update EFLAGS.
903  let AddedComplexity = 10 in {
904    def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),
905              (RORX32ri GR32:$src, (ROT32L2R_imm8 imm:$shamt))>;
906    def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),
907              (RORX64ri GR64:$src, (ROT64L2R_imm8 imm:$shamt))>;
908  }
909
910  def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)),
911            (RORX32mi addr:$src, (ROT32L2R_imm8 imm:$shamt))>;
912  def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)),
913            (RORX64mi addr:$src, (ROT64L2R_imm8 imm:$shamt))>;
914
915  // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not
916  // immedidate shift, i.e. the following code is considered better
917  //
918  //  mov %edi, %esi
919  //  shl $imm, %esi
920  //  ... %edi, ...
921  //
922  // than
923  //
924  //  movb $imm, %sil
925  //  shlx %sil, %edi, %esi
926  //  ... %edi, ...
927  //
928  let AddedComplexity = 1 in {
929    def : Pat<(sra GR32:$src1, GR8:$src2),
930              (SARX32rr GR32:$src1,
931                        (INSERT_SUBREG
932                          (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
933    def : Pat<(sra GR64:$src1, GR8:$src2),
934              (SARX64rr GR64:$src1,
935                        (INSERT_SUBREG
936                          (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
937
938    def : Pat<(srl GR32:$src1, GR8:$src2),
939              (SHRX32rr GR32:$src1,
940                        (INSERT_SUBREG
941                          (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
942    def : Pat<(srl GR64:$src1, GR8:$src2),
943              (SHRX64rr GR64:$src1,
944                        (INSERT_SUBREG
945                          (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
946
947    def : Pat<(shl GR32:$src1, GR8:$src2),
948              (SHLX32rr GR32:$src1,
949                        (INSERT_SUBREG
950                          (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
951    def : Pat<(shl GR64:$src1, GR8:$src2),
952              (SHLX64rr GR64:$src1,
953                        (INSERT_SUBREG
954                          (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
955  }
956
957  // Patterns on SARXrm/SHRXrm/SHLXrm are explicitly omitted to favor
958  //
959  //  mov (%ecx), %esi
960  //  shl $imm, $esi
961  //
962  // over
963  //
964  //  movb $imm %al
965  //  shlx %al, (%ecx), %esi
966  //
967  // As SARXrr/SHRXrr/SHLXrr is favored on variable shift, the peephole
968  // optimization will fold them into SARXrm/SHRXrm/SHLXrm if possible.
969}
970