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