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