[X86] Remove the predicates from the register forms of the 2-byte inc and dec instruc...
[oota-llvm.git] / lib / Target / X86 / X86InstrArithmetic.td
1 //===-- X86InstrArithmetic.td - Integer Arithmetic Instrs --*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the integer arithmetic instructions in the X86
11 // architecture.
12 //
13 //===----------------------------------------------------------------------===//
14
15 //===----------------------------------------------------------------------===//
16 // LEA - Load Effective Address
17 let SchedRW = [WriteLEA] in {
18 let hasSideEffects = 0 in
19 def LEA16r   : I<0x8D, MRMSrcMem,
20                  (outs GR16:$dst), (ins i32mem:$src),
21                  "lea{w}\t{$src|$dst}, {$dst|$src}", [], IIC_LEA_16>, OpSize16;
22 let isReMaterializable = 1 in
23 def LEA32r   : I<0x8D, MRMSrcMem,
24                  (outs GR32:$dst), (ins i32mem:$src),
25                  "lea{l}\t{$src|$dst}, {$dst|$src}",
26                  [(set GR32:$dst, lea32addr:$src)], IIC_LEA>,
27                  OpSize32, Requires<[Not64BitMode]>;
28
29 def LEA64_32r : I<0x8D, MRMSrcMem,
30                   (outs GR32:$dst), (ins lea64_32mem:$src),
31                   "lea{l}\t{$src|$dst}, {$dst|$src}",
32                   [(set GR32:$dst, lea64_32addr:$src)], IIC_LEA>,
33                   OpSize32, Requires<[In64BitMode]>;
34
35 let isReMaterializable = 1 in
36 def LEA64r   : RI<0x8D, MRMSrcMem, (outs GR64:$dst), (ins lea64mem:$src),
37                   "lea{q}\t{$src|$dst}, {$dst|$src}",
38                   [(set GR64:$dst, lea64addr:$src)], IIC_LEA>;
39 } // SchedRW
40
41 //===----------------------------------------------------------------------===//
42 //  Fixed-Register Multiplication and Division Instructions.
43 //
44
45 // SchedModel info for instruction that loads one value and gets the second
46 // (and possibly third) value from a register.
47 // This is used for instructions that put the memory operands before other
48 // uses.
49 class SchedLoadReg<SchedWrite SW> : Sched<[SW,
50   // Memory operand.
51   ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
52   // Register reads (implicit or explicit).
53   ReadAfterLd, ReadAfterLd]>;
54
55 // Extra precision multiplication
56
57 // AL is really implied by AX, but the registers in Defs must match the
58 // SDNode results (i8, i32).
59 // AL,AH = AL*GR8
60 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
61 def MUL8r  : I<0xF6, MRM4r, (outs),  (ins GR8:$src), "mul{b}\t$src",
62                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
63                // This probably ought to be moved to a def : Pat<> if the
64                // syntax can be accepted.
65                [(set AL, (mul AL, GR8:$src)),
66                 (implicit EFLAGS)], IIC_MUL8>, Sched<[WriteIMul]>;
67 // AX,DX = AX*GR16
68 let Defs = [AX,DX,EFLAGS], Uses = [AX], hasSideEffects = 0 in
69 def MUL16r : I<0xF7, MRM4r, (outs),  (ins GR16:$src),
70                "mul{w}\t$src",
71                [], IIC_MUL16_REG>, OpSize16, Sched<[WriteIMul]>;
72 // EAX,EDX = EAX*GR32
73 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX], hasSideEffects = 0 in
74 def MUL32r : I<0xF7, MRM4r, (outs),  (ins GR32:$src),
75                "mul{l}\t$src",
76                [/*(set EAX, EDX, EFLAGS, (X86umul_flag EAX, GR32:$src))*/],
77                IIC_MUL32_REG>, OpSize32, Sched<[WriteIMul]>;
78 // RAX,RDX = RAX*GR64
79 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX], hasSideEffects = 0 in
80 def MUL64r : RI<0xF7, MRM4r, (outs), (ins GR64:$src),
81                 "mul{q}\t$src",
82                 [/*(set RAX, RDX, EFLAGS, (X86umul_flag RAX, GR64:$src))*/],
83                 IIC_MUL64>, Sched<[WriteIMul]>;
84 // AL,AH = AL*[mem8]
85 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
86 def MUL8m  : I<0xF6, MRM4m, (outs), (ins i8mem :$src),
87                "mul{b}\t$src",
88                // FIXME: Used for 8-bit mul, ignore result upper 8 bits.
89                // This probably ought to be moved to a def : Pat<> if the
90                // syntax can be accepted.
91                [(set AL, (mul AL, (loadi8 addr:$src))),
92                 (implicit EFLAGS)], IIC_MUL8>, SchedLoadReg<WriteIMulLd>;
93 // AX,DX = AX*[mem16]
94 let mayLoad = 1, hasSideEffects = 0 in {
95 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
96 def MUL16m : I<0xF7, MRM4m, (outs), (ins i16mem:$src),
97                "mul{w}\t$src",
98                [], IIC_MUL16_MEM>, OpSize16, SchedLoadReg<WriteIMulLd>;
99 // EAX,EDX = EAX*[mem32]
100 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
101 def MUL32m : I<0xF7, MRM4m, (outs), (ins i32mem:$src),
102               "mul{l}\t$src",
103               [], IIC_MUL32_MEM>, OpSize32, SchedLoadReg<WriteIMulLd>;
104 // RAX,RDX = RAX*[mem64]
105 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
106 def MUL64m : RI<0xF7, MRM4m, (outs), (ins i64mem:$src),
107                 "mul{q}\t$src", [], IIC_MUL64>, SchedLoadReg<WriteIMulLd>;
108 }
109
110 let hasSideEffects = 0 in {
111 // AL,AH = AL*GR8
112 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
113 def IMUL8r  : I<0xF6, MRM5r, (outs),  (ins GR8:$src), "imul{b}\t$src", [],
114               IIC_IMUL8>, Sched<[WriteIMul]>;
115 // AX,DX = AX*GR16
116 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
117 def IMUL16r : I<0xF7, MRM5r, (outs),  (ins GR16:$src), "imul{w}\t$src", [],
118               IIC_IMUL16_RR>, OpSize16, Sched<[WriteIMul]>;
119 // EAX,EDX = EAX*GR32
120 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
121 def IMUL32r : I<0xF7, MRM5r, (outs),  (ins GR32:$src), "imul{l}\t$src", [],
122               IIC_IMUL32_RR>, OpSize32, Sched<[WriteIMul]>;
123 // RAX,RDX = RAX*GR64
124 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
125 def IMUL64r : RI<0xF7, MRM5r, (outs), (ins GR64:$src), "imul{q}\t$src", [],
126               IIC_IMUL64_RR>, Sched<[WriteIMul]>;
127
128 let mayLoad = 1 in {
129 // AL,AH = AL*[mem8]
130 let Defs = [AL,EFLAGS,AX], Uses = [AL] in
131 def IMUL8m  : I<0xF6, MRM5m, (outs), (ins i8mem :$src),
132                 "imul{b}\t$src", [], IIC_IMUL8>, SchedLoadReg<WriteIMulLd>;
133 // AX,DX = AX*[mem16]
134 let Defs = [AX,DX,EFLAGS], Uses = [AX] in
135 def IMUL16m : I<0xF7, MRM5m, (outs), (ins i16mem:$src),
136                 "imul{w}\t$src", [], IIC_IMUL16_MEM>, OpSize16,
137               SchedLoadReg<WriteIMulLd>;
138 // EAX,EDX = EAX*[mem32]
139 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
140 def IMUL32m : I<0xF7, MRM5m, (outs), (ins i32mem:$src),
141                 "imul{l}\t$src", [], IIC_IMUL32_MEM>, OpSize32,
142               SchedLoadReg<WriteIMulLd>;
143 // RAX,RDX = RAX*[mem64]
144 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
145 def IMUL64m : RI<0xF7, MRM5m, (outs), (ins i64mem:$src),
146                  "imul{q}\t$src", [], IIC_IMUL64>, SchedLoadReg<WriteIMulLd>;
147 }
148 } // hasSideEffects
149
150
151 let Defs = [EFLAGS] in {
152 let Constraints = "$src1 = $dst" in {
153
154 let isCommutable = 1, SchedRW = [WriteIMul] in {
155 // X = IMUL Y, Z --> X = IMUL Z, Y
156 // Register-Register Signed Integer Multiply
157 def IMUL16rr : I<0xAF, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src1,GR16:$src2),
158                  "imul{w}\t{$src2, $dst|$dst, $src2}",
159                  [(set GR16:$dst, EFLAGS,
160                        (X86smul_flag GR16:$src1, GR16:$src2))], IIC_IMUL16_RR>,
161                        TB, OpSize16;
162 def IMUL32rr : I<0xAF, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src1,GR32:$src2),
163                  "imul{l}\t{$src2, $dst|$dst, $src2}",
164                  [(set GR32:$dst, EFLAGS,
165                        (X86smul_flag GR32:$src1, GR32:$src2))], IIC_IMUL32_RR>,
166                  TB, OpSize32;
167 def IMUL64rr : RI<0xAF, MRMSrcReg, (outs GR64:$dst),
168                                    (ins GR64:$src1, GR64:$src2),
169                   "imul{q}\t{$src2, $dst|$dst, $src2}",
170                   [(set GR64:$dst, EFLAGS,
171                         (X86smul_flag GR64:$src1, GR64:$src2))], IIC_IMUL64_RR>,
172                  TB;
173 } // isCommutable, SchedRW
174
175 // Register-Memory Signed Integer Multiply
176 let SchedRW = [WriteIMulLd, ReadAfterLd] in {
177 def IMUL16rm : I<0xAF, MRMSrcMem, (outs GR16:$dst),
178                                   (ins GR16:$src1, i16mem:$src2),
179                  "imul{w}\t{$src2, $dst|$dst, $src2}",
180                  [(set GR16:$dst, EFLAGS,
181                        (X86smul_flag GR16:$src1, (load addr:$src2)))],
182                        IIC_IMUL16_RM>,
183                TB, OpSize16;
184 def IMUL32rm : I<0xAF, MRMSrcMem, (outs GR32:$dst),
185                  (ins GR32:$src1, i32mem:$src2),
186                  "imul{l}\t{$src2, $dst|$dst, $src2}",
187                  [(set GR32:$dst, EFLAGS,
188                        (X86smul_flag GR32:$src1, (load addr:$src2)))],
189                        IIC_IMUL32_RM>,
190                TB, OpSize32;
191 def IMUL64rm : RI<0xAF, MRMSrcMem, (outs GR64:$dst),
192                                    (ins GR64:$src1, i64mem:$src2),
193                   "imul{q}\t{$src2, $dst|$dst, $src2}",
194                   [(set GR64:$dst, EFLAGS,
195                         (X86smul_flag GR64:$src1, (load addr:$src2)))],
196                         IIC_IMUL64_RM>,
197                TB;
198 } // SchedRW
199 } // Constraints = "$src1 = $dst"
200
201 } // Defs = [EFLAGS]
202
203 // Surprisingly enough, these are not two address instructions!
204 let Defs = [EFLAGS] in {
205 let SchedRW = [WriteIMul] in {
206 // Register-Integer Signed Integer Multiply
207 def IMUL16rri  : Ii16<0x69, MRMSrcReg,                      // GR16 = GR16*I16
208                       (outs GR16:$dst), (ins GR16:$src1, i16imm:$src2),
209                       "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
210                       [(set GR16:$dst, EFLAGS,
211                             (X86smul_flag GR16:$src1, imm:$src2))],
212                             IIC_IMUL16_RRI>, OpSize16;
213 def IMUL16rri8 : Ii8<0x6B, MRMSrcReg,                       // GR16 = GR16*I8
214                      (outs GR16:$dst), (ins GR16:$src1, i16i8imm:$src2),
215                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
216                      [(set GR16:$dst, EFLAGS,
217                            (X86smul_flag GR16:$src1, i16immSExt8:$src2))],
218                            IIC_IMUL16_RRI>, OpSize16;
219 def IMUL32rri  : Ii32<0x69, MRMSrcReg,                      // GR32 = GR32*I32
220                       (outs GR32:$dst), (ins GR32:$src1, i32imm:$src2),
221                       "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
222                       [(set GR32:$dst, EFLAGS,
223                             (X86smul_flag GR32:$src1, imm:$src2))],
224                             IIC_IMUL32_RRI>, OpSize32;
225 def IMUL32rri8 : Ii8<0x6B, MRMSrcReg,                       // GR32 = GR32*I8
226                      (outs GR32:$dst), (ins GR32:$src1, i32i8imm:$src2),
227                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
228                      [(set GR32:$dst, EFLAGS,
229                            (X86smul_flag GR32:$src1, i32immSExt8:$src2))],
230                            IIC_IMUL32_RRI>, OpSize32;
231 def IMUL64rri32 : RIi32S<0x69, MRMSrcReg,                    // GR64 = GR64*I32
232                          (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2),
233                          "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
234                          [(set GR64:$dst, EFLAGS,
235                              (X86smul_flag GR64:$src1, i64immSExt32:$src2))],
236                              IIC_IMUL64_RRI>;
237 def IMUL64rri8 : RIi8<0x6B, MRMSrcReg,                      // GR64 = GR64*I8
238                       (outs GR64:$dst), (ins GR64:$src1, i64i8imm:$src2),
239                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
240                       [(set GR64:$dst, EFLAGS,
241                             (X86smul_flag GR64:$src1, i64immSExt8:$src2))],
242                             IIC_IMUL64_RRI>;
243 } // SchedRW
244
245 // Memory-Integer Signed Integer Multiply
246 let SchedRW = [WriteIMulLd] in {
247 def IMUL16rmi  : Ii16<0x69, MRMSrcMem,                     // GR16 = [mem16]*I16
248                       (outs GR16:$dst), (ins i16mem:$src1, i16imm:$src2),
249                       "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
250                       [(set GR16:$dst, EFLAGS,
251                             (X86smul_flag (load addr:$src1), imm:$src2))],
252                             IIC_IMUL16_RMI>,
253                  OpSize16;
254 def IMUL16rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR16 = [mem16]*I8
255                      (outs GR16:$dst), (ins i16mem:$src1, i16i8imm :$src2),
256                      "imul{w}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
257                      [(set GR16:$dst, EFLAGS,
258                            (X86smul_flag (load addr:$src1),
259                                          i16immSExt8:$src2))], IIC_IMUL16_RMI>,
260                                          OpSize16;
261 def IMUL32rmi  : Ii32<0x69, MRMSrcMem,                     // GR32 = [mem32]*I32
262                       (outs GR32:$dst), (ins i32mem:$src1, i32imm:$src2),
263                       "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
264                       [(set GR32:$dst, EFLAGS,
265                             (X86smul_flag (load addr:$src1), imm:$src2))],
266                             IIC_IMUL32_RMI>, OpSize32;
267 def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem,                       // GR32 = [mem32]*I8
268                      (outs GR32:$dst), (ins i32mem:$src1, i32i8imm: $src2),
269                      "imul{l}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
270                      [(set GR32:$dst, EFLAGS,
271                            (X86smul_flag (load addr:$src1),
272                                          i32immSExt8:$src2))],
273                                          IIC_IMUL32_RMI>, OpSize32;
274 def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem,                   // GR64 = [mem64]*I32
275                          (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2),
276                          "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
277                          [(set GR64:$dst, EFLAGS,
278                               (X86smul_flag (load addr:$src1),
279                                             i64immSExt32:$src2))],
280                                             IIC_IMUL64_RMI>;
281 def IMUL64rmi8 : RIi8<0x6B, MRMSrcMem,                      // GR64 = [mem64]*I8
282                       (outs GR64:$dst), (ins i64mem:$src1, i64i8imm: $src2),
283                       "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}",
284                       [(set GR64:$dst, EFLAGS,
285                             (X86smul_flag (load addr:$src1),
286                                           i64immSExt8:$src2))],
287                                           IIC_IMUL64_RMI>;
288 } // SchedRW
289 } // Defs = [EFLAGS]
290
291
292
293
294 // unsigned division/remainder
295 let hasSideEffects = 1 in { // so that we don't speculatively execute
296 let SchedRW = [WriteIDiv] in {
297 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
298 def DIV8r  : I<0xF6, MRM6r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
299                "div{b}\t$src", [], IIC_DIV8_REG>;
300 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
301 def DIV16r : I<0xF7, MRM6r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
302                "div{w}\t$src", [], IIC_DIV16>, OpSize16;
303 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
304 def DIV32r : I<0xF7, MRM6r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
305                "div{l}\t$src", [], IIC_DIV32>, OpSize32;
306 // RDX:RAX/r64 = RAX,RDX
307 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
308 def DIV64r : RI<0xF7, MRM6r, (outs), (ins GR64:$src),
309                 "div{q}\t$src", [], IIC_DIV64>;
310 } // SchedRW
311
312 let mayLoad = 1 in {
313 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
314 def DIV8m  : I<0xF6, MRM6m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
315                "div{b}\t$src", [], IIC_DIV8_MEM>,
316              SchedLoadReg<WriteIDivLd>;
317 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
318 def DIV16m : I<0xF7, MRM6m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
319                "div{w}\t$src", [], IIC_DIV16>, OpSize16,
320              SchedLoadReg<WriteIDivLd>;
321 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
322 def DIV32m : I<0xF7, MRM6m, (outs), (ins i32mem:$src),
323                "div{l}\t$src", [], IIC_DIV32>,
324              SchedLoadReg<WriteIDivLd>, OpSize32;
325 // RDX:RAX/[mem64] = RAX,RDX
326 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
327 def DIV64m : RI<0xF7, MRM6m, (outs), (ins i64mem:$src),
328                 "div{q}\t$src", [], IIC_DIV64>,
329              SchedLoadReg<WriteIDivLd>;
330 }
331
332 // Signed division/remainder.
333 let SchedRW = [WriteIDiv] in {
334 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
335 def IDIV8r : I<0xF6, MRM7r, (outs),  (ins GR8:$src),    // AX/r8 = AL,AH
336                "idiv{b}\t$src", [], IIC_IDIV8>;
337 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
338 def IDIV16r: I<0xF7, MRM7r, (outs),  (ins GR16:$src),   // DX:AX/r16 = AX,DX
339                "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16;
340 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
341 def IDIV32r: I<0xF7, MRM7r, (outs),  (ins GR32:$src),   // EDX:EAX/r32 = EAX,EDX
342                "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32;
343 // RDX:RAX/r64 = RAX,RDX
344 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
345 def IDIV64r: RI<0xF7, MRM7r, (outs), (ins GR64:$src),
346                 "idiv{q}\t$src", [], IIC_IDIV64>;
347 } // SchedRW
348
349 let mayLoad = 1 in {
350 let Defs = [AL,AH,EFLAGS], Uses = [AX] in
351 def IDIV8m : I<0xF6, MRM7m, (outs), (ins i8mem:$src),   // AX/[mem8] = AL,AH
352                "idiv{b}\t$src", [], IIC_IDIV8>,
353              SchedLoadReg<WriteIDivLd>;
354 let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
355 def IDIV16m: I<0xF7, MRM7m, (outs), (ins i16mem:$src),  // DX:AX/[mem16] = AX,DX
356                "idiv{w}\t$src", [], IIC_IDIV16>, OpSize16,
357              SchedLoadReg<WriteIDivLd>;
358 let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in    // EDX:EAX/[mem32] = EAX,EDX
359 def IDIV32m: I<0xF7, MRM7m, (outs), (ins i32mem:$src),
360                "idiv{l}\t$src", [], IIC_IDIV32>, OpSize32,
361              SchedLoadReg<WriteIDivLd>;
362 let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in // RDX:RAX/[mem64] = RAX,RDX
363 def IDIV64m: RI<0xF7, MRM7m, (outs), (ins i64mem:$src),
364                 "idiv{q}\t$src", [], IIC_IDIV64>,
365              SchedLoadReg<WriteIDivLd>;
366 }
367 } // hasSideEffects = 0
368
369 //===----------------------------------------------------------------------===//
370 //  Two address Instructions.
371 //
372
373 // unary instructions
374 let CodeSize = 2 in {
375 let Defs = [EFLAGS] in {
376 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
377 def NEG8r  : I<0xF6, MRM3r, (outs GR8 :$dst), (ins GR8 :$src1),
378                "neg{b}\t$dst",
379                [(set GR8:$dst, (ineg GR8:$src1)),
380                 (implicit EFLAGS)], IIC_UNARY_REG>;
381 def NEG16r : I<0xF7, MRM3r, (outs GR16:$dst), (ins GR16:$src1),
382                "neg{w}\t$dst",
383                [(set GR16:$dst, (ineg GR16:$src1)),
384                 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize16;
385 def NEG32r : I<0xF7, MRM3r, (outs GR32:$dst), (ins GR32:$src1),
386                "neg{l}\t$dst",
387                [(set GR32:$dst, (ineg GR32:$src1)),
388                 (implicit EFLAGS)], IIC_UNARY_REG>, OpSize32;
389 def NEG64r : RI<0xF7, MRM3r, (outs GR64:$dst), (ins GR64:$src1), "neg{q}\t$dst",
390                 [(set GR64:$dst, (ineg GR64:$src1)),
391                  (implicit EFLAGS)], IIC_UNARY_REG>;
392 } // Constraints = "$src1 = $dst", SchedRW
393
394 // Read-modify-write negate.
395 let SchedRW = [WriteALULd, WriteRMW] in {
396 def NEG8m  : I<0xF6, MRM3m, (outs), (ins i8mem :$dst),
397                "neg{b}\t$dst",
398                [(store (ineg (loadi8 addr:$dst)), addr:$dst),
399                 (implicit EFLAGS)], IIC_UNARY_MEM>;
400 def NEG16m : I<0xF7, MRM3m, (outs), (ins i16mem:$dst),
401                "neg{w}\t$dst",
402                [(store (ineg (loadi16 addr:$dst)), addr:$dst),
403                 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize16;
404 def NEG32m : I<0xF7, MRM3m, (outs), (ins i32mem:$dst),
405                "neg{l}\t$dst",
406                [(store (ineg (loadi32 addr:$dst)), addr:$dst),
407                 (implicit EFLAGS)], IIC_UNARY_MEM>, OpSize32;
408 def NEG64m : RI<0xF7, MRM3m, (outs), (ins i64mem:$dst), "neg{q}\t$dst",
409                 [(store (ineg (loadi64 addr:$dst)), addr:$dst),
410                  (implicit EFLAGS)], IIC_UNARY_MEM>;
411 } // SchedRW
412 } // Defs = [EFLAGS]
413
414
415 // Note: NOT does not set EFLAGS!
416
417 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
418 // Match xor -1 to not. Favors these over a move imm + xor to save code size.
419 let AddedComplexity = 15 in {
420 def NOT8r  : I<0xF6, MRM2r, (outs GR8 :$dst), (ins GR8 :$src1),
421                "not{b}\t$dst",
422                [(set GR8:$dst, (not GR8:$src1))], IIC_UNARY_REG>;
423 def NOT16r : I<0xF7, MRM2r, (outs GR16:$dst), (ins GR16:$src1),
424                "not{w}\t$dst",
425                [(set GR16:$dst, (not GR16:$src1))], IIC_UNARY_REG>, OpSize16;
426 def NOT32r : I<0xF7, MRM2r, (outs GR32:$dst), (ins GR32:$src1),
427                "not{l}\t$dst",
428                [(set GR32:$dst, (not GR32:$src1))], IIC_UNARY_REG>, OpSize32;
429 def NOT64r : RI<0xF7, MRM2r, (outs GR64:$dst), (ins GR64:$src1), "not{q}\t$dst",
430                 [(set GR64:$dst, (not GR64:$src1))], IIC_UNARY_REG>;
431 }
432 } // Constraints = "$src1 = $dst", SchedRW
433
434 let SchedRW = [WriteALULd, WriteRMW] in {
435 def NOT8m  : I<0xF6, MRM2m, (outs), (ins i8mem :$dst),
436                "not{b}\t$dst",
437                [(store (not (loadi8 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
438 def NOT16m : I<0xF7, MRM2m, (outs), (ins i16mem:$dst),
439                "not{w}\t$dst",
440                [(store (not (loadi16 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
441                OpSize16;
442 def NOT32m : I<0xF7, MRM2m, (outs), (ins i32mem:$dst),
443                "not{l}\t$dst",
444                [(store (not (loadi32 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>,
445                OpSize32;
446 def NOT64m : RI<0xF7, MRM2m, (outs), (ins i64mem:$dst), "not{q}\t$dst",
447                 [(store (not (loadi64 addr:$dst)), addr:$dst)], IIC_UNARY_MEM>;
448 } // SchedRW
449 } // CodeSize
450
451 // TODO: inc/dec is slow for P4, but fast for Pentium-M.
452 let Defs = [EFLAGS] in {
453 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
454 let CodeSize = 2 in
455 def INC8r  : I<0xFE, MRM0r, (outs GR8 :$dst), (ins GR8 :$src1),
456                "inc{b}\t$dst",
457                [(set GR8:$dst, EFLAGS, (X86inc_flag GR8:$src1))],
458                IIC_UNARY_REG>;
459
460 let isConvertibleToThreeAddress = 1, CodeSize = 1 in {  // Can xform into LEA.
461 def INC16r : I<0x40, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
462                "inc{w}\t$dst", [], IIC_UNARY_REG>,
463              OpSize16, Requires<[Not64BitMode]>;
464 def INC32r : I<0x40, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
465                "inc{l}\t$dst", [], IIC_UNARY_REG>,
466              OpSize32, Requires<[Not64BitMode]>;
467 def INC64r : RI<0xFF, MRM0r, (outs GR64:$dst), (ins GR64:$src1), "inc{q}\t$dst",
468                 [(set GR64:$dst, EFLAGS, (X86inc_flag GR64:$src1))],
469                 IIC_UNARY_REG>;
470 } // isConvertibleToThreeAddress = 1, CodeSize = 1
471
472
473 // In 64-bit mode, single byte INC and DEC cannot be encoded.
474 let isConvertibleToThreeAddress = 1, CodeSize = 2 in {
475 // Can transform into LEA.
476 def INC64_16r : I<0xFF, MRM0r, (outs GR16:$dst), (ins GR16:$src1),
477                   "inc{w}\t$dst", [], IIC_UNARY_REG>, OpSize16;
478 def INC64_32r : I<0xFF, MRM0r, (outs GR32:$dst), (ins GR32:$src1),
479                   "inc{l}\t$dst", [], IIC_UNARY_REG>, OpSize32;
480 def DEC64_16r : I<0xFF, MRM1r, (outs GR16:$dst), (ins GR16:$src1),
481                   "dec{w}\t$dst", [], IIC_UNARY_REG>, OpSize16;
482 def DEC64_32r : I<0xFF, MRM1r, (outs GR32:$dst), (ins GR32:$src1),
483                   "dec{l}\t$dst", [], IIC_UNARY_REG>, OpSize32;
484 } // isConvertibleToThreeAddress = 1, CodeSize = 2
485
486 } // Constraints = "$src1 = $dst", SchedRW
487
488 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
489   def INC8m  : I<0xFE, MRM0m, (outs), (ins i8mem :$dst), "inc{b}\t$dst",
490                [(store (add (loadi8 addr:$dst), 1), addr:$dst),
491                 (implicit EFLAGS)], IIC_UNARY_MEM>;
492   def INC16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
493                [(store (add (loadi16 addr:$dst), 1), addr:$dst),
494                 (implicit EFLAGS)], IIC_UNARY_MEM>,
495                OpSize16, Requires<[Not64BitMode]>;
496   def INC32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
497                [(store (add (loadi32 addr:$dst), 1), addr:$dst),
498                 (implicit EFLAGS)], IIC_UNARY_MEM>,
499                OpSize32, Requires<[Not64BitMode]>;
500   def INC64m : RI<0xFF, MRM0m, (outs), (ins i64mem:$dst), "inc{q}\t$dst",
501                   [(store (add (loadi64 addr:$dst), 1), addr:$dst),
502                    (implicit EFLAGS)], IIC_UNARY_MEM>;
503
504 // These are duplicates of their 32-bit counterparts. Only needed so X86 knows
505 // how to unfold them.
506 // FIXME: What is this for??
507 def INC64_16m : I<0xFF, MRM0m, (outs), (ins i16mem:$dst), "inc{w}\t$dst",
508                   [(store (add (loadi16 addr:$dst), 1), addr:$dst),
509                     (implicit EFLAGS)], IIC_UNARY_MEM>,
510                 OpSize16, Requires<[In64BitMode]>;
511 def INC64_32m : I<0xFF, MRM0m, (outs), (ins i32mem:$dst), "inc{l}\t$dst",
512                   [(store (add (loadi32 addr:$dst), 1), addr:$dst),
513                     (implicit EFLAGS)], IIC_UNARY_MEM>,
514                 OpSize32, Requires<[In64BitMode]>;
515 def DEC64_16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
516                   [(store (add (loadi16 addr:$dst), -1), addr:$dst),
517                     (implicit EFLAGS)], IIC_UNARY_MEM>,
518                 OpSize16, Requires<[In64BitMode]>;
519 def DEC64_32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
520                   [(store (add (loadi32 addr:$dst), -1), addr:$dst),
521                     (implicit EFLAGS)], IIC_UNARY_MEM>,
522                 OpSize32, Requires<[In64BitMode]>;
523 } // CodeSize = 2, SchedRW
524
525 let Constraints = "$src1 = $dst", SchedRW = [WriteALU] in {
526 let CodeSize = 2 in
527 def DEC8r  : I<0xFE, MRM1r, (outs GR8 :$dst), (ins GR8 :$src1),
528                "dec{b}\t$dst",
529                [(set GR8:$dst, EFLAGS, (X86dec_flag GR8:$src1))],
530                IIC_UNARY_REG>;
531 let isConvertibleToThreeAddress = 1, CodeSize = 1 in {   // Can xform into LEA.
532 def DEC16r : I<0x48, AddRegFrm, (outs GR16:$dst), (ins GR16:$src1),
533                "dec{w}\t$dst", [], IIC_UNARY_REG>,
534              OpSize16, Requires<[Not64BitMode]>;
535 def DEC32r : I<0x48, AddRegFrm, (outs GR32:$dst), (ins GR32:$src1),
536                "dec{l}\t$dst", [], IIC_UNARY_REG>,
537              OpSize32, Requires<[Not64BitMode]>;
538 def DEC64r : RI<0xFF, MRM1r, (outs GR64:$dst), (ins GR64:$src1), "dec{q}\t$dst",
539                 [(set GR64:$dst, EFLAGS, (X86dec_flag GR64:$src1))],
540                 IIC_UNARY_REG>;
541 } // CodeSize = 2
542 } // Constraints = "$src1 = $dst", SchedRW
543
544
545 let CodeSize = 2, SchedRW = [WriteALULd, WriteRMW] in {
546   def DEC8m  : I<0xFE, MRM1m, (outs), (ins i8mem :$dst), "dec{b}\t$dst",
547                [(store (add (loadi8 addr:$dst), -1), addr:$dst),
548                 (implicit EFLAGS)], IIC_UNARY_MEM>;
549   def DEC16m : I<0xFF, MRM1m, (outs), (ins i16mem:$dst), "dec{w}\t$dst",
550                [(store (add (loadi16 addr:$dst), -1), addr:$dst),
551                 (implicit EFLAGS)], IIC_UNARY_MEM>,
552                OpSize16, Requires<[Not64BitMode]>;
553   def DEC32m : I<0xFF, MRM1m, (outs), (ins i32mem:$dst), "dec{l}\t$dst",
554                [(store (add (loadi32 addr:$dst), -1), addr:$dst),
555                 (implicit EFLAGS)], IIC_UNARY_MEM>,
556                OpSize32, Requires<[Not64BitMode]>;
557   def DEC64m : RI<0xFF, MRM1m, (outs), (ins i64mem:$dst), "dec{q}\t$dst",
558                   [(store (add (loadi64 addr:$dst), -1), addr:$dst),
559                    (implicit EFLAGS)], IIC_UNARY_MEM>;
560 } // CodeSize = 2, SchedRW
561 } // Defs = [EFLAGS]
562
563 let Predicates = [Not64BitMode] in {
564   def : Pat<(X86inc_flag GR16:$src1), (INC16r GR16:$src1)>;
565   def : Pat<(X86inc_flag GR32:$src1), (INC32r GR32:$src1)>;
566   def : Pat<(X86dec_flag GR16:$src1), (DEC16r GR16:$src1)>;
567   def : Pat<(X86dec_flag GR32:$src1), (DEC32r GR32:$src1)>;
568 }
569
570 let Predicates = [In64BitMode] in {
571   def : Pat<(X86inc_flag GR16:$src1), (INC64_16r GR16:$src1)>;
572   def : Pat<(X86inc_flag GR32:$src1), (INC64_32r GR32:$src1)>;
573   def : Pat<(X86dec_flag GR16:$src1), (DEC64_16r GR16:$src1)>;
574   def : Pat<(X86dec_flag GR32:$src1), (DEC64_32r GR32:$src1)>;
575 }
576
577 /// X86TypeInfo - This is a bunch of information that describes relevant X86
578 /// information about value types.  For example, it can tell you what the
579 /// register class and preferred load to use.
580 class X86TypeInfo<ValueType vt, string instrsuffix, RegisterClass regclass,
581                   PatFrag loadnode, X86MemOperand memoperand, ImmType immkind,
582                   Operand immoperand, SDPatternOperator immoperator,
583                   Operand imm8operand, SDPatternOperator imm8operator,
584                   bit hasOddOpcode, OperandSize opSize,
585                   bit hasREX_WPrefix> {
586   /// VT - This is the value type itself.
587   ValueType VT = vt;
588
589   /// InstrSuffix - This is the suffix used on instructions with this type.  For
590   /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q".
591   string InstrSuffix = instrsuffix;
592
593   /// RegClass - This is the register class associated with this type.  For
594   /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64.
595   RegisterClass RegClass = regclass;
596
597   /// LoadNode - This is the load node associated with this type.  For
598   /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64.
599   PatFrag LoadNode = loadnode;
600
601   /// MemOperand - This is the memory operand associated with this type.  For
602   /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem.
603   X86MemOperand MemOperand = memoperand;
604
605   /// ImmEncoding - This is the encoding of an immediate of this type.  For
606   /// example, i8 -> Imm8, i16 -> Imm16, i32 -> Imm32.  Note that i64 -> Imm32
607   /// since the immediate fields of i64 instructions is a 32-bit sign extended
608   /// value.
609   ImmType ImmEncoding = immkind;
610
611   /// ImmOperand - This is the operand kind of an immediate of this type.  For
612   /// example, i8 -> i8imm, i16 -> i16imm, i32 -> i32imm.  Note that i64 ->
613   /// i64i32imm since the immediate fields of i64 instructions is a 32-bit sign
614   /// extended value.
615   Operand ImmOperand = immoperand;
616
617   /// ImmOperator - This is the operator that should be used to match an
618   /// immediate of this kind in a pattern (e.g. imm, or i64immSExt32).
619   SDPatternOperator ImmOperator = immoperator;
620
621   /// Imm8Operand - This is the operand kind to use for an imm8 of this type.
622   /// For example, i8 -> <invalid>, i16 -> i16i8imm, i32 -> i32i8imm.  This is
623   /// only used for instructions that have a sign-extended imm8 field form.
624   Operand Imm8Operand = imm8operand;
625
626   /// Imm8Operator - This is the operator that should be used to match an 8-bit
627   /// sign extended immediate of this kind in a pattern (e.g. imm16immSExt8).
628   SDPatternOperator Imm8Operator = imm8operator;
629
630   /// HasOddOpcode - This bit is true if the instruction should have an odd (as
631   /// opposed to even) opcode.  Operations on i8 are usually even, operations on
632   /// other datatypes are odd.
633   bit HasOddOpcode = hasOddOpcode;
634
635   /// OpSize - Selects whether the instruction needs a 0x66 prefix based on
636   /// 16-bit vs 32-bit mode. i8/i64 set this to OpSizeFixed. i16 sets this
637   /// to Opsize16. i32 sets this to OpSize32.
638   OperandSize OpSize = opSize;
639
640   /// HasREX_WPrefix - This bit is set to true if the instruction should have
641   /// the 0x40 REX prefix.  This is set for i64 types.
642   bit HasREX_WPrefix = hasREX_WPrefix;
643 }
644
645 def invalid_node : SDNode<"<<invalid_node>>", SDTIntLeaf,[],"<<invalid_node>>">;
646
647
648 def Xi8  : X86TypeInfo<i8 , "b", GR8 , loadi8 , i8mem ,
649                        Imm8 , i8imm ,    imm,          i8imm   , invalid_node,
650                        0, OpSizeFixed, 0>;
651 def Xi16 : X86TypeInfo<i16, "w", GR16, loadi16, i16mem,
652                        Imm16, i16imm,    imm,          i16i8imm, i16immSExt8,
653                        1, OpSize16, 0>;
654 def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem,
655                        Imm32, i32imm,    imm,          i32i8imm, i32immSExt8,
656                        1, OpSize32, 0>;
657 def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem,
658                        Imm32S, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8,
659                        1, OpSizeFixed, 1>;
660
661 /// ITy - This instruction base class takes the type info for the instruction.
662 /// Using this, it:
663 /// 1. Concatenates together the instruction mnemonic with the appropriate
664 ///    suffix letter, a tab, and the arguments.
665 /// 2. Infers whether the instruction should have a 0x66 prefix byte.
666 /// 3. Infers whether the instruction should have a 0x40 REX_W prefix.
667 /// 4. Infers whether the low bit of the opcode should be 0 (for i8 operations)
668 ///    or 1 (for i16,i32,i64 operations).
669 class ITy<bits<8> opcode, Format f, X86TypeInfo typeinfo, dag outs, dag ins,
670           string mnemonic, string args, list<dag> pattern,
671           InstrItinClass itin = IIC_BIN_NONMEM>
672   : I<{opcode{7}, opcode{6}, opcode{5}, opcode{4},
673        opcode{3}, opcode{2}, opcode{1}, typeinfo.HasOddOpcode },
674       f, outs, ins,
675       !strconcat(mnemonic, "{", typeinfo.InstrSuffix, "}\t", args), pattern,
676       itin> {
677
678   // Infer instruction prefixes from type info.
679   let OpSize = typeinfo.OpSize;
680   let hasREX_WPrefix  = typeinfo.HasREX_WPrefix;
681 }
682
683 // BinOpRR - Instructions like "add reg, reg, reg".
684 class BinOpRR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
685               dag outlist, list<dag> pattern, InstrItinClass itin,
686               Format f = MRMDestReg>
687   : ITy<opcode, f, typeinfo, outlist,
688         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
689         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
690     Sched<[WriteALU]>;
691
692 // BinOpRR_F - Instructions like "cmp reg, Reg", where the pattern has
693 // just a EFLAGS as a result.
694 class BinOpRR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
695                 SDPatternOperator opnode, Format f = MRMDestReg>
696   : BinOpRR<opcode, mnemonic, typeinfo, (outs),
697             [(set EFLAGS,
698                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
699             IIC_BIN_NONMEM, f>;
700
701 // BinOpRR_RF - Instructions like "add reg, reg, reg", where the pattern has
702 // both a regclass and EFLAGS as a result.
703 class BinOpRR_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
704                  SDNode opnode>
705   : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
706             [(set typeinfo.RegClass:$dst, EFLAGS,
707                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))],
708                   IIC_BIN_NONMEM>;
709
710 // BinOpRR_RFF - Instructions like "adc reg, reg, reg", where the pattern has
711 // both a regclass and EFLAGS as a result, and has EFLAGS as input.
712 class BinOpRR_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
713                   SDNode opnode>
714   : BinOpRR<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
715             [(set typeinfo.RegClass:$dst, EFLAGS,
716                   (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2,
717                           EFLAGS))], IIC_BIN_CARRY_NONMEM>;
718
719 // BinOpRR_Rev - Instructions like "add reg, reg, reg" (reversed encoding).
720 class BinOpRR_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
721                  InstrItinClass itin = IIC_BIN_NONMEM>
722   : ITy<opcode, MRMSrcReg, typeinfo,
723         (outs typeinfo.RegClass:$dst),
724         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
725         mnemonic, "{$src2, $dst|$dst, $src2}", [], itin>,
726     Sched<[WriteALU]> {
727   // The disassembler should know about this, but not the asmparser.
728   let isCodeGenOnly = 1;
729   let ForceDisassemble = 1;
730   let hasSideEffects = 0;
731 }
732
733 // BinOpRR_RDD_Rev - Instructions like "adc reg, reg, reg" (reversed encoding).
734 class BinOpRR_RFF_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
735   : BinOpRR_Rev<opcode, mnemonic, typeinfo, IIC_BIN_CARRY_NONMEM>;
736
737 // BinOpRR_F_Rev - Instructions like "cmp reg, reg" (reversed encoding).
738 class BinOpRR_F_Rev<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo>
739   : ITy<opcode, MRMSrcReg, typeinfo, (outs),
740         (ins typeinfo.RegClass:$src1, typeinfo.RegClass:$src2),
741         mnemonic, "{$src2, $src1|$src1, $src2}", [], IIC_BIN_NONMEM>,
742     Sched<[WriteALU]> {
743   // The disassembler should know about this, but not the asmparser.
744   let isCodeGenOnly = 1;
745   let ForceDisassemble = 1;
746   let hasSideEffects = 0;
747 }
748
749 // BinOpRM - Instructions like "add reg, reg, [mem]".
750 class BinOpRM<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
751               dag outlist, list<dag> pattern,
752               InstrItinClass itin = IIC_BIN_MEM>
753   : ITy<opcode, MRMSrcMem, typeinfo, outlist,
754         (ins typeinfo.RegClass:$src1, typeinfo.MemOperand:$src2),
755         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
756     Sched<[WriteALULd, ReadAfterLd]>;
757
758 // BinOpRM_R - Instructions like "add reg, reg, [mem]".
759 class BinOpRM_R<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
760               SDNode opnode>
761   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
762             [(set typeinfo.RegClass:$dst,
763             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
764
765 // BinOpRM_F - Instructions like "cmp reg, [mem]".
766 class BinOpRM_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
767               SDPatternOperator opnode>
768   : BinOpRM<opcode, mnemonic, typeinfo, (outs),
769             [(set EFLAGS,
770             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
771
772 // BinOpRM_RF - Instructions like "add reg, reg, [mem]".
773 class BinOpRM_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
774                  SDNode opnode>
775   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
776             [(set typeinfo.RegClass:$dst, EFLAGS,
777             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2)))]>;
778
779 // BinOpRM_RFF - Instructions like "adc reg, reg, [mem]".
780 class BinOpRM_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
781                  SDNode opnode>
782   : BinOpRM<opcode, mnemonic, typeinfo, (outs typeinfo.RegClass:$dst),
783             [(set typeinfo.RegClass:$dst, EFLAGS,
784             (opnode typeinfo.RegClass:$src1, (typeinfo.LoadNode addr:$src2),
785                     EFLAGS))], IIC_BIN_CARRY_MEM>;
786
787 // BinOpRI - Instructions like "add reg, reg, imm".
788 class BinOpRI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
789               Format f, dag outlist, list<dag> pattern,
790               InstrItinClass itin = IIC_BIN_NONMEM>
791   : ITy<opcode, f, typeinfo, outlist,
792         (ins typeinfo.RegClass:$src1, typeinfo.ImmOperand:$src2),
793         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
794     Sched<[WriteALU]> {
795   let ImmT = typeinfo.ImmEncoding;
796 }
797
798 // BinOpRI_F - Instructions like "cmp reg, imm".
799 class BinOpRI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
800                 SDPatternOperator opnode, Format f>
801   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs),
802             [(set EFLAGS,
803                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
804
805 // BinOpRI_RF - Instructions like "add reg, reg, imm".
806 class BinOpRI_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
807                  SDNode opnode, Format f>
808   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
809             [(set typeinfo.RegClass:$dst, EFLAGS,
810                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2))]>;
811 // BinOpRI_RFF - Instructions like "adc reg, reg, imm".
812 class BinOpRI_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
813                  SDNode opnode, Format f>
814   : BinOpRI<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
815             [(set typeinfo.RegClass:$dst, EFLAGS,
816                 (opnode typeinfo.RegClass:$src1, typeinfo.ImmOperator:$src2,
817                         EFLAGS))], IIC_BIN_CARRY_NONMEM>;
818
819 // BinOpRI8 - Instructions like "add reg, reg, imm8".
820 class BinOpRI8<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
821                Format f, dag outlist, list<dag> pattern,
822                InstrItinClass itin = IIC_BIN_NONMEM>
823   : ITy<opcode, f, typeinfo, outlist,
824         (ins typeinfo.RegClass:$src1, typeinfo.Imm8Operand:$src2),
825         mnemonic, "{$src2, $src1|$src1, $src2}", pattern, itin>,
826     Sched<[WriteALU]> {
827   let ImmT = Imm8; // Always 8-bit immediate.
828 }
829
830 // BinOpRI8_F - Instructions like "cmp reg, imm8".
831 class BinOpRI8_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
832                   SDPatternOperator opnode, Format f>
833   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs),
834              [(set EFLAGS,
835                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
836
837 // BinOpRI8_RF - Instructions like "add reg, reg, imm8".
838 class BinOpRI8_RF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
839                   SDPatternOperator opnode, Format f>
840   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
841              [(set typeinfo.RegClass:$dst, EFLAGS,
842                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2))]>;
843
844 // BinOpRI8_RFF - Instructions like "adc reg, reg, imm8".
845 class BinOpRI8_RFF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
846                    SDPatternOperator opnode, Format f>
847   : BinOpRI8<opcode, mnemonic, typeinfo, f, (outs typeinfo.RegClass:$dst),
848              [(set typeinfo.RegClass:$dst, EFLAGS,
849                (opnode typeinfo.RegClass:$src1, typeinfo.Imm8Operator:$src2,
850                        EFLAGS))], IIC_BIN_CARRY_NONMEM>;
851
852 // BinOpMR - Instructions like "add [mem], reg".
853 class BinOpMR<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
854               list<dag> pattern, InstrItinClass itin = IIC_BIN_MEM>
855   : ITy<opcode, MRMDestMem, typeinfo,
856         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.RegClass:$src),
857         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
858     Sched<[WriteALULd, WriteRMW]>;
859
860 // BinOpMR_RMW - Instructions like "add [mem], reg".
861 class BinOpMR_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
862                   SDNode opnode>
863   : BinOpMR<opcode, mnemonic, typeinfo,
864           [(store (opnode (load addr:$dst), typeinfo.RegClass:$src), addr:$dst),
865            (implicit EFLAGS)]>;
866
867 // BinOpMR_RMW_FF - Instructions like "adc [mem], reg".
868 class BinOpMR_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
869                     SDNode opnode>
870   : BinOpMR<opcode, mnemonic, typeinfo,
871           [(store (opnode (load addr:$dst), typeinfo.RegClass:$src, EFLAGS),
872                   addr:$dst),
873            (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
874
875 // BinOpMR_F - Instructions like "cmp [mem], reg".
876 class BinOpMR_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
877                   SDNode opnode>
878   : BinOpMR<opcode, mnemonic, typeinfo,
879             [(set EFLAGS, (opnode (load addr:$dst), typeinfo.RegClass:$src))]>;
880
881 // BinOpMI - Instructions like "add [mem], imm".
882 class BinOpMI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
883               Format f, list<dag> pattern,
884               InstrItinClass itin = IIC_BIN_MEM>
885   : ITy<opcode, f, typeinfo,
886         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.ImmOperand:$src),
887         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
888     Sched<[WriteALULd, WriteRMW]> {
889   let ImmT = typeinfo.ImmEncoding;
890 }
891
892 // BinOpMI_RMW - Instructions like "add [mem], imm".
893 class BinOpMI_RMW<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
894                   SDNode opnode, Format f>
895   : BinOpMI<opcode, mnemonic, typeinfo, f,
896             [(store (opnode (typeinfo.VT (load addr:$dst)),
897                             typeinfo.ImmOperator:$src), addr:$dst),
898              (implicit EFLAGS)]>;
899 // BinOpMI_RMW_FF - Instructions like "adc [mem], imm".
900 class BinOpMI_RMW_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
901                      SDNode opnode, Format f>
902   : BinOpMI<opcode, mnemonic, typeinfo, f,
903             [(store (opnode (typeinfo.VT (load addr:$dst)),
904                             typeinfo.ImmOperator:$src, EFLAGS), addr:$dst),
905              (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
906
907 // BinOpMI_F - Instructions like "cmp [mem], imm".
908 class BinOpMI_F<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
909                 SDPatternOperator opnode, Format f>
910   : BinOpMI<opcode, mnemonic, typeinfo, f,
911             [(set EFLAGS, (opnode (typeinfo.VT (load addr:$dst)),
912                                                typeinfo.ImmOperator:$src))]>;
913
914 // BinOpMI8 - Instructions like "add [mem], imm8".
915 class BinOpMI8<string mnemonic, X86TypeInfo typeinfo,
916                Format f, list<dag> pattern,
917                InstrItinClass itin = IIC_BIN_MEM>
918   : ITy<0x82, f, typeinfo,
919         (outs), (ins typeinfo.MemOperand:$dst, typeinfo.Imm8Operand:$src),
920         mnemonic, "{$src, $dst|$dst, $src}", pattern, itin>,
921     Sched<[WriteALULd, WriteRMW]> {
922   let ImmT = Imm8; // Always 8-bit immediate.
923 }
924
925 // BinOpMI8_RMW - Instructions like "add [mem], imm8".
926 class BinOpMI8_RMW<string mnemonic, X86TypeInfo typeinfo,
927                    SDPatternOperator opnode, Format f>
928   : BinOpMI8<mnemonic, typeinfo, f,
929              [(store (opnode (load addr:$dst),
930                              typeinfo.Imm8Operator:$src), addr:$dst),
931               (implicit EFLAGS)]>;
932
933 // BinOpMI8_RMW_FF - Instructions like "adc [mem], imm8".
934 class BinOpMI8_RMW_FF<string mnemonic, X86TypeInfo typeinfo,
935                       SDPatternOperator opnode, Format f>
936   : BinOpMI8<mnemonic, typeinfo, f,
937              [(store (opnode (load addr:$dst),
938                              typeinfo.Imm8Operator:$src, EFLAGS), addr:$dst),
939               (implicit EFLAGS)], IIC_BIN_CARRY_MEM>;
940
941 // BinOpMI8_F - Instructions like "cmp [mem], imm8".
942 class BinOpMI8_F<string mnemonic, X86TypeInfo typeinfo,
943                  SDPatternOperator opnode, Format f>
944   : BinOpMI8<mnemonic, typeinfo, f,
945              [(set EFLAGS, (opnode (load addr:$dst),
946                                    typeinfo.Imm8Operator:$src))]>;
947
948 // BinOpAI - Instructions like "add %eax, %eax, imm", that imp-def EFLAGS.
949 class BinOpAI<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
950               Register areg, string operands,
951               InstrItinClass itin = IIC_BIN_NONMEM>
952   : ITy<opcode, RawFrm, typeinfo,
953         (outs), (ins typeinfo.ImmOperand:$src),
954         mnemonic, operands, [], itin>, Sched<[WriteALU]> {
955   let ImmT = typeinfo.ImmEncoding;
956   let Uses = [areg];
957   let Defs = [areg, EFLAGS];
958   let hasSideEffects = 0;
959 }
960
961 // BinOpAI_FF - Instructions like "adc %eax, %eax, imm", that implicitly define
962 // and use EFLAGS.
963 class BinOpAI_FF<bits<8> opcode, string mnemonic, X86TypeInfo typeinfo,
964                 Register areg, string operands>
965   : BinOpAI<opcode, mnemonic, typeinfo, areg, operands,
966             IIC_BIN_CARRY_NONMEM> {
967   let Uses = [areg, EFLAGS];
968 }
969
970 /// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
971 /// defined with "(set GPR:$dst, EFLAGS, (...".
972 ///
973 /// It would be nice to get rid of the second and third argument here, but
974 /// tblgen can't handle dependent type references aggressively enough: PR8330
975 multiclass ArithBinOp_RF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
976                          string mnemonic, Format RegMRM, Format MemMRM,
977                          SDNode opnodeflag, SDNode opnode,
978                          bit CommutableRR, bit ConvertibleToThreeAddress> {
979   let Defs = [EFLAGS] in {
980     let Constraints = "$src1 = $dst" in {
981       let isCommutable = CommutableRR in {
982         def NAME#8rr  : BinOpRR_RF<BaseOpc, mnemonic, Xi8 , opnodeflag>;
983         let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
984           def NAME#16rr : BinOpRR_RF<BaseOpc, mnemonic, Xi16, opnodeflag>;
985           def NAME#32rr : BinOpRR_RF<BaseOpc, mnemonic, Xi32, opnodeflag>;
986           def NAME#64rr : BinOpRR_RF<BaseOpc, mnemonic, Xi64, opnodeflag>;
987         } // isConvertibleToThreeAddress
988       } // isCommutable
989
990       def NAME#8rr_REV  : BinOpRR_Rev<BaseOpc2, mnemonic, Xi8>;
991       def NAME#16rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi16>;
992       def NAME#32rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi32>;
993       def NAME#64rr_REV : BinOpRR_Rev<BaseOpc2, mnemonic, Xi64>;
994
995       def NAME#8rm   : BinOpRM_RF<BaseOpc2, mnemonic, Xi8 , opnodeflag>;
996       def NAME#16rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi16, opnodeflag>;
997       def NAME#32rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi32, opnodeflag>;
998       def NAME#64rm  : BinOpRM_RF<BaseOpc2, mnemonic, Xi64, opnodeflag>;
999
1000       def NAME#8ri   : BinOpRI_RF<0x80, mnemonic, Xi8 , opnodeflag, RegMRM>;
1001
1002       let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1003         // NOTE: These are order specific, we want the ri8 forms to be listed
1004         // first so that they are slightly preferred to the ri forms.
1005         def NAME#16ri8 : BinOpRI8_RF<0x82, mnemonic, Xi16, opnodeflag, RegMRM>;
1006         def NAME#32ri8 : BinOpRI8_RF<0x82, mnemonic, Xi32, opnodeflag, RegMRM>;
1007         def NAME#64ri8 : BinOpRI8_RF<0x82, mnemonic, Xi64, opnodeflag, RegMRM>;
1008
1009         def NAME#16ri  : BinOpRI_RF<0x80, mnemonic, Xi16, opnodeflag, RegMRM>;
1010         def NAME#32ri  : BinOpRI_RF<0x80, mnemonic, Xi32, opnodeflag, RegMRM>;
1011         def NAME#64ri32: BinOpRI_RF<0x80, mnemonic, Xi64, opnodeflag, RegMRM>;
1012       }
1013     } // Constraints = "$src1 = $dst"
1014
1015     def NAME#8mr    : BinOpMR_RMW<BaseOpc, mnemonic, Xi8 , opnode>;
1016     def NAME#16mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi16, opnode>;
1017     def NAME#32mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi32, opnode>;
1018     def NAME#64mr   : BinOpMR_RMW<BaseOpc, mnemonic, Xi64, opnode>;
1019
1020     // NOTE: These are order specific, we want the mi8 forms to be listed
1021     // first so that they are slightly preferred to the mi forms.
1022     def NAME#16mi8  : BinOpMI8_RMW<mnemonic, Xi16, opnode, MemMRM>;
1023     def NAME#32mi8  : BinOpMI8_RMW<mnemonic, Xi32, opnode, MemMRM>;
1024     def NAME#64mi8  : BinOpMI8_RMW<mnemonic, Xi64, opnode, MemMRM>;
1025
1026     def NAME#8mi    : BinOpMI_RMW<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1027     def NAME#16mi   : BinOpMI_RMW<0x80, mnemonic, Xi16, opnode, MemMRM>;
1028     def NAME#32mi   : BinOpMI_RMW<0x80, mnemonic, Xi32, opnode, MemMRM>;
1029     def NAME#64mi32 : BinOpMI_RMW<0x80, mnemonic, Xi64, opnode, MemMRM>;
1030
1031     // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1032     // not in 64-bit mode.
1033     let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1034         hasSideEffects = 0 in {
1035       let Constraints = "$src1 = $dst" in
1036         def NAME#8ri8 : BinOpRI8_RF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1037       let mayLoad = 1, mayStore = 1 in
1038         def NAME#8mi8 : BinOpMI8_RMW<mnemonic, Xi8, null_frag, MemMRM>;
1039     }
1040   } // Defs = [EFLAGS]
1041
1042   def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1043                            "{$src, %al|al, $src}">;
1044   def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1045                            "{$src, %ax|ax, $src}">;
1046   def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1047                            "{$src, %eax|eax, $src}">;
1048   def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1049                            "{$src, %rax|rax, $src}">;
1050 }
1051
1052 /// ArithBinOp_RFF - This is an arithmetic binary operator where the pattern is
1053 /// defined with "(set GPR:$dst, EFLAGS, (node LHS, RHS, EFLAGS))" like ADC and
1054 /// SBB.
1055 ///
1056 /// It would be nice to get rid of the second and third argument here, but
1057 /// tblgen can't handle dependent type references aggressively enough: PR8330
1058 multiclass ArithBinOp_RFF<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1059                           string mnemonic, Format RegMRM, Format MemMRM,
1060                           SDNode opnode, bit CommutableRR,
1061                            bit ConvertibleToThreeAddress> {
1062   let Uses = [EFLAGS], Defs = [EFLAGS] in {
1063     let Constraints = "$src1 = $dst" in {
1064       let isCommutable = CommutableRR in {
1065         def NAME#8rr  : BinOpRR_RFF<BaseOpc, mnemonic, Xi8 , opnode>;
1066         let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1067           def NAME#16rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi16, opnode>;
1068           def NAME#32rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi32, opnode>;
1069           def NAME#64rr : BinOpRR_RFF<BaseOpc, mnemonic, Xi64, opnode>;
1070         } // isConvertibleToThreeAddress
1071       } // isCommutable
1072
1073       def NAME#8rr_REV  : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi8>;
1074       def NAME#16rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi16>;
1075       def NAME#32rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi32>;
1076       def NAME#64rr_REV : BinOpRR_RFF_Rev<BaseOpc2, mnemonic, Xi64>;
1077
1078       def NAME#8rm   : BinOpRM_RFF<BaseOpc2, mnemonic, Xi8 , opnode>;
1079       def NAME#16rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi16, opnode>;
1080       def NAME#32rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi32, opnode>;
1081       def NAME#64rm  : BinOpRM_RFF<BaseOpc2, mnemonic, Xi64, opnode>;
1082
1083       def NAME#8ri   : BinOpRI_RFF<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1084
1085       let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1086         // NOTE: These are order specific, we want the ri8 forms to be listed
1087         // first so that they are slightly preferred to the ri forms.
1088         def NAME#16ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi16, opnode, RegMRM>;
1089         def NAME#32ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi32, opnode, RegMRM>;
1090         def NAME#64ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi64, opnode, RegMRM>;
1091
1092         def NAME#16ri  : BinOpRI_RFF<0x80, mnemonic, Xi16, opnode, RegMRM>;
1093         def NAME#32ri  : BinOpRI_RFF<0x80, mnemonic, Xi32, opnode, RegMRM>;
1094         def NAME#64ri32: BinOpRI_RFF<0x80, mnemonic, Xi64, opnode, RegMRM>;
1095       }
1096     } // Constraints = "$src1 = $dst"
1097
1098     def NAME#8mr    : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi8 , opnode>;
1099     def NAME#16mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi16, opnode>;
1100     def NAME#32mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi32, opnode>;
1101     def NAME#64mr   : BinOpMR_RMW_FF<BaseOpc, mnemonic, Xi64, opnode>;
1102
1103     // NOTE: These are order specific, we want the mi8 forms to be listed
1104     // first so that they are slightly preferred to the mi forms.
1105     def NAME#16mi8  : BinOpMI8_RMW_FF<mnemonic, Xi16, opnode, MemMRM>;
1106     def NAME#32mi8  : BinOpMI8_RMW_FF<mnemonic, Xi32, opnode, MemMRM>;
1107     def NAME#64mi8  : BinOpMI8_RMW_FF<mnemonic, Xi64, opnode, MemMRM>;
1108
1109     def NAME#8mi    : BinOpMI_RMW_FF<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1110     def NAME#16mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi16, opnode, MemMRM>;
1111     def NAME#32mi   : BinOpMI_RMW_FF<0x80, mnemonic, Xi32, opnode, MemMRM>;
1112     def NAME#64mi32 : BinOpMI_RMW_FF<0x80, mnemonic, Xi64, opnode, MemMRM>;
1113
1114     // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1115     // not in 64-bit mode.
1116     let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1117         hasSideEffects = 0 in {
1118       let Constraints = "$src1 = $dst" in
1119         def NAME#8ri8 : BinOpRI8_RFF<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1120       let mayLoad = 1, mayStore = 1 in
1121         def NAME#8mi8 : BinOpMI8_RMW_FF<mnemonic, Xi8, null_frag, MemMRM>;
1122     }
1123   } // Uses = [EFLAGS], Defs = [EFLAGS]
1124
1125   def NAME#8i8   : BinOpAI_FF<BaseOpc4, mnemonic, Xi8 , AL,
1126                               "{$src, %al|al, $src}">;
1127   def NAME#16i16 : BinOpAI_FF<BaseOpc4, mnemonic, Xi16, AX,
1128                               "{$src, %ax|ax, $src}">;
1129   def NAME#32i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi32, EAX,
1130                               "{$src, %eax|eax, $src}">;
1131   def NAME#64i32 : BinOpAI_FF<BaseOpc4, mnemonic, Xi64, RAX,
1132                               "{$src, %rax|rax, $src}">;
1133 }
1134
1135 /// ArithBinOp_F - This is an arithmetic binary operator where the pattern is
1136 /// defined with "(set EFLAGS, (...".  It would be really nice to find a way
1137 /// to factor this with the other ArithBinOp_*.
1138 ///
1139 multiclass ArithBinOp_F<bits<8> BaseOpc, bits<8> BaseOpc2, bits<8> BaseOpc4,
1140                         string mnemonic, Format RegMRM, Format MemMRM,
1141                         SDNode opnode,
1142                         bit CommutableRR, bit ConvertibleToThreeAddress> {
1143   let Defs = [EFLAGS] in {
1144     let isCommutable = CommutableRR in {
1145       def NAME#8rr  : BinOpRR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1146       let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1147         def NAME#16rr : BinOpRR_F<BaseOpc, mnemonic, Xi16, opnode>;
1148         def NAME#32rr : BinOpRR_F<BaseOpc, mnemonic, Xi32, opnode>;
1149         def NAME#64rr : BinOpRR_F<BaseOpc, mnemonic, Xi64, opnode>;
1150       }
1151     } // isCommutable
1152
1153     def NAME#8rr_REV  : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi8>;
1154     def NAME#16rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi16>;
1155     def NAME#32rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi32>;
1156     def NAME#64rr_REV : BinOpRR_F_Rev<BaseOpc2, mnemonic, Xi64>;
1157
1158     def NAME#8rm   : BinOpRM_F<BaseOpc2, mnemonic, Xi8 , opnode>;
1159     def NAME#16rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi16, opnode>;
1160     def NAME#32rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi32, opnode>;
1161     def NAME#64rm  : BinOpRM_F<BaseOpc2, mnemonic, Xi64, opnode>;
1162
1163     def NAME#8ri   : BinOpRI_F<0x80, mnemonic, Xi8 , opnode, RegMRM>;
1164
1165     let isConvertibleToThreeAddress = ConvertibleToThreeAddress in {
1166       // NOTE: These are order specific, we want the ri8 forms to be listed
1167       // first so that they are slightly preferred to the ri forms.
1168       def NAME#16ri8 : BinOpRI8_F<0x82, mnemonic, Xi16, opnode, RegMRM>;
1169       def NAME#32ri8 : BinOpRI8_F<0x82, mnemonic, Xi32, opnode, RegMRM>;
1170       def NAME#64ri8 : BinOpRI8_F<0x82, mnemonic, Xi64, opnode, RegMRM>;
1171
1172       def NAME#16ri  : BinOpRI_F<0x80, mnemonic, Xi16, opnode, RegMRM>;
1173       def NAME#32ri  : BinOpRI_F<0x80, mnemonic, Xi32, opnode, RegMRM>;
1174       def NAME#64ri32: BinOpRI_F<0x80, mnemonic, Xi64, opnode, RegMRM>;
1175     }
1176
1177     def NAME#8mr    : BinOpMR_F<BaseOpc, mnemonic, Xi8 , opnode>;
1178     def NAME#16mr   : BinOpMR_F<BaseOpc, mnemonic, Xi16, opnode>;
1179     def NAME#32mr   : BinOpMR_F<BaseOpc, mnemonic, Xi32, opnode>;
1180     def NAME#64mr   : BinOpMR_F<BaseOpc, mnemonic, Xi64, opnode>;
1181
1182     // NOTE: These are order specific, we want the mi8 forms to be listed
1183     // first so that they are slightly preferred to the mi forms.
1184     def NAME#16mi8  : BinOpMI8_F<mnemonic, Xi16, opnode, MemMRM>;
1185     def NAME#32mi8  : BinOpMI8_F<mnemonic, Xi32, opnode, MemMRM>;
1186     def NAME#64mi8  : BinOpMI8_F<mnemonic, Xi64, opnode, MemMRM>;
1187
1188     def NAME#8mi    : BinOpMI_F<0x80, mnemonic, Xi8 , opnode, MemMRM>;
1189     def NAME#16mi   : BinOpMI_F<0x80, mnemonic, Xi16, opnode, MemMRM>;
1190     def NAME#32mi   : BinOpMI_F<0x80, mnemonic, Xi32, opnode, MemMRM>;
1191     def NAME#64mi32 : BinOpMI_F<0x80, mnemonic, Xi64, opnode, MemMRM>;
1192
1193     // These are for the disassembler since 0x82 opcode behaves like 0x80, but
1194     // not in 64-bit mode.
1195     let Predicates = [Not64BitMode], isCodeGenOnly = 1, ForceDisassemble = 1,
1196         hasSideEffects = 0 in {
1197       def NAME#8ri8 : BinOpRI8_F<0x82, mnemonic, Xi8, null_frag, RegMRM>;
1198       let mayLoad = 1 in
1199         def NAME#8mi8 : BinOpMI8_F<mnemonic, Xi8, null_frag, MemMRM>;
1200     }
1201   } // Defs = [EFLAGS]
1202
1203   def NAME#8i8   : BinOpAI<BaseOpc4, mnemonic, Xi8 , AL,
1204                            "{$src, %al|al, $src}">;
1205   def NAME#16i16 : BinOpAI<BaseOpc4, mnemonic, Xi16, AX,
1206                            "{$src, %ax|ax, $src}">;
1207   def NAME#32i32 : BinOpAI<BaseOpc4, mnemonic, Xi32, EAX,
1208                            "{$src, %eax|eax, $src}">;
1209   def NAME#64i32 : BinOpAI<BaseOpc4, mnemonic, Xi64, RAX,
1210                            "{$src, %rax|rax, $src}">;
1211 }
1212
1213
1214 defm AND : ArithBinOp_RF<0x20, 0x22, 0x24, "and", MRM4r, MRM4m,
1215                          X86and_flag, and, 1, 0>;
1216 defm OR  : ArithBinOp_RF<0x08, 0x0A, 0x0C, "or", MRM1r, MRM1m,
1217                          X86or_flag, or, 1, 0>;
1218 defm XOR : ArithBinOp_RF<0x30, 0x32, 0x34, "xor", MRM6r, MRM6m,
1219                          X86xor_flag, xor, 1, 0>;
1220 defm ADD : ArithBinOp_RF<0x00, 0x02, 0x04, "add", MRM0r, MRM0m,
1221                          X86add_flag, add, 1, 1>;
1222 let isCompare = 1 in {
1223 defm SUB : ArithBinOp_RF<0x28, 0x2A, 0x2C, "sub", MRM5r, MRM5m,
1224                          X86sub_flag, sub, 0, 0>;
1225 }
1226
1227 // Arithmetic.
1228 defm ADC : ArithBinOp_RFF<0x10, 0x12, 0x14, "adc", MRM2r, MRM2m, X86adc_flag,
1229                           1, 0>;
1230 defm SBB : ArithBinOp_RFF<0x18, 0x1A, 0x1C, "sbb", MRM3r, MRM3m, X86sbb_flag,
1231                           0, 0>;
1232
1233 let isCompare = 1 in {
1234 defm CMP : ArithBinOp_F<0x38, 0x3A, 0x3C, "cmp", MRM7r, MRM7m, X86cmp, 0, 0>;
1235 }
1236
1237
1238 //===----------------------------------------------------------------------===//
1239 // Semantically, test instructions are similar like AND, except they don't
1240 // generate a result.  From an encoding perspective, they are very different:
1241 // they don't have all the usual imm8 and REV forms, and are encoded into a
1242 // different space.
1243 def X86testpat : PatFrag<(ops node:$lhs, node:$rhs),
1244                          (X86cmp (and_su node:$lhs, node:$rhs), 0)>;
1245
1246 let isCompare = 1 in {
1247   let Defs = [EFLAGS] in {
1248     let isCommutable = 1 in {
1249       def TEST8rr  : BinOpRR_F<0x84, "test", Xi8 , X86testpat, MRMSrcReg>;
1250       def TEST16rr : BinOpRR_F<0x84, "test", Xi16, X86testpat, MRMSrcReg>;
1251       def TEST32rr : BinOpRR_F<0x84, "test", Xi32, X86testpat, MRMSrcReg>;
1252       def TEST64rr : BinOpRR_F<0x84, "test", Xi64, X86testpat, MRMSrcReg>;
1253     } // isCommutable
1254
1255     def TEST8rm    : BinOpRM_F<0x84, "test", Xi8 , X86testpat>;
1256     def TEST16rm   : BinOpRM_F<0x84, "test", Xi16, X86testpat>;
1257     def TEST32rm   : BinOpRM_F<0x84, "test", Xi32, X86testpat>;
1258     def TEST64rm   : BinOpRM_F<0x84, "test", Xi64, X86testpat>;
1259
1260     def TEST8ri    : BinOpRI_F<0xF6, "test", Xi8 , X86testpat, MRM0r>;
1261     def TEST16ri   : BinOpRI_F<0xF6, "test", Xi16, X86testpat, MRM0r>;
1262     def TEST32ri   : BinOpRI_F<0xF6, "test", Xi32, X86testpat, MRM0r>;
1263     def TEST64ri32 : BinOpRI_F<0xF6, "test", Xi64, X86testpat, MRM0r>;
1264
1265     def TEST8mi    : BinOpMI_F<0xF6, "test", Xi8 , X86testpat, MRM0m>;
1266     def TEST16mi   : BinOpMI_F<0xF6, "test", Xi16, X86testpat, MRM0m>;
1267     def TEST32mi   : BinOpMI_F<0xF6, "test", Xi32, X86testpat, MRM0m>;
1268     def TEST64mi32 : BinOpMI_F<0xF6, "test", Xi64, X86testpat, MRM0m>;
1269
1270     // When testing the result of EXTRACT_SUBREG sub_8bit_hi, make sure the
1271     // register class is constrained to GR8_NOREX. This pseudo is explicitly
1272     // marked side-effect free, since it doesn't have an isel pattern like
1273     // other test instructions.
1274     let isPseudo = 1, hasSideEffects = 0 in
1275     def TEST8ri_NOREX : I<0, Pseudo, (outs), (ins GR8_NOREX:$src, i8imm:$mask),
1276                           "", [], IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1277   } // Defs = [EFLAGS]
1278
1279   def TEST8i8    : BinOpAI<0xA8, "test", Xi8 , AL,
1280                            "{$src, %al|al, $src}">;
1281   def TEST16i16  : BinOpAI<0xA8, "test", Xi16, AX,
1282                            "{$src, %ax|ax, $src}">;
1283   def TEST32i32  : BinOpAI<0xA8, "test", Xi32, EAX,
1284                            "{$src, %eax|eax, $src}">;
1285   def TEST64i32  : BinOpAI<0xA8, "test", Xi64, RAX,
1286                            "{$src, %rax|rax, $src}">;
1287 } // isCompare
1288
1289 //===----------------------------------------------------------------------===//
1290 // ANDN Instruction
1291 //
1292 multiclass bmi_andn<string mnemonic, RegisterClass RC, X86MemOperand x86memop,
1293                     PatFrag ld_frag> {
1294   def rr : I<0xF2, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1295             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1296             [(set RC:$dst, EFLAGS, (X86and_flag (not RC:$src1), RC:$src2))],
1297             IIC_BIN_NONMEM>, Sched<[WriteALU]>;
1298   def rm : I<0xF2, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1299             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1300             [(set RC:$dst, EFLAGS,
1301              (X86and_flag (not RC:$src1), (ld_frag addr:$src2)))], IIC_BIN_MEM>,
1302            Sched<[WriteALULd, ReadAfterLd]>;
1303 }
1304
1305 let Predicates = [HasBMI], Defs = [EFLAGS] in {
1306   defm ANDN32 : bmi_andn<"andn{l}", GR32, i32mem, loadi32>, T8PS, VEX_4V;
1307   defm ANDN64 : bmi_andn<"andn{q}", GR64, i64mem, loadi64>, T8PS, VEX_4V, VEX_W;
1308 }
1309
1310 let Predicates = [HasBMI] in {
1311   def : Pat<(and (not GR32:$src1), GR32:$src2),
1312             (ANDN32rr GR32:$src1, GR32:$src2)>;
1313   def : Pat<(and (not GR64:$src1), GR64:$src2),
1314             (ANDN64rr GR64:$src1, GR64:$src2)>;
1315   def : Pat<(and (not GR32:$src1), (loadi32 addr:$src2)),
1316             (ANDN32rm GR32:$src1, addr:$src2)>;
1317   def : Pat<(and (not GR64:$src1), (loadi64 addr:$src2)),
1318             (ANDN64rm GR64:$src1, addr:$src2)>;
1319 }
1320
1321 //===----------------------------------------------------------------------===//
1322 // MULX Instruction
1323 //
1324 multiclass bmi_mulx<string mnemonic, RegisterClass RC, X86MemOperand x86memop> {
1325 let hasSideEffects = 0 in {
1326   let isCommutable = 1 in
1327   def rr : I<0xF6, MRMSrcReg, (outs RC:$dst1, RC:$dst2), (ins RC:$src),
1328              !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1329              [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMul, WriteIMulH]>;
1330
1331   let mayLoad = 1 in
1332   def rm : I<0xF6, MRMSrcMem, (outs RC:$dst1, RC:$dst2), (ins x86memop:$src),
1333              !strconcat(mnemonic, "\t{$src, $dst2, $dst1|$dst1, $dst2, $src}"),
1334              [], IIC_MUL8>, T8XD, VEX_4V, Sched<[WriteIMulLd, WriteIMulH]>;
1335 }
1336 }
1337
1338 let Predicates = [HasBMI2] in {
1339   let Uses = [EDX] in
1340     defm MULX32 : bmi_mulx<"mulx{l}", GR32, i32mem>;
1341   let Uses = [RDX] in
1342     defm MULX64 : bmi_mulx<"mulx{q}", GR64, i64mem>, VEX_W;
1343 }
1344
1345 //===----------------------------------------------------------------------===//
1346 // ADCX Instruction
1347 //
1348 let Predicates = [HasADX], Defs = [EFLAGS], Uses = [EFLAGS],
1349     Constraints = "$src0 = $dst", AddedComplexity = 10 in {
1350   let SchedRW = [WriteALU] in {
1351   def ADCX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst),
1352              (ins GR32:$src0, GR32:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1353              [(set GR32:$dst, EFLAGS,
1354                  (X86adc_flag GR32:$src0, GR32:$src, EFLAGS))],
1355              IIC_BIN_CARRY_NONMEM>, T8PD;
1356   def ADCX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst),
1357              (ins GR64:$src0, GR64:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1358              [(set GR64:$dst, EFLAGS,
1359                  (X86adc_flag GR64:$src0, GR64:$src, EFLAGS))],
1360              IIC_BIN_CARRY_NONMEM>, T8PD;
1361   } // SchedRW
1362
1363   let mayLoad = 1, SchedRW = [WriteALULd] in {
1364   def ADCX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst),
1365              (ins GR32:$src0, i32mem:$src), "adcx{l}\t{$src, $dst|$dst, $src}",
1366              [(set GR32:$dst, EFLAGS,
1367                  (X86adc_flag GR32:$src0, (loadi32 addr:$src), EFLAGS))],
1368              IIC_BIN_CARRY_MEM>, T8PD;
1369
1370   def ADCX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst),
1371              (ins GR64:$src0, i64mem:$src), "adcx{q}\t{$src, $dst|$dst, $src}",
1372              [(set GR64:$dst, EFLAGS,
1373                  (X86adc_flag GR64:$src0, (loadi64 addr:$src), EFLAGS))],
1374              IIC_BIN_CARRY_MEM>, T8PD;
1375   }
1376 }
1377
1378 //===----------------------------------------------------------------------===//
1379 // ADOX Instruction
1380 //
1381 let Predicates = [HasADX], hasSideEffects = 0, Defs = [EFLAGS],
1382     Uses = [EFLAGS] in {
1383   let SchedRW = [WriteALU] in {
1384   def ADOX32rr : I<0xF6, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1385              "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1386
1387   def ADOX64rr : RI<0xF6, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1388              "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_NONMEM>, T8XS;
1389   } // SchedRW
1390
1391   let mayLoad = 1, SchedRW = [WriteALULd] in {
1392   def ADOX32rm : I<0xF6, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1393              "adox{l}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1394
1395   def ADOX64rm : RI<0xF6, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1396              "adox{q}\t{$src, $dst|$dst, $src}", [], IIC_BIN_MEM>, T8XS;
1397   }
1398 }