blob: c2f72ef4d63d81111e67741cf25ad3629bf28cd5 [file] [log] [blame]
Chris Lattner87be16a2010-10-05 06:04:14 +00001//===- X86InstrCompiler.td - Compiler Pseudos and Patterns -*- 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 various pseudo instructions used by the compiler,
11// as well as Pat patterns used during instruction selection.
12//
13//===----------------------------------------------------------------------===//
14
15
16//===----------------------------------------------------------------------===//
17// EH Pseudo Instructions
18//
19let isTerminator = 1, isReturn = 1, isBarrier = 1,
20 hasCtrlDep = 1, isCodeGenOnly = 1 in {
21def EH_RETURN : I<0xC3, RawFrm, (outs), (ins GR32:$addr),
22 "ret\t#eh_return, addr: $addr",
23 [(X86ehret GR32:$addr)]>;
24
25}
26
27let isTerminator = 1, isReturn = 1, isBarrier = 1,
28 hasCtrlDep = 1, isCodeGenOnly = 1 in {
29def EH_RETURN64 : I<0xC3, RawFrm, (outs), (ins GR64:$addr),
30 "ret\t#eh_return, addr: $addr",
31 [(X86ehret GR64:$addr)]>;
32
33}
34
35
36//===----------------------------------------------------------------------===//
37// Non-Instruction Patterns
38//===----------------------------------------------------------------------===//
39
40// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
41def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>;
42def : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>;
43def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>;
44def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>;
45def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>;
46def : Pat<(i32 (X86Wrapper tblockaddress:$dst)), (MOV32ri tblockaddress:$dst)>;
47
48def : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)),
49 (ADD32ri GR32:$src1, tconstpool:$src2)>;
50def : Pat<(add GR32:$src1, (X86Wrapper tjumptable:$src2)),
51 (ADD32ri GR32:$src1, tjumptable:$src2)>;
52def : Pat<(add GR32:$src1, (X86Wrapper tglobaladdr :$src2)),
53 (ADD32ri GR32:$src1, tglobaladdr:$src2)>;
54def : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)),
55 (ADD32ri GR32:$src1, texternalsym:$src2)>;
56def : Pat<(add GR32:$src1, (X86Wrapper tblockaddress:$src2)),
57 (ADD32ri GR32:$src1, tblockaddress:$src2)>;
58
59def : Pat<(store (i32 (X86Wrapper tglobaladdr:$src)), addr:$dst),
60 (MOV32mi addr:$dst, tglobaladdr:$src)>;
61def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst),
62 (MOV32mi addr:$dst, texternalsym:$src)>;
63def : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst),
64 (MOV32mi addr:$dst, tblockaddress:$src)>;
65
66
67
68// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable when not in small
69// code model mode, should use 'movabs'. FIXME: This is really a hack, the
70// 'movabs' predicate should handle this sort of thing.
71def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
72 (MOV64ri tconstpool :$dst)>, Requires<[FarData]>;
73def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
74 (MOV64ri tjumptable :$dst)>, Requires<[FarData]>;
75def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
76 (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>;
77def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
78 (MOV64ri texternalsym:$dst)>, Requires<[FarData]>;
79def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
80 (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>;
81
82// In static codegen with small code model, we can get the address of a label
83// into a register with 'movl'. FIXME: This is a hack, the 'imm' predicate of
84// the MOV64ri64i32 should accept these.
85def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
86 (MOV64ri64i32 tconstpool :$dst)>, Requires<[SmallCode]>;
87def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
88 (MOV64ri64i32 tjumptable :$dst)>, Requires<[SmallCode]>;
89def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
90 (MOV64ri64i32 tglobaladdr :$dst)>, Requires<[SmallCode]>;
91def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
92 (MOV64ri64i32 texternalsym:$dst)>, Requires<[SmallCode]>;
93def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
94 (MOV64ri64i32 tblockaddress:$dst)>, Requires<[SmallCode]>;
95
96// In kernel code model, we can get the address of a label
97// into a register with 'movq'. FIXME: This is a hack, the 'imm' predicate of
98// the MOV64ri32 should accept these.
99def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
100 (MOV64ri32 tconstpool :$dst)>, Requires<[KernelCode]>;
101def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
102 (MOV64ri32 tjumptable :$dst)>, Requires<[KernelCode]>;
103def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
104 (MOV64ri32 tglobaladdr :$dst)>, Requires<[KernelCode]>;
105def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
106 (MOV64ri32 texternalsym:$dst)>, Requires<[KernelCode]>;
107def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
108 (MOV64ri32 tblockaddress:$dst)>, Requires<[KernelCode]>;
109
110// If we have small model and -static mode, it is safe to store global addresses
111// directly as immediates. FIXME: This is really a hack, the 'imm' predicate
112// for MOV64mi32 should handle this sort of thing.
113def : Pat<(store (i64 (X86Wrapper tconstpool:$src)), addr:$dst),
114 (MOV64mi32 addr:$dst, tconstpool:$src)>,
115 Requires<[NearData, IsStatic]>;
116def : Pat<(store (i64 (X86Wrapper tjumptable:$src)), addr:$dst),
117 (MOV64mi32 addr:$dst, tjumptable:$src)>,
118 Requires<[NearData, IsStatic]>;
119def : Pat<(store (i64 (X86Wrapper tglobaladdr:$src)), addr:$dst),
120 (MOV64mi32 addr:$dst, tglobaladdr:$src)>,
121 Requires<[NearData, IsStatic]>;
122def : Pat<(store (i64 (X86Wrapper texternalsym:$src)), addr:$dst),
123 (MOV64mi32 addr:$dst, texternalsym:$src)>,
124 Requires<[NearData, IsStatic]>;
125def : Pat<(store (i64 (X86Wrapper tblockaddress:$src)), addr:$dst),
126 (MOV64mi32 addr:$dst, tblockaddress:$src)>,
127 Requires<[NearData, IsStatic]>;
128
129
130
131// Calls
132
133// tls has some funny stuff here...
134// This corresponds to movabs $foo@tpoff, %rax
135def : Pat<(i64 (X86Wrapper tglobaltlsaddr :$dst)),
136 (MOV64ri tglobaltlsaddr :$dst)>;
137// This corresponds to add $foo@tpoff, %rax
138def : Pat<(add GR64:$src1, (X86Wrapper tglobaltlsaddr :$dst)),
139 (ADD64ri32 GR64:$src1, tglobaltlsaddr :$dst)>;
140// This corresponds to mov foo@tpoff(%rbx), %eax
141def : Pat<(load (i64 (X86Wrapper tglobaltlsaddr :$dst))),
142 (MOV64rm tglobaltlsaddr :$dst)>;
143
144
145// Direct PC relative function call for small code model. 32-bit displacement
146// sign extended to 64-bit.
147def : Pat<(X86call (i64 tglobaladdr:$dst)),
148 (CALL64pcrel32 tglobaladdr:$dst)>, Requires<[NotWin64]>;
149def : Pat<(X86call (i64 texternalsym:$dst)),
150 (CALL64pcrel32 texternalsym:$dst)>, Requires<[NotWin64]>;
151
152def : Pat<(X86call (i64 tglobaladdr:$dst)),
153 (WINCALL64pcrel32 tglobaladdr:$dst)>, Requires<[IsWin64]>;
154def : Pat<(X86call (i64 texternalsym:$dst)),
155 (WINCALL64pcrel32 texternalsym:$dst)>, Requires<[IsWin64]>;
156
157// tailcall stuff
158def : Pat<(X86tcret GR32_TC:$dst, imm:$off),
159 (TCRETURNri GR32_TC:$dst, imm:$off)>,
160 Requires<[In32BitMode]>;
161
162// FIXME: This is disabled for 32-bit PIC mode because the global base
163// register which is part of the address mode may be assigned a
164// callee-saved register.
165def : Pat<(X86tcret (load addr:$dst), imm:$off),
166 (TCRETURNmi addr:$dst, imm:$off)>,
167 Requires<[In32BitMode, IsNotPIC]>;
168
169def : Pat<(X86tcret (i32 tglobaladdr:$dst), imm:$off),
170 (TCRETURNdi texternalsym:$dst, imm:$off)>,
171 Requires<[In32BitMode]>;
172
173def : Pat<(X86tcret (i32 texternalsym:$dst), imm:$off),
174 (TCRETURNdi texternalsym:$dst, imm:$off)>,
175 Requires<[In32BitMode]>;
176
177def : Pat<(X86tcret GR64_TC:$dst, imm:$off),
178 (TCRETURNri64 GR64_TC:$dst, imm:$off)>,
179 Requires<[In64BitMode]>;
180
181def : Pat<(X86tcret (load addr:$dst), imm:$off),
182 (TCRETURNmi64 addr:$dst, imm:$off)>,
183 Requires<[In64BitMode]>;
184
185def : Pat<(X86tcret (i64 tglobaladdr:$dst), imm:$off),
186 (TCRETURNdi64 tglobaladdr:$dst, imm:$off)>,
187 Requires<[In64BitMode]>;
188
189def : Pat<(X86tcret (i64 texternalsym:$dst), imm:$off),
190 (TCRETURNdi64 texternalsym:$dst, imm:$off)>,
191 Requires<[In64BitMode]>;
192
193// Normal calls, with various flavors of addresses.
194def : Pat<(X86call (i32 tglobaladdr:$dst)),
195 (CALLpcrel32 tglobaladdr:$dst)>;
196def : Pat<(X86call (i32 texternalsym:$dst)),
197 (CALLpcrel32 texternalsym:$dst)>;
198def : Pat<(X86call (i32 imm:$dst)),
199 (CALLpcrel32 imm:$dst)>, Requires<[CallImmAddr]>;
200
201// X86 specific add which produces a flag.
202def : Pat<(addc GR32:$src1, GR32:$src2),
203 (ADD32rr GR32:$src1, GR32:$src2)>;
204def : Pat<(addc GR32:$src1, (load addr:$src2)),
205 (ADD32rm GR32:$src1, addr:$src2)>;
206def : Pat<(addc GR32:$src1, imm:$src2),
207 (ADD32ri GR32:$src1, imm:$src2)>;
208def : Pat<(addc GR32:$src1, i32immSExt8:$src2),
209 (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
210
211def : Pat<(addc GR64:$src1, GR64:$src2),
212 (ADD64rr GR64:$src1, GR64:$src2)>;
213def : Pat<(addc GR64:$src1, (load addr:$src2)),
214 (ADD64rm GR64:$src1, addr:$src2)>;
215def : Pat<(addc GR64:$src1, i64immSExt8:$src2),
216 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
217def : Pat<(addc GR64:$src1, i64immSExt32:$src2),
218 (ADD64ri32 GR64:$src1, imm:$src2)>;
219
220def : Pat<(subc GR32:$src1, GR32:$src2),
221 (SUB32rr GR32:$src1, GR32:$src2)>;
222def : Pat<(subc GR32:$src1, (load addr:$src2)),
223 (SUB32rm GR32:$src1, addr:$src2)>;
224def : Pat<(subc GR32:$src1, imm:$src2),
225 (SUB32ri GR32:$src1, imm:$src2)>;
226def : Pat<(subc GR32:$src1, i32immSExt8:$src2),
227 (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;
228
229def : Pat<(subc GR64:$src1, GR64:$src2),
230 (SUB64rr GR64:$src1, GR64:$src2)>;
231def : Pat<(subc GR64:$src1, (load addr:$src2)),
232 (SUB64rm GR64:$src1, addr:$src2)>;
233def : Pat<(subc GR64:$src1, i64immSExt8:$src2),
234 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
235def : Pat<(subc GR64:$src1, imm:$src2),
236 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
237
238// Comparisons.
239
240// TEST R,R is smaller than CMP R,0
241def : Pat<(X86cmp GR8:$src1, 0),
242 (TEST8rr GR8:$src1, GR8:$src1)>;
243def : Pat<(X86cmp GR16:$src1, 0),
244 (TEST16rr GR16:$src1, GR16:$src1)>;
245def : Pat<(X86cmp GR32:$src1, 0),
246 (TEST32rr GR32:$src1, GR32:$src1)>;
247def : Pat<(X86cmp GR64:$src1, 0),
248 (TEST64rr GR64:$src1, GR64:$src1)>;
249
250// Conditional moves with folded loads with operands swapped and conditions
251// inverted.
252def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_B, EFLAGS),
253 (CMOVAE16rm GR16:$src2, addr:$src1)>;
254def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_B, EFLAGS),
255 (CMOVAE32rm GR32:$src2, addr:$src1)>;
256def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_AE, EFLAGS),
257 (CMOVB16rm GR16:$src2, addr:$src1)>;
258def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_AE, EFLAGS),
259 (CMOVB32rm GR32:$src2, addr:$src1)>;
260def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_E, EFLAGS),
261 (CMOVNE16rm GR16:$src2, addr:$src1)>;
262def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_E, EFLAGS),
263 (CMOVNE32rm GR32:$src2, addr:$src1)>;
264def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_NE, EFLAGS),
265 (CMOVE16rm GR16:$src2, addr:$src1)>;
266def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_NE, EFLAGS),
267 (CMOVE32rm GR32:$src2, addr:$src1)>;
268def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_BE, EFLAGS),
269 (CMOVA16rm GR16:$src2, addr:$src1)>;
270def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_BE, EFLAGS),
271 (CMOVA32rm GR32:$src2, addr:$src1)>;
272def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_A, EFLAGS),
273 (CMOVBE16rm GR16:$src2, addr:$src1)>;
274def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_A, EFLAGS),
275 (CMOVBE32rm GR32:$src2, addr:$src1)>;
276def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_L, EFLAGS),
277 (CMOVGE16rm GR16:$src2, addr:$src1)>;
278def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_L, EFLAGS),
279 (CMOVGE32rm GR32:$src2, addr:$src1)>;
280def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_GE, EFLAGS),
281 (CMOVL16rm GR16:$src2, addr:$src1)>;
282def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_GE, EFLAGS),
283 (CMOVL32rm GR32:$src2, addr:$src1)>;
284def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_LE, EFLAGS),
285 (CMOVG16rm GR16:$src2, addr:$src1)>;
286def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_LE, EFLAGS),
287 (CMOVG32rm GR32:$src2, addr:$src1)>;
288def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_G, EFLAGS),
289 (CMOVLE16rm GR16:$src2, addr:$src1)>;
290def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_G, EFLAGS),
291 (CMOVLE32rm GR32:$src2, addr:$src1)>;
292def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_P, EFLAGS),
293 (CMOVNP16rm GR16:$src2, addr:$src1)>;
294def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_P, EFLAGS),
295 (CMOVNP32rm GR32:$src2, addr:$src1)>;
296def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_NP, EFLAGS),
297 (CMOVP16rm GR16:$src2, addr:$src1)>;
298def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_NP, EFLAGS),
299 (CMOVP32rm GR32:$src2, addr:$src1)>;
300def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_S, EFLAGS),
301 (CMOVNS16rm GR16:$src2, addr:$src1)>;
302def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_S, EFLAGS),
303 (CMOVNS32rm GR32:$src2, addr:$src1)>;
304def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_NS, EFLAGS),
305 (CMOVS16rm GR16:$src2, addr:$src1)>;
306def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_NS, EFLAGS),
307 (CMOVS32rm GR32:$src2, addr:$src1)>;
308def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_O, EFLAGS),
309 (CMOVNO16rm GR16:$src2, addr:$src1)>;
310def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_O, EFLAGS),
311 (CMOVNO32rm GR32:$src2, addr:$src1)>;
312def : Pat<(X86cmov (loadi16 addr:$src1), GR16:$src2, X86_COND_NO, EFLAGS),
313 (CMOVO16rm GR16:$src2, addr:$src1)>;
314def : Pat<(X86cmov (loadi32 addr:$src1), GR32:$src2, X86_COND_NO, EFLAGS),
315 (CMOVO32rm GR32:$src2, addr:$src1)>;
316
317def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_B, EFLAGS),
318 (CMOVAE64rm GR64:$src2, addr:$src1)>;
319def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_AE, EFLAGS),
320 (CMOVB64rm GR64:$src2, addr:$src1)>;
321def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_E, EFLAGS),
322 (CMOVNE64rm GR64:$src2, addr:$src1)>;
323def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NE, EFLAGS),
324 (CMOVE64rm GR64:$src2, addr:$src1)>;
325def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_BE, EFLAGS),
326 (CMOVA64rm GR64:$src2, addr:$src1)>;
327def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_A, EFLAGS),
328 (CMOVBE64rm GR64:$src2, addr:$src1)>;
329def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_L, EFLAGS),
330 (CMOVGE64rm GR64:$src2, addr:$src1)>;
331def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_GE, EFLAGS),
332 (CMOVL64rm GR64:$src2, addr:$src1)>;
333def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_LE, EFLAGS),
334 (CMOVG64rm GR64:$src2, addr:$src1)>;
335def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_G, EFLAGS),
336 (CMOVLE64rm GR64:$src2, addr:$src1)>;
337def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_P, EFLAGS),
338 (CMOVNP64rm GR64:$src2, addr:$src1)>;
339def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NP, EFLAGS),
340 (CMOVP64rm GR64:$src2, addr:$src1)>;
341def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_S, EFLAGS),
342 (CMOVNS64rm GR64:$src2, addr:$src1)>;
343def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NS, EFLAGS),
344 (CMOVS64rm GR64:$src2, addr:$src1)>;
345def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_O, EFLAGS),
346 (CMOVNO64rm GR64:$src2, addr:$src1)>;
347def : Pat<(X86cmov (loadi64 addr:$src1), GR64:$src2, X86_COND_NO, EFLAGS),
348 (CMOVO64rm GR64:$src2, addr:$src1)>;
349
350
351// zextload bool -> zextload byte
352def : Pat<(zextloadi8i1 addr:$src), (MOV8rm addr:$src)>;
353def : Pat<(zextloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
354def : Pat<(zextloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
355def : Pat<(zextloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
356
357// extload bool -> extload byte
358// When extloading from 16-bit and smaller memory locations into 64-bit
359// registers, use zero-extending loads so that the entire 64-bit register is
360// defined, avoiding partial-register updates.
361
362def : Pat<(extloadi8i1 addr:$src), (MOV8rm addr:$src)>;
363def : Pat<(extloadi16i1 addr:$src), (MOVZX16rm8 addr:$src)>;
364def : Pat<(extloadi32i1 addr:$src), (MOVZX32rm8 addr:$src)>;
365def : Pat<(extloadi16i8 addr:$src), (MOVZX16rm8 addr:$src)>;
366def : Pat<(extloadi32i8 addr:$src), (MOVZX32rm8 addr:$src)>;
367def : Pat<(extloadi32i16 addr:$src), (MOVZX32rm16 addr:$src)>;
368
369def : Pat<(extloadi64i1 addr:$src), (MOVZX64rm8 addr:$src)>;
370def : Pat<(extloadi64i8 addr:$src), (MOVZX64rm8 addr:$src)>;
371def : Pat<(extloadi64i16 addr:$src), (MOVZX64rm16 addr:$src)>;
372// For other extloads, use subregs, since the high contents of the register are
373// defined after an extload.
374def : Pat<(extloadi64i32 addr:$src),
375 (SUBREG_TO_REG (i64 0), (MOV32rm addr:$src),
376 sub_32bit)>;
377
378// anyext. Define these to do an explicit zero-extend to
379// avoid partial-register updates.
380def : Pat<(i16 (anyext GR8 :$src)), (MOVZX16rr8 GR8 :$src)>;
381def : Pat<(i32 (anyext GR8 :$src)), (MOVZX32rr8 GR8 :$src)>;
382
383// Except for i16 -> i32 since isel expect i16 ops to be promoted to i32.
384def : Pat<(i32 (anyext GR16:$src)),
385 (INSERT_SUBREG (i32 (IMPLICIT_DEF)), GR16:$src, sub_16bit)>;
386
387def : Pat<(i64 (anyext GR8 :$src)), (MOVZX64rr8 GR8 :$src)>;
388def : Pat<(i64 (anyext GR16:$src)), (MOVZX64rr16 GR16 :$src)>;
389def : Pat<(i64 (anyext GR32:$src)),
390 (SUBREG_TO_REG (i64 0), GR32:$src, sub_32bit)>;
391
392//===----------------------------------------------------------------------===//
393// Some peepholes
394//===----------------------------------------------------------------------===//
395
396// Odd encoding trick: -128 fits into an 8-bit immediate field while
397// +128 doesn't, so in this special case use a sub instead of an add.
398def : Pat<(add GR16:$src1, 128),
399 (SUB16ri8 GR16:$src1, -128)>;
400def : Pat<(store (add (loadi16 addr:$dst), 128), addr:$dst),
401 (SUB16mi8 addr:$dst, -128)>;
402
403def : Pat<(add GR32:$src1, 128),
404 (SUB32ri8 GR32:$src1, -128)>;
405def : Pat<(store (add (loadi32 addr:$dst), 128), addr:$dst),
406 (SUB32mi8 addr:$dst, -128)>;
407
408def : Pat<(add GR64:$src1, 128),
409 (SUB64ri8 GR64:$src1, -128)>;
410def : Pat<(store (add (loadi64 addr:$dst), 128), addr:$dst),
411 (SUB64mi8 addr:$dst, -128)>;
412
413// The same trick applies for 32-bit immediate fields in 64-bit
414// instructions.
415def : Pat<(add GR64:$src1, 0x0000000080000000),
416 (SUB64ri32 GR64:$src1, 0xffffffff80000000)>;
417def : Pat<(store (add (loadi64 addr:$dst), 0x00000000800000000), addr:$dst),
418 (SUB64mi32 addr:$dst, 0xffffffff80000000)>;
419
420// Use a 32-bit and with implicit zero-extension instead of a 64-bit and if it
421// has an immediate with at least 32 bits of leading zeros, to avoid needing to
422// materialize that immediate in a register first.
423def : Pat<(and GR64:$src, i64immZExt32:$imm),
424 (SUBREG_TO_REG
425 (i64 0),
426 (AND32ri
427 (EXTRACT_SUBREG GR64:$src, sub_32bit),
428 (i32 (GetLo32XForm imm:$imm))),
429 sub_32bit)>;
430
431
432// r & (2^16-1) ==> movz
433def : Pat<(and GR32:$src1, 0xffff),
434 (MOVZX32rr16 (EXTRACT_SUBREG GR32:$src1, sub_16bit))>;
435// r & (2^8-1) ==> movz
436def : Pat<(and GR32:$src1, 0xff),
437 (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src1,
438 GR32_ABCD)),
439 sub_8bit))>,
440 Requires<[In32BitMode]>;
441// r & (2^8-1) ==> movz
442def : Pat<(and GR16:$src1, 0xff),
443 (MOVZX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src1,
444 GR16_ABCD)),
445 sub_8bit))>,
446 Requires<[In32BitMode]>;
447
448// r & (2^32-1) ==> movz
449def : Pat<(and GR64:$src, 0x00000000FFFFFFFF),
450 (MOVZX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>;
451// r & (2^16-1) ==> movz
452def : Pat<(and GR64:$src, 0xffff),
453 (MOVZX64rr16 (i16 (EXTRACT_SUBREG GR64:$src, sub_16bit)))>;
454// r & (2^8-1) ==> movz
455def : Pat<(and GR64:$src, 0xff),
456 (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, sub_8bit)))>;
457// r & (2^8-1) ==> movz
458def : Pat<(and GR32:$src1, 0xff),
459 (MOVZX32rr8 (EXTRACT_SUBREG GR32:$src1, sub_8bit))>,
460 Requires<[In64BitMode]>;
461// r & (2^8-1) ==> movz
462def : Pat<(and GR16:$src1, 0xff),
463 (MOVZX16rr8 (i8 (EXTRACT_SUBREG GR16:$src1, sub_8bit)))>,
464 Requires<[In64BitMode]>;
465
466
467// sext_inreg patterns
468def : Pat<(sext_inreg GR32:$src, i16),
469 (MOVSX32rr16 (EXTRACT_SUBREG GR32:$src, sub_16bit))>;
470def : Pat<(sext_inreg GR32:$src, i8),
471 (MOVSX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src,
472 GR32_ABCD)),
473 sub_8bit))>,
474 Requires<[In32BitMode]>;
475def : Pat<(sext_inreg GR16:$src, i8),
476 (MOVSX16rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src,
477 GR16_ABCD)),
478 sub_8bit))>,
479 Requires<[In32BitMode]>;
480
481def : Pat<(sext_inreg GR64:$src, i32),
482 (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, sub_32bit))>;
483def : Pat<(sext_inreg GR64:$src, i16),
484 (MOVSX64rr16 (EXTRACT_SUBREG GR64:$src, sub_16bit))>;
485def : Pat<(sext_inreg GR64:$src, i8),
486 (MOVSX64rr8 (EXTRACT_SUBREG GR64:$src, sub_8bit))>;
487def : Pat<(sext_inreg GR32:$src, i8),
488 (MOVSX32rr8 (EXTRACT_SUBREG GR32:$src, sub_8bit))>,
489 Requires<[In64BitMode]>;
490def : Pat<(sext_inreg GR16:$src, i8),
491 (MOVSX16rr8 (i8 (EXTRACT_SUBREG GR16:$src, sub_8bit)))>,
492 Requires<[In64BitMode]>;
493
494
495// trunc patterns
496def : Pat<(i16 (trunc GR32:$src)),
497 (EXTRACT_SUBREG GR32:$src, sub_16bit)>;
498def : Pat<(i8 (trunc GR32:$src)),
499 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
500 sub_8bit)>,
501 Requires<[In32BitMode]>;
502def : Pat<(i8 (trunc GR16:$src)),
503 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
504 sub_8bit)>,
505 Requires<[In32BitMode]>;
506def : Pat<(i32 (trunc GR64:$src)),
507 (EXTRACT_SUBREG GR64:$src, sub_32bit)>;
508def : Pat<(i16 (trunc GR64:$src)),
509 (EXTRACT_SUBREG GR64:$src, sub_16bit)>;
510def : Pat<(i8 (trunc GR64:$src)),
511 (EXTRACT_SUBREG GR64:$src, sub_8bit)>;
512def : Pat<(i8 (trunc GR32:$src)),
513 (EXTRACT_SUBREG GR32:$src, sub_8bit)>,
514 Requires<[In64BitMode]>;
515def : Pat<(i8 (trunc GR16:$src)),
516 (EXTRACT_SUBREG GR16:$src, sub_8bit)>,
517 Requires<[In64BitMode]>;
518
519// h-register tricks
520def : Pat<(i8 (trunc (srl_su GR16:$src, (i8 8)))),
521 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
522 sub_8bit_hi)>,
523 Requires<[In32BitMode]>;
524def : Pat<(i8 (trunc (srl_su GR32:$src, (i8 8)))),
525 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
526 sub_8bit_hi)>,
527 Requires<[In32BitMode]>;
528def : Pat<(srl GR16:$src, (i8 8)),
529 (EXTRACT_SUBREG
530 (MOVZX32rr8
531 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
532 sub_8bit_hi)),
533 sub_16bit)>,
534 Requires<[In32BitMode]>;
535def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
536 (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src,
537 GR16_ABCD)),
538 sub_8bit_hi))>,
539 Requires<[In32BitMode]>;
540def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))),
541 (MOVZX32rr8 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src,
542 GR16_ABCD)),
543 sub_8bit_hi))>,
544 Requires<[In32BitMode]>;
545def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
546 (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src,
547 GR32_ABCD)),
548 sub_8bit_hi))>,
549 Requires<[In32BitMode]>;
550def : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)),
551 (MOVZX32rr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src,
552 GR32_ABCD)),
553 sub_8bit_hi))>,
554 Requires<[In32BitMode]>;
555
556// h-register tricks.
557// For now, be conservative on x86-64 and use an h-register extract only if the
558// value is immediately zero-extended or stored, which are somewhat common
559// cases. This uses a bunch of code to prevent a register requiring a REX prefix
560// from being allocated in the same instruction as the h register, as there's
561// currently no way to describe this requirement to the register allocator.
562
563// h-register extract and zero-extend.
564def : Pat<(and (srl_su GR64:$src, (i8 8)), (i64 255)),
565 (SUBREG_TO_REG
566 (i64 0),
567 (MOVZX32_NOREXrr8
568 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)),
569 sub_8bit_hi)),
570 sub_32bit)>;
571def : Pat<(and (srl_su GR32:$src, (i8 8)), (i32 255)),
572 (MOVZX32_NOREXrr8
573 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
574 sub_8bit_hi))>,
575 Requires<[In64BitMode]>;
576def : Pat<(srl (and_su GR32:$src, 0xff00), (i8 8)),
577 (MOVZX32_NOREXrr8 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src,
578 GR32_ABCD)),
579 sub_8bit_hi))>,
580 Requires<[In64BitMode]>;
581def : Pat<(srl GR16:$src, (i8 8)),
582 (EXTRACT_SUBREG
583 (MOVZX32_NOREXrr8
584 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
585 sub_8bit_hi)),
586 sub_16bit)>,
587 Requires<[In64BitMode]>;
588def : Pat<(i32 (zext (srl_su GR16:$src, (i8 8)))),
589 (MOVZX32_NOREXrr8
590 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
591 sub_8bit_hi))>,
592 Requires<[In64BitMode]>;
593def : Pat<(i32 (anyext (srl_su GR16:$src, (i8 8)))),
594 (MOVZX32_NOREXrr8
595 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
596 sub_8bit_hi))>,
597 Requires<[In64BitMode]>;
598def : Pat<(i64 (zext (srl_su GR16:$src, (i8 8)))),
599 (SUBREG_TO_REG
600 (i64 0),
601 (MOVZX32_NOREXrr8
602 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
603 sub_8bit_hi)),
604 sub_32bit)>;
605def : Pat<(i64 (anyext (srl_su GR16:$src, (i8 8)))),
606 (SUBREG_TO_REG
607 (i64 0),
608 (MOVZX32_NOREXrr8
609 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
610 sub_8bit_hi)),
611 sub_32bit)>;
612
613// h-register extract and store.
614def : Pat<(store (i8 (trunc_su (srl_su GR64:$src, (i8 8)))), addr:$dst),
615 (MOV8mr_NOREX
616 addr:$dst,
617 (EXTRACT_SUBREG (i64 (COPY_TO_REGCLASS GR64:$src, GR64_ABCD)),
618 sub_8bit_hi))>;
619def : Pat<(store (i8 (trunc_su (srl_su GR32:$src, (i8 8)))), addr:$dst),
620 (MOV8mr_NOREX
621 addr:$dst,
622 (EXTRACT_SUBREG (i32 (COPY_TO_REGCLASS GR32:$src, GR32_ABCD)),
623 sub_8bit_hi))>,
624 Requires<[In64BitMode]>;
625def : Pat<(store (i8 (trunc_su (srl_su GR16:$src, (i8 8)))), addr:$dst),
626 (MOV8mr_NOREX
627 addr:$dst,
628 (EXTRACT_SUBREG (i16 (COPY_TO_REGCLASS GR16:$src, GR16_ABCD)),
629 sub_8bit_hi))>,
630 Requires<[In64BitMode]>;
631
632
633// (shl x, 1) ==> (add x, x)
634def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>;
635def : Pat<(shl GR16:$src1, (i8 1)), (ADD16rr GR16:$src1, GR16:$src1)>;
636def : Pat<(shl GR32:$src1, (i8 1)), (ADD32rr GR32:$src1, GR32:$src1)>;
637def : Pat<(shl GR64:$src1, (i8 1)), (ADD64rr GR64:$src1, GR64:$src1)>;
638
639// (shl x (and y, 31)) ==> (shl x, y)
640def : Pat<(shl GR8:$src1, (and CL, 31)),
641 (SHL8rCL GR8:$src1)>;
642def : Pat<(shl GR16:$src1, (and CL, 31)),
643 (SHL16rCL GR16:$src1)>;
644def : Pat<(shl GR32:$src1, (and CL, 31)),
645 (SHL32rCL GR32:$src1)>;
646def : Pat<(store (shl (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
647 (SHL8mCL addr:$dst)>;
648def : Pat<(store (shl (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
649 (SHL16mCL addr:$dst)>;
650def : Pat<(store (shl (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
651 (SHL32mCL addr:$dst)>;
652
653def : Pat<(srl GR8:$src1, (and CL, 31)),
654 (SHR8rCL GR8:$src1)>;
655def : Pat<(srl GR16:$src1, (and CL, 31)),
656 (SHR16rCL GR16:$src1)>;
657def : Pat<(srl GR32:$src1, (and CL, 31)),
658 (SHR32rCL GR32:$src1)>;
659def : Pat<(store (srl (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
660 (SHR8mCL addr:$dst)>;
661def : Pat<(store (srl (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
662 (SHR16mCL addr:$dst)>;
663def : Pat<(store (srl (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
664 (SHR32mCL addr:$dst)>;
665
666def : Pat<(sra GR8:$src1, (and CL, 31)),
667 (SAR8rCL GR8:$src1)>;
668def : Pat<(sra GR16:$src1, (and CL, 31)),
669 (SAR16rCL GR16:$src1)>;
670def : Pat<(sra GR32:$src1, (and CL, 31)),
671 (SAR32rCL GR32:$src1)>;
672def : Pat<(store (sra (loadi8 addr:$dst), (and CL, 31)), addr:$dst),
673 (SAR8mCL addr:$dst)>;
674def : Pat<(store (sra (loadi16 addr:$dst), (and CL, 31)), addr:$dst),
675 (SAR16mCL addr:$dst)>;
676def : Pat<(store (sra (loadi32 addr:$dst), (and CL, 31)), addr:$dst),
677 (SAR32mCL addr:$dst)>;
678
679// (shl x (and y, 63)) ==> (shl x, y)
680def : Pat<(shl GR64:$src1, (and CL, 63)),
681 (SHL64rCL GR64:$src1)>;
682def : Pat<(store (shl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
683 (SHL64mCL addr:$dst)>;
684
685def : Pat<(srl GR64:$src1, (and CL, 63)),
686 (SHR64rCL GR64:$src1)>;
687def : Pat<(store (srl (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
688 (SHR64mCL addr:$dst)>;
689
690def : Pat<(sra GR64:$src1, (and CL, 63)),
691 (SAR64rCL GR64:$src1)>;
692def : Pat<(store (sra (loadi64 addr:$dst), (and CL, 63)), addr:$dst),
693 (SAR64mCL addr:$dst)>;
694
695
696// (anyext (setcc_carry)) -> (setcc_carry)
697def : Pat<(i16 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
698 (SETB_C16r)>;
699def : Pat<(i32 (anyext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
700 (SETB_C32r)>;
701def : Pat<(i32 (anyext (i16 (X86setcc_c X86_COND_B, EFLAGS)))),
702 (SETB_C32r)>;
703
704// (or x1, x2) -> (add x1, x2) if two operands are known not to share bits.
705let AddedComplexity = 5 in { // Try this before the selecting to OR
706def : Pat<(or_is_add GR16:$src1, imm:$src2),
707 (ADD16ri GR16:$src1, imm:$src2)>;
708def : Pat<(or_is_add GR32:$src1, imm:$src2),
709 (ADD32ri GR32:$src1, imm:$src2)>;
710def : Pat<(or_is_add GR16:$src1, i16immSExt8:$src2),
711 (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>;
712def : Pat<(or_is_add GR32:$src1, i32immSExt8:$src2),
713 (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
714def : Pat<(or_is_add GR16:$src1, GR16:$src2),
715 (ADD16rr GR16:$src1, GR16:$src2)>;
716def : Pat<(or_is_add GR32:$src1, GR32:$src2),
717 (ADD32rr GR32:$src1, GR32:$src2)>;
718def : Pat<(or_is_add GR64:$src1, i64immSExt8:$src2),
719 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
720def : Pat<(or_is_add GR64:$src1, i64immSExt32:$src2),
721 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
722def : Pat<(or_is_add GR64:$src1, GR64:$src2),
723 (ADD64rr GR64:$src1, GR64:$src2)>;
724} // AddedComplexity
725
726//===----------------------------------------------------------------------===//
727// EFLAGS-defining Patterns
728//===----------------------------------------------------------------------===//
729
730// add reg, reg
731def : Pat<(add GR8 :$src1, GR8 :$src2), (ADD8rr GR8 :$src1, GR8 :$src2)>;
732def : Pat<(add GR16:$src1, GR16:$src2), (ADD16rr GR16:$src1, GR16:$src2)>;
733def : Pat<(add GR32:$src1, GR32:$src2), (ADD32rr GR32:$src1, GR32:$src2)>;
734
735// add reg, mem
736def : Pat<(add GR8:$src1, (loadi8 addr:$src2)),
737 (ADD8rm GR8:$src1, addr:$src2)>;
738def : Pat<(add GR16:$src1, (loadi16 addr:$src2)),
739 (ADD16rm GR16:$src1, addr:$src2)>;
740def : Pat<(add GR32:$src1, (loadi32 addr:$src2)),
741 (ADD32rm GR32:$src1, addr:$src2)>;
742
743// add reg, imm
744def : Pat<(add GR8 :$src1, imm:$src2), (ADD8ri GR8:$src1 , imm:$src2)>;
745def : Pat<(add GR16:$src1, imm:$src2), (ADD16ri GR16:$src1, imm:$src2)>;
746def : Pat<(add GR32:$src1, imm:$src2), (ADD32ri GR32:$src1, imm:$src2)>;
747def : Pat<(add GR16:$src1, i16immSExt8:$src2),
748 (ADD16ri8 GR16:$src1, i16immSExt8:$src2)>;
749def : Pat<(add GR32:$src1, i32immSExt8:$src2),
750 (ADD32ri8 GR32:$src1, i32immSExt8:$src2)>;
751
752// sub reg, reg
753def : Pat<(sub GR8 :$src1, GR8 :$src2), (SUB8rr GR8 :$src1, GR8 :$src2)>;
754def : Pat<(sub GR16:$src1, GR16:$src2), (SUB16rr GR16:$src1, GR16:$src2)>;
755def : Pat<(sub GR32:$src1, GR32:$src2), (SUB32rr GR32:$src1, GR32:$src2)>;
756
757// sub reg, mem
758def : Pat<(sub GR8:$src1, (loadi8 addr:$src2)),
759 (SUB8rm GR8:$src1, addr:$src2)>;
760def : Pat<(sub GR16:$src1, (loadi16 addr:$src2)),
761 (SUB16rm GR16:$src1, addr:$src2)>;
762def : Pat<(sub GR32:$src1, (loadi32 addr:$src2)),
763 (SUB32rm GR32:$src1, addr:$src2)>;
764
765// sub reg, imm
766def : Pat<(sub GR8:$src1, imm:$src2),
767 (SUB8ri GR8:$src1, imm:$src2)>;
768def : Pat<(sub GR16:$src1, imm:$src2),
769 (SUB16ri GR16:$src1, imm:$src2)>;
770def : Pat<(sub GR32:$src1, imm:$src2),
771 (SUB32ri GR32:$src1, imm:$src2)>;
772def : Pat<(sub GR16:$src1, i16immSExt8:$src2),
773 (SUB16ri8 GR16:$src1, i16immSExt8:$src2)>;
774def : Pat<(sub GR32:$src1, i32immSExt8:$src2),
775 (SUB32ri8 GR32:$src1, i32immSExt8:$src2)>;
776
777// mul reg, reg
778def : Pat<(mul GR16:$src1, GR16:$src2),
779 (IMUL16rr GR16:$src1, GR16:$src2)>;
780def : Pat<(mul GR32:$src1, GR32:$src2),
781 (IMUL32rr GR32:$src1, GR32:$src2)>;
782
783// mul reg, mem
784def : Pat<(mul GR16:$src1, (loadi16 addr:$src2)),
785 (IMUL16rm GR16:$src1, addr:$src2)>;
786def : Pat<(mul GR32:$src1, (loadi32 addr:$src2)),
787 (IMUL32rm GR32:$src1, addr:$src2)>;
788
789// mul reg, imm
790def : Pat<(mul GR16:$src1, imm:$src2),
791 (IMUL16rri GR16:$src1, imm:$src2)>;
792def : Pat<(mul GR32:$src1, imm:$src2),
793 (IMUL32rri GR32:$src1, imm:$src2)>;
794def : Pat<(mul GR16:$src1, i16immSExt8:$src2),
795 (IMUL16rri8 GR16:$src1, i16immSExt8:$src2)>;
796def : Pat<(mul GR32:$src1, i32immSExt8:$src2),
797 (IMUL32rri8 GR32:$src1, i32immSExt8:$src2)>;
798
799// reg = mul mem, imm
800def : Pat<(mul (loadi16 addr:$src1), imm:$src2),
801 (IMUL16rmi addr:$src1, imm:$src2)>;
802def : Pat<(mul (loadi32 addr:$src1), imm:$src2),
803 (IMUL32rmi addr:$src1, imm:$src2)>;
804def : Pat<(mul (loadi16 addr:$src1), i16immSExt8:$src2),
805 (IMUL16rmi8 addr:$src1, i16immSExt8:$src2)>;
806def : Pat<(mul (loadi32 addr:$src1), i32immSExt8:$src2),
807 (IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>;
808
809// Optimize multiply by 2 with EFLAGS result.
810let AddedComplexity = 2 in {
811def : Pat<(X86smul_flag GR16:$src1, 2), (ADD16rr GR16:$src1, GR16:$src1)>;
812def : Pat<(X86smul_flag GR32:$src1, 2), (ADD32rr GR32:$src1, GR32:$src1)>;
813}
814
815// Patterns for nodes that do not produce flags, for instructions that do.
816
817// addition
818def : Pat<(add GR64:$src1, GR64:$src2),
819 (ADD64rr GR64:$src1, GR64:$src2)>;
820def : Pat<(add GR64:$src1, i64immSExt8:$src2),
821 (ADD64ri8 GR64:$src1, i64immSExt8:$src2)>;
822def : Pat<(add GR64:$src1, i64immSExt32:$src2),
823 (ADD64ri32 GR64:$src1, i64immSExt32:$src2)>;
824def : Pat<(add GR64:$src1, (loadi64 addr:$src2)),
825 (ADD64rm GR64:$src1, addr:$src2)>;
826
827// subtraction
828def : Pat<(sub GR64:$src1, GR64:$src2),
829 (SUB64rr GR64:$src1, GR64:$src2)>;
830def : Pat<(sub GR64:$src1, (loadi64 addr:$src2)),
831 (SUB64rm GR64:$src1, addr:$src2)>;
832def : Pat<(sub GR64:$src1, i64immSExt8:$src2),
833 (SUB64ri8 GR64:$src1, i64immSExt8:$src2)>;
834def : Pat<(sub GR64:$src1, i64immSExt32:$src2),
835 (SUB64ri32 GR64:$src1, i64immSExt32:$src2)>;
836
837// Multiply
838def : Pat<(mul GR64:$src1, GR64:$src2),
839 (IMUL64rr GR64:$src1, GR64:$src2)>;
840def : Pat<(mul GR64:$src1, (loadi64 addr:$src2)),
841 (IMUL64rm GR64:$src1, addr:$src2)>;
842def : Pat<(mul GR64:$src1, i64immSExt8:$src2),
843 (IMUL64rri8 GR64:$src1, i64immSExt8:$src2)>;
844def : Pat<(mul GR64:$src1, i64immSExt32:$src2),
845 (IMUL64rri32 GR64:$src1, i64immSExt32:$src2)>;
846def : Pat<(mul (loadi64 addr:$src1), i64immSExt8:$src2),
847 (IMUL64rmi8 addr:$src1, i64immSExt8:$src2)>;
848def : Pat<(mul (loadi64 addr:$src1), i64immSExt32:$src2),
849 (IMUL64rmi32 addr:$src1, i64immSExt32:$src2)>;
850
851// Increment reg.
852def : Pat<(add GR8 :$src, 1), (INC8r GR8 :$src)>;
853def : Pat<(add GR16:$src, 1), (INC16r GR16:$src)>, Requires<[In32BitMode]>;
854def : Pat<(add GR16:$src, 1), (INC64_16r GR16:$src)>, Requires<[In64BitMode]>;
855def : Pat<(add GR32:$src, 1), (INC32r GR32:$src)>, Requires<[In32BitMode]>;
856def : Pat<(add GR32:$src, 1), (INC64_32r GR32:$src)>, Requires<[In64BitMode]>;
857def : Pat<(add GR64:$src, 1), (INC64r GR64:$src)>;
858
859// Decrement reg.
860def : Pat<(add GR8 :$src, -1), (DEC8r GR8 :$src)>;
861def : Pat<(add GR16:$src, -1), (DEC16r GR16:$src)>, Requires<[In32BitMode]>;
862def : Pat<(add GR16:$src, -1), (DEC64_16r GR16:$src)>, Requires<[In64BitMode]>;
863def : Pat<(add GR32:$src, -1), (DEC32r GR32:$src)>, Requires<[In32BitMode]>;
864def : Pat<(add GR32:$src, -1), (DEC64_32r GR32:$src)>, Requires<[In64BitMode]>;
865def : Pat<(add GR64:$src, -1), (DEC64r GR64:$src)>;
866
867// or reg/reg.
868def : Pat<(or GR8 :$src1, GR8 :$src2), (OR8rr GR8 :$src1, GR8 :$src2)>;
869def : Pat<(or GR16:$src1, GR16:$src2), (OR16rr GR16:$src1, GR16:$src2)>;
870def : Pat<(or GR32:$src1, GR32:$src2), (OR32rr GR32:$src1, GR32:$src2)>;
871def : Pat<(or GR64:$src1, GR64:$src2), (OR64rr GR64:$src1, GR64:$src2)>;
872
873// or reg/mem
874def : Pat<(or GR8:$src1, (loadi8 addr:$src2)),
875 (OR8rm GR8:$src1, addr:$src2)>;
876def : Pat<(or GR16:$src1, (loadi16 addr:$src2)),
877 (OR16rm GR16:$src1, addr:$src2)>;
878def : Pat<(or GR32:$src1, (loadi32 addr:$src2)),
879 (OR32rm GR32:$src1, addr:$src2)>;
880def : Pat<(or GR64:$src1, (loadi64 addr:$src2)),
881 (OR64rm GR64:$src1, addr:$src2)>;
882
883// or reg/imm
884def : Pat<(or GR8:$src1 , imm:$src2), (OR8ri GR8 :$src1, imm:$src2)>;
885def : Pat<(or GR16:$src1, imm:$src2), (OR16ri GR16:$src1, imm:$src2)>;
886def : Pat<(or GR32:$src1, imm:$src2), (OR32ri GR32:$src1, imm:$src2)>;
887def : Pat<(or GR16:$src1, i16immSExt8:$src2),
888 (OR16ri8 GR16:$src1, i16immSExt8:$src2)>;
889def : Pat<(or GR32:$src1, i32immSExt8:$src2),
890 (OR32ri8 GR32:$src1, i32immSExt8:$src2)>;
891def : Pat<(or GR64:$src1, i64immSExt8:$src2),
892 (OR64ri8 GR64:$src1, i64immSExt8:$src2)>;
893def : Pat<(or GR64:$src1, i64immSExt32:$src2),
894 (OR64ri32 GR64:$src1, i64immSExt32:$src2)>;
895
896// xor reg/reg
897def : Pat<(xor GR8 :$src1, GR8 :$src2), (XOR8rr GR8 :$src1, GR8 :$src2)>;
898def : Pat<(xor GR16:$src1, GR16:$src2), (XOR16rr GR16:$src1, GR16:$src2)>;
899def : Pat<(xor GR32:$src1, GR32:$src2), (XOR32rr GR32:$src1, GR32:$src2)>;
900def : Pat<(xor GR64:$src1, GR64:$src2), (XOR64rr GR64:$src1, GR64:$src2)>;
901
902// xor reg/mem
903def : Pat<(xor GR8:$src1, (loadi8 addr:$src2)),
904 (XOR8rm GR8:$src1, addr:$src2)>;
905def : Pat<(xor GR16:$src1, (loadi16 addr:$src2)),
906 (XOR16rm GR16:$src1, addr:$src2)>;
907def : Pat<(xor GR32:$src1, (loadi32 addr:$src2)),
908 (XOR32rm GR32:$src1, addr:$src2)>;
909def : Pat<(xor GR64:$src1, (loadi64 addr:$src2)),
910 (XOR64rm GR64:$src1, addr:$src2)>;
911
912// xor reg/imm
913def : Pat<(xor GR8:$src1, imm:$src2),
914 (XOR8ri GR8:$src1, imm:$src2)>;
915def : Pat<(xor GR16:$src1, imm:$src2),
916 (XOR16ri GR16:$src1, imm:$src2)>;
917def : Pat<(xor GR32:$src1, imm:$src2),
918 (XOR32ri GR32:$src1, imm:$src2)>;
919def : Pat<(xor GR16:$src1, i16immSExt8:$src2),
920 (XOR16ri8 GR16:$src1, i16immSExt8:$src2)>;
921def : Pat<(xor GR32:$src1, i32immSExt8:$src2),
922 (XOR32ri8 GR32:$src1, i32immSExt8:$src2)>;
923def : Pat<(xor GR64:$src1, i64immSExt8:$src2),
924 (XOR64ri8 GR64:$src1, i64immSExt8:$src2)>;
925def : Pat<(xor GR64:$src1, i64immSExt32:$src2),
926 (XOR64ri32 GR64:$src1, i64immSExt32:$src2)>;
927
928// and reg/reg
929def : Pat<(and GR8 :$src1, GR8 :$src2), (AND8rr GR8 :$src1, GR8 :$src2)>;
930def : Pat<(and GR16:$src1, GR16:$src2), (AND16rr GR16:$src1, GR16:$src2)>;
931def : Pat<(and GR32:$src1, GR32:$src2), (AND32rr GR32:$src1, GR32:$src2)>;
932def : Pat<(and GR64:$src1, GR64:$src2), (AND64rr GR64:$src1, GR64:$src2)>;
933
934// and reg/mem
935def : Pat<(and GR8:$src1, (loadi8 addr:$src2)),
936 (AND8rm GR8:$src1, addr:$src2)>;
937def : Pat<(and GR16:$src1, (loadi16 addr:$src2)),
938 (AND16rm GR16:$src1, addr:$src2)>;
939def : Pat<(and GR32:$src1, (loadi32 addr:$src2)),
940 (AND32rm GR32:$src1, addr:$src2)>;
941def : Pat<(and GR64:$src1, (loadi64 addr:$src2)),
942 (AND64rm GR64:$src1, addr:$src2)>;
943
944// and reg/imm
945def : Pat<(and GR8:$src1, imm:$src2),
946 (AND8ri GR8:$src1, imm:$src2)>;
947def : Pat<(and GR16:$src1, imm:$src2),
948 (AND16ri GR16:$src1, imm:$src2)>;
949def : Pat<(and GR32:$src1, imm:$src2),
950 (AND32ri GR32:$src1, imm:$src2)>;
951def : Pat<(and GR16:$src1, i16immSExt8:$src2),
952 (AND16ri8 GR16:$src1, i16immSExt8:$src2)>;
953def : Pat<(and GR32:$src1, i32immSExt8:$src2),
954 (AND32ri8 GR32:$src1, i32immSExt8:$src2)>;
955def : Pat<(and GR64:$src1, i64immSExt8:$src2),
956 (AND64ri8 GR64:$src1, i64immSExt8:$src2)>;
957def : Pat<(and GR64:$src1, i64immSExt32:$src2),
958 (AND64ri32 GR64:$src1, i64immSExt32:$src2)>;
959
960
961