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