blob: e0bf47fd3fdaba80812e229603888a40dc500ad6 [file] [log] [blame]
Eli Friedman23457332017-01-30 22:04:23 +00001//===-- 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 {
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +000019let Uses = [CL], SchedRW = [WriteShiftCL] in {
Eli Friedman23457332017-01-30 22:04:23 +000020def SHL8rCL : I<0xD2, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1),
21 "shl{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000022 [(set GR8:$dst, (shl GR8:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +000023def SHL16rCL : I<0xD3, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
24 "shl{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000025 [(set GR16:$dst, (shl GR16:$src1, CL))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +000026def SHL32rCL : I<0xD3, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
27 "shl{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000028 [(set GR32:$dst, (shl GR32:$src1, CL))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +000029def SHL64rCL : RI<0xD3, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
30 "shl{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000031 [(set GR64:$dst, (shl GR64:$src1, CL))]>;
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +000032} // Uses = [CL], SchedRW
Eli Friedman23457332017-01-30 22:04:23 +000033
34def SHL8ri : Ii8<0xC0, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
35 "shl{b}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000036 [(set GR8:$dst, (shl GR8:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +000037
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}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000041 [(set GR16:$dst, (shl GR16:$src1, (i8 imm:$src2)))]>,
Eli Friedman23457332017-01-30 22:04:23 +000042 OpSize16;
43def SHL32ri : Ii8<0xC1, MRM4r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
44 "shl{l}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000045 [(set GR32:$dst, (shl GR32:$src1, (i8 imm:$src2)))]>,
Eli Friedman23457332017-01-30 22:04:23 +000046 OpSize32;
47def SHL64ri : RIi8<0xC1, MRM4r, (outs GR64:$dst),
48 (ins GR64:$src1, u8imm:$src2),
49 "shl{q}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000050 [(set GR64:$dst, (shl GR64:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +000051} // isConvertibleToThreeAddress = 1
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),
Simon Pilgrimdec781c2018-04-12 18:25:38 +000057 "shl{b}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +000058def SHL16r1 : I<0xD1, MRM4r, (outs GR16:$dst), (ins GR16:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +000059 "shl{w}\t$dst", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +000060def SHL32r1 : I<0xD1, MRM4r, (outs GR32:$dst), (ins GR32:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +000061 "shl{l}\t$dst", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +000062def SHL64r1 : RI<0xD1, MRM4r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +000063 "shl{q}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +000064} // hasSideEffects = 0
65} // Constraints = "$src = $dst", SchedRW
66
Eli Friedman23457332017-01-30 22:04:23 +000067// FIXME: Why do we need an explicit "Uses = [CL]" when the instr has a pattern
68// using CL?
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +000069let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +000070def SHL8mCL : I<0xD2, MRM4m, (outs), (ins i8mem :$dst),
71 "shl{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000072 [(store (shl (loadi8 addr:$dst), CL), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +000073def SHL16mCL : I<0xD3, MRM4m, (outs), (ins i16mem:$dst),
74 "shl{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000075 [(store (shl (loadi16 addr:$dst), CL), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +000076 OpSize16;
77def SHL32mCL : I<0xD3, MRM4m, (outs), (ins i32mem:$dst),
78 "shl{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000079 [(store (shl (loadi32 addr:$dst), CL), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +000080 OpSize32;
81def SHL64mCL : RI<0xD3, MRM4m, (outs), (ins i64mem:$dst),
82 "shl{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000083 [(store (shl (loadi64 addr:$dst), CL), addr:$dst)]>,
Craig Topper23c34882017-12-15 19:01:51 +000084 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +000085}
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +000086
87let SchedRW = [WriteShiftLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +000088def SHL8mi : Ii8<0xC0, MRM4m, (outs), (ins i8mem :$dst, u8imm:$src),
89 "shl{b}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000090 [(store (shl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +000091def SHL16mi : Ii8<0xC1, MRM4m, (outs), (ins i16mem:$dst, u8imm:$src),
92 "shl{w}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000093 [(store (shl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
94 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +000095def SHL32mi : Ii8<0xC1, MRM4m, (outs), (ins i32mem:$dst, u8imm:$src),
96 "shl{l}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +000097 [(store (shl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
98 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +000099def SHL64mi : RIi8<0xC1, MRM4m, (outs), (ins i64mem:$dst, u8imm:$src),
100 "shl{q}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000101 [(store (shl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
102 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000103
104// Shift by 1
105def SHL8m1 : I<0xD0, MRM4m, (outs), (ins i8mem :$dst),
106 "shl{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000107 [(store (shl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000108def SHL16m1 : I<0xD1, MRM4m, (outs), (ins i16mem:$dst),
109 "shl{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000110 [(store (shl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
111 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000112def SHL32m1 : I<0xD1, MRM4m, (outs), (ins i32mem:$dst),
113 "shl{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000114 [(store (shl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
115 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000116def SHL64m1 : RI<0xD1, MRM4m, (outs), (ins i64mem:$dst),
117 "shl{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000118 [(store (shl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
119 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000120} // SchedRW
121
122let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000123let Uses = [CL], SchedRW = [WriteShiftCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000124def SHR8rCL : I<0xD2, MRM5r, (outs GR8 :$dst), (ins GR8 :$src1),
125 "shr{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000126 [(set GR8:$dst, (srl GR8:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000127def SHR16rCL : I<0xD3, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
128 "shr{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000129 [(set GR16:$dst, (srl GR16:$src1, CL))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000130def SHR32rCL : I<0xD3, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
131 "shr{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000132 [(set GR32:$dst, (srl GR32:$src1, CL))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000133def SHR64rCL : RI<0xD3, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
134 "shr{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000135 [(set GR64:$dst, (srl GR64:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000136}
137
138def SHR8ri : Ii8<0xC0, MRM5r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$src2),
139 "shr{b}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000140 [(set GR8:$dst, (srl GR8:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000141def SHR16ri : Ii8<0xC1, MRM5r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
142 "shr{w}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000143 [(set GR16:$dst, (srl GR16:$src1, (i8 imm:$src2)))]>,
144 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000145def SHR32ri : Ii8<0xC1, MRM5r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
146 "shr{l}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000147 [(set GR32:$dst, (srl GR32:$src1, (i8 imm:$src2)))]>,
148 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000149def SHR64ri : RIi8<0xC1, MRM5r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$src2),
150 "shr{q}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000151 [(set GR64:$dst, (srl GR64:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000152
153// Shift right by 1
154def SHR8r1 : I<0xD0, MRM5r, (outs GR8:$dst), (ins GR8:$src1),
155 "shr{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000156 [(set GR8:$dst, (srl GR8:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000157def SHR16r1 : I<0xD1, MRM5r, (outs GR16:$dst), (ins GR16:$src1),
158 "shr{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000159 [(set GR16:$dst, (srl GR16:$src1, (i8 1)))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000160def SHR32r1 : I<0xD1, MRM5r, (outs GR32:$dst), (ins GR32:$src1),
161 "shr{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000162 [(set GR32:$dst, (srl GR32:$src1, (i8 1)))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000163def SHR64r1 : RI<0xD1, MRM5r, (outs GR64:$dst), (ins GR64:$src1),
164 "shr{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000165 [(set GR64:$dst, (srl GR64:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000166} // Constraints = "$src = $dst", SchedRW
167
168
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000169let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000170def SHR8mCL : I<0xD2, MRM5m, (outs), (ins i8mem :$dst),
171 "shr{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000172 [(store (srl (loadi8 addr:$dst), CL), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000173def SHR16mCL : I<0xD3, MRM5m, (outs), (ins i16mem:$dst),
174 "shr{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000175 [(store (srl (loadi16 addr:$dst), CL), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000176 OpSize16;
177def SHR32mCL : I<0xD3, MRM5m, (outs), (ins i32mem:$dst),
178 "shr{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000179 [(store (srl (loadi32 addr:$dst), CL), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000180 OpSize32;
181def SHR64mCL : RI<0xD3, MRM5m, (outs), (ins i64mem:$dst),
182 "shr{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000183 [(store (srl (loadi64 addr:$dst), CL), addr:$dst)]>,
Craig Topper23c34882017-12-15 19:01:51 +0000184 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000185}
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000186
187let SchedRW = [WriteShiftLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000188def SHR8mi : Ii8<0xC0, MRM5m, (outs), (ins i8mem :$dst, u8imm:$src),
189 "shr{b}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000190 [(store (srl (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000191def SHR16mi : Ii8<0xC1, MRM5m, (outs), (ins i16mem:$dst, u8imm:$src),
192 "shr{w}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000193 [(store (srl (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
194 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000195def SHR32mi : Ii8<0xC1, MRM5m, (outs), (ins i32mem:$dst, u8imm:$src),
196 "shr{l}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000197 [(store (srl (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
198 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000199def SHR64mi : RIi8<0xC1, MRM5m, (outs), (ins i64mem:$dst, u8imm:$src),
200 "shr{q}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000201 [(store (srl (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
202 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000203
204// Shift by 1
205def SHR8m1 : I<0xD0, MRM5m, (outs), (ins i8mem :$dst),
206 "shr{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000207 [(store (srl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000208def SHR16m1 : I<0xD1, MRM5m, (outs), (ins i16mem:$dst),
209 "shr{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000210 [(store (srl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
211 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000212def SHR32m1 : I<0xD1, MRM5m, (outs), (ins i32mem:$dst),
213 "shr{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000214 [(store (srl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
215 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000216def SHR64m1 : RI<0xD1, MRM5m, (outs), (ins i64mem:$dst),
217 "shr{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000218 [(store (srl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
219 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000220} // SchedRW
221
222let Constraints = "$src1 = $dst", SchedRW = [WriteShift] in {
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000223let Uses = [CL], SchedRW = [WriteShiftCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000224def SAR8rCL : I<0xD2, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
225 "sar{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000226 [(set GR8:$dst, (sra GR8:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000227def SAR16rCL : I<0xD3, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
228 "sar{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000229 [(set GR16:$dst, (sra GR16:$src1, CL))]>,
230 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000231def SAR32rCL : I<0xD3, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
232 "sar{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000233 [(set GR32:$dst, (sra GR32:$src1, CL))]>,
234 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000235def SAR64rCL : RI<0xD3, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
236 "sar{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000237 [(set GR64:$dst, (sra GR64:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000238}
239
240def SAR8ri : Ii8<0xC0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
241 "sar{b}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000242 [(set GR8:$dst, (sra GR8:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000243def SAR16ri : Ii8<0xC1, MRM7r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
244 "sar{w}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000245 [(set GR16:$dst, (sra GR16:$src1, (i8 imm:$src2)))]>,
246 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000247def SAR32ri : Ii8<0xC1, MRM7r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
248 "sar{l}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000249 [(set GR32:$dst, (sra GR32:$src1, (i8 imm:$src2)))]>,
250 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000251def SAR64ri : RIi8<0xC1, MRM7r, (outs GR64:$dst),
252 (ins GR64:$src1, u8imm:$src2),
253 "sar{q}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000254 [(set GR64:$dst, (sra GR64:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000255
256// Shift by 1
257def SAR8r1 : I<0xD0, MRM7r, (outs GR8 :$dst), (ins GR8 :$src1),
258 "sar{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000259 [(set GR8:$dst, (sra GR8:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000260def SAR16r1 : I<0xD1, MRM7r, (outs GR16:$dst), (ins GR16:$src1),
261 "sar{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000262 [(set GR16:$dst, (sra GR16:$src1, (i8 1)))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000263def SAR32r1 : I<0xD1, MRM7r, (outs GR32:$dst), (ins GR32:$src1),
264 "sar{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000265 [(set GR32:$dst, (sra GR32:$src1, (i8 1)))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000266def SAR64r1 : RI<0xD1, MRM7r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000267 "sar{q}\t$dst",
268 [(set GR64:$dst, (sra GR64:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000269} // Constraints = "$src = $dst", SchedRW
270
271
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000272let Uses = [CL], SchedRW = [WriteShiftCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000273def SAR8mCL : I<0xD2, MRM7m, (outs), (ins i8mem :$dst),
274 "sar{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000275 [(store (sra (loadi8 addr:$dst), CL), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000276def SAR16mCL : I<0xD3, MRM7m, (outs), (ins i16mem:$dst),
277 "sar{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000278 [(store (sra (loadi16 addr:$dst), CL), addr:$dst)]>,
279 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000280def SAR32mCL : I<0xD3, MRM7m, (outs), (ins i32mem:$dst),
281 "sar{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000282 [(store (sra (loadi32 addr:$dst), CL), addr:$dst)]>,
283 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000284def SAR64mCL : RI<0xD3, MRM7m, (outs), (ins i64mem:$dst),
285 "sar{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000286 [(store (sra (loadi64 addr:$dst), CL), addr:$dst)]>,
287 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000288}
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000289
290let SchedRW = [WriteShiftLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000291def SAR8mi : Ii8<0xC0, MRM7m, (outs), (ins i8mem :$dst, u8imm:$src),
292 "sar{b}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000293 [(store (sra (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000294def SAR16mi : Ii8<0xC1, MRM7m, (outs), (ins i16mem:$dst, u8imm:$src),
295 "sar{w}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000296 [(store (sra (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
297 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000298def SAR32mi : Ii8<0xC1, MRM7m, (outs), (ins i32mem:$dst, u8imm:$src),
299 "sar{l}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000300 [(store (sra (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
301 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000302def SAR64mi : RIi8<0xC1, MRM7m, (outs), (ins i64mem:$dst, u8imm:$src),
303 "sar{q}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000304 [(store (sra (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
305 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000306
307// Shift by 1
308def SAR8m1 : I<0xD0, MRM7m, (outs), (ins i8mem :$dst),
309 "sar{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000310 [(store (sra (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000311def SAR16m1 : I<0xD1, MRM7m, (outs), (ins i16mem:$dst),
312 "sar{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000313 [(store (sra (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
314 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000315def SAR32m1 : I<0xD1, MRM7m, (outs), (ins i32mem:$dst),
316 "sar{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000317 [(store (sra (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
318 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000319def SAR64m1 : RI<0xD1, MRM7m, (outs), (ins i64mem:$dst),
320 "sar{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000321 [(store (sra (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
322 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000323} // SchedRW
324
325//===----------------------------------------------------------------------===//
326// Rotate instructions
327//===----------------------------------------------------------------------===//
328
329let hasSideEffects = 0 in {
Simon Pilgrim5f9d91202018-09-23 15:12:10 +0000330let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in {
Eli Friedman23457332017-01-30 22:04:23 +0000331
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000332let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000333def RCL8rCL : I<0xD2, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000334 "rcl{b}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000335def RCL16rCL : I<0xD3, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000336 "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000337def RCL32rCL : I<0xD3, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000338 "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000339def RCL64rCL : RI<0xD3, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000340 "rcl{q}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000341} // Uses = [CL, EFLAGS]
342
343let Uses = [EFLAGS] in {
344def RCL8r1 : I<0xD0, MRM2r, (outs GR8:$dst), (ins GR8:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000345 "rcl{b}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000346def RCL8ri : Ii8<0xC0, MRM2r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000347 "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000348def RCL16r1 : I<0xD1, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000349 "rcl{w}\t$dst", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000350def RCL16ri : Ii8<0xC1, MRM2r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000351 "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000352def RCL32r1 : I<0xD1, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000353 "rcl{l}\t$dst", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000354def RCL32ri : Ii8<0xC1, MRM2r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000355 "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000356def RCL64r1 : RI<0xD1, MRM2r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000357 "rcl{q}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000358def RCL64ri : RIi8<0xC1, MRM2r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000359 "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000360} // Uses = [EFLAGS]
361
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000362let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000363def RCR8rCL : I<0xD2, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000364 "rcr{b}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000365def RCR16rCL : I<0xD3, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000366 "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000367def RCR32rCL : I<0xD3, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000368 "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000369def RCR64rCL : RI<0xD3, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000370 "rcr{q}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000371} // Uses = [CL, EFLAGS]
372
373let Uses = [EFLAGS] in {
374def RCR8r1 : I<0xD0, MRM3r, (outs GR8:$dst), (ins GR8:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000375 "rcr{b}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000376def RCR8ri : Ii8<0xC0, MRM3r, (outs GR8:$dst), (ins GR8:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000377 "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000378def RCR16r1 : I<0xD1, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000379 "rcr{w}\t$dst", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000380def RCR16ri : Ii8<0xC1, MRM3r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000381 "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000382def RCR32r1 : I<0xD1, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000383 "rcr{l}\t$dst", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000384def RCR32ri : Ii8<0xC1, MRM3r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000385 "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000386def RCR64r1 : RI<0xD1, MRM3r, (outs GR64:$dst), (ins GR64:$src1),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000387 "rcr{q}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000388def RCR64ri : RIi8<0xC1, MRM3r, (outs GR64:$dst), (ins GR64:$src1, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000389 "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000390} // Uses = [EFLAGS]
391
392} // Constraints = "$src = $dst"
393
Simon Pilgrim5f9d91202018-09-23 15:12:10 +0000394let SchedRW = [WriteRotateLd, WriteRMW], mayStore = 1 in {
Eli Friedman23457332017-01-30 22:04:23 +0000395let Uses = [EFLAGS] in {
396def RCL8m1 : I<0xD0, MRM2m, (outs), (ins i8mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000397 "rcl{b}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000398def RCL8mi : Ii8<0xC0, MRM2m, (outs), (ins i8mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000399 "rcl{b}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000400def RCL16m1 : I<0xD1, MRM2m, (outs), (ins i16mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000401 "rcl{w}\t$dst", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000402def RCL16mi : Ii8<0xC1, MRM2m, (outs), (ins i16mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000403 "rcl{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000404def RCL32m1 : I<0xD1, MRM2m, (outs), (ins i32mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000405 "rcl{l}\t$dst", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000406def RCL32mi : Ii8<0xC1, MRM2m, (outs), (ins i32mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000407 "rcl{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000408def RCL64m1 : RI<0xD1, MRM2m, (outs), (ins i64mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000409 "rcl{q}\t$dst", []>, Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000410def RCL64mi : RIi8<0xC1, MRM2m, (outs), (ins i64mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000411 "rcl{q}\t{$cnt, $dst|$dst, $cnt}", []>,
Craig Topper23c34882017-12-15 19:01:51 +0000412 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000413
414def RCR8m1 : I<0xD0, MRM3m, (outs), (ins i8mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000415 "rcr{b}\t$dst", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000416def RCR8mi : Ii8<0xC0, MRM3m, (outs), (ins i8mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000417 "rcr{b}\t{$cnt, $dst|$dst, $cnt}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000418def RCR16m1 : I<0xD1, MRM3m, (outs), (ins i16mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000419 "rcr{w}\t$dst", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000420def RCR16mi : Ii8<0xC1, MRM3m, (outs), (ins i16mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000421 "rcr{w}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000422def RCR32m1 : I<0xD1, MRM3m, (outs), (ins i32mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000423 "rcr{l}\t$dst", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000424def RCR32mi : Ii8<0xC1, MRM3m, (outs), (ins i32mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000425 "rcr{l}\t{$cnt, $dst|$dst, $cnt}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000426def RCR64m1 : RI<0xD1, MRM3m, (outs), (ins i64mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000427 "rcr{q}\t$dst", []>, Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000428def RCR64mi : RIi8<0xC1, MRM3m, (outs), (ins i64mem:$dst, u8imm:$cnt),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000429 "rcr{q}\t{$cnt, $dst|$dst, $cnt}", []>,
Craig Topper23c34882017-12-15 19:01:51 +0000430 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000431} // Uses = [EFLAGS]
432
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000433let Uses = [CL, EFLAGS], SchedRW = [WriteRotateCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000434def RCL8mCL : I<0xD2, MRM2m, (outs), (ins i8mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000435 "rcl{b}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000436def RCL16mCL : I<0xD3, MRM2m, (outs), (ins i16mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000437 "rcl{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000438def RCL32mCL : I<0xD3, MRM2m, (outs), (ins i32mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000439 "rcl{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000440def RCL64mCL : RI<0xD3, MRM2m, (outs), (ins i64mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000441 "rcl{q}\t{%cl, $dst|$dst, cl}", []>,
Craig Topper23c34882017-12-15 19:01:51 +0000442 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000443
444def RCR8mCL : I<0xD2, MRM3m, (outs), (ins i8mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000445 "rcr{b}\t{%cl, $dst|$dst, cl}", []>;
Eli Friedman23457332017-01-30 22:04:23 +0000446def RCR16mCL : I<0xD3, MRM3m, (outs), (ins i16mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000447 "rcr{w}\t{%cl, $dst|$dst, cl}", []>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000448def RCR32mCL : I<0xD3, MRM3m, (outs), (ins i32mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000449 "rcr{l}\t{%cl, $dst|$dst, cl}", []>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000450def RCR64mCL : RI<0xD3, MRM3m, (outs), (ins i64mem:$dst),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000451 "rcr{q}\t{%cl, $dst|$dst, cl}", []>,
Craig Topper23c34882017-12-15 19:01:51 +0000452 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000453} // Uses = [CL, EFLAGS]
454} // SchedRW
455} // hasSideEffects = 0
456
Simon Pilgrim5f9d91202018-09-23 15:12:10 +0000457let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in {
Eli Friedman23457332017-01-30 22:04:23 +0000458// FIXME: provide shorter instructions when imm8 == 1
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000459let Uses = [CL], SchedRW = [WriteRotateCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000460def ROL8rCL : I<0xD2, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
461 "rol{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000462 [(set GR8:$dst, (rotl GR8:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000463def ROL16rCL : I<0xD3, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
464 "rol{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000465 [(set GR16:$dst, (rotl GR16:$src1, CL))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000466def ROL32rCL : I<0xD3, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
467 "rol{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000468 [(set GR32:$dst, (rotl GR32:$src1, CL))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000469def ROL64rCL : RI<0xD3, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
470 "rol{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000471 [(set GR64:$dst, (rotl GR64:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000472}
473
474def ROL8ri : Ii8<0xC0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
475 "rol{b}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000476 [(set GR8:$dst, (rotl GR8:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000477def ROL16ri : Ii8<0xC1, MRM0r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
478 "rol{w}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000479 [(set GR16:$dst, (rotl GR16:$src1, (i8 imm:$src2)))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000480def ROL32ri : Ii8<0xC1, MRM0r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
481 "rol{l}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000482 [(set GR32:$dst, (rotl GR32:$src1, (i8 imm:$src2)))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000483def ROL64ri : RIi8<0xC1, MRM0r, (outs GR64:$dst),
484 (ins GR64:$src1, u8imm:$src2),
485 "rol{q}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000486 [(set GR64:$dst, (rotl GR64:$src1, (i8 imm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000487
488// Rotate by 1
489def ROL8r1 : I<0xD0, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
490 "rol{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000491 [(set GR8:$dst, (rotl GR8:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000492def ROL16r1 : I<0xD1, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
493 "rol{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000494 [(set GR16:$dst, (rotl GR16:$src1, (i8 1)))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000495def ROL32r1 : I<0xD1, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
496 "rol{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000497 [(set GR32:$dst, (rotl GR32:$src1, (i8 1)))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000498def ROL64r1 : RI<0xD1, MRM0r, (outs GR64:$dst), (ins GR64:$src1),
499 "rol{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000500 [(set GR64:$dst, (rotl GR64:$src1, (i8 1)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000501} // Constraints = "$src = $dst", SchedRW
502
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000503let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000504def ROL8mCL : I<0xD2, MRM0m, (outs), (ins i8mem :$dst),
505 "rol{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000506 [(store (rotl (loadi8 addr:$dst), CL), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000507def ROL16mCL : I<0xD3, MRM0m, (outs), (ins i16mem:$dst),
508 "rol{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000509 [(store (rotl (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000510def ROL32mCL : I<0xD3, MRM0m, (outs), (ins i32mem:$dst),
511 "rol{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000512 [(store (rotl (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000513def ROL64mCL : RI<0xD3, MRM0m, (outs), (ins i64mem:$dst),
514 "rol{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000515 [(store (rotl (loadi64 addr:$dst), CL), addr:$dst)]>,
516 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000517}
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000518
519let SchedRW = [WriteRotateLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000520def ROL8mi : Ii8<0xC0, MRM0m, (outs), (ins i8mem :$dst, u8imm:$src1),
521 "rol{b}\t{$src1, $dst|$dst, $src1}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000522 [(store (rotl (loadi8 addr:$dst), (i8 imm:$src1)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000523def ROL16mi : Ii8<0xC1, MRM0m, (outs), (ins i16mem:$dst, u8imm:$src1),
524 "rol{w}\t{$src1, $dst|$dst, $src1}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000525 [(store (rotl (loadi16 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
526 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000527def ROL32mi : Ii8<0xC1, MRM0m, (outs), (ins i32mem:$dst, u8imm:$src1),
528 "rol{l}\t{$src1, $dst|$dst, $src1}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000529 [(store (rotl (loadi32 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
530 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000531def ROL64mi : RIi8<0xC1, MRM0m, (outs), (ins i64mem:$dst, u8imm:$src1),
532 "rol{q}\t{$src1, $dst|$dst, $src1}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000533 [(store (rotl (loadi64 addr:$dst), (i8 imm:$src1)), addr:$dst)]>,
534 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000535
536// Rotate by 1
537def ROL8m1 : I<0xD0, MRM0m, (outs), (ins i8mem :$dst),
538 "rol{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000539 [(store (rotl (loadi8 addr:$dst), (i8 1)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000540def ROL16m1 : I<0xD1, MRM0m, (outs), (ins i16mem:$dst),
541 "rol{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000542 [(store (rotl (loadi16 addr:$dst), (i8 1)), addr:$dst)]>,
543 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000544def ROL32m1 : I<0xD1, MRM0m, (outs), (ins i32mem:$dst),
545 "rol{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000546 [(store (rotl (loadi32 addr:$dst), (i8 1)), addr:$dst)]>,
547 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000548def ROL64m1 : RI<0xD1, MRM0m, (outs), (ins i64mem:$dst),
549 "rol{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000550 [(store (rotl (loadi64 addr:$dst), (i8 1)), addr:$dst)]>,
551 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000552} // SchedRW
553
Simon Pilgrim5f9d91202018-09-23 15:12:10 +0000554let Constraints = "$src1 = $dst", SchedRW = [WriteRotate] in {
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000555let Uses = [CL], SchedRW = [WriteRotateCL] in {
Eli Friedman23457332017-01-30 22:04:23 +0000556def ROR8rCL : I<0xD2, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
557 "ror{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000558 [(set GR8:$dst, (rotr GR8:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000559def ROR16rCL : I<0xD3, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
560 "ror{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000561 [(set GR16:$dst, (rotr GR16:$src1, CL))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000562def ROR32rCL : I<0xD3, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
563 "ror{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000564 [(set GR32:$dst, (rotr GR32:$src1, CL))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000565def ROR64rCL : RI<0xD3, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
566 "ror{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000567 [(set GR64:$dst, (rotr GR64:$src1, CL))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000568}
569
570def ROR8ri : Ii8<0xC0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1, u8imm:$src2),
571 "ror{b}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000572 [(set GR8:$dst, (rotr GR8:$src1, (i8 relocImm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000573def ROR16ri : Ii8<0xC1, MRM1r, (outs GR16:$dst), (ins GR16:$src1, u8imm:$src2),
574 "ror{w}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000575 [(set GR16:$dst, (rotr GR16:$src1, (i8 relocImm:$src2)))]>,
576 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000577def ROR32ri : Ii8<0xC1, MRM1r, (outs GR32:$dst), (ins GR32:$src1, u8imm:$src2),
578 "ror{l}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000579 [(set GR32:$dst, (rotr GR32:$src1, (i8 relocImm:$src2)))]>,
580 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000581def ROR64ri : RIi8<0xC1, MRM1r, (outs GR64:$dst),
582 (ins GR64:$src1, u8imm:$src2),
583 "ror{q}\t{$src2, $dst|$dst, $src2}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000584 [(set GR64:$dst, (rotr GR64:$src1, (i8 relocImm:$src2)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000585
586// Rotate by 1
587def ROR8r1 : I<0xD0, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
588 "ror{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000589 [(set GR8:$dst, (rotl GR8:$src1, (i8 7)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000590def ROR16r1 : I<0xD1, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
591 "ror{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000592 [(set GR16:$dst, (rotl GR16:$src1, (i8 15)))]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000593def ROR32r1 : I<0xD1, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
594 "ror{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000595 [(set GR32:$dst, (rotl GR32:$src1, (i8 31)))]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000596def ROR64r1 : RI<0xD1, MRM1r, (outs GR64:$dst), (ins GR64:$src1),
597 "ror{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000598 [(set GR64:$dst, (rotl GR64:$src1, (i8 63)))]>;
Eli Friedman23457332017-01-30 22:04:23 +0000599} // Constraints = "$src = $dst", SchedRW
600
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000601let Uses = [CL], SchedRW = [WriteRotateCLLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000602def ROR8mCL : I<0xD2, MRM1m, (outs), (ins i8mem :$dst),
603 "ror{b}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000604 [(store (rotr (loadi8 addr:$dst), CL), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000605def ROR16mCL : I<0xD3, MRM1m, (outs), (ins i16mem:$dst),
606 "ror{w}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000607 [(store (rotr (loadi16 addr:$dst), CL), addr:$dst)]>, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000608def ROR32mCL : I<0xD3, MRM1m, (outs), (ins i32mem:$dst),
609 "ror{l}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000610 [(store (rotr (loadi32 addr:$dst), CL), addr:$dst)]>, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000611def ROR64mCL : RI<0xD3, MRM1m, (outs), (ins i64mem:$dst),
612 "ror{q}\t{%cl, $dst|$dst, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000613 [(store (rotr (loadi64 addr:$dst), CL), addr:$dst)]>,
614 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000615}
Simon Pilgrimf3f3dd52018-09-23 21:19:15 +0000616
617let SchedRW = [WriteRotateLd, WriteRMW] in {
Eli Friedman23457332017-01-30 22:04:23 +0000618def ROR8mi : Ii8<0xC0, MRM1m, (outs), (ins i8mem :$dst, u8imm:$src),
619 "ror{b}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000620 [(store (rotr (loadi8 addr:$dst), (i8 imm:$src)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000621def ROR16mi : Ii8<0xC1, MRM1m, (outs), (ins i16mem:$dst, u8imm:$src),
622 "ror{w}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000623 [(store (rotr (loadi16 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
624 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000625def ROR32mi : Ii8<0xC1, MRM1m, (outs), (ins i32mem:$dst, u8imm:$src),
626 "ror{l}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000627 [(store (rotr (loadi32 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
628 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000629def ROR64mi : RIi8<0xC1, MRM1m, (outs), (ins i64mem:$dst, u8imm:$src),
630 "ror{q}\t{$src, $dst|$dst, $src}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000631 [(store (rotr (loadi64 addr:$dst), (i8 imm:$src)), addr:$dst)]>,
632 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000633
634// Rotate by 1
635def ROR8m1 : I<0xD0, MRM1m, (outs), (ins i8mem :$dst),
636 "ror{b}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000637 [(store (rotl (loadi8 addr:$dst), (i8 7)), addr:$dst)]>;
Eli Friedman23457332017-01-30 22:04:23 +0000638def ROR16m1 : I<0xD1, MRM1m, (outs), (ins i16mem:$dst),
639 "ror{w}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000640 [(store (rotl (loadi16 addr:$dst), (i8 15)), addr:$dst)]>,
641 OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000642def ROR32m1 : I<0xD1, MRM1m, (outs), (ins i32mem:$dst),
643 "ror{l}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000644 [(store (rotl (loadi32 addr:$dst), (i8 31)), addr:$dst)]>,
645 OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000646def ROR64m1 : RI<0xD1, MRM1m, (outs), (ins i64mem:$dst),
647 "ror{q}\t$dst",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000648 [(store (rotl (loadi64 addr:$dst), (i8 63)), addr:$dst)]>,
649 Requires<[In64BitMode]>;
Eli Friedman23457332017-01-30 22:04:23 +0000650} // SchedRW
651
652
653//===----------------------------------------------------------------------===//
654// Double shift instructions (generalizations of rotate)
655//===----------------------------------------------------------------------===//
656
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000657let Constraints = "$src1 = $dst" in {
Eli Friedman23457332017-01-30 22:04:23 +0000658
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000659let Uses = [CL], SchedRW = [WriteSHDrrcl] in {
Eli Friedman23457332017-01-30 22:04:23 +0000660def SHLD16rrCL : I<0xA5, MRMDestReg, (outs GR16:$dst),
661 (ins GR16:$src1, GR16:$src2),
662 "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000663 [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2, CL))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000664 TB, OpSize16;
665def SHRD16rrCL : I<0xAD, MRMDestReg, (outs GR16:$dst),
666 (ins GR16:$src1, GR16:$src2),
667 "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000668 [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2, CL))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000669 TB, OpSize16;
670def SHLD32rrCL : I<0xA5, MRMDestReg, (outs GR32:$dst),
671 (ins GR32:$src1, GR32:$src2),
672 "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000673 [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2, CL))]>,
674 TB, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000675def SHRD32rrCL : I<0xAD, MRMDestReg, (outs GR32:$dst),
676 (ins GR32:$src1, GR32:$src2),
677 "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000678 [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2, CL))]>,
679 TB, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000680def SHLD64rrCL : RI<0xA5, MRMDestReg, (outs GR64:$dst),
681 (ins GR64:$src1, GR64:$src2),
682 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000683 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2, CL))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000684 TB;
685def SHRD64rrCL : RI<0xAD, MRMDestReg, (outs GR64:$dst),
686 (ins GR64:$src1, GR64:$src2),
687 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000688 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2, CL))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000689 TB;
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000690} // SchedRW
Eli Friedman23457332017-01-30 22:04:23 +0000691
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000692let isCommutable = 1, SchedRW = [WriteSHDrri] in { // These instructions commute to each other.
Eli Friedman23457332017-01-30 22:04:23 +0000693def SHLD16rri8 : Ii8<0xA4, MRMDestReg,
694 (outs GR16:$dst),
695 (ins GR16:$src1, GR16:$src2, u8imm:$src3),
696 "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
697 [(set GR16:$dst, (X86shld GR16:$src1, GR16:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000698 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000699 TB, OpSize16;
700def SHRD16rri8 : Ii8<0xAC, MRMDestReg,
701 (outs GR16:$dst),
702 (ins GR16:$src1, GR16:$src2, u8imm:$src3),
703 "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
704 [(set GR16:$dst, (X86shrd GR16:$src1, GR16:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000705 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000706 TB, OpSize16;
707def SHLD32rri8 : Ii8<0xA4, MRMDestReg,
708 (outs GR32:$dst),
709 (ins GR32:$src1, GR32:$src2, u8imm:$src3),
710 "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
711 [(set GR32:$dst, (X86shld GR32:$src1, GR32:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000712 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000713 TB, OpSize32;
714def SHRD32rri8 : Ii8<0xAC, MRMDestReg,
715 (outs GR32:$dst),
716 (ins GR32:$src1, GR32:$src2, u8imm:$src3),
717 "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
718 [(set GR32:$dst, (X86shrd GR32:$src1, GR32:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000719 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000720 TB, OpSize32;
721def SHLD64rri8 : RIi8<0xA4, MRMDestReg,
722 (outs GR64:$dst),
723 (ins GR64:$src1, GR64:$src2, u8imm:$src3),
724 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
725 [(set GR64:$dst, (X86shld GR64:$src1, GR64:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000726 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000727 TB;
728def SHRD64rri8 : RIi8<0xAC, MRMDestReg,
729 (outs GR64:$dst),
730 (ins GR64:$src1, GR64:$src2, u8imm:$src3),
731 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
732 [(set GR64:$dst, (X86shrd GR64:$src1, GR64:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000733 (i8 imm:$src3)))]>,
Eli Friedman23457332017-01-30 22:04:23 +0000734 TB;
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000735} // SchedRW
736} // Constraints = "$src = $dst"
Eli Friedman23457332017-01-30 22:04:23 +0000737
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000738let Uses = [CL], SchedRW = [WriteSHDmrcl] in {
Eli Friedman23457332017-01-30 22:04:23 +0000739def SHLD16mrCL : I<0xA5, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
740 "shld{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
741 [(store (X86shld (loadi16 addr:$dst), GR16:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000742 addr:$dst)]>, TB, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000743def SHRD16mrCL : I<0xAD, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src2),
744 "shrd{w}\t{%cl, $src2, $dst|$dst, $src2, cl}",
745 [(store (X86shrd (loadi16 addr:$dst), GR16:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000746 addr:$dst)]>, TB, OpSize16;
Eli Friedman23457332017-01-30 22:04:23 +0000747
748def SHLD32mrCL : I<0xA5, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
749 "shld{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
750 [(store (X86shld (loadi32 addr:$dst), GR32:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000751 addr:$dst)]>, TB, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000752def SHRD32mrCL : I<0xAD, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src2),
753 "shrd{l}\t{%cl, $src2, $dst|$dst, $src2, cl}",
754 [(store (X86shrd (loadi32 addr:$dst), GR32:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000755 addr:$dst)]>, TB, OpSize32;
Eli Friedman23457332017-01-30 22:04:23 +0000756
757def SHLD64mrCL : RI<0xA5, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
758 "shld{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
759 [(store (X86shld (loadi64 addr:$dst), GR64:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000760 addr:$dst)]>, TB;
Eli Friedman23457332017-01-30 22:04:23 +0000761def SHRD64mrCL : RI<0xAD, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src2),
762 "shrd{q}\t{%cl, $src2, $dst|$dst, $src2, cl}",
763 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2, CL),
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000764 addr:$dst)]>, TB;
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000765} // SchedRW
Eli Friedman23457332017-01-30 22:04:23 +0000766
Andrew V. Tischenkoe5640552018-07-31 10:14:43 +0000767let SchedRW = [WriteSHDmri] in {
Eli Friedman23457332017-01-30 22:04:23 +0000768def SHLD16mri8 : Ii8<0xA4, MRMDestMem,
769 (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3),
770 "shld{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
771 [(store (X86shld (loadi16 addr:$dst), GR16:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000772 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000773 TB, OpSize16;
774def SHRD16mri8 : Ii8<0xAC, MRMDestMem,
775 (outs), (ins i16mem:$dst, GR16:$src2, u8imm:$src3),
776 "shrd{w}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
777 [(store (X86shrd (loadi16 addr:$dst), GR16:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000778 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000779 TB, OpSize16;
780
781def SHLD32mri8 : Ii8<0xA4, MRMDestMem,
782 (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3),
783 "shld{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
784 [(store (X86shld (loadi32 addr:$dst), GR32:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000785 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000786 TB, OpSize32;
787def SHRD32mri8 : Ii8<0xAC, MRMDestMem,
788 (outs), (ins i32mem:$dst, GR32:$src2, u8imm:$src3),
789 "shrd{l}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
790 [(store (X86shrd (loadi32 addr:$dst), GR32:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000791 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000792 TB, OpSize32;
793
794def SHLD64mri8 : RIi8<0xA4, MRMDestMem,
795 (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3),
796 "shld{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
797 [(store (X86shld (loadi64 addr:$dst), GR64:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000798 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000799 TB;
800def SHRD64mri8 : RIi8<0xAC, MRMDestMem,
801 (outs), (ins i64mem:$dst, GR64:$src2, u8imm:$src3),
802 "shrd{q}\t{$src3, $src2, $dst|$dst, $src2, $src3}",
803 [(store (X86shrd (loadi64 addr:$dst), GR64:$src2,
Simon Pilgrimdec781c2018-04-12 18:25:38 +0000804 (i8 imm:$src3)), addr:$dst)]>,
Eli Friedman23457332017-01-30 22:04:23 +0000805 TB;
806} // SchedRW
807
808} // Defs = [EFLAGS]
809
Craig Topperd88389a2017-02-21 06:39:13 +0000810// Sandy Bridge and newer Intel processors support faster rotates using
811// SHLD to avoid a partial flag update on the normal rotate instructions.
812let Predicates = [HasFastSHLDRotate], AddedComplexity = 5 in {
813 def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),
814 (SHLD32rri8 GR32:$src, GR32:$src, imm:$shamt)>;
815 def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),
816 (SHLD64rri8 GR64:$src, GR64:$src, imm:$shamt)>;
817}
818
Eli Friedman23457332017-01-30 22:04:23 +0000819def ROT32L2R_imm8 : SDNodeXForm<imm, [{
820 // Convert a ROTL shamt to a ROTR shamt on 32-bit integer.
821 return getI8Imm(32 - N->getZExtValue(), SDLoc(N));
822}]>;
823
824def ROT64L2R_imm8 : SDNodeXForm<imm, [{
825 // Convert a ROTL shamt to a ROTR shamt on 64-bit integer.
826 return getI8Imm(64 - N->getZExtValue(), SDLoc(N));
827}]>;
828
Simon Pilgrim4b500862018-09-23 16:17:13 +0000829// NOTE: We use WriteShift for these rotates as they avoid the stalls
830// of many of the older x86 rotate instructions.
Eli Friedman23457332017-01-30 22:04:23 +0000831multiclass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop> {
832let hasSideEffects = 0 in {
833 def ri : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, u8imm:$src2),
834 !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
Simon Pilgrim4b500862018-09-23 16:17:13 +0000835 []>, TAXD, VEX, Sched<[WriteShift]>;
Eli Friedman23457332017-01-30 22:04:23 +0000836 let mayLoad = 1 in
837 def mi : Ii8<0xF0, MRMSrcMem, (outs RC:$dst),
838 (ins x86memop:$src1, u8imm:$src2),
839 !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
Simon Pilgrim4b500862018-09-23 16:17:13 +0000840 []>, TAXD, VEX, Sched<[WriteShiftLd]>;
Eli Friedman23457332017-01-30 22:04:23 +0000841}
842}
843
844multiclass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop> {
845let hasSideEffects = 0 in {
846 def rr : I<0xF7, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
847 !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
848 VEX, Sched<[WriteShift]>;
849 let mayLoad = 1 in
850 def rm : I<0xF7, MRMSrcMem4VOp3,
851 (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
852 !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
853 VEX, Sched<[WriteShiftLd,
854 // x86memop:$src1
855 ReadDefault, ReadDefault, ReadDefault, ReadDefault,
856 ReadDefault,
Craig Topperee3c19f2018-03-29 22:03:05 +0000857 // RC:$src2
Eli Friedman23457332017-01-30 22:04:23 +0000858 ReadAfterLd]>;
859}
860}
861
862let Predicates = [HasBMI2] in {
863 defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>;
864 defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, VEX_W;
865 defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8XS;
866 defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8XS, VEX_W;
867 defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8XD;
868 defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8XD, VEX_W;
869 defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8PD;
870 defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8PD, VEX_W;
871
872 // Prefer RORX which is non-destructive and doesn't update EFLAGS.
873 let AddedComplexity = 10 in {
874 def : Pat<(rotl GR32:$src, (i8 imm:$shamt)),
875 (RORX32ri GR32:$src, (ROT32L2R_imm8 imm:$shamt))>;
876 def : Pat<(rotl GR64:$src, (i8 imm:$shamt)),
877 (RORX64ri GR64:$src, (ROT64L2R_imm8 imm:$shamt))>;
878 }
879
880 def : Pat<(rotl (loadi32 addr:$src), (i8 imm:$shamt)),
881 (RORX32mi addr:$src, (ROT32L2R_imm8 imm:$shamt))>;
882 def : Pat<(rotl (loadi64 addr:$src), (i8 imm:$shamt)),
883 (RORX64mi addr:$src, (ROT64L2R_imm8 imm:$shamt))>;
884
885 // Prefer SARX/SHRX/SHLX over SAR/SHR/SHL with variable shift BUT not
886 // immedidate shift, i.e. the following code is considered better
887 //
888 // mov %edi, %esi
889 // shl $imm, %esi
890 // ... %edi, ...
891 //
892 // than
893 //
894 // movb $imm, %sil
895 // shlx %sil, %edi, %esi
896 // ... %edi, ...
897 //
898 let AddedComplexity = 1 in {
899 def : Pat<(sra GR32:$src1, GR8:$src2),
900 (SARX32rr GR32:$src1,
901 (INSERT_SUBREG
902 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
903 def : Pat<(sra GR64:$src1, GR8:$src2),
904 (SARX64rr GR64:$src1,
905 (INSERT_SUBREG
906 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
907
908 def : Pat<(srl GR32:$src1, GR8:$src2),
909 (SHRX32rr GR32:$src1,
910 (INSERT_SUBREG
911 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
912 def : Pat<(srl GR64:$src1, GR8:$src2),
913 (SHRX64rr GR64:$src1,
914 (INSERT_SUBREG
915 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
916
917 def : Pat<(shl GR32:$src1, GR8:$src2),
918 (SHLX32rr GR32:$src1,
919 (INSERT_SUBREG
920 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
921 def : Pat<(shl GR64:$src1, GR8:$src2),
922 (SHLX64rr GR64:$src1,
923 (INSERT_SUBREG
924 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
925 }
926
Craig Topperab70f582018-06-28 00:47:41 +0000927 // We prefer to use
Eli Friedman23457332017-01-30 22:04:23 +0000928 // mov (%ecx), %esi
929 // shl $imm, $esi
930 //
931 // over
932 //
Craig Topper6912d7f2017-07-23 03:59:37 +0000933 // movb $imm, %al
Eli Friedman23457332017-01-30 22:04:23 +0000934 // shlx %al, (%ecx), %esi
Craig Topperab70f582018-06-28 00:47:41 +0000935 //
936 // This priority is enforced by IsProfitableToFoldLoad.
937 def : Pat<(sra (loadi32 addr:$src1), GR8:$src2),
938 (SARX32rm addr:$src1,
939 (INSERT_SUBREG
940 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
941 def : Pat<(sra (loadi64 addr:$src1), GR8:$src2),
942 (SARX64rm addr:$src1,
943 (INSERT_SUBREG
944 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
Craig Topper6912d7f2017-07-23 03:59:37 +0000945
Craig Topperab70f582018-06-28 00:47:41 +0000946 def : Pat<(srl (loadi32 addr:$src1), GR8:$src2),
947 (SHRX32rm addr:$src1,
948 (INSERT_SUBREG
949 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
950 def : Pat<(srl (loadi64 addr:$src1), GR8:$src2),
951 (SHRX64rm addr:$src1,
952 (INSERT_SUBREG
953 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
Craig Topper6912d7f2017-07-23 03:59:37 +0000954
Craig Topperab70f582018-06-28 00:47:41 +0000955 def : Pat<(shl (loadi32 addr:$src1), GR8:$src2),
956 (SHLX32rm addr:$src1,
957 (INSERT_SUBREG
958 (i32 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
959 def : Pat<(shl (loadi64 addr:$src1), GR8:$src2),
960 (SHLX64rm addr:$src1,
961 (INSERT_SUBREG
962 (i64 (IMPLICIT_DEF)), GR8:$src2, sub_8bit))>;
Eli Friedman23457332017-01-30 22:04:23 +0000963}