• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 neverHasSideEffects = 1 in
19def LEA16r   : I<0x8D, MRMSrcMem,
20                 (outs GR16:$dst), (ins i32mem:$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 i32mem:$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], neverHasSideEffects = 1 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], neverHasSideEffects = 1 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], neverHasSideEffects = 1 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, neverHasSideEffects = 1 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 neverHasSideEffects = 1 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} // neverHasSideEffects
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>;
459
460let isConvertibleToThreeAddress = 1, CodeSize = 1 in {  // Can xform into LEA.
461def INC16r : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
462               "inc{w}\t$dst",
463               [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))], IIC_UNARY_REG>,
464             OpSize16, Requires<[Not64BitMode]>;
465def INC32r : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
466               "inc{l}\t$dst",
467               [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
468               IIC_UNARY_REG>,
469             OpSize32, Requires<[Not64BitMode]>;
470def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
471                [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
472                IIC_UNARY_REG>;
473} // isConvertibleToThreeAddress = 1, CodeSize = 1
474
475
476// In 64-bit mode, single byte INC and DEC cannot be encoded.
477let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
478// Can transform into LEA.
479def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
480                  "inc{w}\t$dst",
481                  [(set GR16:$dst, EFLAGS, (X86inc_flag GR16:$src1))],
482                  IIC_UNARY_REG>,
483                OpSize16, Requires<[In64BitMode]>;
484def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
485                  "inc{l}\t$dst",
486                  [(set GR32:$dst, EFLAGS, (X86inc_flag GR32:$src1))],
487                  IIC_UNARY_REG>,
488                OpSize32, Requires<[In64BitMode]>;
489def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
490                  "dec{w}\t$dst",
491                  [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
492                  IIC_UNARY_REG>,
493                OpSize16, Requires<[In64BitMode]>;
494def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
495                  "dec{l}\t$dst",
496                  [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
497                  IIC_UNARY_REG>,
498                OpSize32, Requires<[In64BitMode]>;
499} // isConvertibleToThreeAddress = 1, CodeSize = 2
500
501let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
502    CodeSize = 2 in {
503def INC32_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
504                  "inc{w}\t$dst", [], IIC_UNARY_REG>,
505                OpSize16, Requires<[Not64BitMode]>;
506def INC32_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
507                  "inc{l}\t$dst", [], IIC_UNARY_REG>,
508                OpSize32, Requires<[Not64BitMode]>;
509def DEC32_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
510                  "dec{w}\t$dst", [], IIC_UNARY_REG>,
511                OpSize16, Requires<[Not64BitMode]>;
512def DEC32_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
513                  "dec{l}\t$dst", [], IIC_UNARY_REG>,
514                OpSize32, Requires<[Not64BitMode]>;
515} // isCodeGenOnly = 1, ForceDisassemble = 1, HasSideEffects = 0, CodeSize = 2
516
517} // Constraints = "$src1 = $dst", SchedRW
518
519let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
520  def INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
521               [(store (add (loadi8 addr:$dst), 1), addr:$dst),
522                (implicit EFLAGS)], IIC_UNARY_MEM>;
523  def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
524               [(store (add (loadi16 addr:$dst), 1), addr:$dst),
525                (implicit EFLAGS)], IIC_UNARY_MEM>,
526               OpSize16, Requires<[Not64BitMode]>;
527  def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
528               [(store (add (loadi32 addr:$dst), 1), addr:$dst),
529                (implicit EFLAGS)], IIC_UNARY_MEM>,
530               OpSize32, Requires<[Not64BitMode]>;
531  def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
532                  [(store (add (loadi64 addr:$dst), 1), addr:$dst),
533                   (implicit EFLAGS)], IIC_UNARY_MEM>;
534
535// These are duplicates of their 32-bit counterparts. Only needed so X86 knows
536// how to unfold them.
537// FIXME: What is this for??
538def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
539                  [(store (add (loadi16 addr:$dst), 1), addr:$dst),
540                    (implicit EFLAGS)], IIC_UNARY_MEM>,
541                OpSize16, Requires<[In64BitMode]>;
542def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
543                  [(store (add (loadi32 addr:$dst), 1), addr:$dst),
544                    (implicit EFLAGS)], IIC_UNARY_MEM>,
545                OpSize32, Requires<[In64BitMode]>;
546def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
547                  [(store (add (loadi16 addr:$dst), -1), addr:$dst),
548                    (implicit EFLAGS)], IIC_UNARY_MEM>,
549                OpSize16, Requires<[In64BitMode]>;
550def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
551                  [(store (add (loadi32 addr:$dst), -1), addr:$dst),
552                    (implicit EFLAGS)], IIC_UNARY_MEM>,
553                OpSize32, Requires<[In64BitMode]>;
554} // CodeSize = 2, SchedRW
555
556let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
557let CodeSize = 2 in
558def DEC8r  : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
559               "dec{b}\t$dst",
560               [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
561               IIC_UNARY_REG>;
562let isConvertibleToThreeAddress = 1, CodeSize = 1 in {   // Can xform into LEA.
563def DEC16r : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
564               "dec{w}\t$dst",
565               [(set GR16:$dst, EFLAGS, (X86dec_flag GR16:$src1))],
566               IIC_UNARY_REG>,
567             OpSize16, Requires<[Not64BitMode]>;
568def DEC32r : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
569               "dec{l}\t$dst",
570               [(set GR32:$dst, EFLAGS, (X86dec_flag GR32:$src1))],
571               IIC_UNARY_REG>,
572             OpSize32, Requires<[Not64BitMode]>;
573def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
574                [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
575                IIC_UNARY_REG>;
576} // CodeSize = 2
577} // Constraints = "$src1 = $dst", SchedRW
578
579
580let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
581  def DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
582               [(store (add (loadi8 addr:$dst), -1), addr:$dst),
583                (implicit EFLAGS)], IIC_UNARY_MEM>;
584  def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
585               [(store (add (loadi16 addr:$dst), -1), addr:$dst),
586                (implicit EFLAGS)], IIC_UNARY_MEM>,
587               OpSize16, Requires<[Not64BitMode]>;
588  def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
589               [(store (add (loadi32 addr:$dst), -1), addr:$dst),
590                (implicit EFLAGS)], IIC_UNARY_MEM>,
591               OpSize32, Requires<[Not64BitMode]>;
592  def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
593                  [(store (add (loadi64 addr:$dst), -1), addr:$dst),
594                   (implicit EFLAGS)], IIC_UNARY_MEM>;
595} // CodeSize = 2, SchedRW
596} // Defs = [EFLAGS]
597
598/// X86TypeInfo - This is a bunch of information that describes relevant X86
599/// information about value types.  For example, it can tell you what the
600/// register class and preferred load to use.
601class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
602                  PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
603                  Operand immoperand, SDPatternOperator immoperator,
604                  Operand imm8operand, SDPatternOperator imm8operator,
605                  bit hasOddOpcode, OperandSize opSize,
606                  bit hasREX_WPrefix> {
607  /// VT - This is the value type itself.
608  ValueType VT = vt;
609
610  /// InstrSuffix - This is the suffix used on instructions with this type.  For
611  /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
612  string InstrSuffix = instrsuffix;
613
614  /// RegClass - This is the register class associated with this type.  For
615  /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
616  RegisterClass RegClass = regclass;
617
618  /// LoadNode - This is the load node associated with this type.  For
619  /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
620  PatFrag LoadNode = loadnode;
621
622  /// MemOperand - This is the memory operand associated with this type.  For
623  /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
624  X86MemOperand MemOperand = memoperand;
625
626  /// ImmEncoding - This is the encoding of an immediate of this type.  For
627  /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32.  Note that i64 -> Imm32
628  /// since the immediate fields of i64 instructions is a 32-bit sign extended
629  /// value.
630  ImmType ImmEncoding = immkind;
631
632  /// ImmOperand - This is the operand kind of an immediate of this type.  For
633  /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm.  Note that i64 ->
634  /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
635  /// extended value.
636  Operand ImmOperand = immoperand;
637
638  /// ImmOperator - This is the operator that should be used to match an
639  /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
640  SDPatternOperator ImmOperator = immoperator;
641
642  /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
643  /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
644  /// only used for instructions that have a sign-extended imm8 field form.
645  Operand Imm8Operand = imm8operand;
646
647  /// Imm8Operator - This is the operator that should be used to match an 8-bit
648  /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
649  SDPatternOperator Imm8Operator = imm8operator;
650
651  /// HasOddOpcode - This bit is true if the instruction should have an odd (as
652  /// opposed to even) opcode.  Operations on i8 are usually even, operations on
653  /// other datatypes are odd.
654  bit HasOddOpcode = hasOddOpcode;
655
656  /// OpSize - Selects whether the instruction needs a 0x66 prefix based on
657  /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this
658  /// to Opsize16. i32 sets this to OpSize32.
659  OperandSize OpSize = opSize;
660
661  /// HasREX_WPrefix - This bit is set to true if the instruction should have
662  /// the 0x40 REX prefix.  This is set for i64 types.
663  bit HasREX_WPrefix = hasREX_WPrefix;
664}
665
666def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
667
668
669def Xi8  : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
670                       Imm8 , i8imm ,    imm,          i8imm   , invalid_node,
671                       0, OpSizeFixed, 0>;
672def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
673                       Imm16, i16imm,    imm,          i16i8imm, i16immSExt8,
674                       1, OpSize16, 0>;
675def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
676                       Imm32, i32imm,    imm,          i32i8imm, i32immSExt8,
677                       1, OpSize32, 0>;
678def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
679                       Imm32S, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8,
680                       1, OpSizeFixed, 1>;
681
682/// ITy - This instruction base class takes the type info for the instruction.
683/// Using this, it:
684/// 1. Concatenates together the instruction mnemonic with the appropriate
685///    suffix letter, a tab, and the arguments.
686/// 2. Infers whether the instruction should have a 0x66 prefix byte.
687/// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
688/// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
689///    or 1 (for i16,i32,i64 operations).
690class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
691          string mnemonic, string args, list<dag> pattern,
692          InstrItinClass itin = IIC_BIN_NONMEM>
693  : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
694       opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
695      f, outs, ins,
696      !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
697      itin> {
698
699  // Infer instruction prefixes from type info.
700  let OpSize = typeinfo.OpSize;
701  let hasREX_WPrefix  = typeinfo.HasREX_WPrefix;
702}
703
704// BinOpRR - Instructions like "add reg, reg, reg".
705class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
706              dag outlist, list<dag> pattern, InstrItinClass itin,
707              Format f = MRMDestReg>
708  : ITy<opcode, f, typeinfo, outlist,
709        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
710        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
711    Sched<[WriteALU]>;
712
713// BinOpRR_R - Instructions like "add reg, reg, reg", where the pattern has
714// just a regclass (no eflags) as a result.
715class BinOpRR_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
716                SDNode opnode>
717  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
718            [(set typeinfo.RegClass:$dst,
719                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
720                  IIC_BIN_NONMEM>;
721
722// BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
723// just a EFLAGS as a result.
724class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
725                SDPatternOperator opnode, Format f = MRMDestReg>
726  : BinOpRR<opcode, mnemonic, typeinfo, (outs),
727            [(set EFLAGS,
728                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
729            IIC_BIN_NONMEM, f>;
730
731// BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
732// both a regclass and EFLAGS as a result.
733class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
734                 SDNode opnode>
735  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
736            [(set typeinfo.RegClass:$dst, EFLAGS,
737                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
738                  IIC_BIN_NONMEM>;
739
740// BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
741// both a regclass and EFLAGS as a result, and has EFLAGS as input.
742class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
743                  SDNode opnode>
744  : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
745            [(set typeinfo.RegClass:$dst, EFLAGS,
746                  (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
747                          EFLAGS))], IIC_BIN_CARRY_NONMEM>;
748
749// BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
750class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
751                 InstrItinClass itin = IIC_BIN_NONMEM>
752  : ITy<opcode, MRMSrcReg, typeinfo,
753        (outs typeinfo.RegClass:$dst),
754        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
755        mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
756    Sched<[WriteALU]> {
757  // The disassembler should know about this, but not the asmparser.
758  let isCodeGenOnly = 1;
759  let ForceDisassemble = 1;
760  let hasSideEffects = 0;
761}
762
763// BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
764class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
765  : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
766
767// BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
768class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
769  : ITy<opcode, MRMSrcReg, typeinfo, (outs),
770        (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
771        mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
772    Sched<[WriteALU]> {
773  // The disassembler should know about this, but not the asmparser.
774  let isCodeGenOnly = 1;
775  let ForceDisassemble = 1;
776  let hasSideEffects = 0;
777}
778
779// BinOpRM - Instructions like "add reg, reg, [mem]".
780class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
781              dag outlist, list<dag> pattern,
782              InstrItinClass itin = IIC_BIN_MEM>
783  : ITy<opcode, MRMSrcMem, typeinfo, outlist,
784        (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
785        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
786    Sched<[WriteALULd, ReadAfterLd]>;
787
788// BinOpRM_R - Instructions like "add reg, reg, [mem]".
789class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
790              SDNode opnode>
791  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
792            [(set typeinfo.RegClass:$dst,
793            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
794
795// BinOpRM_F - Instructions like "cmp reg, [mem]".
796class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
797              SDPatternOperator opnode>
798  : BinOpRM<opcode, mnemonic, typeinfo, (outs),
799            [(set EFLAGS,
800            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
801
802// BinOpRM_RF - Instructions like "add reg, reg, [mem]".
803class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
804                 SDNode opnode>
805  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
806            [(set typeinfo.RegClass:$dst, EFLAGS,
807            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
808
809// BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
810class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
811                 SDNode opnode>
812  : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
813            [(set typeinfo.RegClass:$dst, EFLAGS,
814            (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
815                    EFLAGS))], IIC_BIN_CARRY_MEM>;
816
817// BinOpRI - Instructions like "add reg, reg, imm".
818class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
819              Format f, dag outlist, list<dag> pattern,
820              InstrItinClass itin = IIC_BIN_NONMEM>
821  : ITy<opcode, f, typeinfo, outlist,
822        (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
823        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
824    Sched<[WriteALU]> {
825  let ImmT = typeinfo.ImmEncoding;
826}
827
828// BinOpRI_R - Instructions like "add reg, reg, imm".
829class BinOpRI_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
830                SDNode opnode, Format f>
831  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
832            [(set typeinfo.RegClass:$dst,
833                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
834
835// BinOpRI_F - Instructions like "cmp reg, imm".
836class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
837                SDPatternOperator opnode, Format f>
838  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
839            [(set EFLAGS,
840                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
841
842// BinOpRI_RF - Instructions like "add reg, reg, imm".
843class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
844                 SDNode opnode, Format f>
845  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
846            [(set typeinfo.RegClass:$dst, EFLAGS,
847                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
848// BinOpRI_RFF - Instructions like "adc reg, reg, imm".
849class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
850                 SDNode opnode, Format f>
851  : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
852            [(set typeinfo.RegClass:$dst, EFLAGS,
853                (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
854                        EFLAGS))], IIC_BIN_CARRY_NONMEM>;
855
856// BinOpRI8 - Instructions like "add reg, reg, imm8".
857class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
858               Format f, dag outlist, list<dag> pattern,
859               InstrItinClass itin = IIC_BIN_NONMEM>
860  : ITy<opcode, f, typeinfo, outlist,
861        (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
862        mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
863    Sched<[WriteALU]> {
864  let ImmT = Imm8; // Always 8-bit immediate.
865}
866
867// BinOpRI8_R - Instructions like "add reg, reg, imm8".
868class BinOpRI8_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
869                  SDNode opnode, Format f>
870  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
871             [(set typeinfo.RegClass:$dst,
872               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
873
874// BinOpRI8_F - Instructions like "cmp reg, imm8".
875class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
876                  SDNode opnode, Format f>
877  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
878             [(set EFLAGS,
879               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
880
881// BinOpRI8_RF - Instructions like "add reg, reg, imm8".
882class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
883                  SDNode opnode, Format f>
884  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
885             [(set typeinfo.RegClass:$dst, EFLAGS,
886               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
887
888// BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
889class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
890                   SDNode opnode, Format f>
891  : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
892             [(set typeinfo.RegClass:$dst, EFLAGS,
893               (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
894                       EFLAGS))], IIC_BIN_CARRY_NONMEM>;
895
896// BinOpMR - Instructions like "add [mem], reg".
897class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
898              list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
899  : ITy<opcode, MRMDestMem, typeinfo,
900        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
901        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
902    Sched<[WriteALULd, WriteRMW]>;
903
904// BinOpMR_RMW - Instructions like "add [mem], reg".
905class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
906                  SDNode opnode>
907  : BinOpMR<opcode, mnemonic, typeinfo,
908          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
909           (implicit EFLAGS)]>;
910
911// BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
912class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
913                    SDNode opnode>
914  : BinOpMR<opcode, mnemonic, typeinfo,
915          [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
916                  addr:$dst),
917           (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
918
919// BinOpMR_F - Instructions like "cmp [mem], reg".
920class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
921                  SDNode opnode>
922  : BinOpMR<opcode, mnemonic, typeinfo,
923            [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
924
925// BinOpMI - Instructions like "add [mem], imm".
926class BinOpMI<string mnemonic, X86TypeInfo typeinfo,
927              Format f, list<dag> pattern, bits<8> opcode = 0x80,
928              InstrItinClass itin = IIC_BIN_MEM>
929  : ITy<opcode, f, typeinfo,
930        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
931        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
932    Sched<[WriteALULd, WriteRMW]> {
933  let ImmT = typeinfo.ImmEncoding;
934}
935
936// BinOpMI_RMW - Instructions like "add [mem], imm".
937class BinOpMI_RMW<string mnemonic, X86TypeInfo typeinfo,
938                  SDNode opnode, Format f>
939  : BinOpMI<mnemonic, typeinfo, f,
940            [(store (opnode (typeinfo.VT (load addr:$dst)),
941                            typeinfo.ImmOperator:$src), addr:$dst),
942             (implicit EFLAGS)]>;
943// BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
944class BinOpMI_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
945                  SDNode opnode, Format f>
946  : BinOpMI<mnemonic, typeinfo, f,
947            [(store (opnode (typeinfo.VT (load addr:$dst)),
948                            typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
949             (implicit EFLAGS)], 0x80, IIC_BIN_CARRY_MEM>;
950
951// BinOpMI_F - Instructions like "cmp [mem], imm".
952class BinOpMI_F<string mnemonic, X86TypeInfo typeinfo,
953                SDPatternOperator opnode, Format f, bits<8> opcode = 0x80>
954  : BinOpMI<mnemonic, typeinfo, f,
955            [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
956                                               typeinfo.ImmOperator:$src))],
957            opcode>;
958
959// BinOpMI8 - Instructions like "add [mem], imm8".
960class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
961               Format f, list<dag> pattern,
962               InstrItinClass itin = IIC_BIN_MEM>
963  : ITy<0x82, f, typeinfo,
964        (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
965        mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
966    Sched<[WriteALULd, WriteRMW]> {
967  let ImmT = Imm8; // Always 8-bit immediate.
968}
969
970// BinOpMI8_RMW - Instructions like "add [mem], imm8".
971class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
972                   SDNode opnode, Format f>
973  : BinOpMI8<mnemonic, typeinfo, f,
974             [(store (opnode (load addr:$dst),
975                             typeinfo.Imm8Operator:$src), addr:$dst),
976              (implicit EFLAGS)]>;
977
978// BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
979class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
980                   SDNode opnode, Format f>
981  : BinOpMI8<mnemonic, typeinfo, f,
982             [(store (opnode (load addr:$dst),
983                             typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
984              (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
985
986// BinOpMI8_F - Instructions like "cmp [mem], imm8".
987class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
988                 SDNode opnode, Format f>
989  : BinOpMI8<mnemonic, typeinfo, f,
990             [(set EFLAGS, (opnode (load addr:$dst),
991                                   typeinfo.Imm8Operator:$src))]>;
992
993// BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
994class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
995              Register areg, string operands,
996              InstrItinClass itin = IIC_BIN_NONMEM>
997  : ITy<opcode, RawFrm, typeinfo,
998        (outs), (ins typeinfo.ImmOperand:$src),
999        mnemonic, operands, [], itin>, Sched<[WriteALU]> {
1000  let ImmT = typeinfo.ImmEncoding;
1001  let Uses = [areg];
1002  let Defs = [areg, EFLAGS];
1003  let hasSideEffects = 0;
1004}
1005
1006// BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
1007// and use EFLAGS.
1008class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
1009                Register areg, string operands>
1010  : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
1011            IIC_BIN_CARRY_NONMEM> {
1012  let Uses = [areg, EFLAGS];
1013}
1014
1015/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
1016/// defined with "(set GPR:$dst, EFLAGS, (...".
1017///
1018/// It would be nice to get rid of the second and third argument here, but
1019/// tblgen can't handle dependent type references aggressively enough: PR8330
1020multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1021                         string mnemonic, Format RegMRM, Format MemMRM,
1022                         SDNode opnodeflag, SDNode opnode,
1023                         bit CommutableRR, bit ConvertibleToThreeAddress> {
1024  let Defs = [EFLAGS] in {
1025    let Constraints = "$src1 = $dst" in {
1026      let isCommutable = CommutableRR,
1027          isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1028        def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
1029        def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
1030        def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
1031        def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
1032      } // isCommutable
1033
1034      def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
1035      def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
1036      def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
1037      def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
1038
1039      def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
1040      def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
1041      def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
1042      def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
1043
1044      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1045        // NOTE: These are order specific, we want the ri8 forms to be listed
1046        // first so that they are slightly preferred to the ri forms.
1047        def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
1048        def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
1049        def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
1050
1051        def NAME#8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
1052        def NAME#16ri  : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
1053        def NAME#32ri  : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
1054        def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
1055      }
1056    } // Constraints = "$src1 = $dst"
1057
1058    def NAME#8mr    : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
1059    def NAME#16mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
1060    def NAME#32mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
1061    def NAME#64mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
1062
1063    // NOTE: These are order specific, we want the mi8 forms to be listed
1064    // first so that they are slightly preferred to the mi forms.
1065    def NAME#16mi8  : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1066    def NAME#32mi8  : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1067    def NAME#64mi8  : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1068
1069    def NAME#8mi    : BinOpMI_RMW<mnemonic, Xi8 , opnode, MemMRM>;
1070    def NAME#16mi   : BinOpMI_RMW<mnemonic, Xi16, opnode, MemMRM>;
1071    def NAME#32mi   : BinOpMI_RMW<mnemonic, Xi32, opnode, MemMRM>;
1072    def NAME#64mi32 : BinOpMI_RMW<mnemonic, Xi64, opnode, MemMRM>;
1073  } // Defs = [EFLAGS]
1074
1075  def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1076                           "{$src, %al|al, $src}">;
1077  def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1078                           "{$src, %ax|ax, $src}">;
1079  def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1080                           "{$src, %eax|eax, $src}">;
1081  def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1082                           "{$src, %rax|rax, $src}">;
1083}
1084
1085/// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1086/// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1087/// SBB.
1088///
1089/// It would be nice to get rid of the second and third argument here, but
1090/// tblgen can't handle dependent type references aggressively enough: PR8330
1091multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1092                          string mnemonic, Format RegMRM, Format MemMRM,
1093                          SDNode opnode, bit CommutableRR,
1094                           bit ConvertibleToThreeAddress> {
1095  let Uses = [EFLAGS], Defs = [EFLAGS] in {
1096    let Constraints = "$src1 = $dst" in {
1097      let isCommutable = CommutableRR,
1098          isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1099        def NAME#8rr  : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1100        def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1101        def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1102        def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1103      } // isCommutable
1104
1105      def NAME#8rr_REV  : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
1106      def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
1107      def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
1108      def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
1109
1110      def NAME#8rm   : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1111      def NAME#16rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1112      def NAME#32rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1113      def NAME#64rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1114
1115      let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1116        // NOTE: These are order specific, we want the ri8 forms to be listed
1117        // first so that they are slightly preferred to the ri forms.
1118        def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1119        def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1120        def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1121
1122        def NAME#8ri   : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1123        def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1124        def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1125        def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1126      }
1127    } // Constraints = "$src1 = $dst"
1128
1129    def NAME#8mr    : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1130    def NAME#16mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1131    def NAME#32mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1132    def NAME#64mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1133
1134    // NOTE: These are order specific, we want the mi8 forms to be listed
1135    // first so that they are slightly preferred to the mi forms.
1136    def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1137    def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1138    def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1139
1140    def NAME#8mi    : BinOpMI_RMW_FF<mnemonic, Xi8 , opnode, MemMRM>;
1141    def NAME#16mi   : BinOpMI_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1142    def NAME#32mi   : BinOpMI_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1143    def NAME#64mi32 : BinOpMI_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1144  } // Uses = [EFLAGS], Defs = [EFLAGS]
1145
1146  def NAME#8i8   : BinOpAI_FF<BaseOpc4, mnemonic, Xi8 , AL,
1147                              "{$src, %al|al, $src}">;
1148  def NAME#16i16 : BinOpAI_FF<BaseOpc4, mnemonic, Xi16, AX,
1149                              "{$src, %ax|ax, $src}">;
1150  def NAME#32i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi32, EAX,
1151                              "{$src, %eax|eax, $src}">;
1152  def NAME#64i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi64, RAX,
1153                              "{$src, %rax|rax, $src}">;
1154}
1155
1156/// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1157/// defined with "(set EFLAGS, (...".  It would be really nice to find a way
1158/// to factor this with the other ArithBinOp_*.
1159///
1160multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1161                        string mnemonic, Format RegMRM, Format MemMRM,
1162                        SDNode opnode,
1163                        bit CommutableRR, bit ConvertibleToThreeAddress> {
1164  let Defs = [EFLAGS] in {
1165    let isCommutable = CommutableRR,
1166        isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1167      def NAME#8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1168      def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1169      def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1170      def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1171    } // isCommutable
1172
1173    def NAME#8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
1174    def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
1175    def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
1176    def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
1177
1178    def NAME#8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1179    def NAME#16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1180    def NAME#32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1181    def NAME#64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1182
1183    let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1184      // NOTE: These are order specific, we want the ri8 forms to be listed
1185      // first so that they are slightly preferred to the ri forms.
1186      def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1187      def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1188      def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1189
1190      def NAME#8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1191      def NAME#16ri  : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1192      def NAME#32ri  : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1193      def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1194    }
1195
1196    def NAME#8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1197    def NAME#16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1198    def NAME#32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1199    def NAME#64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1200
1201    // NOTE: These are order specific, we want the mi8 forms to be listed
1202    // first so that they are slightly preferred to the mi forms.
1203    def NAME#16mi8  : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1204    def NAME#32mi8  : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1205    def NAME#64mi8  : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1206
1207    def NAME#8mi    : BinOpMI_F<mnemonic, Xi8 , opnode, MemMRM>;
1208    def NAME#16mi   : BinOpMI_F<mnemonic, Xi16, opnode, MemMRM>;
1209    def NAME#32mi   : BinOpMI_F<mnemonic, Xi32, opnode, MemMRM>;
1210    def NAME#64mi32 : BinOpMI_F<mnemonic, Xi64, opnode, MemMRM>;
1211  } // Defs = [EFLAGS]
1212
1213  def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1214                           "{$src, %al|al, $src}">;
1215  def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1216                           "{$src, %ax|ax, $src}">;
1217  def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1218                           "{$src, %eax|eax, $src}">;
1219  def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1220                           "{$src, %rax|rax, $src}">;
1221}
1222
1223
1224defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1225                         X86and_flag, and, 1, 0>;
1226defm OR  : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1227                         X86or_flag, or, 1, 0>;
1228defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1229                         X86xor_flag, xor, 1, 0>;
1230defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1231                         X86add_flag, add, 1, 1>;
1232let isCompare = 1 in {
1233defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1234                         X86sub_flag, sub, 0, 0>;
1235}
1236
1237// Arithmetic.
1238defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1239                          1, 0>;
1240defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1241                          0, 0>;
1242
1243let isCompare = 1 in {
1244defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1245}
1246
1247
1248//===----------------------------------------------------------------------===//
1249// Semantically, test instructions are similar like AND, except they don't
1250// generate a result.  From an encoding perspective, they are very different:
1251// they don't have all the usual imm8 and REV forms, and are encoded into a
1252// different space.
1253def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1254                         (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1255
1256let isCompare = 1 in {
1257  let Defs = [EFLAGS] in {
1258    let isCommutable = 1 in {
1259      def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>;
1260      def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>;
1261      def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>;
1262      def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>;
1263    } // isCommutable
1264
1265    def TEST8rm    : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
1266    def TEST16rm   : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
1267    def TEST32rm   : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
1268    def TEST64rm   : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
1269
1270    def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1271    def TEST16ri   : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1272    def TEST32ri   : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1273    def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1274
1275    def TEST8mi    : BinOpMI_F<"test", Xi8 , X86testpat, MRM0m, 0xF6>;
1276    def TEST16mi   : BinOpMI_F<"test", Xi16, X86testpat, MRM0m, 0xF6>;
1277    def TEST32mi   : BinOpMI_F<"test", Xi32, X86testpat, MRM0m, 0xF6>;
1278    def TEST64mi32 : BinOpMI_F<"test", Xi64, X86testpat, MRM0m, 0xF6>;
1279
1280    // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1281    // register class is constrained to GR8_NOREX. This pseudo is explicitly
1282    // marked side-effect free, since it doesn't have an isel pattern like
1283    // other test instructions.
1284    let isPseudo = 1, hasSideEffects = 0 in
1285    def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1286                          "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1287  } // Defs = [EFLAGS]
1288
1289  def TEST8i8    : BinOpAI<0xA8, "test", Xi8 , AL,
1290                           "{$src, %al|al, $src}">;
1291  def TEST16i16  : BinOpAI<0xA8, "test", Xi16, AX,
1292                           "{$src, %ax|ax, $src}">;
1293  def TEST32i32  : BinOpAI<0xA8, "test", Xi32, EAX,
1294                           "{$src, %eax|eax, $src}">;
1295  def TEST64i32  : BinOpAI<0xA8, "test", Xi64, RAX,
1296                           "{$src, %rax|rax, $src}">;
1297} // isCompare
1298
1299//===----------------------------------------------------------------------===//
1300// ANDN Instruction
1301//
1302multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1303                    PatFrag ld_frag> {
1304  def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1305            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1306            [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1307            IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1308  def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1309            !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1310            [(set RC:$dst, EFLAGS,
1311             (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1312           Sched<[WriteALULd, ReadAfterLd]>;
1313}
1314
1315let Predicates = [HasBMI], Defs = [EFLAGS] in {
1316  defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1317  defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1318}
1319
1320let Predicates = [HasBMI] in {
1321  def : Pat<(and (not GR32:$src1), GR32:$src2),
1322            (ANDN32rr GR32:$src1, GR32:$src2)>;
1323  def : Pat<(and (not GR64:$src1), GR64:$src2),
1324            (ANDN64rr GR64:$src1, GR64:$src2)>;
1325  def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1326            (ANDN32rm GR32:$src1, addr:$src2)>;
1327  def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1328            (ANDN64rm GR64:$src1, addr:$src2)>;
1329}
1330
1331//===----------------------------------------------------------------------===//
1332// MULX Instruction
1333//
1334multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1335let neverHasSideEffects = 1 in {
1336  let isCommutable = 1 in
1337  def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1338             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1339             [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1340
1341  let mayLoad = 1 in
1342  def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1343             !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1344             [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1345}
1346}
1347
1348let Predicates = [HasBMI2] in {
1349  let Uses = [EDX] in
1350    defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1351  let Uses = [RDX] in
1352    defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1353}
1354
1355//===----------------------------------------------------------------------===//
1356// ADCX Instruction
1357//
1358let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
1359  let SchedRW = [WriteALU] in {
1360  def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1361             "adcx{l}\t{$src, $dst|$dst, $src}",
1362             [], IIC_BIN_NONMEM>, T8PD;
1363
1364  def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1365             "adcx{q}\t{$src, $dst|$dst, $src}",
1366             [], IIC_BIN_NONMEM>, T8PD, Requires<[In64BitMode]>;
1367  } // SchedRW
1368
1369  let mayLoad = 1, SchedRW = [WriteALULd] in {
1370  def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1371             "adcx{l}\t{$src, $dst|$dst, $src}",
1372             [], IIC_BIN_MEM>, T8PD;
1373
1374  def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1375             "adcx{q}\t{$src, $dst|$dst, $src}",
1376             [], IIC_BIN_MEM>, T8PD, Requires<[In64BitMode]>;
1377  }
1378}
1379
1380//===----------------------------------------------------------------------===//
1381// ADOX Instruction
1382//
1383let hasSideEffects = 0, Predicates = [HasADX], Defs = [EFLAGS] in {
1384  let SchedRW = [WriteALU] in {
1385  def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1386             "adox{l}\t{$src, $dst|$dst, $src}",
1387             [], IIC_BIN_NONMEM>, T8XS;
1388
1389  def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1390             "adox{q}\t{$src, $dst|$dst, $src}",
1391             [], IIC_BIN_NONMEM>, T8XS, Requires<[In64BitMode]>;
1392  } // SchedRW
1393
1394  let mayLoad = 1, SchedRW = [WriteALULd] in {
1395  def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1396             "adox{l}\t{$src, $dst|$dst, $src}",
1397             [], IIC_BIN_MEM>, T8XS;
1398
1399  def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1400             "adox{q}\t{$src, $dst|$dst, $src}",
1401             [], IIC_BIN_MEM>, T8XS, Requires<[In64BitMode]>;
1402  }
1403}
1404