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