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