1//===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the integer arithmetic instructions in the X86
10// architecture.
11//
12//===----------------------------------------------------------------------===//
13
14//===----------------------------------------------------------------------===//
15// LEA - Load Effective Address
16let SchedRW = [WriteLEA] in {
17let hasSideEffects = 0 in
18def LEA16r   : I<0x8D, MRMSrcMem,
19                 (outs GR16:$dst), (ins anymem:$src),
20                 "lea{w}\t{$src|$dst}, {$dst|$src}", []>, OpSize16;
21let isReMaterializable = 1 in
22def LEA32r   : I<0x8D, MRMSrcMem,
23                 (outs GR32:$dst), (ins anymem:$src),
24                 "lea{l}\t{$src|$dst}, {$dst|$src}",
25                 [(set GR32:$dst, lea32addr:$src)]>,
26                 OpSize32, Requires<[Not64BitMode]>;
27
28def LEA64_32r : I<0x8D, MRMSrcMem,
29                  (outs GR32:$dst), (ins lea64_32mem:$src),
30                  "lea{l}\t{$src|$dst}, {$dst|$src}",
31                  [(set GR32:$dst, lea64_32addr:$src)]>,
32                  OpSize32, Requires<[In64BitMode]>;
33
34let isReMaterializable = 1 in
35def LEA64r   : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
36                  "lea{q}\t{$src|$dst}, {$dst|$src}",
37                  [(set GR64:$dst, lea64addr:$src)]>;
38} // SchedRW
39
40//===----------------------------------------------------------------------===//
41//  Fixed-Register Multiplication and Division Instructions.
42//
43
44// SchedModel info for instruction that loads one value and gets the second
45// (and possibly third) value from a register.
46// This is used for instructions that put the memory operands before other
47// uses.
48class SchedLoadReg<X86FoldableSchedWrite Sched> : Sched<[Sched.Folded,
49  // Memory operand.
50  ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
51  // Register reads (implicit or explicit).
52  Sched.ReadAfterFold, Sched.ReadAfterFold]>;
53
54// Extra precision multiplication
55
56// AL is really implied by AX, but the registers in Defs must match the
57// SDNode results (i8, i32).
58// AL,AH = AL*GR8
59let Defs = [AL,EFLAGS,AX], Uses = [AL] in
60def MUL8r  : I<0xF6, MRM4r, (outs),  (ins GR8:$src), "mul{b}\t$src",
61               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
62               // This probably ought to be moved to a def : Pat<> if the
63               // syntax can be accepted.
64               [(set AL, (mul AL, GR8:$src)),
65                (implicit EFLAGS)]>, Sched<[WriteIMul8]>;
66// AX,DX = AX*GR16
67let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
68def MUL16r : I<0xF7, MRM4r, (outs),  (ins GR16:$src),
69               "mul{w}\t$src",
70               []>, OpSize16, Sched<[WriteIMul16]>;
71// EAX,EDX = EAX*GR32
72let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
73def MUL32r : I<0xF7, MRM4r, (outs),  (ins GR32:$src),
74               "mul{l}\t$src",
75               [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/]>,
76               OpSize32, Sched<[WriteIMul32]>;
77// RAX,RDX = RAX*GR64
78let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
79def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
80                "mul{q}\t$src",
81                [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/]>,
82                Sched<[WriteIMul64]>;
83// AL,AH = AL*[mem8]
84let Defs = [AL,EFLAGS,AX], Uses = [AL] in
85def MUL8m  : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
86               "mul{b}\t$src",
87               // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
88               // This probably ought to be moved to a def : Pat<> if the
89               // syntax can be accepted.
90               [(set AL, (mul AL, (loadi8 addr:$src))),
91                (implicit EFLAGS)]>, SchedLoadReg<WriteIMul8>;
92// AX,DX = AX*[mem16]
93let mayLoad = 1, hasSideEffects = 0 in {
94let Defs = [AX,DX,EFLAGS], Uses = [AX] in
95def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
96               "mul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul16>;
97// EAX,EDX = EAX*[mem32]
98let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
99def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
100              "mul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul32>;
101// RAX,RDX = RAX*[mem64]
102let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
103def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
104                "mul{q}\t$src", []>, SchedLoadReg<WriteIMul64>,
105                Requires<[In64BitMode]>;
106}
107
108let hasSideEffects = 0 in {
109// AL,AH = AL*GR8
110let Defs = [AL,EFLAGS,AX], Uses = [AL] in
111def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", []>,
112                Sched<[WriteIMul8]>;
113// AX,DX = AX*GR16
114let Defs = [AX,DX,EFLAGS], Uses = [AX] in
115def IMUL16r : I<0xF7, MRM5r, (outs),  (ins GR16:$src), "imul{w}\t$src", []>,
116                OpSize16, Sched<[WriteIMul16]>;
117// EAX,EDX = EAX*GR32
118let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
119def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", []>,
120                OpSize32, Sched<[WriteIMul32]>;
121// RAX,RDX = RAX*GR64
122let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
123def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", []>,
124                 Sched<[WriteIMul64]>;
125
126let mayLoad = 1 in {
127// AL,AH = AL*[mem8]
128let Defs = [AL,EFLAGS,AX], Uses = [AL] in
129def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
130                "imul{b}\t$src", []>, SchedLoadReg<WriteIMul8>;
131// AX,DX = AX*[mem16]
132let Defs = [AX,DX,EFLAGS], Uses = [AX] in
133def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
134                "imul{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIMul16>;
135// EAX,EDX = EAX*[mem32]
136let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
137def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
138                "imul{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIMul32>;
139// RAX,RDX = RAX*[mem64]
140let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
141def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
142                 "imul{q}\t$src", []>, SchedLoadReg<WriteIMul64>,
143                 Requires<[In64BitMode]>;
144}
145} // hasSideEffects
146
147
148let Defs = [EFLAGS] in {
149let Constraints = "$src1 = $dst" in {
150
151let isCommutable = 1 in {
152// X = IMUL Y, Z --> X = IMUL Z, Y
153// Register-Register Signed Integer Multiply
154def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
155                 "imul{w}\t{$src2, $dst|$dst, $src2}",
156                 [(set GR16:$dst, EFLAGS,
157                       (X86smul_flag GR16:$src1, GR16:$src2))]>,
158                 Sched<[WriteIMul16Reg]>, TB, OpSize16;
159def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
160                 "imul{l}\t{$src2, $dst|$dst, $src2}",
161                 [(set GR32:$dst, EFLAGS,
162                       (X86smul_flag GR32:$src1, GR32:$src2))]>,
163                 Sched<[WriteIMul32Reg]>, TB, OpSize32;
164def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
165                                   (ins GR64:$src1, GR64:$src2),
166                  "imul{q}\t{$src2, $dst|$dst, $src2}",
167                  [(set GR64:$dst, EFLAGS,
168                        (X86smul_flag GR64:$src1, GR64:$src2))]>,
169                  Sched<[WriteIMul64Reg]>, TB;
170} // isCommutable
171
172// Register-Memory Signed Integer Multiply
173def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
174                                  (ins GR16:$src1, i16mem:$src2),
175                 "imul{w}\t{$src2, $dst|$dst, $src2}",
176                 [(set GR16:$dst, EFLAGS,
177                       (X86smul_flag GR16:$src1, (loadi16 addr:$src2)))]>,
178                 Sched<[WriteIMul16Reg.Folded, WriteIMul16Reg.ReadAfterFold]>, TB, OpSize16;
179def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
180                 (ins GR32:$src1, i32mem:$src2),
181                 "imul{l}\t{$src2, $dst|$dst, $src2}",
182                 [(set GR32:$dst, EFLAGS,
183                       (X86smul_flag GR32:$src1, (loadi32 addr:$src2)))]>,
184                 Sched<[WriteIMul32Reg.Folded, WriteIMul32Reg.ReadAfterFold]>, TB, OpSize32;
185def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
186                                   (ins GR64:$src1, i64mem:$src2),
187                  "imul{q}\t{$src2, $dst|$dst, $src2}",
188                  [(set GR64:$dst, EFLAGS,
189                        (X86smul_flag GR64:$src1, (loadi64 addr:$src2)))]>,
190                  Sched<[WriteIMul64Reg.Folded, WriteIMul32Reg.ReadAfterFold]>, TB;
191} // Constraints = "$src1 = $dst"
192
193} // Defs = [EFLAGS]
194
195// Surprisingly enough, these are not two address instructions!
196let Defs = [EFLAGS] in {
197// NOTE: These are order specific, we want the ri8 forms to be listed
198// first so that they are slightly preferred to the ri forms.
199
200// Register-Integer Signed Integer Multiply
201def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // GR16 = GR16*I8
202                     (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
203                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
204                     [(set GR16:$dst, EFLAGS,
205                           (X86smul_flag GR16:$src1, i16immSExt8:$src2))]>,
206                     Sched<[WriteIMul16Imm]>, OpSize16;
207def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // GR16 = GR16*I16
208                      (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
209                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
210                      [(set GR16:$dst, EFLAGS,
211                            (X86smul_flag GR16:$src1, imm:$src2))]>,
212                      Sched<[WriteIMul16Imm]>, OpSize16;
213def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // GR32 = GR32*I32
214                      (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
215                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
216                      [(set GR32:$dst, EFLAGS,
217                            (X86smul_flag GR32:$src1, imm:$src2))]>,
218                      Sched<[WriteIMul32Imm]>, OpSize32;
219def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // GR32 = GR32*I8
220                     (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
221                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
222                     [(set GR32:$dst, EFLAGS,
223                           (X86smul_flag GR32:$src1, i32immSExt8:$src2))]>,
224                     Sched<[WriteIMul32Imm]>, OpSize32;
225def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64 = GR64*I8
226                      (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
227                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
228                      [(set GR64:$dst, EFLAGS,
229                            (X86smul_flag GR64:$src1, i64immSExt8:$src2))]>,
230                      Sched<[WriteIMul64Imm]>;
231def IMUL64rri32 : RIi32S<0x69, MRMSrcReg,                    // GR64 = GR64*I32
232                         (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
233                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
234                         [(set GR64:$dst, EFLAGS,
235                             (X86smul_flag GR64:$src1, i64immSExt32:$src2))]>,
236                         Sched<[WriteIMul64Imm]>;
237
238// Memory-Integer Signed Integer Multiply
239def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR16 = [mem16]*I8
240                     (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
241                     "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
242                     [(set GR16:$dst, EFLAGS,
243                           (X86smul_flag (loadi16 addr:$src1),
244                                         i16immSExt8:$src2))]>,
245                     Sched<[WriteIMul16Imm.Folded]>, OpSize16;
246def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                     // GR16 = [mem16]*I16
247                      (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
248                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
249                      [(set GR16:$dst, EFLAGS,
250                            (X86smul_flag (loadi16 addr:$src1), imm:$src2))]>,
251                      Sched<[WriteIMul16Imm.Folded]>, OpSize16;
252def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR32 = [mem32]*I8
253                     (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
254                     "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
255                     [(set GR32:$dst, EFLAGS,
256                           (X86smul_flag (loadi32 addr:$src1),
257                                         i32immSExt8:$src2))]>,
258                     Sched<[WriteIMul32Imm.Folded]>, OpSize32;
259def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                     // GR32 = [mem32]*I32
260                      (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
261                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
262                      [(set GR32:$dst, EFLAGS,
263                            (X86smul_flag (loadi32 addr:$src1), imm:$src2))]>,
264                      Sched<[WriteIMul32Imm.Folded]>, OpSize32;
265def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64 = [mem64]*I8
266                      (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
267                      "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
268                      [(set GR64:$dst, EFLAGS,
269                            (X86smul_flag (loadi64 addr:$src1),
270                                          i64immSExt8:$src2))]>,
271                      Sched<[WriteIMul64Imm.Folded]>;
272def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem,                   // GR64 = [mem64]*I32
273                         (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
274                         "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
275                         [(set GR64:$dst, EFLAGS,
276                              (X86smul_flag (loadi64 addr:$src1),
277                                            i64immSExt32:$src2))]>,
278                         Sched<[WriteIMul64Imm.Folded]>;
279} // Defs = [EFLAGS]
280
281// unsigned division/remainder
282let hasSideEffects = 1 in { // so that we don't speculatively execute
283let Defs = [AL,AH,EFLAGS], Uses = [AX] in
284def DIV8r  : I<0xF6, MRM6r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
285               "div{b}\t$src", []>, Sched<[WriteDiv8]>;
286let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
287def DIV16r : I<0xF7, MRM6r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
288               "div{w}\t$src", []>, Sched<[WriteDiv16]>, OpSize16;
289let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
290def DIV32r : I<0xF7, MRM6r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
291               "div{l}\t$src", []>, Sched<[WriteDiv32]>, OpSize32;
292// RDX:RAX/r64 = RAX,RDX
293let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
294def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
295                "div{q}\t$src", []>, Sched<[WriteDiv64]>;
296
297let mayLoad = 1 in {
298let Defs = [AL,AH,EFLAGS], Uses = [AX] in
299def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
300               "div{b}\t$src", []>, SchedLoadReg<WriteDiv8>;
301let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
302def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
303               "div{w}\t$src", []>, OpSize16, SchedLoadReg<WriteDiv16>;
304let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
305def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
306               "div{l}\t$src", []>, SchedLoadReg<WriteDiv32>, OpSize32;
307// RDX:RAX/[mem64] = RAX,RDX
308let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
309def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
310                "div{q}\t$src", []>, SchedLoadReg<WriteDiv64>,
311                Requires<[In64BitMode]>;
312}
313
314// Signed division/remainder.
315let Defs = [AL,AH,EFLAGS], Uses = [AX] in
316def IDIV8r : I<0xF6, MRM7r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
317               "idiv{b}\t$src", []>, Sched<[WriteIDiv8]>;
318let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
319def IDIV16r: I<0xF7, MRM7r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
320               "idiv{w}\t$src", []>, Sched<[WriteIDiv16]>, OpSize16;
321let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
322def IDIV32r: I<0xF7, MRM7r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
323               "idiv{l}\t$src", []>, Sched<[WriteIDiv32]>, OpSize32;
324// RDX:RAX/r64 = RAX,RDX
325let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
326def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
327                "idiv{q}\t$src", []>, Sched<[WriteIDiv64]>;
328
329let mayLoad = 1 in {
330let Defs = [AL,AH,EFLAGS], Uses = [AX] in
331def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
332               "idiv{b}\t$src", []>, SchedLoadReg<WriteIDiv8>;
333let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
334def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
335               "idiv{w}\t$src", []>, OpSize16, SchedLoadReg<WriteIDiv16>;
336let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
337def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
338               "idiv{l}\t$src", []>, OpSize32, SchedLoadReg<WriteIDiv32>;
339let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
340def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
341                "idiv{q}\t$src", []>, SchedLoadReg<WriteIDiv64>,
342                Requires<[In64BitMode]>;
343}
344} // hasSideEffects = 0
345
346//===----------------------------------------------------------------------===//
347//  Two address Instructions.
348//
349
350// unary instructions
351let CodeSize = 2 in {
352let Defs = [EFLAGS] in {
353let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
354def NEG8r  : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
355               "neg{b}\t$dst",
356               [(set GR8:$dst, (ineg GR8:$src1)),
357                (implicit EFLAGS)]>;
358def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
359               "neg{w}\t$dst",
360               [(set GR16:$dst, (ineg GR16:$src1)),
361                (implicit EFLAGS)]>, OpSize16;
362def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
363               "neg{l}\t$dst",
364               [(set GR32:$dst, (ineg GR32:$src1)),
365                (implicit EFLAGS)]>, OpSize32;
366def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
367                [(set GR64:$dst, (ineg GR64:$src1)),
368                 (implicit EFLAGS)]>;
369} // Constraints = "$src1 = $dst", SchedRW
370
371// Read-modify-write negate.
372let SchedRW = [WriteALURMW] in {
373def NEG8m  : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
374               "neg{b}\t$dst",
375               [(store (ineg (loadi8 addr:$dst)), addr:$dst),
376                (implicit EFLAGS)]>;
377def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
378               "neg{w}\t$dst",
379               [(store (ineg (loadi16 addr:$dst)), addr:$dst),
380                (implicit EFLAGS)]>, OpSize16;
381def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
382               "neg{l}\t$dst",
383               [(store (ineg (loadi32 addr:$dst)), addr:$dst),
384                (implicit EFLAGS)]>, OpSize32;
385def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
386                [(store (ineg (loadi64 addr:$dst)), addr:$dst),
387                 (implicit EFLAGS)]>,
388                Requires<[In64BitMode]>;
389} // SchedRW
390} // Defs = [EFLAGS]
391
392
393// Note: NOT does not set EFLAGS!
394
395let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
396def NOT8r  : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
397               "not{b}\t$dst",
398               [(set GR8:$dst, (not GR8:$src1))]>;
399def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
400               "not{w}\t$dst",
401               [(set GR16:$dst, (not GR16:$src1))]>, OpSize16;
402def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
403               "not{l}\t$dst",
404               [(set GR32:$dst, (not GR32:$src1))]>, OpSize32;
405def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
406                [(set GR64:$dst, (not GR64:$src1))]>;
407} // Constraints = "$src1 = $dst", SchedRW
408
409let SchedRW = [WriteALURMW] in {
410def NOT8m  : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
411               "not{b}\t$dst",
412               [(store (not (loadi8 addr:$dst)), addr:$dst)]>;
413def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
414               "not{w}\t$dst",
415               [(store (not (loadi16 addr:$dst)), addr:$dst)]>,
416               OpSize16;
417def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
418               "not{l}\t$dst",
419               [(store (not (loadi32 addr:$dst)), addr:$dst)]>,
420               OpSize32;
421def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
422                [(store (not (loadi64 addr:$dst)), addr:$dst)]>,
423                Requires<[In64BitMode]>;
424} // SchedRW
425} // CodeSize
426
427def X86add_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
428                               (X86add_flag node:$lhs, node:$rhs), [{
429  return hasNoCarryFlagUses(SDValue(N, 1));
430}]>;
431
432def X86sub_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
433                               (X86sub_flag node:$lhs, node:$rhs), [{
434  // Only use DEC if the result is used.
435  return !SDValue(N, 0).use_empty() && hasNoCarryFlagUses(SDValue(N, 1));
436}]>;
437
438// TODO: inc/dec is slow for P4, but fast for Pentium-M.
439let Defs = [EFLAGS] in {
440let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
441let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
442def INC8r  : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
443               "inc{b}\t$dst",
444               [(set GR8:$dst, EFLAGS, (X86add_flag_nocf GR8:$src1, 1))]>;
445def INC16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
446               "inc{w}\t$dst",
447               [(set GR16:$dst, EFLAGS, (X86add_flag_nocf GR16:$src1, 1))]>,
448               OpSize16;
449def INC32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
450               "inc{l}\t$dst",
451               [(set GR32:$dst, EFLAGS, (X86add_flag_nocf GR32:$src1, 1))]>,
452               OpSize32;
453def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
454                [(set GR64:$dst, EFLAGS, (X86add_flag_nocf GR64:$src1, 1))]>;
455} // isConvertibleToThreeAddress = 1, CodeSize = 2
456
457// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
458let CodeSize = 1, hasSideEffects = 0 in {
459def INC16r_alt : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
460                   "inc{w}\t$dst", []>,
461                 OpSize16, Requires<[Not64BitMode]>;
462def INC32r_alt : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
463                   "inc{l}\t$dst", []>,
464                 OpSize32, Requires<[Not64BitMode]>;
465} // CodeSize = 1, hasSideEffects = 0
466} // Constraints = "$src1 = $dst", SchedRW
467
468let CodeSize = 2, SchedRW = [WriteALURMW] in {
469let Predicates = [UseIncDec] in {
470  def INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
471               [(store (add (loadi8 addr:$dst), 1), addr:$dst),
472                (implicit EFLAGS)]>;
473  def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
474               [(store (add (loadi16 addr:$dst), 1), addr:$dst),
475                (implicit EFLAGS)]>, OpSize16;
476  def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
477               [(store (add (loadi32 addr:$dst), 1), addr:$dst),
478                (implicit EFLAGS)]>, OpSize32;
479} // Predicates
480let Predicates = [UseIncDec, In64BitMode] in {
481  def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
482                  [(store (add (loadi64 addr:$dst), 1), addr:$dst),
483                   (implicit EFLAGS)]>;
484} // Predicates
485} // CodeSize = 2, SchedRW
486
487let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
488let isConvertibleToThreeAddress = 1, CodeSize = 2 in { // Can xform into LEA.
489def DEC8r  : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
490               "dec{b}\t$dst",
491               [(set GR8:$dst, EFLAGS, (X86sub_flag_nocf GR8:$src1, 1))]>;
492def DEC16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
493               "dec{w}\t$dst",
494               [(set GR16:$dst, EFLAGS, (X86sub_flag_nocf GR16:$src1, 1))]>,
495               OpSize16;
496def DEC32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
497               "dec{l}\t$dst",
498               [(set GR32:$dst, EFLAGS, (X86sub_flag_nocf GR32:$src1, 1))]>,
499               OpSize32;
500def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
501                [(set GR64:$dst, EFLAGS, (X86sub_flag_nocf GR64:$src1, 1))]>;
502} // isConvertibleToThreeAddress = 1, CodeSize = 2
503
504// Short forms only valid in 32-bit mode. Selected during MCInst lowering.
505let CodeSize = 1, hasSideEffects = 0 in {
506def DEC16r_alt : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
507                   "dec{w}\t$dst", []>,
508                 OpSize16, Requires<[Not64BitMode]>;
509def DEC32r_alt : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
510                   "dec{l}\t$dst", []>,
511                 OpSize32, Requires<[Not64BitMode]>;
512} // CodeSize = 1, hasSideEffects = 0
513} // Constraints = "$src1 = $dst", SchedRW
514
515
516let CodeSize = 2, SchedRW = [WriteALURMW] in {
517let Predicates = [UseIncDec] in {
518  def DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
519               [(store (add (loadi8 addr:$dst), -1), addr:$dst),
520                (implicit EFLAGS)]>;
521  def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
522               [(store (add (loadi16 addr:$dst), -1), addr:$dst),
523                (implicit EFLAGS)]>, OpSize16;
524  def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
525               [(store (add (loadi32 addr:$dst), -1), addr:$dst),
526                (implicit EFLAGS)]>, OpSize32;
527} // Predicates
528let Predicates = [UseIncDec, In64BitMode] in {
529  def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
530                  [(store (add (loadi64 addr:$dst), -1), addr:$dst),
531                   (implicit EFLAGS)]>;
532} // Predicates
533} // CodeSize = 2, SchedRW
534} // Defs = [EFLAGS]
535
536/// X86TypeInfo - This is a bunch of information that describes relevant X86
537/// information about value types.  For example, it can tell you what the
538/// register class and preferred load to use.
539class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
540                  PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
541                  Operand immoperand, SDPatternOperator immoperator,
542                  Operand imm8operand, SDPatternOperator imm8operator,
543                  bit hasOddOpcode, OperandSize opSize,
544                  bit hasREX_W> {
545  /// VT - This is the value type itself.
546  ValueType VT = vt;
547
548  /// InstrSuffix - This is the suffix used on instructions with this type.  For
549  /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
550  string InstrSuffix = instrsuffix;
551
552  /// RegClass - This is the register class associated with this type.  For
553  /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
554  RegisterClass RegClass = regclass;
555
556  /// LoadNode - This is the load node associated with this type.  For
557  /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
558  PatFrag LoadNode = loadnode;
559
560  /// MemOperand - This is the memory operand associated with this type.  For
561  /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
562  X86MemOperand MemOperand = memoperand;
563
564  /// ImmEncoding - This is the encoding of an immediate of this type.  For
565  /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32.  Note that i64 -> Imm32
566  /// since the immediate fields of i64 instructions is a 32-bit sign extended
567  /// value.
568  ImmType ImmEncoding = immkind;
569
570  /// ImmOperand - This is the operand kind of an immediate of this type.  For
571  /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm.  Note that i64 ->
572  /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
573  /// extended value.
574  Operand ImmOperand = immoperand;
575
576  /// ImmOperator - This is the operator that should be used to match an
577  /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
578  SDPatternOperator ImmOperator = immoperator;
579
580  /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
581  /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
582  /// only used for instructions that have a sign-extended imm8 field form.
583  Operand Imm8Operand = imm8operand;
584
585  /// Imm8Operator - This is the operator that should be used to match an 8-bit
586  /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
587  SDPatternOperator Imm8Operator = imm8operator;
588
589  /// HasOddOpcode - This bit is true if the instruction should have an odd (as
590  /// opposed to even) opcode.  Operations on i8 are usually even, operations on
591  /// other datatypes are odd.
592  bit HasOddOpcode = hasOddOpcode;
593
594  /// OpSize - Selects whether the instruction needs a 0x66 prefix based on
595  /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this
596  /// to Opsize16. i32 sets this to OpSize32.
597  OperandSize OpSize = opSize;
598
599  /// HasREX_W - This bit is set to true if the instruction should have
600  /// the 0x40 REX prefix.  This is set for i64 types.
601  bit HasREX_W = hasREX_W;
602}
603
604def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
605
606
607def Xi8  : X86TypeInfo<i8, "b", GR8, loadi8, i8mem,
608                       Imm8, i8imm, imm_su, i8imm, invalid_node,
609                       0, OpSizeFixed, 0>;
610def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
611                       Imm16, i16imm, imm_su, i16i8imm, i16immSExt8_su,
612                       1, OpSize16, 0>;
613def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
614                       Imm32, i32imm, imm_su, i32i8imm, i32immSExt8_su,
615                       1, OpSize32, 0>;
616def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
617                       Imm32S, i64i32imm, i64immSExt32_su, i64i8imm, i64immSExt8_su,
618                       1, OpSizeFixed, 1>;
619
620/// ITy - This instruction base class takes the type info for the instruction.
621/// Using this, it:
622/// 1. Concatenates together the instruction mnemonic with the appropriate
623///    suffix letter, a tab, and the arguments.
624/// 2. Infers whether the instruction should have a 0x66 prefix byte.
625/// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
626/// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
627///    or 1 (for i16,i32,i64 operations).
628class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
629          string mnemonic, string args, list<dag> pattern>
630  : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
631       opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
632      f, outs, ins,
633      !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern> {
634
635  // Infer instruction prefixes from type info.
636  let OpSize = typeinfo.OpSize;
637  let hasREX_W  = typeinfo.HasREX_W;
638}
639
640// BinOpRR - Instructions like "add reg, reg, reg".
641class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
642              dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
643  : ITy<opcode, MRMDestReg, typeinfo, outlist,
644        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
645        mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
646    Sched<[sched]>;
647
648// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
649// just a EFLAGS as a result.
650class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
651                SDPatternOperator opnode>
652  : BinOpRR<opcode, mnemonic, typeinfo, (outs), WriteALU,
653            [(set EFLAGS,
654                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>;
655
656// BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
657// both a regclass and EFLAGS as a result.
658class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
659                 SDNode opnode>
660  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU,
661            [(set typeinfo.RegClass:$dst, EFLAGS,
662                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>;
663
664// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
665// both a regclass and EFLAGS as a result, and has EFLAGS as input.
666class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
667                  SDNode opnode>
668  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC,
669            [(set typeinfo.RegClass:$dst, EFLAGS,
670                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
671                          EFLAGS))]>;
672
673// BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
674class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
675                  X86FoldableSchedWrite sched = WriteALU>
676  : ITy<opcode, MRMSrcReg, typeinfo,
677        (outs typeinfo.RegClass:$dst),
678        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
679        mnemonic, "{$src2, $dst|$dst, $src2}", []>,
680    Sched<[sched]> {
681  // The disassembler should know about this, but not the asmparser.
682  let isCodeGenOnly = 1;
683  let ForceDisassemble = 1;
684  let hasSideEffects = 0;
685}
686
687// BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
688class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
689  : BinOpRR_Rev<opcode, mnemonic, typeinfo, WriteADC>;
690
691// BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
692class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
693  : ITy<opcode, MRMSrcReg, typeinfo, (outs),
694        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
695        mnemonic, "{$src2, $src1|$src1, $src2}", []>,
696    Sched<[WriteALU]> {
697  // The disassembler should know about this, but not the asmparser.
698  let isCodeGenOnly = 1;
699  let ForceDisassemble = 1;
700  let hasSideEffects = 0;
701}
702
703// BinOpRM - Instructions like "add reg, reg, [mem]".
704class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
705              dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
706  : ITy<opcode, MRMSrcMem, typeinfo, outlist,
707        (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
708        mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
709    Sched<[sched.Folded, sched.ReadAfterFold]>;
710
711// BinOpRM - Instructions like "adc reg, reg, [mem]".
712// There is an implicit register read at the end of the operand sequence.
713class BinOpRM_ImplicitUse<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
714              dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
715  : ITy<opcode, MRMSrcMem, typeinfo, outlist,
716        (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
717        mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
718    Sched<[sched.Folded, sched.ReadAfterFold,
719           // base, scale, index, offset, segment.
720           ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
721           // implicit register read.
722           sched.ReadAfterFold]>;
723
724// BinOpRM_F - Instructions like "cmp reg, [mem]".
725class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
726                SDNode opnode>
727  : BinOpRM<opcode, mnemonic, typeinfo, (outs), WriteALU,
728            [(set EFLAGS,
729            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
730
731// BinOpRM_RF - Instructions like "add reg, reg, [mem]".
732class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
733                 SDNode opnode>
734  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteALU,
735            [(set typeinfo.RegClass:$dst, EFLAGS,
736            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
737
738// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
739class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
740                 SDNode opnode>
741  : BinOpRM_ImplicitUse<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst), WriteADC,
742            [(set typeinfo.RegClass:$dst, EFLAGS,
743            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
744                    EFLAGS))]>;
745
746// BinOpRI - Instructions like "add reg, reg, imm".
747class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
748              Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
749  : ITy<opcode, f, typeinfo, outlist,
750        (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
751        mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
752    Sched<[sched]> {
753  let ImmT = typeinfo.ImmEncoding;
754}
755
756// BinOpRI_F - Instructions like "cmp reg, imm".
757class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
758                SDPatternOperator opnode, Format f>
759  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs), WriteALU,
760            [(set EFLAGS,
761                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
762
763// BinOpRI_RF - Instructions like "add reg, reg, imm".
764class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
765                 SDNode opnode, Format f>
766  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU,
767            [(set typeinfo.RegClass:$dst, EFLAGS,
768                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
769// BinOpRI_RFF - Instructions like "adc reg, reg, imm".
770class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
771                 SDNode opnode, Format f>
772  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC,
773            [(set typeinfo.RegClass:$dst, EFLAGS,
774                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
775                        EFLAGS))]>;
776
777// BinOpRI8 - Instructions like "add reg, reg, imm8".
778class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
779               Format f, dag outlist, X86FoldableSchedWrite sched, list<dag> pattern>
780  : ITy<opcode, f, typeinfo, outlist,
781        (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
782        mnemonic, "{$src2, $src1|$src1, $src2}", pattern>,
783    Sched<[sched]> {
784  let ImmT = Imm8; // Always 8-bit immediate.
785}
786
787// BinOpRI8_F - Instructions like "cmp reg, imm8".
788class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
789                  SDPatternOperator opnode, Format f>
790  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs), WriteALU,
791             [(set EFLAGS,
792               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
793
794// BinOpRI8_RF - Instructions like "add reg, reg, imm8".
795class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
796                  SDPatternOperator opnode, Format f>
797  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteALU,
798             [(set typeinfo.RegClass:$dst, EFLAGS,
799               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
800
801// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
802class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
803                   SDPatternOperator opnode, Format f>
804  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst), WriteADC,
805             [(set typeinfo.RegClass:$dst, EFLAGS,
806               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
807                       EFLAGS))]>;
808
809// BinOpMR - Instructions like "add [mem], reg".
810class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
811              list<dag> pattern>
812  : ITy<opcode, MRMDestMem, typeinfo,
813        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
814        mnemonic, "{$src, $dst|$dst, $src}", pattern>;
815
816// BinOpMR_RMW - Instructions like "add [mem], reg".
817class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
818                  SDNode opnode>
819  : BinOpMR<opcode, mnemonic, typeinfo,
820          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
821           (implicit EFLAGS)]>, Sched<[WriteALURMW,
822                                       // base, scale, index, offset, segment
823                                       ReadDefault, ReadDefault, ReadDefault,
824                                       ReadDefault, ReadDefault,
825                                       WriteALU.ReadAfterFold]>;  // reg
826
827// BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
828class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
829                    SDNode opnode>
830  : BinOpMR<opcode, mnemonic, typeinfo,
831            [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
832                    addr:$dst),
833             (implicit EFLAGS)]>, Sched<[WriteADCRMW,
834                                         // base, scale, index, offset, segment
835                                         ReadDefault, ReadDefault, ReadDefault,
836                                         ReadDefault, ReadDefault,
837                                         WriteALU.ReadAfterFold,    // reg
838                                         WriteALU.ReadAfterFold]>;  // EFLAGS
839
840// BinOpMR_F - Instructions like "cmp [mem], reg".
841class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
842                SDPatternOperator opnode>
843  : BinOpMR<opcode, mnemonic, typeinfo,
844            [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
845                                   typeinfo.RegClass:$src))]>,
846            Sched<[WriteALU.Folded, ReadDefault, ReadDefault, ReadDefault,
847                   ReadDefault, ReadDefault, WriteALU.ReadAfterFold]>;
848
849// BinOpMI - Instructions like "add [mem], imm".
850class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
851              Format f, list<dag> pattern>
852  : ITy<opcode, f, typeinfo,
853        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
854        mnemonic, "{$src, $dst|$dst, $src}", pattern> {
855  let ImmT = typeinfo.ImmEncoding;
856}
857
858// BinOpMI_RMW - Instructions like "add [mem], imm".
859class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
860                  SDNode opnode, Format f>
861  : BinOpMI<opcode, mnemonic, typeinfo, f,
862            [(store (opnode (typeinfo.VT (load addr:$dst)),
863                            typeinfo.ImmOperator:$src), addr:$dst),
864             (implicit EFLAGS)]>, Sched<[WriteALURMW]>;
865// BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
866class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
867                     SDNode opnode, Format f>
868  : BinOpMI<opcode, mnemonic, typeinfo, f,
869            [(store (opnode (typeinfo.VT (load addr:$dst)),
870                             typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
871             (implicit EFLAGS)]>, Sched<[WriteADCRMW]>;
872
873// BinOpMI_F - Instructions like "cmp [mem], imm".
874class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
875                SDPatternOperator opnode, Format f>
876  : BinOpMI<opcode, mnemonic, typeinfo, f,
877            [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
878                                  typeinfo.ImmOperator:$src))]>,
879            Sched<[WriteALU.Folded]>;
880
881// BinOpMI8 - Instructions like "add [mem], imm8".
882class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
883               Format f, list<dag> pattern>
884  : ITy<0x82, f, typeinfo,
885        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
886        mnemonic, "{$src, $dst|$dst, $src}", pattern> {
887  let ImmT = Imm8; // Always 8-bit immediate.
888}
889
890// BinOpMI8_RMW - Instructions like "add [mem], imm8".
891class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
892                   SDPatternOperator opnode, Format f>
893  : BinOpMI8<mnemonic, typeinfo, f,
894             [(store (opnode (load addr:$dst),
895                             typeinfo.Imm8Operator:$src), addr:$dst),
896              (implicit EFLAGS)]>, Sched<[WriteALURMW]>;
897
898// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
899class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
900                      SDPatternOperator opnode, Format f>
901  : BinOpMI8<mnemonic, typeinfo, f,
902             [(store (opnode (load addr:$dst),
903                             typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
904              (implicit EFLAGS)]>, Sched<[WriteADCRMW]>;
905
906// BinOpMI8_F - Instructions like "cmp [mem], imm8".
907class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
908                 SDPatternOperator opnode, Format f>
909  : BinOpMI8<mnemonic, typeinfo, f,
910             [(set EFLAGS, (opnode (typeinfo.LoadNode addr:$dst),
911                                    typeinfo.Imm8Operator:$src))]>,
912             Sched<[WriteALU.Folded]>;
913
914// BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
915class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
916              Register areg, string operands, X86FoldableSchedWrite sched = WriteALU>
917  : ITy<opcode, RawFrm, typeinfo,
918        (outs), (ins typeinfo.ImmOperand:$src),
919        mnemonic, operands, []>, Sched<[sched]> {
920  let ImmT = typeinfo.ImmEncoding;
921  let Uses = [areg];
922  let Defs = [areg, EFLAGS];
923  let hasSideEffects = 0;
924}
925
926// BinOpAI_RFF - Instructions like "adc %eax, %eax, imm", that implicitly define
927// and use EFLAGS.
928class BinOpAI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
929                  Register areg, string operands>
930  : BinOpAI<opcode, mnemonic, typeinfo, areg, operands, WriteADC> {
931  let Uses = [areg, EFLAGS];
932}
933
934// BinOpAI_F - Instructions like "cmp %eax, %eax, imm", that imp-def EFLAGS.
935class BinOpAI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
936                Register areg, string operands>
937  : BinOpAI<opcode, mnemonic, typeinfo, areg, operands> {
938  let Defs = [EFLAGS];
939}
940
941/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
942/// defined with "(set GPR:$dst, EFLAGS, (...".
943///
944/// It would be nice to get rid of the second and third argument here, but
945/// tblgen can't handle dependent type references aggressively enough: PR8330
946multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
947                         string mnemonic, Format RegMRM, Format MemMRM,
948                         SDNode opnodeflag, SDNode opnode,
949                         bit CommutableRR, bit ConvertibleToThreeAddress,
950                         bit ConvertibleToThreeAddressRR> {
951  let Defs = [EFLAGS] in {
952    let Constraints = "$src1 = $dst" in {
953      let isCommutable = CommutableRR in {
954        let isConvertibleToThreeAddress = ConvertibleToThreeAddressRR in {
955          def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
956          def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
957          def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
958          def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
959        } // isConvertibleToThreeAddress
960      } // isCommutable
961
962      def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
963      def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
964      def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
965      def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
966
967      def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
968      def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
969      def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
970      def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
971
972      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
973        def NAME#8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
974
975        // NOTE: These are order specific, we want the ri8 forms to be listed
976        // first so that they are slightly preferred to the ri forms.
977        def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
978        def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
979        def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
980
981        def NAME#16ri  : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
982        def NAME#32ri  : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
983        def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
984      }
985    } // Constraints = "$src1 = $dst"
986
987    let mayLoad = 1, mayStore = 1 in {
988      def NAME#8mr    : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
989      def NAME#16mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
990      def NAME#32mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
991      def NAME#64mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
992    }
993
994    // NOTE: These are order specific, we want the mi8 forms to be listed
995    // first so that they are slightly preferred to the mi forms.
996    def NAME#16mi8  : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
997    def NAME#32mi8  : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
998    let Predicates = [In64BitMode] in
999    def NAME#64mi8  : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1000
1001    def NAME#8mi    : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1002    def NAME#16mi   : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1003    def NAME#32mi   : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1004    let Predicates = [In64BitMode] in
1005    def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1006
1007    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1008    // not in 64-bit mode.
1009    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1010        hasSideEffects = 0 in {
1011      let Constraints = "$src1 = $dst" in
1012        def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1013      let mayLoad = 1, mayStore = 1 in
1014        def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>;
1015    }
1016  } // Defs = [EFLAGS]
1017
1018  def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1019                           "{$src, %al|al, $src}">;
1020  def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1021                           "{$src, %ax|ax, $src}">;
1022  def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1023                           "{$src, %eax|eax, $src}">;
1024  def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1025                           "{$src, %rax|rax, $src}">;
1026}
1027
1028/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1029/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1030/// SBB.
1031///
1032/// It would be nice to get rid of the second and third argument here, but
1033/// tblgen can't handle dependent type references aggressively enough: PR8330
1034multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1035                          string mnemonic, Format RegMRM, Format MemMRM,
1036                          SDNode opnode, bit CommutableRR,
1037                           bit ConvertibleToThreeAddress> {
1038  let Uses = [EFLAGS], Defs = [EFLAGS] in {
1039    let Constraints = "$src1 = $dst" in {
1040      let isCommutable = CommutableRR in {
1041        def NAME#8rr  : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1042        let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1043          def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1044          def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1045          def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1046        } // isConvertibleToThreeAddress
1047      } // isCommutable
1048
1049      def NAME#8rr_REV  : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
1050      def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
1051      def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
1052      def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
1053
1054      def NAME#8rm   : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1055      def NAME#16rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1056      def NAME#32rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1057      def NAME#64rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1058
1059      def NAME#8ri   : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1060
1061      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1062        // NOTE: These are order specific, we want the ri8 forms to be listed
1063        // first so that they are slightly preferred to the ri forms.
1064        def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1065        def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1066        def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1067
1068        def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1069        def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1070        def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1071      }
1072    } // Constraints = "$src1 = $dst"
1073
1074    def NAME#8mr    : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1075    def NAME#16mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1076    def NAME#32mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1077    def NAME#64mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1078
1079    // NOTE: These are order specific, we want the mi8 forms to be listed
1080    // first so that they are slightly preferred to the mi forms.
1081    def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1082    def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1083    let Predicates = [In64BitMode] in
1084    def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1085
1086    def NAME#8mi    : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1087    def NAME#16mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
1088    def NAME#32mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>;
1089    let Predicates = [In64BitMode] in
1090    def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1091
1092    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1093    // not in 64-bit mode.
1094    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1095        hasSideEffects = 0 in {
1096      let Constraints = "$src1 = $dst" in
1097        def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1098      let mayLoad = 1, mayStore = 1 in
1099        def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
1100    }
1101  } // Uses = [EFLAGS], Defs = [EFLAGS]
1102
1103  def NAME#8i8   : BinOpAI_RFF<BaseOpc4, mnemonic, Xi8 , AL,
1104                               "{$src, %al|al, $src}">;
1105  def NAME#16i16 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi16, AX,
1106                               "{$src, %ax|ax, $src}">;
1107  def NAME#32i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi32, EAX,
1108                               "{$src, %eax|eax, $src}">;
1109  def NAME#64i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi64, RAX,
1110                               "{$src, %rax|rax, $src}">;
1111}
1112
1113/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1114/// defined with "(set EFLAGS, (...".  It would be really nice to find a way
1115/// to factor this with the other ArithBinOp_*.
1116///
1117multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1118                        string mnemonic, Format RegMRM, Format MemMRM,
1119                        SDNode opnode,
1120                        bit CommutableRR, bit ConvertibleToThreeAddress> {
1121  let Defs = [EFLAGS] in {
1122    let isCommutable = CommutableRR in {
1123      def NAME#8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1124      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1125        def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1126        def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1127        def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1128      }
1129    } // isCommutable
1130
1131    def NAME#8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>, FoldGenData<NAME#8rr>;
1132    def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>, FoldGenData<NAME#16rr>;
1133    def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>, FoldGenData<NAME#32rr>;
1134    def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>, FoldGenData<NAME#64rr>;
1135
1136    def NAME#8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1137    def NAME#16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1138    def NAME#32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1139    def NAME#64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1140
1141    def NAME#8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1142
1143    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1144      // NOTE: These are order specific, we want the ri8 forms to be listed
1145      // first so that they are slightly preferred to the ri forms.
1146      def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1147      def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1148      def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1149
1150      def NAME#16ri  : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1151      def NAME#32ri  : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1152      def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1153    }
1154
1155    def NAME#8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1156    def NAME#16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1157    def NAME#32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1158    def NAME#64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1159
1160    // NOTE: These are order specific, we want the mi8 forms to be listed
1161    // first so that they are slightly preferred to the mi forms.
1162    def NAME#16mi8  : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1163    def NAME#32mi8  : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1164    let Predicates = [In64BitMode] in
1165    def NAME#64mi8  : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1166
1167    def NAME#8mi    : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1168    def NAME#16mi   : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1169    def NAME#32mi   : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1170    let Predicates = [In64BitMode] in
1171    def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1172
1173    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1174    // not in 64-bit mode.
1175    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1176        hasSideEffects = 0 in {
1177      def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1178      let mayLoad = 1 in
1179        def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>;
1180    }
1181  } // Defs = [EFLAGS]
1182
1183  def NAME#8i8   : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL,
1184                             "{$src, %al|al, $src}">;
1185  def NAME#16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX,
1186                             "{$src, %ax|ax, $src}">;
1187  def NAME#32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX,
1188                             "{$src, %eax|eax, $src}">;
1189  def NAME#64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX,
1190                             "{$src, %rax|rax, $src}">;
1191}
1192
1193
1194defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1195                         X86and_flag, and, 1, 0, 0>;
1196defm OR  : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1197                         X86or_flag, or, 1, 0, 0>;
1198defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1199                         X86xor_flag, xor, 1, 0, 0>;
1200defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1201                         X86add_flag, add, 1, 1, 1>;
1202let isCompare = 1 in {
1203defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1204                         X86sub_flag, sub, 0, 1, 0>;
1205}
1206
1207// Version of XOR8rr_NOREX that use GR8_NOREX. This is used by the handling of
1208// __builtin_parity where the last step xors an h-register with an l-register.
1209let isCodeGenOnly = 1, hasSideEffects = 0, Constraints = "$src1 = $dst",
1210    Defs = [EFLAGS], isCommutable = 1 in
1211def XOR8rr_NOREX : I<0x30, MRMDestReg, (outs GR8_NOREX:$dst),
1212                     (ins GR8_NOREX:$src1, GR8_NOREX:$src2),
1213                     "xor{b}\t{$src2, $dst|$dst, $src2}", []>,
1214                     Sched<[WriteALU]>;
1215
1216// Arithmetic.
1217defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1218                          1, 0>;
1219defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1220                          0, 0>;
1221
1222let isCompare = 1 in {
1223defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1224}
1225
1226// Patterns to recognize loads on the LHS of an ADC. We can't make X86adc_flag
1227// commutable since it has EFLAGs as an input.
1228def : Pat<(X86adc_flag (loadi8 addr:$src2), GR8:$src1, EFLAGS),
1229          (ADC8rm GR8:$src1, addr:$src2)>;
1230def : Pat<(X86adc_flag (loadi16 addr:$src2), GR16:$src1, EFLAGS),
1231          (ADC16rm GR16:$src1, addr:$src2)>;
1232def : Pat<(X86adc_flag (loadi32 addr:$src2), GR32:$src1, EFLAGS),
1233          (ADC32rm GR32:$src1, addr:$src2)>;
1234def : Pat<(X86adc_flag (loadi64 addr:$src2), GR64:$src1, EFLAGS),
1235          (ADC64rm GR64:$src1, addr:$src2)>;
1236
1237// Patterns to recognize RMW ADC with loads in operand 1.
1238def : Pat<(store (X86adc_flag GR8:$src, (loadi8 addr:$dst), EFLAGS),
1239                 addr:$dst),
1240          (ADC8mr addr:$dst, GR8:$src)>;
1241def : Pat<(store (X86adc_flag GR16:$src, (loadi16 addr:$dst), EFLAGS),
1242                 addr:$dst),
1243          (ADC16mr addr:$dst, GR16:$src)>;
1244def : Pat<(store (X86adc_flag GR32:$src, (loadi32 addr:$dst), EFLAGS),
1245                 addr:$dst),
1246          (ADC32mr addr:$dst, GR32:$src)>;
1247def : Pat<(store (X86adc_flag GR64:$src, (loadi64 addr:$dst), EFLAGS),
1248                 addr:$dst),
1249          (ADC64mr addr:$dst, GR64:$src)>;
1250
1251// Patterns for basic arithmetic ops with relocImm for the immediate field.
1252multiclass ArithBinOp_RF_relocImm_Pats<SDNode OpNodeFlag, SDNode OpNode> {
1253  def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2),
1254            (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;
1255  def : Pat<(OpNodeFlag GR16:$src1, i16relocImmSExt8_su:$src2),
1256            (!cast<Instruction>(NAME#"16ri8") GR16:$src1, i16relocImmSExt8_su:$src2)>;
1257  def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2),
1258            (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;
1259  def : Pat<(OpNodeFlag GR32:$src1, i32relocImmSExt8_su:$src2),
1260            (!cast<Instruction>(NAME#"32ri8") GR32:$src1, i32relocImmSExt8_su:$src2)>;
1261  def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2),
1262            (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;
1263  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt8_su:$src2),
1264            (!cast<Instruction>(NAME#"64ri8") GR64:$src1, i64relocImmSExt8_su:$src2)>;
1265  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2),
1266            (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;
1267
1268  def : Pat<(store (OpNode (load addr:$dst), relocImm8_su:$src), addr:$dst),
1269            (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>;
1270  def : Pat<(store (OpNode (load addr:$dst), i16relocImmSExt8_su:$src), addr:$dst),
1271            (!cast<Instruction>(NAME#"16mi8") addr:$dst, i16relocImmSExt8_su:$src)>;
1272  def : Pat<(store (OpNode (load addr:$dst), relocImm16_su:$src), addr:$dst),
1273            (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>;
1274  def : Pat<(store (OpNode (load addr:$dst), i32relocImmSExt8_su:$src), addr:$dst),
1275            (!cast<Instruction>(NAME#"32mi8") addr:$dst, i32relocImmSExt8_su:$src)>;
1276  def : Pat<(store (OpNode (load addr:$dst), relocImm32_su:$src), addr:$dst),
1277            (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>;
1278  def : Pat<(store (OpNode (load addr:$dst), i64relocImmSExt8_su:$src), addr:$dst),
1279            (!cast<Instruction>(NAME#"64mi8") addr:$dst, i64relocImmSExt8_su:$src)>;
1280  def : Pat<(store (OpNode (load addr:$dst), i64relocImmSExt32_su:$src), addr:$dst),
1281            (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>;
1282}
1283
1284multiclass ArithBinOp_RFF_relocImm_Pats<SDNode OpNodeFlag> {
1285  def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2, EFLAGS),
1286            (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;
1287  def : Pat<(OpNodeFlag GR16:$src1, i16relocImmSExt8_su:$src2, EFLAGS),
1288            (!cast<Instruction>(NAME#"16ri8") GR16:$src1, i16relocImmSExt8_su:$src2)>;
1289  def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2, EFLAGS),
1290            (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;
1291  def : Pat<(OpNodeFlag GR32:$src1, i32relocImmSExt8_su:$src2, EFLAGS),
1292            (!cast<Instruction>(NAME#"32ri8") GR32:$src1, i32relocImmSExt8_su:$src2)>;
1293  def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2, EFLAGS),
1294            (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;
1295  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt8_su:$src2, EFLAGS),
1296            (!cast<Instruction>(NAME#"64ri8") GR64:$src1, i64relocImmSExt8_su:$src2)>;
1297  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2, EFLAGS),
1298            (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;
1299
1300  def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm8_su:$src, EFLAGS), addr:$dst),
1301            (!cast<Instruction>(NAME#"8mi") addr:$dst, relocImm8_su:$src)>;
1302  def : Pat<(store (OpNodeFlag (load addr:$dst), i16relocImmSExt8_su:$src, EFLAGS), addr:$dst),
1303            (!cast<Instruction>(NAME#"16mi8") addr:$dst, i16relocImmSExt8_su:$src)>;
1304  def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm16_su:$src, EFLAGS), addr:$dst),
1305            (!cast<Instruction>(NAME#"16mi") addr:$dst, relocImm16_su:$src)>;
1306  def : Pat<(store (OpNodeFlag (load addr:$dst), i32relocImmSExt8_su:$src, EFLAGS), addr:$dst),
1307            (!cast<Instruction>(NAME#"32mi8") addr:$dst, i32relocImmSExt8_su:$src)>;
1308  def : Pat<(store (OpNodeFlag (load addr:$dst), relocImm32_su:$src, EFLAGS), addr:$dst),
1309            (!cast<Instruction>(NAME#"32mi") addr:$dst, relocImm32_su:$src)>;
1310  def : Pat<(store (OpNodeFlag (load addr:$dst), i64relocImmSExt8_su:$src, EFLAGS), addr:$dst),
1311            (!cast<Instruction>(NAME#"64mi8") addr:$dst, i64relocImmSExt8_su:$src)>;
1312  def : Pat<(store (OpNodeFlag (load addr:$dst), i64relocImmSExt32_su:$src, EFLAGS), addr:$dst),
1313            (!cast<Instruction>(NAME#"64mi32") addr:$dst, i64relocImmSExt32_su:$src)>;
1314}
1315
1316multiclass ArithBinOp_F_relocImm_Pats<SDNode OpNodeFlag> {
1317  def : Pat<(OpNodeFlag GR8:$src1, relocImm8_su:$src2),
1318            (!cast<Instruction>(NAME#"8ri") GR8:$src1, relocImm8_su:$src2)>;
1319  def : Pat<(OpNodeFlag GR16:$src1, i16relocImmSExt8_su:$src2),
1320            (!cast<Instruction>(NAME#"16ri8") GR16:$src1, i16relocImmSExt8_su:$src2)>;
1321  def : Pat<(OpNodeFlag GR16:$src1, relocImm16_su:$src2),
1322            (!cast<Instruction>(NAME#"16ri") GR16:$src1, relocImm16_su:$src2)>;
1323  def : Pat<(OpNodeFlag GR32:$src1, i32relocImmSExt8_su:$src2),
1324            (!cast<Instruction>(NAME#"32ri8") GR32:$src1, i32relocImmSExt8_su:$src2)>;
1325  def : Pat<(OpNodeFlag GR32:$src1, relocImm32_su:$src2),
1326            (!cast<Instruction>(NAME#"32ri") GR32:$src1, relocImm32_su:$src2)>;
1327  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt8_su:$src2),
1328            (!cast<Instruction>(NAME#"64ri8") GR64:$src1, i64relocImmSExt8_su:$src2)>;
1329  def : Pat<(OpNodeFlag GR64:$src1, i64relocImmSExt32_su:$src2),
1330            (!cast<Instruction>(NAME#"64ri32") GR64:$src1, i64relocImmSExt32_su:$src2)>;
1331
1332  def : Pat<(OpNodeFlag (loadi8 addr:$src1), relocImm8_su:$src2),
1333            (!cast<Instruction>(NAME#"8mi") addr:$src1, relocImm8_su:$src2)>;
1334  def : Pat<(OpNodeFlag (loadi16 addr:$src1), i16relocImmSExt8_su:$src2),
1335            (!cast<Instruction>(NAME#"16mi8") addr:$src1, i16relocImmSExt8_su:$src2)>;
1336  def : Pat<(OpNodeFlag (loadi16 addr:$src1), relocImm16_su:$src2),
1337            (!cast<Instruction>(NAME#"16mi") addr:$src1, relocImm16_su:$src2)>;
1338  def : Pat<(OpNodeFlag (loadi32 addr:$src1), i32relocImmSExt8_su:$src2),
1339            (!cast<Instruction>(NAME#"32mi8") addr:$src1, i32relocImmSExt8_su:$src2)>;
1340  def : Pat<(OpNodeFlag (loadi32 addr:$src1), relocImm32_su:$src2),
1341            (!cast<Instruction>(NAME#"32mi") addr:$src1, relocImm32_su:$src2)>;
1342  def : Pat<(OpNodeFlag (loadi64 addr:$src1), i64relocImmSExt8_su:$src2),
1343            (!cast<Instruction>(NAME#"64mi8") addr:$src1, i64relocImmSExt8_su:$src2)>;
1344  def : Pat<(OpNodeFlag (loadi64 addr:$src1), i64relocImmSExt32_su:$src2),
1345            (!cast<Instruction>(NAME#"64mi32") addr:$src1, i64relocImmSExt32_su:$src2)>;
1346}
1347
1348defm AND : ArithBinOp_RF_relocImm_Pats<X86and_flag, and>;
1349defm OR  : ArithBinOp_RF_relocImm_Pats<X86or_flag, or>;
1350defm XOR : ArithBinOp_RF_relocImm_Pats<X86xor_flag, xor>;
1351defm ADD : ArithBinOp_RF_relocImm_Pats<X86add_flag, add>;
1352defm SUB : ArithBinOp_RF_relocImm_Pats<X86sub_flag, sub>;
1353
1354defm ADC : ArithBinOp_RFF_relocImm_Pats<X86adc_flag>;
1355defm SBB : ArithBinOp_RFF_relocImm_Pats<X86sbb_flag>;
1356
1357defm CMP : ArithBinOp_F_relocImm_Pats<X86cmp>;
1358
1359// ADC is commutable, but we can't indicate that to tablegen. So manually
1360// reverse the operands.
1361def : Pat<(X86adc_flag GR8:$src1, relocImm8_su:$src2, EFLAGS),
1362          (ADC8ri relocImm8_su:$src2, GR8:$src1)>;
1363def : Pat<(X86adc_flag i16relocImmSExt8_su:$src2, GR16:$src1, EFLAGS),
1364          (ADC16ri8 GR16:$src1, i16relocImmSExt8_su:$src2)>;
1365def : Pat<(X86adc_flag relocImm16_su:$src2, GR16:$src1, EFLAGS),
1366          (ADC16ri GR16:$src1, relocImm16_su:$src2)>;
1367def : Pat<(X86adc_flag i32relocImmSExt8_su:$src2, GR32:$src1, EFLAGS),
1368          (ADC32ri8 GR32:$src1, i32relocImmSExt8_su:$src2)>;
1369def : Pat<(X86adc_flag relocImm32_su:$src2, GR32:$src1, EFLAGS),
1370          (ADC32ri GR32:$src1, relocImm32_su:$src2)>;
1371def : Pat<(X86adc_flag i64relocImmSExt8_su:$src2, GR64:$src1, EFLAGS),
1372          (ADC64ri8 GR64:$src1, i64relocImmSExt8_su:$src2)>;
1373def : Pat<(X86adc_flag i64relocImmSExt32_su:$src2, GR64:$src1, EFLAGS),
1374          (ADC64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>;
1375
1376def : Pat<(store (X86adc_flag relocImm8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1377          (ADC8mi addr:$dst, relocImm8_su:$src)>;
1378def : Pat<(store (X86adc_flag i16relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1379          (ADC16mi8 addr:$dst, i16relocImmSExt8_su:$src)>;
1380def : Pat<(store (X86adc_flag relocImm16_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1381          (ADC16mi addr:$dst, relocImm16_su:$src)>;
1382def : Pat<(store (X86adc_flag i32relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1383          (ADC32mi8 addr:$dst, i32relocImmSExt8_su:$src)>;
1384def : Pat<(store (X86adc_flag relocImm32_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1385          (ADC32mi addr:$dst, relocImm32_su:$src)>;
1386def : Pat<(store (X86adc_flag i64relocImmSExt8_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1387          (ADC64mi8 addr:$dst, i64relocImmSExt8_su:$src)>;
1388def : Pat<(store (X86adc_flag i64relocImmSExt32_su:$src, (load addr:$dst), EFLAGS), addr:$dst),
1389          (ADC64mi32 addr:$dst, i64relocImmSExt32_su:$src)>;
1390
1391//===----------------------------------------------------------------------===//
1392// Semantically, test instructions are similar like AND, except they don't
1393// generate a result.  From an encoding perspective, they are very different:
1394// they don't have all the usual imm8 and REV forms, and are encoded into a
1395// different space.
1396def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1397                         (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1398
1399let isCompare = 1 in {
1400  let Defs = [EFLAGS] in {
1401    let isCommutable = 1 in {
1402      // Avoid selecting these and instead use a test+and. Post processing will
1403      // combine them. This gives bunch of other patterns that start with
1404      // and a chance to match.
1405      def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , null_frag>;
1406      def TEST16rr : BinOpRR_F<0x84, "test", Xi16, null_frag>;
1407      def TEST32rr : BinOpRR_F<0x84, "test", Xi32, null_frag>;
1408      def TEST64rr : BinOpRR_F<0x84, "test", Xi64, null_frag>;
1409    } // isCommutable
1410
1411    let hasSideEffects = 0, mayLoad = 1 in {
1412    def TEST8mr    : BinOpMR_F<0x84, "test", Xi8 , null_frag>;
1413    def TEST16mr   : BinOpMR_F<0x84, "test", Xi16, null_frag>;
1414    def TEST32mr   : BinOpMR_F<0x84, "test", Xi32, null_frag>;
1415    def TEST64mr   : BinOpMR_F<0x84, "test", Xi64, null_frag>;
1416    }
1417
1418    def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1419    def TEST16ri   : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1420    def TEST32ri   : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1421    def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1422
1423    def TEST8mi    : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1424    def TEST16mi   : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1425    def TEST32mi   : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1426    let Predicates = [In64BitMode] in
1427    def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1428  } // Defs = [EFLAGS]
1429
1430  def TEST8i8    : BinOpAI_F<0xA8, "test", Xi8 , AL,
1431                             "{$src, %al|al, $src}">;
1432  def TEST16i16  : BinOpAI_F<0xA8, "test", Xi16, AX,
1433                             "{$src, %ax|ax, $src}">;
1434  def TEST32i32  : BinOpAI_F<0xA8, "test", Xi32, EAX,
1435                             "{$src, %eax|eax, $src}">;
1436  def TEST64i32  : BinOpAI_F<0xA8, "test", Xi64, RAX,
1437                             "{$src, %rax|rax, $src}">;
1438} // isCompare
1439
1440// Patterns to match a relocImm into the immediate field.
1441def : Pat<(X86testpat GR8:$src1, relocImm8_su:$src2),
1442          (TEST8ri GR8:$src1, relocImm8_su:$src2)>;
1443def : Pat<(X86testpat GR16:$src1, relocImm16_su:$src2),
1444          (TEST16ri GR16:$src1, relocImm16_su:$src2)>;
1445def : Pat<(X86testpat GR32:$src1, relocImm32_su:$src2),
1446          (TEST32ri GR32:$src1, relocImm32_su:$src2)>;
1447def : Pat<(X86testpat GR64:$src1, i64relocImmSExt32_su:$src2),
1448          (TEST64ri32 GR64:$src1, i64relocImmSExt32_su:$src2)>;
1449
1450def : Pat<(X86testpat (loadi8 addr:$src1), relocImm8_su:$src2),
1451          (TEST8mi addr:$src1, relocImm8_su:$src2)>;
1452def : Pat<(X86testpat (loadi16 addr:$src1), relocImm16_su:$src2),
1453          (TEST16mi addr:$src1, relocImm16_su:$src2)>;
1454def : Pat<(X86testpat (loadi32 addr:$src1), relocImm32_su:$src2),
1455          (TEST32mi addr:$src1, relocImm32_su:$src2)>;
1456def : Pat<(X86testpat (loadi64 addr:$src1), i64relocImmSExt32_su:$src2),
1457          (TEST64mi32 addr:$src1, i64relocImmSExt32_su:$src2)>;
1458
1459//===----------------------------------------------------------------------===//
1460// ANDN Instruction
1461//
1462multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1463                    PatFrag ld_frag, X86FoldableSchedWrite sched> {
1464  def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1465            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1466            [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))]>,
1467            Sched<[sched]>;
1468  def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1469            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1470            [(set RC:$dst, EFLAGS,
1471             (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))]>,
1472           Sched<[sched.Folded, sched.ReadAfterFold]>;
1473}
1474
1475// Complexity is reduced to give and with immediate a chance to match first.
1476let Predicates = [HasBMI], Defs = [EFLAGS], AddedComplexity = -6 in {
1477  defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32, WriteALU>, T8PS, VEX_4V;
1478  defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64, WriteALU>, T8PS, VEX_4V, VEX_W;
1479}
1480
1481let Predicates = [HasBMI], AddedComplexity = -6 in {
1482  def : Pat<(and (not GR32:$src1), GR32:$src2),
1483            (ANDN32rr GR32:$src1, GR32:$src2)>;
1484  def : Pat<(and (not GR64:$src1), GR64:$src2),
1485            (ANDN64rr GR64:$src1, GR64:$src2)>;
1486  def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1487            (ANDN32rm GR32:$src1, addr:$src2)>;
1488  def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1489            (ANDN64rm GR64:$src1, addr:$src2)>;
1490}
1491
1492//===----------------------------------------------------------------------===//
1493// MULX Instruction
1494//
1495multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1496                    X86FoldableSchedWrite sched> {
1497let hasSideEffects = 0 in {
1498  def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1499             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1500             []>, T8XD, VEX_4V, Sched<[WriteIMulH, sched]>;
1501
1502  let mayLoad = 1 in
1503  def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1504             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1505             []>, T8XD, VEX_4V,
1506             Sched<[WriteIMulHLd, sched.Folded,
1507                    // Memory operand.
1508                    ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1509                    // Implicit read of EDX/RDX
1510                    sched.ReadAfterFold]>;
1511
1512  // Pseudo instructions to be used when the low result isn't used. The
1513  // instruction is defined to keep the high if both destinations are the same.
1514  def Hrr : PseudoI<(outs RC:$dst), (ins RC:$src),
1515                    []>, Sched<[sched]>;
1516
1517  let mayLoad = 1 in
1518  def Hrm : PseudoI<(outs RC:$dst), (ins x86memop:$src),
1519                    []>, Sched<[sched.Folded]>;
1520}
1521}
1522
1523let Predicates = [HasBMI2] in {
1524  let Uses = [EDX] in
1525    defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem, WriteMULX32>;
1526  let Uses = [RDX] in
1527    defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem, WriteMULX64>, VEX_W;
1528}
1529
1530//===----------------------------------------------------------------------===//
1531// ADCX and ADOX Instructions
1532//
1533// We don't have patterns for these as there is no advantage over ADC for
1534// most code.
1535let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1536    Constraints = "$src1 = $dst", hasSideEffects = 0 in {
1537  let SchedRW = [WriteADC], isCommutable = 1 in {
1538  def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1539                   (ins GR32:$src1, GR32:$src2),
1540                   "adcx{l}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
1541  def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1542                    (ins GR64:$src1, GR64:$src2),
1543                    "adcx{q}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
1544
1545  def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1546                   (ins GR32:$src1, GR32:$src2),
1547                   "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
1548
1549  def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1550                    (ins GR64:$src1, GR64:$src2),
1551                    "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
1552  } // SchedRW
1553
1554  let mayLoad = 1,
1555      SchedRW = [WriteADC.Folded, WriteADC.ReadAfterFold,
1556                 // Memory operand.
1557                 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1558                 // Implicit read of EFLAGS
1559                 WriteADC.ReadAfterFold] in {
1560  def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1561                   (ins GR32:$src1, i32mem:$src2),
1562                   "adcx{l}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
1563
1564  def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1565                    (ins GR64:$src1, i64mem:$src2),
1566                    "adcx{q}\t{$src2, $dst|$dst, $src2}", []>, T8PD;
1567
1568  def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1569                   (ins GR32:$src1, i32mem:$src2),
1570                   "adox{l}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
1571
1572  def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1573                    (ins GR64:$src1, i64mem:$src2),
1574                    "adox{q}\t{$src2, $dst|$dst, $src2}", []>, T8XS;
1575  } // mayLoad, SchedRW
1576}
1577