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, imm8_su, i8imm, invalid_node,
620                       0, OpSizeFixed, 0>;
621def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
622                       Imm16, i16imm, imm16_su, i16i8imm, i16immSExt8_su,
623                       1, OpSize16, 0>;
624def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
625                       Imm32, i32imm, imm32_su, i32i8imm, i32immSExt8_su,
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_RFF - Instructions like "adc %eax, %eax, imm", that implicitly define
932// and use EFLAGS.
933class BinOpAI_RFF<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// BinOpAI_F - Instructions like "cmp %eax, %eax, imm", that imp-def EFLAGS.
941class BinOpAI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
942                Register areg, string operands>
943  : BinOpAI<opcode, mnemonic, typeinfo, areg, operands> {
944  let Defs = [EFLAGS];
945}
946
947/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
948/// defined with "(set GPR:$dst, EFLAGS, (...".
949///
950/// It would be nice to get rid of the second and third argument here, but
951/// tblgen can't handle dependent type references aggressively enough: PR8330
952multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
953                         string mnemonic, Format RegMRM, Format MemMRM,
954                         SDNode opnodeflag, SDNode opnode,
955                         bit CommutableRR, bit ConvertibleToThreeAddress> {
956  let Defs = [EFLAGS] in {
957    let Constraints = "$src1 = $dst" in {
958      let isCommutable = CommutableRR in {
959        def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
960        let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
961          def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
962          def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
963          def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
964        } // isConvertibleToThreeAddress
965      } // isCommutable
966
967      def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
968      def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
969      def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
970      def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
971
972      def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
973      def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
974      def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
975      def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
976
977      def NAME#8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
978
979      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
980        // NOTE: These are order specific, we want the ri8 forms to be listed
981        // first so that they are slightly preferred to the ri forms.
982        def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
983        def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
984        def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
985
986        def NAME#16ri  : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
987        def NAME#32ri  : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
988        def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
989      }
990    } // Constraints = "$src1 = $dst"
991
992    def NAME#8mr    : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
993    def NAME#16mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
994    def NAME#32mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
995    def NAME#64mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
996
997    // NOTE: These are order specific, we want the mi8 forms to be listed
998    // first so that they are slightly preferred to the mi forms.
999    def NAME#16mi8  : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1000    def NAME#32mi8  : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1001    def NAME#64mi8  : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1002
1003    def NAME#8mi    : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1004    def NAME#16mi   : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1005    def NAME#32mi   : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1006    def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1007
1008    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1009    // not in 64-bit mode.
1010    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1011        hasSideEffects = 0 in {
1012      let Constraints = "$src1 = $dst" in
1013        def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1014      let mayLoad = 1, mayStore = 1 in
1015        def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>;
1016    }
1017  } // Defs = [EFLAGS]
1018
1019  def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1020                           "{$src, %al|al, $src}">;
1021  def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1022                           "{$src, %ax|ax, $src}">;
1023  def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1024                           "{$src, %eax|eax, $src}">;
1025  def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1026                           "{$src, %rax|rax, $src}">;
1027}
1028
1029/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1030/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1031/// SBB.
1032///
1033/// It would be nice to get rid of the second and third argument here, but
1034/// tblgen can't handle dependent type references aggressively enough: PR8330
1035multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1036                          string mnemonic, Format RegMRM, Format MemMRM,
1037                          SDNode opnode, bit CommutableRR,
1038                           bit ConvertibleToThreeAddress> {
1039  let Uses = [EFLAGS], Defs = [EFLAGS] in {
1040    let Constraints = "$src1 = $dst" in {
1041      let isCommutable = CommutableRR in {
1042        def NAME#8rr  : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1043        let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1044          def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1045          def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1046          def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1047        } // isConvertibleToThreeAddress
1048      } // isCommutable
1049
1050      def NAME#8rr_REV  : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
1051      def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
1052      def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
1053      def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
1054
1055      def NAME#8rm   : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1056      def NAME#16rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1057      def NAME#32rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1058      def NAME#64rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1059
1060      def NAME#8ri   : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1061
1062      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1063        // NOTE: These are order specific, we want the ri8 forms to be listed
1064        // first so that they are slightly preferred to the ri forms.
1065        def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1066        def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1067        def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1068
1069        def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1070        def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1071        def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1072      }
1073    } // Constraints = "$src1 = $dst"
1074
1075    def NAME#8mr    : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1076    def NAME#16mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1077    def NAME#32mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1078    def NAME#64mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1079
1080    // NOTE: These are order specific, we want the mi8 forms to be listed
1081    // first so that they are slightly preferred to the mi forms.
1082    def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1083    def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
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    def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1090
1091    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1092    // not in 64-bit mode.
1093    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1094        hasSideEffects = 0 in {
1095      let Constraints = "$src1 = $dst" in
1096        def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1097      let mayLoad = 1, mayStore = 1 in
1098        def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
1099    }
1100  } // Uses = [EFLAGS], Defs = [EFLAGS]
1101
1102  def NAME#8i8   : BinOpAI_RFF<BaseOpc4, mnemonic, Xi8 , AL,
1103                               "{$src, %al|al, $src}">;
1104  def NAME#16i16 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi16, AX,
1105                               "{$src, %ax|ax, $src}">;
1106  def NAME#32i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi32, EAX,
1107                               "{$src, %eax|eax, $src}">;
1108  def NAME#64i32 : BinOpAI_RFF<BaseOpc4, mnemonic, Xi64, RAX,
1109                               "{$src, %rax|rax, $src}">;
1110}
1111
1112/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1113/// defined with "(set EFLAGS, (...".  It would be really nice to find a way
1114/// to factor this with the other ArithBinOp_*.
1115///
1116multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1117                        string mnemonic, Format RegMRM, Format MemMRM,
1118                        SDNode opnode,
1119                        bit CommutableRR, bit ConvertibleToThreeAddress> {
1120  let Defs = [EFLAGS] in {
1121    let isCommutable = CommutableRR in {
1122      def NAME#8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1123      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1124        def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1125        def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1126        def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1127      }
1128    } // isCommutable
1129
1130    def NAME#8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
1131    def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
1132    def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
1133    def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
1134
1135    def NAME#8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1136    def NAME#16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1137    def NAME#32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1138    def NAME#64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1139
1140    def NAME#8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1141
1142    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1143      // NOTE: These are order specific, we want the ri8 forms to be listed
1144      // first so that they are slightly preferred to the ri forms.
1145      def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1146      def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1147      def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1148
1149      def NAME#16ri  : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1150      def NAME#32ri  : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1151      def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1152    }
1153
1154    def NAME#8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1155    def NAME#16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1156    def NAME#32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1157    def NAME#64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1158
1159    // NOTE: These are order specific, we want the mi8 forms to be listed
1160    // first so that they are slightly preferred to the mi forms.
1161    def NAME#16mi8  : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1162    def NAME#32mi8  : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1163    def NAME#64mi8  : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1164
1165    def NAME#8mi    : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1166    def NAME#16mi   : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1167    def NAME#32mi   : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1168    def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1169
1170    // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1171    // not in 64-bit mode.
1172    let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1173        hasSideEffects = 0 in {
1174      def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1175      let mayLoad = 1 in
1176        def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>;
1177    }
1178  } // Defs = [EFLAGS]
1179
1180  def NAME#8i8   : BinOpAI_F<BaseOpc4, mnemonic, Xi8 , AL,
1181                             "{$src, %al|al, $src}">;
1182  def NAME#16i16 : BinOpAI_F<BaseOpc4, mnemonic, Xi16, AX,
1183                             "{$src, %ax|ax, $src}">;
1184  def NAME#32i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi32, EAX,
1185                             "{$src, %eax|eax, $src}">;
1186  def NAME#64i32 : BinOpAI_F<BaseOpc4, mnemonic, Xi64, RAX,
1187                             "{$src, %rax|rax, $src}">;
1188}
1189
1190
1191defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1192                         X86and_flag, and, 1, 0>;
1193defm OR  : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1194                         X86or_flag, or, 1, 0>;
1195defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1196                         X86xor_flag, xor, 1, 0>;
1197defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1198                         X86add_flag, add, 1, 1>;
1199let isCompare = 1 in {
1200defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1201                         X86sub_flag, sub, 0, 0>;
1202}
1203
1204// Arithmetic.
1205defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1206                          1, 0>;
1207defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1208                          0, 0>;
1209
1210let isCompare = 1 in {
1211defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1212}
1213
1214
1215//===----------------------------------------------------------------------===//
1216// Semantically, test instructions are similar like AND, except they don't
1217// generate a result.  From an encoding perspective, they are very different:
1218// they don't have all the usual imm8 and REV forms, and are encoded into a
1219// different space.
1220def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1221                         (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1222
1223let isCompare = 1 in {
1224  let Defs = [EFLAGS] in {
1225    let isCommutable = 1 in {
1226      def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , X86testpat>;
1227      def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat>;
1228      def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat>;
1229      def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat>;
1230    } // isCommutable
1231
1232    def TEST8rm    : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
1233    def TEST16rm   : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
1234    def TEST32rm   : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
1235    def TEST64rm   : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
1236
1237    def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1238    def TEST16ri   : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1239    def TEST32ri   : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1240    def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1241
1242    def TEST8mi    : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1243    def TEST16mi   : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1244    def TEST32mi   : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1245    def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1246
1247    // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1248    // register class is constrained to GR8_NOREX. This pseudo is explicitly
1249    // marked side-effect free, since it doesn't have an isel pattern like
1250    // other test instructions.
1251    let isPseudo = 1, hasSideEffects = 0 in
1252    def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1253                          "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1254  } // Defs = [EFLAGS]
1255
1256  def TEST8i8    : BinOpAI_F<0xA8, "test", Xi8 , AL,
1257                             "{$src, %al|al, $src}">;
1258  def TEST16i16  : BinOpAI_F<0xA8, "test", Xi16, AX,
1259                             "{$src, %ax|ax, $src}">;
1260  def TEST32i32  : BinOpAI_F<0xA8, "test", Xi32, EAX,
1261                             "{$src, %eax|eax, $src}">;
1262  def TEST64i32  : BinOpAI_F<0xA8, "test", Xi64, RAX,
1263                             "{$src, %rax|rax, $src}">;
1264} // isCompare
1265
1266//===----------------------------------------------------------------------===//
1267// ANDN Instruction
1268//
1269multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1270                    PatFrag ld_frag> {
1271  def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1272            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1273            [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1274            IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1275  def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1276            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1277            [(set RC:$dst, EFLAGS,
1278             (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1279           Sched<[WriteALULd, ReadAfterLd]>;
1280}
1281
1282let Predicates = [HasBMI], Defs = [EFLAGS] in {
1283  defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1284  defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1285}
1286
1287let Predicates = [HasBMI] in {
1288  def : Pat<(and (not GR32:$src1), GR32:$src2),
1289            (ANDN32rr GR32:$src1, GR32:$src2)>;
1290  def : Pat<(and (not GR64:$src1), GR64:$src2),
1291            (ANDN64rr GR64:$src1, GR64:$src2)>;
1292  def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1293            (ANDN32rm GR32:$src1, addr:$src2)>;
1294  def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1295            (ANDN64rm GR64:$src1, addr:$src2)>;
1296}
1297
1298//===----------------------------------------------------------------------===//
1299// MULX Instruction
1300//
1301multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1302let hasSideEffects = 0 in {
1303  let isCommutable = 1 in
1304  def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1305             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1306             [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1307
1308  let mayLoad = 1 in
1309  def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1310             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1311             [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1312}
1313}
1314
1315let Predicates = [HasBMI2] in {
1316  let Uses = [EDX] in
1317    defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1318  let Uses = [RDX] in
1319    defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1320}
1321
1322//===----------------------------------------------------------------------===//
1323// ADCX Instruction
1324//
1325let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1326    Constraints = "$src0 = $dst", AddedComplexity = 10 in {
1327  let SchedRW = [WriteALU] in {
1328  def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1329             (ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1330             [(set GR32:$dst, EFLAGS,
1331                 (X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
1332             IIC_BIN_CARRY_NONMEM>, T8PD;
1333  def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1334             (ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1335             [(set GR64:$dst, EFLAGS,
1336                 (X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
1337             IIC_BIN_CARRY_NONMEM>, T8PD;
1338  } // SchedRW
1339
1340  let mayLoad = 1, SchedRW = [WriteALULd] in {
1341  def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1342             (ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1343             [(set GR32:$dst, EFLAGS,
1344                 (X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
1345             IIC_BIN_CARRY_MEM>, T8PD;
1346
1347  def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1348             (ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1349             [(set GR64:$dst, EFLAGS,
1350                 (X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
1351             IIC_BIN_CARRY_MEM>, T8PD;
1352  }
1353}
1354
1355//===----------------------------------------------------------------------===//
1356// ADOX Instruction
1357//
1358let Predicates = [HasADX], hasSideEffects = 0, Defs = [EFLAGS],
1359    Uses = [EFLAGS] in {
1360  let SchedRW = [WriteALU] in {
1361  def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1362             "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1363
1364  def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1365             "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1366  } // SchedRW
1367
1368  let mayLoad = 1, SchedRW = [WriteALULd] in {
1369  def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1370             "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1371
1372  def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1373             "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1374  }
1375}
1376