[x86] Refactor some tablegen instruction info classes slightly to prepare for another...
[oota-llvm.git] / lib / Target / X86 / X86InstrArithmetic.td
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
17 let SchedRW = [WriteLEA] in {
18 let hasSideEffects = 0 in
19 def LEA16r   : I<0x8D, MRMSrcMem,
20                  (outs GR16:$dst), (ins i32mem:$src),
21                  "lea{w}\t{$src|$dst}, {$dst|$src}", [], IIC_LEA_16>, OpSize16;
22 let isReMaterializable = 1 in
23 def 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
29 def 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
35 let isReMaterializable = 1 in
36 def 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.
49 class 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
60 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
61 def 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
68 let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
69 def 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
73 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
74 def 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
79 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
80 def 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]
85 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
86 def 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]
94 let mayLoad = 1, hasSideEffects = 0 in {
95 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
96 def 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]
100 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
101 def 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]
105 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
106 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
107                 "mul{q}\t$src", [], IIC_MUL64>, SchedLoadReg<WriteIMulLd>;
108 }
109
110 let hasSideEffects = 0 in {
111 // AL,AH = AL*GR8
112 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
113 def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", [],
114               IIC_IMUL8>, Sched<[WriteIMul]>;
115 // AX,DX = AX*GR16
116 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
117 def IMUL16r : I<0xF7, MRM5r, (outs),  (ins GR16:$src), "imul{w}\t$src", [],
118               IIC_IMUL16_RR>, OpSize16, Sched<[WriteIMul]>;
119 // EAX,EDX = EAX*GR32
120 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
121 def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", [],
122               IIC_IMUL32_RR>, OpSize32, Sched<[WriteIMul]>;
123 // RAX,RDX = RAX*GR64
124 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
125 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
126               IIC_IMUL64_RR>, Sched<[WriteIMul]>;
127
128 let mayLoad = 1 in {
129 // AL,AH = AL*[mem8]
130 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
131 def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
132                 "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
133 // AX,DX = AX*[mem16]
134 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
135 def 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]
139 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
140 def 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]
144 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
145 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
146                  "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>;
147 }
148 } // hasSideEffects
149
150
151 let Defs = [EFLAGS] in {
152 let Constraints = "$src1 = $dst" in {
153
154 let isCommutable = 1, SchedRW = [WriteIMul] in {
155 // X = IMUL Y, Z --> X = IMUL Z, Y
156 // Register-Register Signed Integer Multiply
157 def 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;
162 def 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;
167 def 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
176 let SchedRW = [WriteIMulLd, ReadAfterLd] in {
177 def 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;
184 def 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;
191 def 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!
204 let Defs = [EFLAGS] in {
205 let SchedRW = [WriteIMul] in {
206 // Register-Integer Signed Integer Multiply
207 def 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;
213 def 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;
219 def 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;
225 def 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;
231 def 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>;
237 def 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
246 let SchedRW = [WriteIMulLd] in {
247 def 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;
254 def 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;
261 def 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;
267 def 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;
274 def 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>;
281 def 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
295 let hasSideEffects = 1 in { // so that we don't speculatively execute
296 let SchedRW = [WriteIDiv] in {
297 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
298 def DIV8r  : I<0xF6, MRM6r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
299                "div{b}\t$src", [], IIC_DIV8_REG>;
300 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
301 def DIV16r : I<0xF7, MRM6r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
302                "div{w}\t$src", [], IIC_DIV16>, OpSize16;
303 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
304 def 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
307 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
308 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
309                 "div{q}\t$src", [], IIC_DIV64>;
310 } // SchedRW
311
312 let mayLoad = 1 in {
313 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
314 def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
315                "div{b}\t$src", [], IIC_DIV8_MEM>,
316              SchedLoadReg<WriteIDivLd>;
317 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
318 def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
319                "div{w}\t$src", [], IIC_DIV16>, OpSize16,
320              SchedLoadReg<WriteIDivLd>;
321 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
322 def 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
326 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
327 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
328                 "div{q}\t$src", [], IIC_DIV64>,
329              SchedLoadReg<WriteIDivLd>;
330 }
331
332 // Signed division/remainder.
333 let SchedRW = [WriteIDiv] in {
334 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
335 def IDIV8r : I<0xF6, MRM7r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
336                "idiv{b}\t$src", [], IIC_IDIV8>;
337 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
338 def IDIV16r: I<0xF7, MRM7r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
339                "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16;
340 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
341 def 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
344 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
345 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
346                 "idiv{q}\t$src", [], IIC_IDIV64>;
347 } // SchedRW
348
349 let mayLoad = 1 in {
350 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
351 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
352                "idiv{b}\t$src", [], IIC_IDIV8>,
353              SchedLoadReg<WriteIDivLd>;
354 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
355 def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
356                "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16,
357              SchedLoadReg<WriteIDivLd>;
358 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
359 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
360                "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32,
361              SchedLoadReg<WriteIDivLd>;
362 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
363 def 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
374 let CodeSize = 2 in {
375 let Defs = [EFLAGS] in {
376 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
377 def 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>;
381 def 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;
385 def 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;
389 def 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.
395 let SchedRW = [WriteALULd, WriteRMW] in {
396 def 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>;
400 def 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;
404 def 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;
408 def 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
417 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
418 // Match xor -1 to not. Favors these over a move imm + xor to save code size.
419 let AddedComplexity = 15 in {
420 def 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>;
423 def 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;
426 def 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;
429 def 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
434 let SchedRW = [WriteALULd, WriteRMW] in {
435 def NOT8m  : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
436                "not{b}\t$dst",
437                [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
438 def 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;
442 def 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;
446 def 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.
452 let Defs = [EFLAGS] in {
453 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
454 let CodeSize = 2 in
455 def 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
460 let isConvertibleToThreeAddress = 1, CodeSize = 1 in {  // Can xform into LEA.
461 def 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]>;
465 def 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]>;
470 def 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.
477 let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
478 // Can transform into LEA.
479 def 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]>;
484 def 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]>;
489 def 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]>;
494 def 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
501 let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
502     CodeSize = 2 in {
503 def INC32_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
504                   "inc{w}\t$dst", [], IIC_UNARY_REG>,
505                 OpSize16, Requires<[Not64BitMode]>;
506 def INC32_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
507                   "inc{l}\t$dst", [], IIC_UNARY_REG>,
508                 OpSize32, Requires<[Not64BitMode]>;
509 def DEC32_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
510                   "dec{w}\t$dst", [], IIC_UNARY_REG>,
511                 OpSize16, Requires<[Not64BitMode]>;
512 def 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
519 let 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??
538 def 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]>;
542 def 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]>;
546 def 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]>;
550 def 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
556 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
557 let CodeSize = 2 in
558 def 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>;
562 let isConvertibleToThreeAddress = 1, CodeSize = 1 in {   // Can xform into LEA.
563 def 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]>;
568 def 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]>;
573 def 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
580 let 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.
601 class 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
666 def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
667
668
669 def Xi8  : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
670                        Imm8 , i8imm ,    imm,          i8imm   , invalid_node,
671                        0, OpSizeFixed, 0>;
672 def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
673                        Imm16, i16imm,    imm,          i16i8imm, i16immSExt8,
674                        1, OpSize16, 0>;
675 def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
676                        Imm32, i32imm,    imm,          i32i8imm, i32immSExt8,
677                        1, OpSize32, 0>;
678 def 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).
690 class 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".
705 class 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_F - Instructions like "cmp reg, Reg", where the pattern has
714 // just a EFLAGS as a result.
715 class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
716                 SDPatternOperator opnode, Format f = MRMDestReg>
717   : BinOpRR<opcode, mnemonic, typeinfo, (outs),
718             [(set EFLAGS,
719                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
720             IIC_BIN_NONMEM, f>;
721
722 // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
723 // both a regclass and EFLAGS as a result.
724 class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
725                  SDNode opnode>
726   : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
727             [(set typeinfo.RegClass:$dst, EFLAGS,
728                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
729                   IIC_BIN_NONMEM>;
730
731 // BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
732 // both a regclass and EFLAGS as a result, and has EFLAGS as input.
733 class BinOpRR_RFF<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                           EFLAGS))], IIC_BIN_CARRY_NONMEM>;
739
740 // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
741 class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
742                  InstrItinClass itin = IIC_BIN_NONMEM>
743   : ITy<opcode, MRMSrcReg, typeinfo,
744         (outs typeinfo.RegClass:$dst),
745         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
746         mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
747     Sched<[WriteALU]> {
748   // The disassembler should know about this, but not the asmparser.
749   let isCodeGenOnly = 1;
750   let ForceDisassemble = 1;
751   let hasSideEffects = 0;
752 }
753
754 // BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
755 class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
756   : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
757
758 // BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
759 class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
760   : ITy<opcode, MRMSrcReg, typeinfo, (outs),
761         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
762         mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
763     Sched<[WriteALU]> {
764   // The disassembler should know about this, but not the asmparser.
765   let isCodeGenOnly = 1;
766   let ForceDisassemble = 1;
767   let hasSideEffects = 0;
768 }
769
770 // BinOpRM - Instructions like "add reg, reg, [mem]".
771 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
772               dag outlist, list<dag> pattern,
773               InstrItinClass itin = IIC_BIN_MEM>
774   : ITy<opcode, MRMSrcMem, typeinfo, outlist,
775         (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
776         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
777     Sched<[WriteALULd, ReadAfterLd]>;
778
779 // BinOpRM_R - Instructions like "add reg, reg, [mem]".
780 class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
781               SDNode opnode>
782   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
783             [(set typeinfo.RegClass:$dst,
784             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
785
786 // BinOpRM_F - Instructions like "cmp reg, [mem]".
787 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
788               SDPatternOperator opnode>
789   : BinOpRM<opcode, mnemonic, typeinfo, (outs),
790             [(set EFLAGS,
791             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
792
793 // BinOpRM_RF - Instructions like "add reg, reg, [mem]".
794 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
795                  SDNode opnode>
796   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
797             [(set typeinfo.RegClass:$dst, EFLAGS,
798             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
799
800 // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
801 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
802                  SDNode opnode>
803   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
804             [(set typeinfo.RegClass:$dst, EFLAGS,
805             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
806                     EFLAGS))], IIC_BIN_CARRY_MEM>;
807
808 // BinOpRI - Instructions like "add reg, reg, imm".
809 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
810               Format f, dag outlist, list<dag> pattern,
811               InstrItinClass itin = IIC_BIN_NONMEM>
812   : ITy<opcode, f, typeinfo, outlist,
813         (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
814         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
815     Sched<[WriteALU]> {
816   let ImmT = typeinfo.ImmEncoding;
817 }
818
819 // BinOpRI_F - Instructions like "cmp reg, imm".
820 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
821                 SDPatternOperator opnode, Format f>
822   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
823             [(set EFLAGS,
824                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
825
826 // BinOpRI_RF - Instructions like "add reg, reg, imm".
827 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
828                  SDNode opnode, Format f>
829   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
830             [(set typeinfo.RegClass:$dst, EFLAGS,
831                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
832 // BinOpRI_RFF - Instructions like "adc reg, reg, imm".
833 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
834                  SDNode opnode, Format f>
835   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
836             [(set typeinfo.RegClass:$dst, EFLAGS,
837                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
838                         EFLAGS))], IIC_BIN_CARRY_NONMEM>;
839
840 // BinOpRI8 - Instructions like "add reg, reg, imm8".
841 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
842                Format f, dag outlist, list<dag> pattern,
843                InstrItinClass itin = IIC_BIN_NONMEM>
844   : ITy<opcode, f, typeinfo, outlist,
845         (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
846         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
847     Sched<[WriteALU]> {
848   let ImmT = Imm8; // Always 8-bit immediate.
849 }
850
851 // BinOpRI8_F - Instructions like "cmp reg, imm8".
852 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
853                   SDNode opnode, Format f>
854   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
855              [(set EFLAGS,
856                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
857
858 // BinOpRI8_RF - Instructions like "add reg, reg, imm8".
859 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
860                   SDNode opnode, Format f>
861   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
862              [(set typeinfo.RegClass:$dst, EFLAGS,
863                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
864
865 // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
866 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
867                    SDNode opnode, Format f>
868   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
869              [(set typeinfo.RegClass:$dst, EFLAGS,
870                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
871                        EFLAGS))], IIC_BIN_CARRY_NONMEM>;
872
873 // BinOpMR - Instructions like "add [mem], reg".
874 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
875               list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
876   : ITy<opcode, MRMDestMem, typeinfo,
877         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
878         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
879     Sched<[WriteALULd, WriteRMW]>;
880
881 // BinOpMR_RMW - Instructions like "add [mem], reg".
882 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
883                   SDNode opnode>
884   : BinOpMR<opcode, mnemonic, typeinfo,
885           [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
886            (implicit EFLAGS)]>;
887
888 // BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
889 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
890                     SDNode opnode>
891   : BinOpMR<opcode, mnemonic, typeinfo,
892           [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
893                   addr:$dst),
894            (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
895
896 // BinOpMR_F - Instructions like "cmp [mem], reg".
897 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
898                   SDNode opnode>
899   : BinOpMR<opcode, mnemonic, typeinfo,
900             [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
901
902 // BinOpMI - Instructions like "add [mem], imm".
903 class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
904               Format f, list<dag> pattern,
905               InstrItinClass itin = IIC_BIN_MEM>
906   : ITy<opcode, f, typeinfo,
907         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
908         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
909     Sched<[WriteALULd, WriteRMW]> {
910   let ImmT = typeinfo.ImmEncoding;
911 }
912
913 // BinOpMI_RMW - Instructions like "add [mem], imm".
914 class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
915                   SDNode opnode, Format f>
916   : BinOpMI<opcode, mnemonic, typeinfo, f,
917             [(store (opnode (typeinfo.VT (load addr:$dst)),
918                             typeinfo.ImmOperator:$src), addr:$dst),
919              (implicit EFLAGS)]>;
920 // BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
921 class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
922                      SDNode opnode, Format f>
923   : BinOpMI<opcode, mnemonic, typeinfo, f,
924             [(store (opnode (typeinfo.VT (load addr:$dst)),
925                             typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
926              (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
927
928 // BinOpMI_F - Instructions like "cmp [mem], imm".
929 class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
930                 SDPatternOperator opnode, Format f>
931   : BinOpMI<opcode, mnemonic, typeinfo, f,
932             [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
933                                                typeinfo.ImmOperator:$src))]>;
934
935 // BinOpMI8 - Instructions like "add [mem], imm8".
936 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
937                Format f, list<dag> pattern,
938                InstrItinClass itin = IIC_BIN_MEM>
939   : ITy<0x82, f, typeinfo,
940         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
941         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
942     Sched<[WriteALULd, WriteRMW]> {
943   let ImmT = Imm8; // Always 8-bit immediate.
944 }
945
946 // BinOpMI8_RMW - Instructions like "add [mem], imm8".
947 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
948                    SDNode opnode, Format f>
949   : BinOpMI8<mnemonic, typeinfo, f,
950              [(store (opnode (load addr:$dst),
951                              typeinfo.Imm8Operator:$src), addr:$dst),
952               (implicit EFLAGS)]>;
953
954 // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
955 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
956                    SDNode opnode, Format f>
957   : BinOpMI8<mnemonic, typeinfo, f,
958              [(store (opnode (load addr:$dst),
959                              typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
960               (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
961
962 // BinOpMI8_F - Instructions like "cmp [mem], imm8".
963 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
964                  SDNode opnode, Format f>
965   : BinOpMI8<mnemonic, typeinfo, f,
966              [(set EFLAGS, (opnode (load addr:$dst),
967                                    typeinfo.Imm8Operator:$src))]>;
968
969 // BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
970 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
971               Register areg, string operands,
972               InstrItinClass itin = IIC_BIN_NONMEM>
973   : ITy<opcode, RawFrm, typeinfo,
974         (outs), (ins typeinfo.ImmOperand:$src),
975         mnemonic, operands, [], itin>, Sched<[WriteALU]> {
976   let ImmT = typeinfo.ImmEncoding;
977   let Uses = [areg];
978   let Defs = [areg, EFLAGS];
979   let hasSideEffects = 0;
980 }
981
982 // BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
983 // and use EFLAGS.
984 class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
985                 Register areg, string operands>
986   : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
987             IIC_BIN_CARRY_NONMEM> {
988   let Uses = [areg, EFLAGS];
989 }
990
991 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
992 /// defined with "(set GPR:$dst, EFLAGS, (...".
993 ///
994 /// It would be nice to get rid of the second and third argument here, but
995 /// tblgen can't handle dependent type references aggressively enough: PR8330
996 multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
997                          string mnemonic, Format RegMRM, Format MemMRM,
998                          SDNode opnodeflag, SDNode opnode,
999                          bit CommutableRR, bit ConvertibleToThreeAddress> {
1000   let Defs = [EFLAGS] in {
1001     let Constraints = "$src1 = $dst" in {
1002       let isCommutable = CommutableRR,
1003           isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1004         def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
1005         def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
1006         def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
1007         def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
1008       } // isCommutable
1009
1010       def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
1011       def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
1012       def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
1013       def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
1014
1015       def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
1016       def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
1017       def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
1018       def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
1019
1020       let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1021         // NOTE: These are order specific, we want the ri8 forms to be listed
1022         // first so that they are slightly preferred to the ri forms.
1023         def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
1024         def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
1025         def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
1026
1027         def NAME#8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
1028         def NAME#16ri  : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
1029         def NAME#32ri  : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
1030         def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
1031       }
1032     } // Constraints = "$src1 = $dst"
1033
1034     def NAME#8mr    : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
1035     def NAME#16mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
1036     def NAME#32mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
1037     def NAME#64mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
1038
1039     // NOTE: These are order specific, we want the mi8 forms to be listed
1040     // first so that they are slightly preferred to the mi forms.
1041     def NAME#16mi8  : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1042     def NAME#32mi8  : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1043     def NAME#64mi8  : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1044
1045     def NAME#8mi    : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1046     def NAME#16mi   : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1047     def NAME#32mi   : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1048     def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1049   } // Defs = [EFLAGS]
1050
1051   def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1052                            "{$src, %al|al, $src}">;
1053   def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1054                            "{$src, %ax|ax, $src}">;
1055   def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1056                            "{$src, %eax|eax, $src}">;
1057   def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1058                            "{$src, %rax|rax, $src}">;
1059 }
1060
1061 /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1062 /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1063 /// SBB.
1064 ///
1065 /// It would be nice to get rid of the second and third argument here, but
1066 /// tblgen can't handle dependent type references aggressively enough: PR8330
1067 multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1068                           string mnemonic, Format RegMRM, Format MemMRM,
1069                           SDNode opnode, bit CommutableRR,
1070                            bit ConvertibleToThreeAddress> {
1071   let Uses = [EFLAGS], Defs = [EFLAGS] in {
1072     let Constraints = "$src1 = $dst" in {
1073       let isCommutable = CommutableRR,
1074           isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1075         def NAME#8rr  : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1076         def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1077         def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1078         def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1079       } // isCommutable
1080
1081       def NAME#8rr_REV  : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
1082       def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
1083       def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
1084       def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
1085
1086       def NAME#8rm   : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1087       def NAME#16rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1088       def NAME#32rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1089       def NAME#64rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1090
1091       let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1092         // NOTE: These are order specific, we want the ri8 forms to be listed
1093         // first so that they are slightly preferred to the ri forms.
1094         def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1095         def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1096         def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1097
1098         def NAME#8ri   : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1099         def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1100         def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1101         def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1102       }
1103     } // Constraints = "$src1 = $dst"
1104
1105     def NAME#8mr    : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1106     def NAME#16mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1107     def NAME#32mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1108     def NAME#64mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1109
1110     // NOTE: These are order specific, we want the mi8 forms to be listed
1111     // first so that they are slightly preferred to the mi forms.
1112     def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1113     def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1114     def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1115
1116     def NAME#8mi    : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1117     def NAME#16mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
1118     def NAME#32mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>;
1119     def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1120   } // Uses = [EFLAGS], Defs = [EFLAGS]
1121
1122   def NAME#8i8   : BinOpAI_FF<BaseOpc4, mnemonic, Xi8 , AL,
1123                               "{$src, %al|al, $src}">;
1124   def NAME#16i16 : BinOpAI_FF<BaseOpc4, mnemonic, Xi16, AX,
1125                               "{$src, %ax|ax, $src}">;
1126   def NAME#32i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi32, EAX,
1127                               "{$src, %eax|eax, $src}">;
1128   def NAME#64i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi64, RAX,
1129                               "{$src, %rax|rax, $src}">;
1130 }
1131
1132 /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1133 /// defined with "(set EFLAGS, (...".  It would be really nice to find a way
1134 /// to factor this with the other ArithBinOp_*.
1135 ///
1136 multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1137                         string mnemonic, Format RegMRM, Format MemMRM,
1138                         SDNode opnode,
1139                         bit CommutableRR, bit ConvertibleToThreeAddress> {
1140   let Defs = [EFLAGS] in {
1141     let isCommutable = CommutableRR,
1142         isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1143       def NAME#8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1144       def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1145       def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1146       def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1147     } // isCommutable
1148
1149     def NAME#8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
1150     def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
1151     def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
1152     def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
1153
1154     def NAME#8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1155     def NAME#16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1156     def NAME#32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1157     def NAME#64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1158
1159     let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1160       // NOTE: These are order specific, we want the ri8 forms to be listed
1161       // first so that they are slightly preferred to the ri forms.
1162       def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1163       def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1164       def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1165
1166       def NAME#8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1167       def NAME#16ri  : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1168       def NAME#32ri  : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1169       def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1170     }
1171
1172     def NAME#8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1173     def NAME#16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1174     def NAME#32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1175     def NAME#64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1176
1177     // NOTE: These are order specific, we want the mi8 forms to be listed
1178     // first so that they are slightly preferred to the mi forms.
1179     def NAME#16mi8  : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1180     def NAME#32mi8  : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1181     def NAME#64mi8  : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1182
1183     def NAME#8mi    : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1184     def NAME#16mi   : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1185     def NAME#32mi   : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1186     def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1187   } // Defs = [EFLAGS]
1188
1189   def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1190                            "{$src, %al|al, $src}">;
1191   def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1192                            "{$src, %ax|ax, $src}">;
1193   def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1194                            "{$src, %eax|eax, $src}">;
1195   def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1196                            "{$src, %rax|rax, $src}">;
1197 }
1198
1199
1200 defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1201                          X86and_flag, and, 1, 0>;
1202 defm OR  : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1203                          X86or_flag, or, 1, 0>;
1204 defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1205                          X86xor_flag, xor, 1, 0>;
1206 defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1207                          X86add_flag, add, 1, 1>;
1208 let isCompare = 1 in {
1209 defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1210                          X86sub_flag, sub, 0, 0>;
1211 }
1212
1213 // Arithmetic.
1214 defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1215                           1, 0>;
1216 defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1217                           0, 0>;
1218
1219 let isCompare = 1 in {
1220 defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1221 }
1222
1223
1224 //===----------------------------------------------------------------------===//
1225 // Semantically, test instructions are similar like AND, except they don't
1226 // generate a result.  From an encoding perspective, they are very different:
1227 // they don't have all the usual imm8 and REV forms, and are encoded into a
1228 // different space.
1229 def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1230                          (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1231
1232 let isCompare = 1 in {
1233   let Defs = [EFLAGS] in {
1234     let isCommutable = 1 in {
1235       def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>;
1236       def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>;
1237       def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>;
1238       def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>;
1239     } // isCommutable
1240
1241     def TEST8rm    : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
1242     def TEST16rm   : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
1243     def TEST32rm   : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
1244     def TEST64rm   : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
1245
1246     def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1247     def TEST16ri   : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1248     def TEST32ri   : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1249     def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1250
1251     def TEST8mi    : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1252     def TEST16mi   : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1253     def TEST32mi   : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1254     def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1255
1256     // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1257     // register class is constrained to GR8_NOREX. This pseudo is explicitly
1258     // marked side-effect free, since it doesn't have an isel pattern like
1259     // other test instructions.
1260     let isPseudo = 1, hasSideEffects = 0 in
1261     def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1262                           "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1263   } // Defs = [EFLAGS]
1264
1265   def TEST8i8    : BinOpAI<0xA8, "test", Xi8 , AL,
1266                            "{$src, %al|al, $src}">;
1267   def TEST16i16  : BinOpAI<0xA8, "test", Xi16, AX,
1268                            "{$src, %ax|ax, $src}">;
1269   def TEST32i32  : BinOpAI<0xA8, "test", Xi32, EAX,
1270                            "{$src, %eax|eax, $src}">;
1271   def TEST64i32  : BinOpAI<0xA8, "test", Xi64, RAX,
1272                            "{$src, %rax|rax, $src}">;
1273 } // isCompare
1274
1275 //===----------------------------------------------------------------------===//
1276 // ANDN Instruction
1277 //
1278 multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1279                     PatFrag ld_frag> {
1280   def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1281             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1282             [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1283             IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1284   def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1285             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1286             [(set RC:$dst, EFLAGS,
1287              (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1288            Sched<[WriteALULd, ReadAfterLd]>;
1289 }
1290
1291 let Predicates = [HasBMI], Defs = [EFLAGS] in {
1292   defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1293   defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1294 }
1295
1296 let Predicates = [HasBMI] in {
1297   def : Pat<(and (not GR32:$src1), GR32:$src2),
1298             (ANDN32rr GR32:$src1, GR32:$src2)>;
1299   def : Pat<(and (not GR64:$src1), GR64:$src2),
1300             (ANDN64rr GR64:$src1, GR64:$src2)>;
1301   def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1302             (ANDN32rm GR32:$src1, addr:$src2)>;
1303   def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1304             (ANDN64rm GR64:$src1, addr:$src2)>;
1305 }
1306
1307 //===----------------------------------------------------------------------===//
1308 // MULX Instruction
1309 //
1310 multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1311 let hasSideEffects = 0 in {
1312   let isCommutable = 1 in
1313   def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1314              !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1315              [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1316
1317   let mayLoad = 1 in
1318   def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1319              !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1320              [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1321 }
1322 }
1323
1324 let Predicates = [HasBMI2] in {
1325   let Uses = [EDX] in
1326     defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1327   let Uses = [RDX] in
1328     defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1329 }
1330
1331 //===----------------------------------------------------------------------===//
1332 // ADCX Instruction
1333 //
1334 let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1335     Constraints = "$src0 = $dst", AddedComplexity = 10 in {
1336   let SchedRW = [WriteALU] in {
1337   def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1338              (ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1339              [(set GR32:$dst, EFLAGS,
1340                  (X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
1341              IIC_BIN_CARRY_NONMEM>, T8PD;
1342   def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1343              (ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1344              [(set GR64:$dst, EFLAGS,
1345                  (X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
1346              IIC_BIN_CARRY_NONMEM>, T8PD;
1347   } // SchedRW
1348
1349   let mayLoad = 1, SchedRW = [WriteALULd] in {
1350   def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1351              (ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1352              [(set GR32:$dst, EFLAGS,
1353                  (X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
1354              IIC_BIN_CARRY_MEM>, T8PD;
1355
1356   def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1357              (ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1358              [(set GR64:$dst, EFLAGS,
1359                  (X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
1360              IIC_BIN_CARRY_MEM>, T8PD;
1361   }
1362 }
1363
1364 //===----------------------------------------------------------------------===//
1365 // ADOX Instruction
1366 //
1367 let Predicates = [HasADX], hasSideEffects = 0, Defs = [EFLAGS],
1368     Uses = [EFLAGS] in {
1369   let SchedRW = [WriteALU] in {
1370   def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1371              "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1372
1373   def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1374              "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1375   } // SchedRW
1376
1377   let mayLoad = 1, SchedRW = [WriteALULd] in {
1378   def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1379              "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1380
1381   def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1382              "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1383   }
1384 }