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