xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/X86InstrMisc.td (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1*06c3fb27SDimitry Andric//===-- X86InstrMisc.td - Misc X86 Instruction Definition -*- tablegen -*-===//
2*06c3fb27SDimitry Andric//
3*06c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*06c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5*06c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*06c3fb27SDimitry Andric//
7*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
8*06c3fb27SDimitry Andric//
9*06c3fb27SDimitry Andric// This file defining the misc X86 instructions.
10*06c3fb27SDimitry Andric//
11*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
12*06c3fb27SDimitry Andric
13*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
14*06c3fb27SDimitry Andric// Instruction list.
15*06c3fb27SDimitry Andric//
16*06c3fb27SDimitry Andric
17*06c3fb27SDimitry Andric// Nop
18*06c3fb27SDimitry Andriclet hasSideEffects = 0, SchedRW = [WriteNop] in {
19*06c3fb27SDimitry Andric  def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
20*06c3fb27SDimitry Andric  def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
21*06c3fb27SDimitry Andric                "nop{w}\t$zero", []>, TB, OpSize16;
22*06c3fb27SDimitry Andric  def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
23*06c3fb27SDimitry Andric                "nop{l}\t$zero", []>, TB, OpSize32;
24*06c3fb27SDimitry Andric  def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
25*06c3fb27SDimitry Andric                "nop{q}\t$zero", []>, TB, Requires<[In64BitMode]>;
26*06c3fb27SDimitry Andric  // Also allow register so we can assemble/disassemble
27*06c3fb27SDimitry Andric  def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
28*06c3fb27SDimitry Andric                 "nop{w}\t$zero", []>, TB, OpSize16;
29*06c3fb27SDimitry Andric  def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
30*06c3fb27SDimitry Andric                 "nop{l}\t$zero", []>, TB, OpSize32;
31*06c3fb27SDimitry Andric  def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
32*06c3fb27SDimitry Andric                  "nop{q}\t$zero", []>, TB, Requires<[In64BitMode]>;
33*06c3fb27SDimitry Andric}
34*06c3fb27SDimitry Andric
35*06c3fb27SDimitry Andric
36*06c3fb27SDimitry Andric// Constructing a stack frame.
37*06c3fb27SDimitry Andricdef ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
38*06c3fb27SDimitry Andric                 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
39*06c3fb27SDimitry Andric
40*06c3fb27SDimitry Andriclet SchedRW = [WriteALU] in {
41*06c3fb27SDimitry Andriclet Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
42*06c3fb27SDimitry Andricdef LEAVE    : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
43*06c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
44*06c3fb27SDimitry Andric
45*06c3fb27SDimitry Andriclet Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
46*06c3fb27SDimitry Andricdef LEAVE64  : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
47*06c3fb27SDimitry Andric                 Requires<[In64BitMode]>;
48*06c3fb27SDimitry Andric} // SchedRW
49*06c3fb27SDimitry Andric
50*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
51*06c3fb27SDimitry Andric//  Miscellaneous Instructions.
52*06c3fb27SDimitry Andric//
53*06c3fb27SDimitry Andric
54*06c3fb27SDimitry Andriclet isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
55*06c3fb27SDimitry Andric    SchedRW = [WriteSystem] in
56*06c3fb27SDimitry Andric  def Int_eh_sjlj_setup_dispatch
57*06c3fb27SDimitry Andric    : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
58*06c3fb27SDimitry Andric
59*06c3fb27SDimitry Andriclet Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
60*06c3fb27SDimitry Andriclet mayLoad = 1, SchedRW = [WriteLoad] in {
61*06c3fb27SDimitry Andricdef POP16r  : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
62*06c3fb27SDimitry Andric                OpSize16;
63*06c3fb27SDimitry Andricdef POP32r  : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
64*06c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
65*06c3fb27SDimitry Andric// Long form for the disassembler.
66*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
67*06c3fb27SDimitry Andricdef POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
68*06c3fb27SDimitry Andric                OpSize16;
69*06c3fb27SDimitry Andricdef POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
70*06c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
71*06c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
72*06c3fb27SDimitry Andric} // mayLoad, SchedRW
73*06c3fb27SDimitry Andriclet mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
74*06c3fb27SDimitry Andricdef POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
75*06c3fb27SDimitry Andric                OpSize16;
76*06c3fb27SDimitry Andricdef POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
77*06c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
78*06c3fb27SDimitry Andric} // mayStore, mayLoad, SchedRW
79*06c3fb27SDimitry Andric
80*06c3fb27SDimitry Andriclet mayStore = 1, SchedRW = [WriteStore] in {
81*06c3fb27SDimitry Andricdef PUSH16r  : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
82*06c3fb27SDimitry Andric                 OpSize16;
83*06c3fb27SDimitry Andricdef PUSH32r  : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
84*06c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
85*06c3fb27SDimitry Andric// Long form for the disassembler.
86*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
87*06c3fb27SDimitry Andricdef PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
88*06c3fb27SDimitry Andric                 OpSize16;
89*06c3fb27SDimitry Andricdef PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
90*06c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
91*06c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
92*06c3fb27SDimitry Andric
93*06c3fb27SDimitry Andricdef PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
94*06c3fb27SDimitry Andric                   "push{w}\t$imm", []>, OpSize16;
95*06c3fb27SDimitry Andricdef PUSH16i  : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
96*06c3fb27SDimitry Andric                   "push{w}\t$imm", []>, OpSize16;
97*06c3fb27SDimitry Andric
98*06c3fb27SDimitry Andricdef PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
99*06c3fb27SDimitry Andric                   "push{l}\t$imm", []>, OpSize32,
100*06c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
101*06c3fb27SDimitry Andricdef PUSH32i  : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
102*06c3fb27SDimitry Andric                   "push{l}\t$imm", []>, OpSize32,
103*06c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
104*06c3fb27SDimitry Andric} // mayStore, SchedRW
105*06c3fb27SDimitry Andric
106*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
107*06c3fb27SDimitry Andricdef PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
108*06c3fb27SDimitry Andric                 OpSize16;
109*06c3fb27SDimitry Andricdef PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
110*06c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
111*06c3fb27SDimitry Andric} // mayLoad, mayStore, SchedRW
112*06c3fb27SDimitry Andric
113*06c3fb27SDimitry Andric}
114*06c3fb27SDimitry Andric
115*06c3fb27SDimitry Andriclet isPseudo = 1, mayLoad = 1, mayStore = 1,
116*06c3fb27SDimitry Andric    SchedRW = [WriteRMW], Defs = [ESP] in {
117*06c3fb27SDimitry Andric  let Uses = [ESP] in
118*06c3fb27SDimitry Andric  def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
119*06c3fb27SDimitry Andric                   [(set GR32:$dst, (int_x86_flags_read_u32))]>,
120*06c3fb27SDimitry Andric                Requires<[Not64BitMode]>;
121*06c3fb27SDimitry Andric
122*06c3fb27SDimitry Andric  let Uses = [RSP] in
123*06c3fb27SDimitry Andric  def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
124*06c3fb27SDimitry Andric                   [(set GR64:$dst, (int_x86_flags_read_u64))]>,
125*06c3fb27SDimitry Andric                Requires<[In64BitMode]>;
126*06c3fb27SDimitry Andric}
127*06c3fb27SDimitry Andric
128*06c3fb27SDimitry Andriclet isPseudo = 1, mayLoad = 1, mayStore = 1,
129*06c3fb27SDimitry Andric    SchedRW = [WriteRMW] in {
130*06c3fb27SDimitry Andric  let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
131*06c3fb27SDimitry Andric  def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
132*06c3fb27SDimitry Andric                   [(int_x86_flags_write_u32 GR32:$src)]>,
133*06c3fb27SDimitry Andric                Requires<[Not64BitMode]>;
134*06c3fb27SDimitry Andric
135*06c3fb27SDimitry Andric  let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
136*06c3fb27SDimitry Andric  def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
137*06c3fb27SDimitry Andric                   [(int_x86_flags_write_u64 GR64:$src)]>,
138*06c3fb27SDimitry Andric                Requires<[In64BitMode]>;
139*06c3fb27SDimitry Andric}
140*06c3fb27SDimitry Andric
141*06c3fb27SDimitry Andriclet Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
142*06c3fb27SDimitry Andric    SchedRW = [WriteLoad] in {
143*06c3fb27SDimitry Andricdef POPF16   : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
144*06c3fb27SDimitry Andricdef POPF32   : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
145*06c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
146*06c3fb27SDimitry Andric}
147*06c3fb27SDimitry Andric
148*06c3fb27SDimitry Andriclet Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
149*06c3fb27SDimitry Andric    SchedRW = [WriteStore] in {
150*06c3fb27SDimitry Andricdef PUSHF16  : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
151*06c3fb27SDimitry Andricdef PUSHF32  : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
152*06c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
153*06c3fb27SDimitry Andric}
154*06c3fb27SDimitry Andric
155*06c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
156*06c3fb27SDimitry Andriclet mayLoad = 1, SchedRW = [WriteLoad] in {
157*06c3fb27SDimitry Andricdef POP64r   : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
158*06c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
159*06c3fb27SDimitry Andric// Long form for the disassembler.
160*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
161*06c3fb27SDimitry Andricdef POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
162*06c3fb27SDimitry Andric                OpSize32, Requires<[In64BitMode]>;
163*06c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
164*06c3fb27SDimitry Andric} // mayLoad, SchedRW
165*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
166*06c3fb27SDimitry Andricdef POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
167*06c3fb27SDimitry Andric                OpSize32, Requires<[In64BitMode]>;
168*06c3fb27SDimitry Andriclet mayStore = 1, SchedRW = [WriteStore] in {
169*06c3fb27SDimitry Andricdef PUSH64r  : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
170*06c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
171*06c3fb27SDimitry Andric// Long form for the disassembler.
172*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
173*06c3fb27SDimitry Andricdef PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
174*06c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
175*06c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
176*06c3fb27SDimitry Andric} // mayStore, SchedRW
177*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
178*06c3fb27SDimitry Andricdef PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
179*06c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
180*06c3fb27SDimitry Andric} // mayLoad, mayStore, SchedRW
181*06c3fb27SDimitry Andric}
182*06c3fb27SDimitry Andric
183*06c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
184*06c3fb27SDimitry Andric    SchedRW = [WriteStore] in {
185*06c3fb27SDimitry Andricdef PUSH64i8   : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
186*06c3fb27SDimitry Andric                    "push{q}\t$imm", []>, OpSize32,
187*06c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
188*06c3fb27SDimitry Andricdef PUSH64i32  : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
189*06c3fb27SDimitry Andric                    "push{q}\t$imm", []>, OpSize32,
190*06c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
191*06c3fb27SDimitry Andric}
192*06c3fb27SDimitry Andric
193*06c3fb27SDimitry Andriclet Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
194*06c3fb27SDimitry Andricdef POPF64   : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
195*06c3fb27SDimitry Andric               OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
196*06c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
197*06c3fb27SDimitry Andricdef PUSHF64    : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
198*06c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
199*06c3fb27SDimitry Andric
200*06c3fb27SDimitry Andriclet Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
201*06c3fb27SDimitry Andric    mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
202*06c3fb27SDimitry Andricdef POPA32   : I<0x61, RawFrm, (outs), (ins), "popal", []>,
203*06c3fb27SDimitry Andric               OpSize32, Requires<[Not64BitMode]>;
204*06c3fb27SDimitry Andricdef POPA16   : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
205*06c3fb27SDimitry Andric               OpSize16, Requires<[Not64BitMode]>;
206*06c3fb27SDimitry Andric}
207*06c3fb27SDimitry Andriclet Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
208*06c3fb27SDimitry Andric    mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
209*06c3fb27SDimitry Andricdef PUSHA32  : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
210*06c3fb27SDimitry Andric               OpSize32, Requires<[Not64BitMode]>;
211*06c3fb27SDimitry Andricdef PUSHA16  : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
212*06c3fb27SDimitry Andric               OpSize16, Requires<[Not64BitMode]>;
213*06c3fb27SDimitry Andric}
214*06c3fb27SDimitry Andric
215*06c3fb27SDimitry Andriclet Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
216*06c3fb27SDimitry Andric// This instruction is a consequence of BSWAP32r observing operand size. The
217*06c3fb27SDimitry Andric// encoding is valid, but the behavior is undefined.
218*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
219*06c3fb27SDimitry Andricdef BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
220*06c3fb27SDimitry Andric                     "bswap{w}\t$dst", []>, OpSize16, TB;
221*06c3fb27SDimitry Andric// GR32 = bswap GR32
222*06c3fb27SDimitry Andricdef BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
223*06c3fb27SDimitry Andric                 "bswap{l}\t$dst",
224*06c3fb27SDimitry Andric                 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
225*06c3fb27SDimitry Andric
226*06c3fb27SDimitry Andriclet SchedRW = [WriteBSWAP64] in
227*06c3fb27SDimitry Andricdef BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
228*06c3fb27SDimitry Andric                  "bswap{q}\t$dst",
229*06c3fb27SDimitry Andric                  [(set GR64:$dst, (bswap GR64:$src))]>, TB;
230*06c3fb27SDimitry Andric} // Constraints = "$src = $dst", SchedRW
231*06c3fb27SDimitry Andric
232*06c3fb27SDimitry Andric// Bit scan instructions.
233*06c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
234*06c3fb27SDimitry Andricdef BSF16rr  : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
235*06c3fb27SDimitry Andric                 "bsf{w}\t{$src, $dst|$dst, $src}",
236*06c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
237*06c3fb27SDimitry Andric                  PS, OpSize16, Sched<[WriteBSF]>;
238*06c3fb27SDimitry Andricdef BSF16rm  : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
239*06c3fb27SDimitry Andric                 "bsf{w}\t{$src, $dst|$dst, $src}",
240*06c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
241*06c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSFLd]>;
242*06c3fb27SDimitry Andricdef BSF32rr  : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
243*06c3fb27SDimitry Andric                 "bsf{l}\t{$src, $dst|$dst, $src}",
244*06c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
245*06c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSF]>;
246*06c3fb27SDimitry Andricdef BSF32rm  : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
247*06c3fb27SDimitry Andric                 "bsf{l}\t{$src, $dst|$dst, $src}",
248*06c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
249*06c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSFLd]>;
250*06c3fb27SDimitry Andricdef BSF64rr  : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
251*06c3fb27SDimitry Andric                  "bsf{q}\t{$src, $dst|$dst, $src}",
252*06c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
253*06c3fb27SDimitry Andric                  PS, Sched<[WriteBSF]>;
254*06c3fb27SDimitry Andricdef BSF64rm  : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
255*06c3fb27SDimitry Andric                  "bsf{q}\t{$src, $dst|$dst, $src}",
256*06c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
257*06c3fb27SDimitry Andric                  PS, Sched<[WriteBSFLd]>;
258*06c3fb27SDimitry Andric
259*06c3fb27SDimitry Andricdef BSR16rr  : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
260*06c3fb27SDimitry Andric                 "bsr{w}\t{$src, $dst|$dst, $src}",
261*06c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
262*06c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSR]>;
263*06c3fb27SDimitry Andricdef BSR16rm  : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
264*06c3fb27SDimitry Andric                 "bsr{w}\t{$src, $dst|$dst, $src}",
265*06c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
266*06c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSRLd]>;
267*06c3fb27SDimitry Andricdef BSR32rr  : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
268*06c3fb27SDimitry Andric                 "bsr{l}\t{$src, $dst|$dst, $src}",
269*06c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
270*06c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSR]>;
271*06c3fb27SDimitry Andricdef BSR32rm  : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
272*06c3fb27SDimitry Andric                 "bsr{l}\t{$src, $dst|$dst, $src}",
273*06c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
274*06c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSRLd]>;
275*06c3fb27SDimitry Andricdef BSR64rr  : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
276*06c3fb27SDimitry Andric                  "bsr{q}\t{$src, $dst|$dst, $src}",
277*06c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
278*06c3fb27SDimitry Andric                  PS, Sched<[WriteBSR]>;
279*06c3fb27SDimitry Andricdef BSR64rm  : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
280*06c3fb27SDimitry Andric                  "bsr{q}\t{$src, $dst|$dst, $src}",
281*06c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
282*06c3fb27SDimitry Andric                  PS, Sched<[WriteBSRLd]>;
283*06c3fb27SDimitry Andric} // Defs = [EFLAGS]
284*06c3fb27SDimitry Andric
285*06c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
286*06c3fb27SDimitry Andriclet Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
287*06c3fb27SDimitry Andricdef MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
288*06c3fb27SDimitry Andric              "movsb\t{$src, $dst|$dst, $src}", []>;
289*06c3fb27SDimitry Andricdef MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
290*06c3fb27SDimitry Andric              "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
291*06c3fb27SDimitry Andricdef MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
292*06c3fb27SDimitry Andric              "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
293*06c3fb27SDimitry Andricdef MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
294*06c3fb27SDimitry Andric               "movsq\t{$src, $dst|$dst, $src}", []>,
295*06c3fb27SDimitry Andric               Requires<[In64BitMode]>;
296*06c3fb27SDimitry Andric}
297*06c3fb27SDimitry Andric
298*06c3fb27SDimitry Andriclet Defs = [EDI], Uses = [AL,EDI,DF] in
299*06c3fb27SDimitry Andricdef STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
300*06c3fb27SDimitry Andric              "stosb\t{%al, $dst|$dst, al}", []>;
301*06c3fb27SDimitry Andriclet Defs = [EDI], Uses = [AX,EDI,DF] in
302*06c3fb27SDimitry Andricdef STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
303*06c3fb27SDimitry Andric              "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
304*06c3fb27SDimitry Andriclet Defs = [EDI], Uses = [EAX,EDI,DF] in
305*06c3fb27SDimitry Andricdef STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
306*06c3fb27SDimitry Andric              "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
307*06c3fb27SDimitry Andriclet Defs = [RDI], Uses = [RAX,RDI,DF] in
308*06c3fb27SDimitry Andricdef STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
309*06c3fb27SDimitry Andric               "stosq\t{%rax, $dst|$dst, rax}", []>,
310*06c3fb27SDimitry Andric               Requires<[In64BitMode]>;
311*06c3fb27SDimitry Andric
312*06c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
313*06c3fb27SDimitry Andricdef SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
314*06c3fb27SDimitry Andric              "scasb\t{$dst, %al|al, $dst}", []>;
315*06c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
316*06c3fb27SDimitry Andricdef SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
317*06c3fb27SDimitry Andric              "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
318*06c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
319*06c3fb27SDimitry Andricdef SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
320*06c3fb27SDimitry Andric              "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
321*06c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
322*06c3fb27SDimitry Andricdef SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
323*06c3fb27SDimitry Andric               "scasq\t{$dst, %rax|rax, $dst}", []>,
324*06c3fb27SDimitry Andric               Requires<[In64BitMode]>;
325*06c3fb27SDimitry Andric
326*06c3fb27SDimitry Andriclet Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
327*06c3fb27SDimitry Andricdef CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
328*06c3fb27SDimitry Andric              "cmpsb\t{$dst, $src|$src, $dst}", []>;
329*06c3fb27SDimitry Andricdef CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
330*06c3fb27SDimitry Andric              "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
331*06c3fb27SDimitry Andricdef CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
332*06c3fb27SDimitry Andric              "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
333*06c3fb27SDimitry Andricdef CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
334*06c3fb27SDimitry Andric               "cmpsq\t{$dst, $src|$src, $dst}", []>,
335*06c3fb27SDimitry Andric               Requires<[In64BitMode]>;
336*06c3fb27SDimitry Andric}
337*06c3fb27SDimitry Andric} // SchedRW
338*06c3fb27SDimitry Andric
339*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
340*06c3fb27SDimitry Andric//  Move Instructions.
341*06c3fb27SDimitry Andric//
342*06c3fb27SDimitry Andriclet SchedRW = [WriteMove] in {
343*06c3fb27SDimitry Andriclet hasSideEffects = 0, isMoveReg = 1 in {
344*06c3fb27SDimitry Andricdef MOV8rr  : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
345*06c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}", []>;
346*06c3fb27SDimitry Andricdef MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
347*06c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
348*06c3fb27SDimitry Andricdef MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
349*06c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
350*06c3fb27SDimitry Andricdef MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
351*06c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}", []>;
352*06c3fb27SDimitry Andric}
353*06c3fb27SDimitry Andric
354*06c3fb27SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
355*06c3fb27SDimitry Andricdef MOV8ri  : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
356*06c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}",
357*06c3fb27SDimitry Andric                   [(set GR8:$dst, imm:$src)]>;
358*06c3fb27SDimitry Andricdef MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
359*06c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}",
360*06c3fb27SDimitry Andric                   [(set GR16:$dst, imm:$src)]>, OpSize16;
361*06c3fb27SDimitry Andricdef MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
362*06c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}",
363*06c3fb27SDimitry Andric                   [(set GR32:$dst, imm:$src)]>, OpSize32;
364*06c3fb27SDimitry Andricdef MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
365*06c3fb27SDimitry Andric                       "mov{q}\t{$src, $dst|$dst, $src}",
366*06c3fb27SDimitry Andric                       [(set GR64:$dst, i64immSExt32:$src)]>;
367*06c3fb27SDimitry Andric}
368*06c3fb27SDimitry Andriclet isReMaterializable = 1, isMoveImm = 1 in {
369*06c3fb27SDimitry Andricdef MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
370*06c3fb27SDimitry Andric                    "movabs{q}\t{$src, $dst|$dst, $src}",
371*06c3fb27SDimitry Andric                    [(set GR64:$dst, imm:$src)]>;
372*06c3fb27SDimitry Andric}
373*06c3fb27SDimitry Andric
374*06c3fb27SDimitry Andric// Longer forms that use a ModR/M byte. Needed for disassembler
375*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
376*06c3fb27SDimitry Andricdef MOV8ri_alt  : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
377*06c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}", []>;
378*06c3fb27SDimitry Andricdef MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
379*06c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
380*06c3fb27SDimitry Andricdef MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
381*06c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
382*06c3fb27SDimitry Andric}
383*06c3fb27SDimitry Andric} // SchedRW
384*06c3fb27SDimitry Andric
385*06c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
386*06c3fb27SDimitry Andricdef MOV8mi  : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
387*06c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}",
388*06c3fb27SDimitry Andric                   [(store (i8 imm_su:$src), addr:$dst)]>;
389*06c3fb27SDimitry Andricdef MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
390*06c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}",
391*06c3fb27SDimitry Andric                   [(store (i16 imm_su:$src), addr:$dst)]>, OpSize16;
392*06c3fb27SDimitry Andricdef MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
393*06c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}",
394*06c3fb27SDimitry Andric                   [(store (i32 imm_su:$src), addr:$dst)]>, OpSize32;
395*06c3fb27SDimitry Andricdef MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
396*06c3fb27SDimitry Andric                       "mov{q}\t{$src, $dst|$dst, $src}",
397*06c3fb27SDimitry Andric                       [(store i64immSExt32_su:$src, addr:$dst)]>,
398*06c3fb27SDimitry Andric                       Requires<[In64BitMode]>;
399*06c3fb27SDimitry Andric} // SchedRW
400*06c3fb27SDimitry Andric
401*06c3fb27SDimitry Andricdef : Pat<(i32 relocImm:$src), (MOV32ri relocImm:$src)>;
402*06c3fb27SDimitry Andricdef : Pat<(i64 relocImm:$src), (MOV64ri relocImm:$src)>;
403*06c3fb27SDimitry Andric
404*06c3fb27SDimitry Andricdef : Pat<(store (i8 relocImm8_su:$src), addr:$dst),
405*06c3fb27SDimitry Andric          (MOV8mi addr:$dst, relocImm8_su:$src)>;
406*06c3fb27SDimitry Andricdef : Pat<(store (i16 relocImm16_su:$src), addr:$dst),
407*06c3fb27SDimitry Andric          (MOV16mi addr:$dst, relocImm16_su:$src)>;
408*06c3fb27SDimitry Andricdef : Pat<(store (i32 relocImm32_su:$src), addr:$dst),
409*06c3fb27SDimitry Andric          (MOV32mi addr:$dst, relocImm32_su:$src)>;
410*06c3fb27SDimitry Andricdef : Pat<(store (i64 i64relocImmSExt32_su:$src), addr:$dst),
411*06c3fb27SDimitry Andric          (MOV64mi32 addr:$dst, i64immSExt32_su:$src)>;
412*06c3fb27SDimitry Andric
413*06c3fb27SDimitry Andriclet hasSideEffects = 0 in {
414*06c3fb27SDimitry Andric
415*06c3fb27SDimitry Andric/// Memory offset versions of moves. The immediate is an address mode sized
416*06c3fb27SDimitry Andric/// offset from the segment base.
417*06c3fb27SDimitry Andriclet SchedRW = [WriteALU] in {
418*06c3fb27SDimitry Andriclet mayLoad = 1 in {
419*06c3fb27SDimitry Andriclet Defs = [AL] in
420*06c3fb27SDimitry Andricdef MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
421*06c3fb27SDimitry Andric                    "mov{b}\t{$src, %al|al, $src}", []>,
422*06c3fb27SDimitry Andric                    AdSize32;
423*06c3fb27SDimitry Andriclet Defs = [AX] in
424*06c3fb27SDimitry Andricdef MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
425*06c3fb27SDimitry Andric                     "mov{w}\t{$src, %ax|ax, $src}", []>,
426*06c3fb27SDimitry Andric                     OpSize16, AdSize32;
427*06c3fb27SDimitry Andriclet Defs = [EAX] in
428*06c3fb27SDimitry Andricdef MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
429*06c3fb27SDimitry Andric                     "mov{l}\t{$src, %eax|eax, $src}", []>,
430*06c3fb27SDimitry Andric                     OpSize32, AdSize32;
431*06c3fb27SDimitry Andriclet Defs = [RAX] in
432*06c3fb27SDimitry Andricdef MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
433*06c3fb27SDimitry Andric                      "mov{q}\t{$src, %rax|rax, $src}", []>,
434*06c3fb27SDimitry Andric                      AdSize32;
435*06c3fb27SDimitry Andric
436*06c3fb27SDimitry Andriclet Defs = [AL] in
437*06c3fb27SDimitry Andricdef MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
438*06c3fb27SDimitry Andric                    "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
439*06c3fb27SDimitry Andriclet Defs = [AX] in
440*06c3fb27SDimitry Andricdef MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
441*06c3fb27SDimitry Andric                     "mov{w}\t{$src, %ax|ax, $src}", []>,
442*06c3fb27SDimitry Andric                     OpSize16, AdSize16;
443*06c3fb27SDimitry Andriclet Defs = [EAX] in
444*06c3fb27SDimitry Andricdef MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
445*06c3fb27SDimitry Andric                     "mov{l}\t{$src, %eax|eax, $src}", []>,
446*06c3fb27SDimitry Andric                     AdSize16, OpSize32;
447*06c3fb27SDimitry Andric} // mayLoad
448*06c3fb27SDimitry Andriclet mayStore = 1 in {
449*06c3fb27SDimitry Andriclet Uses = [AL] in
450*06c3fb27SDimitry Andricdef MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
451*06c3fb27SDimitry Andric                    "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
452*06c3fb27SDimitry Andriclet Uses = [AX] in
453*06c3fb27SDimitry Andricdef MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
454*06c3fb27SDimitry Andric                     "mov{w}\t{%ax, $dst|$dst, ax}", []>,
455*06c3fb27SDimitry Andric                     OpSize16, AdSize32;
456*06c3fb27SDimitry Andriclet Uses = [EAX] in
457*06c3fb27SDimitry Andricdef MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
458*06c3fb27SDimitry Andric                     "mov{l}\t{%eax, $dst|$dst, eax}", []>,
459*06c3fb27SDimitry Andric                     OpSize32, AdSize32;
460*06c3fb27SDimitry Andriclet Uses = [RAX] in
461*06c3fb27SDimitry Andricdef MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
462*06c3fb27SDimitry Andric                      "mov{q}\t{%rax, $dst|$dst, rax}", []>,
463*06c3fb27SDimitry Andric                      AdSize32;
464*06c3fb27SDimitry Andric
465*06c3fb27SDimitry Andriclet Uses = [AL] in
466*06c3fb27SDimitry Andricdef MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
467*06c3fb27SDimitry Andric                    "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
468*06c3fb27SDimitry Andriclet Uses = [AX] in
469*06c3fb27SDimitry Andricdef MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
470*06c3fb27SDimitry Andric                     "mov{w}\t{%ax, $dst|$dst, ax}", []>,
471*06c3fb27SDimitry Andric                     OpSize16, AdSize16;
472*06c3fb27SDimitry Andriclet Uses = [EAX] in
473*06c3fb27SDimitry Andricdef MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
474*06c3fb27SDimitry Andric                     "mov{l}\t{%eax, $dst|$dst, eax}", []>,
475*06c3fb27SDimitry Andric                     OpSize32, AdSize16;
476*06c3fb27SDimitry Andric} // mayStore
477*06c3fb27SDimitry Andric
478*06c3fb27SDimitry Andric// These forms all have full 64-bit absolute addresses in their instructions
479*06c3fb27SDimitry Andric// and use the movabs mnemonic to indicate this specific form.
480*06c3fb27SDimitry Andriclet mayLoad = 1 in {
481*06c3fb27SDimitry Andriclet Defs = [AL] in
482*06c3fb27SDimitry Andricdef MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
483*06c3fb27SDimitry Andric                    "movabs{b}\t{$src, %al|al, $src}", []>,
484*06c3fb27SDimitry Andric                    AdSize64;
485*06c3fb27SDimitry Andriclet Defs = [AX] in
486*06c3fb27SDimitry Andricdef MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
487*06c3fb27SDimitry Andric                     "movabs{w}\t{$src, %ax|ax, $src}", []>,
488*06c3fb27SDimitry Andric                     OpSize16, AdSize64;
489*06c3fb27SDimitry Andriclet Defs = [EAX] in
490*06c3fb27SDimitry Andricdef MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
491*06c3fb27SDimitry Andric                     "movabs{l}\t{$src, %eax|eax, $src}", []>,
492*06c3fb27SDimitry Andric                     OpSize32, AdSize64;
493*06c3fb27SDimitry Andriclet Defs = [RAX] in
494*06c3fb27SDimitry Andricdef MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
495*06c3fb27SDimitry Andric                     "movabs{q}\t{$src, %rax|rax, $src}", []>,
496*06c3fb27SDimitry Andric                     AdSize64;
497*06c3fb27SDimitry Andric} // mayLoad
498*06c3fb27SDimitry Andric
499*06c3fb27SDimitry Andriclet mayStore = 1 in {
500*06c3fb27SDimitry Andriclet Uses = [AL] in
501*06c3fb27SDimitry Andricdef MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
502*06c3fb27SDimitry Andric                    "movabs{b}\t{%al, $dst|$dst, al}", []>,
503*06c3fb27SDimitry Andric                    AdSize64;
504*06c3fb27SDimitry Andriclet Uses = [AX] in
505*06c3fb27SDimitry Andricdef MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
506*06c3fb27SDimitry Andric                     "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
507*06c3fb27SDimitry Andric                     OpSize16, AdSize64;
508*06c3fb27SDimitry Andriclet Uses = [EAX] in
509*06c3fb27SDimitry Andricdef MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
510*06c3fb27SDimitry Andric                     "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
511*06c3fb27SDimitry Andric                     OpSize32, AdSize64;
512*06c3fb27SDimitry Andriclet Uses = [RAX] in
513*06c3fb27SDimitry Andricdef MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
514*06c3fb27SDimitry Andric                     "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
515*06c3fb27SDimitry Andric                     AdSize64;
516*06c3fb27SDimitry Andric} // mayStore
517*06c3fb27SDimitry Andric} // SchedRW
518*06c3fb27SDimitry Andric} // hasSideEffects = 0
519*06c3fb27SDimitry Andric
520*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
521*06c3fb27SDimitry Andric    SchedRW = [WriteMove], isMoveReg = 1 in {
522*06c3fb27SDimitry Andricdef MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
523*06c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}", []>;
524*06c3fb27SDimitry Andricdef MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
525*06c3fb27SDimitry Andric                    "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
526*06c3fb27SDimitry Andricdef MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
527*06c3fb27SDimitry Andric                    "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
528*06c3fb27SDimitry Andricdef MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
529*06c3fb27SDimitry Andric                     "mov{q}\t{$src, $dst|$dst, $src}", []>;
530*06c3fb27SDimitry Andric}
531*06c3fb27SDimitry Andric
532*06c3fb27SDimitry Andriclet canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
533*06c3fb27SDimitry Andricdef MOV8rm  : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
534*06c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}",
535*06c3fb27SDimitry Andric                [(set GR8:$dst, (loadi8 addr:$src))]>;
536*06c3fb27SDimitry Andricdef MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
537*06c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}",
538*06c3fb27SDimitry Andric                [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
539*06c3fb27SDimitry Andricdef MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
540*06c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}",
541*06c3fb27SDimitry Andric                [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
542*06c3fb27SDimitry Andricdef MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
543*06c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}",
544*06c3fb27SDimitry Andric                 [(set GR64:$dst, (load addr:$src))]>;
545*06c3fb27SDimitry Andric}
546*06c3fb27SDimitry Andric
547*06c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
548*06c3fb27SDimitry Andricdef MOV8mr  : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
549*06c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}",
550*06c3fb27SDimitry Andric                [(store GR8:$src, addr:$dst)]>;
551*06c3fb27SDimitry Andricdef MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
552*06c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}",
553*06c3fb27SDimitry Andric                [(store GR16:$src, addr:$dst)]>, OpSize16;
554*06c3fb27SDimitry Andricdef MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
555*06c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}",
556*06c3fb27SDimitry Andric                [(store GR32:$src, addr:$dst)]>, OpSize32;
557*06c3fb27SDimitry Andricdef MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
558*06c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}",
559*06c3fb27SDimitry Andric                 [(store GR64:$src, addr:$dst)]>;
560*06c3fb27SDimitry Andric} // SchedRW
561*06c3fb27SDimitry Andric
562*06c3fb27SDimitry Andric// Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
563*06c3fb27SDimitry Andric// that they can be used for copying and storing h registers, which can't be
564*06c3fb27SDimitry Andric// encoded when a REX prefix is present.
565*06c3fb27SDimitry Andriclet isCodeGenOnly = 1 in {
566*06c3fb27SDimitry Andriclet hasSideEffects = 0, isMoveReg = 1 in
567*06c3fb27SDimitry Andricdef MOV8rr_NOREX : I<0x88, MRMDestReg,
568*06c3fb27SDimitry Andric                     (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
569*06c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
570*06c3fb27SDimitry Andric                   Sched<[WriteMove]>;
571*06c3fb27SDimitry Andriclet mayStore = 1, hasSideEffects = 0 in
572*06c3fb27SDimitry Andricdef MOV8mr_NOREX : I<0x88, MRMDestMem,
573*06c3fb27SDimitry Andric                     (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
574*06c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
575*06c3fb27SDimitry Andric                     Sched<[WriteStore]>;
576*06c3fb27SDimitry Andriclet mayLoad = 1, hasSideEffects = 0,
577*06c3fb27SDimitry Andric    canFoldAsLoad = 1, isReMaterializable = 1 in
578*06c3fb27SDimitry Andricdef MOV8rm_NOREX : I<0x8A, MRMSrcMem,
579*06c3fb27SDimitry Andric                     (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
580*06c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
581*06c3fb27SDimitry Andric                     Sched<[WriteLoad]>;
582*06c3fb27SDimitry Andric}
583*06c3fb27SDimitry Andric
584*06c3fb27SDimitry Andric
585*06c3fb27SDimitry Andric// Condition code ops, incl. set if equal/not equal/...
586*06c3fb27SDimitry Andriclet SchedRW = [WriteLAHFSAHF] in {
587*06c3fb27SDimitry Andriclet Defs = [EFLAGS], Uses = [AH], hasSideEffects = 0 in
588*06c3fb27SDimitry Andricdef SAHF     : I<0x9E, RawFrm, (outs),  (ins), "sahf", []>,  // flags = AH
589*06c3fb27SDimitry Andric                 Requires<[HasLAHFSAHF]>;
590*06c3fb27SDimitry Andriclet Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
591*06c3fb27SDimitry Andricdef LAHF     : I<0x9F, RawFrm, (outs),  (ins), "lahf", []>,  // AH = flags
592*06c3fb27SDimitry Andric               Requires<[HasLAHFSAHF]>;
593*06c3fb27SDimitry Andric} // SchedRW
594*06c3fb27SDimitry Andric
595*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
596*06c3fb27SDimitry Andric// Bit tests instructions: BT, BTS, BTR, BTC.
597*06c3fb27SDimitry Andric
598*06c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
599*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTest] in {
600*06c3fb27SDimitry Andricdef BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
601*06c3fb27SDimitry Andric               "bt{w}\t{$src2, $src1|$src1, $src2}",
602*06c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
603*06c3fb27SDimitry Andric               OpSize16, TB;
604*06c3fb27SDimitry Andricdef BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
605*06c3fb27SDimitry Andric               "bt{l}\t{$src2, $src1|$src1, $src2}",
606*06c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
607*06c3fb27SDimitry Andric               OpSize32, TB;
608*06c3fb27SDimitry Andricdef BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
609*06c3fb27SDimitry Andric               "bt{q}\t{$src2, $src1|$src1, $src2}",
610*06c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB;
611*06c3fb27SDimitry Andric} // SchedRW
612*06c3fb27SDimitry Andric
613*06c3fb27SDimitry Andric// Unlike with the register+register form, the memory+register form of the
614*06c3fb27SDimitry Andric// bt instruction does not ignore the high bits of the index. From ISel's
615*06c3fb27SDimitry Andric// perspective, this is pretty bizarre. Make these instructions disassembly
616*06c3fb27SDimitry Andric// only for now. These instructions are also slow on modern CPUs so that's
617*06c3fb27SDimitry Andric// another reason to avoid generating them.
618*06c3fb27SDimitry Andric
619*06c3fb27SDimitry Andriclet mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
620*06c3fb27SDimitry Andric  def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
621*06c3fb27SDimitry Andric                 "bt{w}\t{$src2, $src1|$src1, $src2}",
622*06c3fb27SDimitry Andric                 []>, OpSize16, TB;
623*06c3fb27SDimitry Andric  def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
624*06c3fb27SDimitry Andric                 "bt{l}\t{$src2, $src1|$src1, $src2}",
625*06c3fb27SDimitry Andric                 []>, OpSize32, TB;
626*06c3fb27SDimitry Andric  def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
627*06c3fb27SDimitry Andric                 "bt{q}\t{$src2, $src1|$src1, $src2}",
628*06c3fb27SDimitry Andric                  []>, TB;
629*06c3fb27SDimitry Andric}
630*06c3fb27SDimitry Andric
631*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTest] in {
632*06c3fb27SDimitry Andricdef BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
633*06c3fb27SDimitry Andric                "bt{w}\t{$src2, $src1|$src1, $src2}",
634*06c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
635*06c3fb27SDimitry Andric                OpSize16, TB;
636*06c3fb27SDimitry Andricdef BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
637*06c3fb27SDimitry Andric                "bt{l}\t{$src2, $src1|$src1, $src2}",
638*06c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
639*06c3fb27SDimitry Andric                OpSize32, TB;
640*06c3fb27SDimitry Andricdef BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
641*06c3fb27SDimitry Andric                "bt{q}\t{$src2, $src1|$src1, $src2}",
642*06c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
643*06c3fb27SDimitry Andric} // SchedRW
644*06c3fb27SDimitry Andric
645*06c3fb27SDimitry Andric// Note that these instructions aren't slow because that only applies when the
646*06c3fb27SDimitry Andric// other operand is in a register. When it's an immediate, bt is still fast.
647*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestImmLd] in {
648*06c3fb27SDimitry Andricdef BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
649*06c3fb27SDimitry Andric                  "bt{w}\t{$src2, $src1|$src1, $src2}",
650*06c3fb27SDimitry Andric                  [(set EFLAGS, (X86bt (loadi16 addr:$src1),
651*06c3fb27SDimitry Andric                                       imm:$src2))]>,
652*06c3fb27SDimitry Andric                  OpSize16, TB;
653*06c3fb27SDimitry Andricdef BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
654*06c3fb27SDimitry Andric                  "bt{l}\t{$src2, $src1|$src1, $src2}",
655*06c3fb27SDimitry Andric                  [(set EFLAGS, (X86bt (loadi32 addr:$src1),
656*06c3fb27SDimitry Andric                                       imm:$src2))]>,
657*06c3fb27SDimitry Andric                  OpSize32, TB;
658*06c3fb27SDimitry Andricdef BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
659*06c3fb27SDimitry Andric                "bt{q}\t{$src2, $src1|$src1, $src2}",
660*06c3fb27SDimitry Andric                [(set EFLAGS, (X86bt (loadi64 addr:$src1),
661*06c3fb27SDimitry Andric                                     imm:$src2))]>, TB,
662*06c3fb27SDimitry Andric                Requires<[In64BitMode]>;
663*06c3fb27SDimitry Andric} // SchedRW
664*06c3fb27SDimitry Andric
665*06c3fb27SDimitry Andriclet hasSideEffects = 0 in {
666*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
667*06c3fb27SDimitry Andricdef BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
668*06c3fb27SDimitry Andric                "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
669*06c3fb27SDimitry Andric                OpSize16, TB;
670*06c3fb27SDimitry Andricdef BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
671*06c3fb27SDimitry Andric                "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
672*06c3fb27SDimitry Andric                OpSize32, TB;
673*06c3fb27SDimitry Andricdef BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
674*06c3fb27SDimitry Andric                 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
675*06c3fb27SDimitry Andric} // SchedRW
676*06c3fb27SDimitry Andric
677*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
678*06c3fb27SDimitry Andricdef BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
679*06c3fb27SDimitry Andric                "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
680*06c3fb27SDimitry Andric                OpSize16, TB;
681*06c3fb27SDimitry Andricdef BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
682*06c3fb27SDimitry Andric                "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
683*06c3fb27SDimitry Andric                OpSize32, TB;
684*06c3fb27SDimitry Andricdef BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
685*06c3fb27SDimitry Andric                 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
686*06c3fb27SDimitry Andric}
687*06c3fb27SDimitry Andric
688*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
689*06c3fb27SDimitry Andricdef BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
690*06c3fb27SDimitry Andric                    "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
691*06c3fb27SDimitry Andricdef BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
692*06c3fb27SDimitry Andric                    "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
693*06c3fb27SDimitry Andricdef BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
694*06c3fb27SDimitry Andric                    "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
695*06c3fb27SDimitry Andric} // SchedRW
696*06c3fb27SDimitry Andric
697*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
698*06c3fb27SDimitry Andricdef BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
699*06c3fb27SDimitry Andric                    "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
700*06c3fb27SDimitry Andricdef BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
701*06c3fb27SDimitry Andric                    "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
702*06c3fb27SDimitry Andricdef BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
703*06c3fb27SDimitry Andric                    "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
704*06c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
705*06c3fb27SDimitry Andric}
706*06c3fb27SDimitry Andric
707*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
708*06c3fb27SDimitry Andricdef BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
709*06c3fb27SDimitry Andric                "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
710*06c3fb27SDimitry Andric                OpSize16, TB;
711*06c3fb27SDimitry Andricdef BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
712*06c3fb27SDimitry Andric                "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
713*06c3fb27SDimitry Andric                OpSize32, TB;
714*06c3fb27SDimitry Andricdef BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
715*06c3fb27SDimitry Andric                 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
716*06c3fb27SDimitry Andric} // SchedRW
717*06c3fb27SDimitry Andric
718*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
719*06c3fb27SDimitry Andricdef BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
720*06c3fb27SDimitry Andric                "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
721*06c3fb27SDimitry Andric                OpSize16, TB;
722*06c3fb27SDimitry Andricdef BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
723*06c3fb27SDimitry Andric                "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
724*06c3fb27SDimitry Andric                OpSize32, TB;
725*06c3fb27SDimitry Andricdef BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
726*06c3fb27SDimitry Andric                 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
727*06c3fb27SDimitry Andric}
728*06c3fb27SDimitry Andric
729*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
730*06c3fb27SDimitry Andricdef BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
731*06c3fb27SDimitry Andric                    "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
732*06c3fb27SDimitry Andric                    OpSize16, TB;
733*06c3fb27SDimitry Andricdef BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
734*06c3fb27SDimitry Andric                    "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
735*06c3fb27SDimitry Andric                    OpSize32, TB;
736*06c3fb27SDimitry Andricdef BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
737*06c3fb27SDimitry Andric                    "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
738*06c3fb27SDimitry Andric} // SchedRW
739*06c3fb27SDimitry Andric
740*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
741*06c3fb27SDimitry Andricdef BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
742*06c3fb27SDimitry Andric                    "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
743*06c3fb27SDimitry Andric                    OpSize16, TB;
744*06c3fb27SDimitry Andricdef BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
745*06c3fb27SDimitry Andric                    "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
746*06c3fb27SDimitry Andric                    OpSize32, TB;
747*06c3fb27SDimitry Andricdef BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
748*06c3fb27SDimitry Andric                    "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
749*06c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
750*06c3fb27SDimitry Andric}
751*06c3fb27SDimitry Andric
752*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
753*06c3fb27SDimitry Andricdef BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
754*06c3fb27SDimitry Andric                "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
755*06c3fb27SDimitry Andric                OpSize16, TB;
756*06c3fb27SDimitry Andricdef BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
757*06c3fb27SDimitry Andric                "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
758*06c3fb27SDimitry Andric              OpSize32, TB;
759*06c3fb27SDimitry Andricdef BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
760*06c3fb27SDimitry Andric               "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
761*06c3fb27SDimitry Andric} // SchedRW
762*06c3fb27SDimitry Andric
763*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
764*06c3fb27SDimitry Andricdef BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
765*06c3fb27SDimitry Andric              "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
766*06c3fb27SDimitry Andric              OpSize16, TB;
767*06c3fb27SDimitry Andricdef BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
768*06c3fb27SDimitry Andric              "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
769*06c3fb27SDimitry Andric              OpSize32, TB;
770*06c3fb27SDimitry Andricdef BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
771*06c3fb27SDimitry Andric                 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
772*06c3fb27SDimitry Andric}
773*06c3fb27SDimitry Andric
774*06c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
775*06c3fb27SDimitry Andricdef BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
776*06c3fb27SDimitry Andric                    "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
777*06c3fb27SDimitry Andricdef BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
778*06c3fb27SDimitry Andric                    "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
779*06c3fb27SDimitry Andricdef BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
780*06c3fb27SDimitry Andric                    "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
781*06c3fb27SDimitry Andric} // SchedRW
782*06c3fb27SDimitry Andric
783*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
784*06c3fb27SDimitry Andricdef BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
785*06c3fb27SDimitry Andric                    "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
786*06c3fb27SDimitry Andricdef BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
787*06c3fb27SDimitry Andric                    "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
788*06c3fb27SDimitry Andricdef BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
789*06c3fb27SDimitry Andric                    "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
790*06c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
791*06c3fb27SDimitry Andric}
792*06c3fb27SDimitry Andric} // hasSideEffects = 0
793*06c3fb27SDimitry Andric} // Defs = [EFLAGS]
794*06c3fb27SDimitry Andric
795*06c3fb27SDimitry Andric
796*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
797*06c3fb27SDimitry Andric// Atomic support
798*06c3fb27SDimitry Andric//
799*06c3fb27SDimitry Andric
800*06c3fb27SDimitry Andric// Atomic swap. These are just normal xchg instructions. But since a memory
801*06c3fb27SDimitry Andric// operand is referenced, the atomicity is ensured.
802*06c3fb27SDimitry Andricmulticlass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
803*06c3fb27SDimitry Andric  let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
804*06c3fb27SDimitry Andric    def NAME#8rm  : I<opc8, MRMSrcMem, (outs GR8:$dst),
805*06c3fb27SDimitry Andric                      (ins GR8:$val, i8mem:$ptr),
806*06c3fb27SDimitry Andric                      !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
807*06c3fb27SDimitry Andric                      [(set
808*06c3fb27SDimitry Andric                         GR8:$dst,
809*06c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
810*06c3fb27SDimitry Andric    def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
811*06c3fb27SDimitry Andric                      (ins GR16:$val, i16mem:$ptr),
812*06c3fb27SDimitry Andric                      !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
813*06c3fb27SDimitry Andric                      [(set
814*06c3fb27SDimitry Andric                         GR16:$dst,
815*06c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
816*06c3fb27SDimitry Andric                      OpSize16;
817*06c3fb27SDimitry Andric    def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
818*06c3fb27SDimitry Andric                      (ins GR32:$val, i32mem:$ptr),
819*06c3fb27SDimitry Andric                      !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
820*06c3fb27SDimitry Andric                      [(set
821*06c3fb27SDimitry Andric                         GR32:$dst,
822*06c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
823*06c3fb27SDimitry Andric                      OpSize32;
824*06c3fb27SDimitry Andric    def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
825*06c3fb27SDimitry Andric                       (ins GR64:$val, i64mem:$ptr),
826*06c3fb27SDimitry Andric                       !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
827*06c3fb27SDimitry Andric                       [(set
828*06c3fb27SDimitry Andric                         GR64:$dst,
829*06c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
830*06c3fb27SDimitry Andric  }
831*06c3fb27SDimitry Andric}
832*06c3fb27SDimitry Andric
833*06c3fb27SDimitry Andricdefm XCHG    : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">;
834*06c3fb27SDimitry Andric
835*06c3fb27SDimitry Andric// Swap between registers.
836*06c3fb27SDimitry Andriclet SchedRW = [WriteXCHG] in {
837*06c3fb27SDimitry Andriclet Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
838*06c3fb27SDimitry Andricdef XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
839*06c3fb27SDimitry Andric                (ins GR8:$src1, GR8:$src2),
840*06c3fb27SDimitry Andric                "xchg{b}\t{$src2, $src1|$src1, $src2}", []>;
841*06c3fb27SDimitry Andricdef XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
842*06c3fb27SDimitry Andric                 (ins GR16:$src1, GR16:$src2),
843*06c3fb27SDimitry Andric                 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
844*06c3fb27SDimitry Andric                 OpSize16;
845*06c3fb27SDimitry Andricdef XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
846*06c3fb27SDimitry Andric                 (ins GR32:$src1, GR32:$src2),
847*06c3fb27SDimitry Andric                 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
848*06c3fb27SDimitry Andric                 OpSize32;
849*06c3fb27SDimitry Andricdef XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
850*06c3fb27SDimitry Andric                  (ins GR64:$src1 ,GR64:$src2),
851*06c3fb27SDimitry Andric                  "xchg{q}\t{$src2, $src1|$src1, $src2}", []>;
852*06c3fb27SDimitry Andric}
853*06c3fb27SDimitry Andric
854*06c3fb27SDimitry Andric// Swap between EAX and other registers.
855*06c3fb27SDimitry Andriclet Constraints = "$src = $dst", hasSideEffects = 0 in {
856*06c3fb27SDimitry Andriclet Uses = [AX], Defs = [AX] in
857*06c3fb27SDimitry Andricdef XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
858*06c3fb27SDimitry Andric                  "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
859*06c3fb27SDimitry Andriclet Uses = [EAX], Defs = [EAX] in
860*06c3fb27SDimitry Andricdef XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
861*06c3fb27SDimitry Andric                  "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
862*06c3fb27SDimitry Andriclet Uses = [RAX], Defs = [RAX] in
863*06c3fb27SDimitry Andricdef XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
864*06c3fb27SDimitry Andric                  "xchg{q}\t{$src, %rax|rax, $src}", []>;
865*06c3fb27SDimitry Andric}
866*06c3fb27SDimitry Andric} // SchedRW
867*06c3fb27SDimitry Andric
868*06c3fb27SDimitry Andriclet hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
869*06c3fb27SDimitry Andric    Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
870*06c3fb27SDimitry Andricdef XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
871*06c3fb27SDimitry Andric                (ins GR8:$src1, GR8:$src2),
872*06c3fb27SDimitry Andric                "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
873*06c3fb27SDimitry Andricdef XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
874*06c3fb27SDimitry Andric                 (ins GR16:$src1, GR16:$src2),
875*06c3fb27SDimitry Andric                 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
876*06c3fb27SDimitry Andricdef XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
877*06c3fb27SDimitry Andric                  (ins GR32:$src1, GR32:$src2),
878*06c3fb27SDimitry Andric                 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
879*06c3fb27SDimitry Andricdef XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
880*06c3fb27SDimitry Andric                  (ins GR64:$src1, GR64:$src2),
881*06c3fb27SDimitry Andric                  "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
882*06c3fb27SDimitry Andric} // SchedRW
883*06c3fb27SDimitry Andric
884*06c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
885*06c3fb27SDimitry Andric    Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
886*06c3fb27SDimitry Andricdef XADD8rm   : I<0xC0, MRMSrcMem, (outs GR8:$dst),
887*06c3fb27SDimitry Andric                  (ins GR8:$val, i8mem:$ptr),
888*06c3fb27SDimitry Andric                 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
889*06c3fb27SDimitry Andricdef XADD16rm  : I<0xC1, MRMSrcMem, (outs GR16:$dst),
890*06c3fb27SDimitry Andric                  (ins GR16:$val, i16mem:$ptr),
891*06c3fb27SDimitry Andric                 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
892*06c3fb27SDimitry Andric                 OpSize16;
893*06c3fb27SDimitry Andricdef XADD32rm  : I<0xC1, MRMSrcMem, (outs GR32:$dst),
894*06c3fb27SDimitry Andric                  (ins GR32:$val, i32mem:$ptr),
895*06c3fb27SDimitry Andric                 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
896*06c3fb27SDimitry Andric                 OpSize32;
897*06c3fb27SDimitry Andricdef XADD64rm  : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
898*06c3fb27SDimitry Andric                   (ins GR64:$val, i64mem:$ptr),
899*06c3fb27SDimitry Andric                   "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
900*06c3fb27SDimitry Andric
901*06c3fb27SDimitry Andric}
902*06c3fb27SDimitry Andric
903*06c3fb27SDimitry Andriclet SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
904*06c3fb27SDimitry Andriclet Defs = [AL, EFLAGS], Uses = [AL] in
905*06c3fb27SDimitry Andricdef CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
906*06c3fb27SDimitry Andric                   "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB;
907*06c3fb27SDimitry Andriclet Defs = [AX, EFLAGS], Uses = [AX] in
908*06c3fb27SDimitry Andricdef CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
909*06c3fb27SDimitry Andric                    "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16;
910*06c3fb27SDimitry Andriclet Defs = [EAX, EFLAGS], Uses = [EAX] in
911*06c3fb27SDimitry Andricdef CMPXCHG32rr  : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
912*06c3fb27SDimitry Andric                     "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32;
913*06c3fb27SDimitry Andriclet Defs = [RAX, EFLAGS], Uses = [RAX] in
914*06c3fb27SDimitry Andricdef CMPXCHG64rr  : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
915*06c3fb27SDimitry Andric                      "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
916*06c3fb27SDimitry Andric} // SchedRW, hasSideEffects
917*06c3fb27SDimitry Andric
918*06c3fb27SDimitry Andriclet SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
919*06c3fb27SDimitry Andric    hasSideEffects = 0 in {
920*06c3fb27SDimitry Andriclet Defs = [AL, EFLAGS], Uses = [AL] in
921*06c3fb27SDimitry Andricdef CMPXCHG8rm   : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
922*06c3fb27SDimitry Andric                     "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB;
923*06c3fb27SDimitry Andriclet Defs = [AX, EFLAGS], Uses = [AX] in
924*06c3fb27SDimitry Andricdef CMPXCHG16rm  : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
925*06c3fb27SDimitry Andric                     "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16;
926*06c3fb27SDimitry Andriclet Defs = [EAX, EFLAGS], Uses = [EAX] in
927*06c3fb27SDimitry Andricdef CMPXCHG32rm  : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
928*06c3fb27SDimitry Andric                     "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32;
929*06c3fb27SDimitry Andriclet Defs = [RAX, EFLAGS], Uses = [RAX] in
930*06c3fb27SDimitry Andricdef CMPXCHG64rm  : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
931*06c3fb27SDimitry Andric                      "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
932*06c3fb27SDimitry Andric
933*06c3fb27SDimitry Andriclet Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
934*06c3fb27SDimitry Andricdef CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
935*06c3fb27SDimitry Andric                  "cmpxchg8b\t$dst", []>, TB, Requires<[HasCX8]>;
936*06c3fb27SDimitry Andric
937*06c3fb27SDimitry Andriclet Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
938*06c3fb27SDimitry Andric// NOTE: In64BitMode check needed for the AssemblerPredicate.
939*06c3fb27SDimitry Andricdef CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
940*06c3fb27SDimitry Andric                    "cmpxchg16b\t$dst", []>,
941*06c3fb27SDimitry Andric                    TB, Requires<[HasCX16,In64BitMode]>;
942*06c3fb27SDimitry Andric} // SchedRW, mayLoad, mayStore, hasSideEffects
943*06c3fb27SDimitry Andric
944*06c3fb27SDimitry Andric
945*06c3fb27SDimitry Andric// Lock instruction prefix
946*06c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in
947*06c3fb27SDimitry Andricdef LOCK_PREFIX : I<0xF0, PrefixByte, (outs),  (ins), "lock", []>;
948*06c3fb27SDimitry Andric
949*06c3fb27SDimitry Andriclet SchedRW = [WriteNop] in {
950*06c3fb27SDimitry Andric
951*06c3fb27SDimitry Andric// Rex64 instruction prefix
952*06c3fb27SDimitry Andricdef REX64_PREFIX : I<0x48, PrefixByte, (outs),  (ins), "rex64", []>,
953*06c3fb27SDimitry Andric                     Requires<[In64BitMode]>;
954*06c3fb27SDimitry Andric
955*06c3fb27SDimitry Andric// Data16 instruction prefix
956*06c3fb27SDimitry Andricdef DATA16_PREFIX : I<0x66, PrefixByte, (outs),  (ins), "data16", []>;
957*06c3fb27SDimitry Andric} // SchedRW
958*06c3fb27SDimitry Andric
959*06c3fb27SDimitry Andric// Repeat string operation instruction prefixes
960*06c3fb27SDimitry Andriclet Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
961*06c3fb27SDimitry Andric// Repeat (used with INS, OUTS, MOVS, LODS and STOS)
962*06c3fb27SDimitry Andricdef REP_PREFIX : I<0xF3, PrefixByte, (outs),  (ins), "rep", []>;
963*06c3fb27SDimitry Andric// Repeat while not equal (used with CMPS and SCAS)
964*06c3fb27SDimitry Andricdef REPNE_PREFIX : I<0xF2, PrefixByte, (outs),  (ins), "repne", []>;
965*06c3fb27SDimitry Andric}
966*06c3fb27SDimitry Andric
967*06c3fb27SDimitry Andric// String manipulation instructions
968*06c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
969*06c3fb27SDimitry Andriclet Defs = [AL,ESI], Uses = [ESI,DF] in
970*06c3fb27SDimitry Andricdef LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
971*06c3fb27SDimitry Andric              "lodsb\t{$src, %al|al, $src}", []>;
972*06c3fb27SDimitry Andriclet Defs = [AX,ESI], Uses = [ESI,DF] in
973*06c3fb27SDimitry Andricdef LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
974*06c3fb27SDimitry Andric              "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
975*06c3fb27SDimitry Andriclet Defs = [EAX,ESI], Uses = [ESI,DF] in
976*06c3fb27SDimitry Andricdef LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
977*06c3fb27SDimitry Andric              "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
978*06c3fb27SDimitry Andriclet Defs = [RAX,ESI], Uses = [ESI,DF] in
979*06c3fb27SDimitry Andricdef LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
980*06c3fb27SDimitry Andric               "lodsq\t{$src, %rax|rax, $src}", []>,
981*06c3fb27SDimitry Andric               Requires<[In64BitMode]>;
982*06c3fb27SDimitry Andric}
983*06c3fb27SDimitry Andric
984*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
985*06c3fb27SDimitry Andriclet Defs = [ESI], Uses = [DX,ESI,DF] in {
986*06c3fb27SDimitry Andricdef OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
987*06c3fb27SDimitry Andric             "outsb\t{$src, %dx|dx, $src}", []>;
988*06c3fb27SDimitry Andricdef OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
989*06c3fb27SDimitry Andric              "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
990*06c3fb27SDimitry Andricdef OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
991*06c3fb27SDimitry Andric              "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
992*06c3fb27SDimitry Andric}
993*06c3fb27SDimitry Andric
994*06c3fb27SDimitry Andriclet Defs = [EDI], Uses = [DX,EDI,DF] in {
995*06c3fb27SDimitry Andricdef INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
996*06c3fb27SDimitry Andric             "insb\t{%dx, $dst|$dst, dx}", []>;
997*06c3fb27SDimitry Andricdef INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
998*06c3fb27SDimitry Andric             "insw\t{%dx, $dst|$dst, dx}", []>,  OpSize16;
999*06c3fb27SDimitry Andricdef INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
1000*06c3fb27SDimitry Andric             "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
1001*06c3fb27SDimitry Andric}
1002*06c3fb27SDimitry Andric}
1003*06c3fb27SDimitry Andric
1004*06c3fb27SDimitry Andric// EFLAGS management instructions.
1005*06c3fb27SDimitry Andriclet SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
1006*06c3fb27SDimitry Andricdef CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
1007*06c3fb27SDimitry Andricdef STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
1008*06c3fb27SDimitry Andricdef CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
1009*06c3fb27SDimitry Andric}
1010*06c3fb27SDimitry Andric
1011*06c3fb27SDimitry Andric// DF management instructions.
1012*06c3fb27SDimitry Andriclet SchedRW = [WriteALU], Defs = [DF] in {
1013*06c3fb27SDimitry Andricdef CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
1014*06c3fb27SDimitry Andricdef STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
1015*06c3fb27SDimitry Andric}
1016*06c3fb27SDimitry Andric
1017*06c3fb27SDimitry Andric// Table lookup instructions
1018*06c3fb27SDimitry Andriclet Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
1019*06c3fb27SDimitry Andricdef XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
1020*06c3fb27SDimitry Andric
1021*06c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
1022*06c3fb27SDimitry Andric// ASCII Adjust After Addition
1023*06c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1024*06c3fb27SDimitry Andricdef AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
1025*06c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
1026*06c3fb27SDimitry Andric
1027*06c3fb27SDimitry Andric// ASCII Adjust AX Before Division
1028*06c3fb27SDimitry Andriclet Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1029*06c3fb27SDimitry Andricdef AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
1030*06c3fb27SDimitry Andric                 "aad\t$src", []>, Requires<[Not64BitMode]>;
1031*06c3fb27SDimitry Andric
1032*06c3fb27SDimitry Andric// ASCII Adjust AX After Multiply
1033*06c3fb27SDimitry Andriclet Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1034*06c3fb27SDimitry Andricdef AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
1035*06c3fb27SDimitry Andric                 "aam\t$src", []>, Requires<[Not64BitMode]>;
1036*06c3fb27SDimitry Andric
1037*06c3fb27SDimitry Andric// ASCII Adjust AL After Subtraction - sets
1038*06c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
1039*06c3fb27SDimitry Andricdef AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
1040*06c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
1041*06c3fb27SDimitry Andric
1042*06c3fb27SDimitry Andric// Decimal Adjust AL after Addition
1043*06c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
1044*06c3fb27SDimitry Andricdef DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
1045*06c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
1046*06c3fb27SDimitry Andric
1047*06c3fb27SDimitry Andric// Decimal Adjust AL after Subtraction
1048*06c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
1049*06c3fb27SDimitry Andricdef DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
1050*06c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
1051*06c3fb27SDimitry Andric} // SchedRW
1052*06c3fb27SDimitry Andric
1053*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
1054*06c3fb27SDimitry Andric// Check Array Index Against Bounds
1055*06c3fb27SDimitry Andric// Note: "bound" does not have reversed operands in at&t syntax.
1056*06c3fb27SDimitry Andricdef BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1057*06c3fb27SDimitry Andric                   "bound\t$dst, $src", []>, OpSize16,
1058*06c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
1059*06c3fb27SDimitry Andricdef BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1060*06c3fb27SDimitry Andric                   "bound\t$dst, $src", []>, OpSize32,
1061*06c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
1062*06c3fb27SDimitry Andric
1063*06c3fb27SDimitry Andric// Adjust RPL Field of Segment Selector
1064*06c3fb27SDimitry Andricdef ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
1065*06c3fb27SDimitry Andric                 "arpl\t{$src, $dst|$dst, $src}", []>,
1066*06c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
1067*06c3fb27SDimitry Andriclet mayStore = 1 in
1068*06c3fb27SDimitry Andricdef ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1069*06c3fb27SDimitry Andric                 "arpl\t{$src, $dst|$dst, $src}", []>,
1070*06c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
1071*06c3fb27SDimitry Andric} // SchedRW
1072*06c3fb27SDimitry Andric
1073*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1074*06c3fb27SDimitry Andric// MOVBE Instructions
1075*06c3fb27SDimitry Andric//
1076*06c3fb27SDimitry Andriclet Predicates = [HasMOVBE] in {
1077*06c3fb27SDimitry Andric  let SchedRW = [WriteALULd] in {
1078*06c3fb27SDimitry Andric  def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1079*06c3fb27SDimitry Andric                    "movbe{w}\t{$src, $dst|$dst, $src}",
1080*06c3fb27SDimitry Andric                    [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
1081*06c3fb27SDimitry Andric                    OpSize16, T8PS;
1082*06c3fb27SDimitry Andric  def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1083*06c3fb27SDimitry Andric                    "movbe{l}\t{$src, $dst|$dst, $src}",
1084*06c3fb27SDimitry Andric                    [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
1085*06c3fb27SDimitry Andric                    OpSize32, T8PS;
1086*06c3fb27SDimitry Andric  def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1087*06c3fb27SDimitry Andric                     "movbe{q}\t{$src, $dst|$dst, $src}",
1088*06c3fb27SDimitry Andric                     [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
1089*06c3fb27SDimitry Andric                     T8PS;
1090*06c3fb27SDimitry Andric  }
1091*06c3fb27SDimitry Andric  let SchedRW = [WriteStore] in {
1092*06c3fb27SDimitry Andric  def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
1093*06c3fb27SDimitry Andric                    "movbe{w}\t{$src, $dst|$dst, $src}",
1094*06c3fb27SDimitry Andric                    [(store (bswap GR16:$src), addr:$dst)]>,
1095*06c3fb27SDimitry Andric                    OpSize16, T8PS;
1096*06c3fb27SDimitry Andric  def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1097*06c3fb27SDimitry Andric                    "movbe{l}\t{$src, $dst|$dst, $src}",
1098*06c3fb27SDimitry Andric                    [(store (bswap GR32:$src), addr:$dst)]>,
1099*06c3fb27SDimitry Andric                    OpSize32, T8PS;
1100*06c3fb27SDimitry Andric  def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1101*06c3fb27SDimitry Andric                     "movbe{q}\t{$src, $dst|$dst, $src}",
1102*06c3fb27SDimitry Andric                     [(store (bswap GR64:$src), addr:$dst)]>,
1103*06c3fb27SDimitry Andric                     T8PS;
1104*06c3fb27SDimitry Andric  }
1105*06c3fb27SDimitry Andric}
1106*06c3fb27SDimitry Andric
1107*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1108*06c3fb27SDimitry Andric// RDRAND Instruction
1109*06c3fb27SDimitry Andric//
1110*06c3fb27SDimitry Andriclet Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
1111*06c3fb27SDimitry Andric  def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
1112*06c3fb27SDimitry Andric                    "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
1113*06c3fb27SDimitry Andric                    OpSize16, PS;
1114*06c3fb27SDimitry Andric  def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
1115*06c3fb27SDimitry Andric                    "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
1116*06c3fb27SDimitry Andric                    OpSize32, PS;
1117*06c3fb27SDimitry Andric  def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
1118*06c3fb27SDimitry Andric                     "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
1119*06c3fb27SDimitry Andric                     PS;
1120*06c3fb27SDimitry Andric}
1121*06c3fb27SDimitry Andric
1122*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1123*06c3fb27SDimitry Andric// RDSEED Instruction
1124*06c3fb27SDimitry Andric//
1125*06c3fb27SDimitry Andriclet Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
1126*06c3fb27SDimitry Andric  def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
1127*06c3fb27SDimitry Andric                    [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
1128*06c3fb27SDimitry Andric  def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
1129*06c3fb27SDimitry Andric                    [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
1130*06c3fb27SDimitry Andric  def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
1131*06c3fb27SDimitry Andric                     [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
1132*06c3fb27SDimitry Andric}
1133*06c3fb27SDimitry Andric
1134*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1135*06c3fb27SDimitry Andric// LZCNT Instruction
1136*06c3fb27SDimitry Andric//
1137*06c3fb27SDimitry Andriclet Predicates = [HasLZCNT], Defs = [EFLAGS] in {
1138*06c3fb27SDimitry Andric  def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1139*06c3fb27SDimitry Andric                    "lzcnt{w}\t{$src, $dst|$dst, $src}",
1140*06c3fb27SDimitry Andric                    [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
1141*06c3fb27SDimitry Andric                    XS, OpSize16, Sched<[WriteLZCNT]>;
1142*06c3fb27SDimitry Andric  def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1143*06c3fb27SDimitry Andric                    "lzcnt{w}\t{$src, $dst|$dst, $src}",
1144*06c3fb27SDimitry Andric                    [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
1145*06c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
1146*06c3fb27SDimitry Andric
1147*06c3fb27SDimitry Andric  def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1148*06c3fb27SDimitry Andric                    "lzcnt{l}\t{$src, $dst|$dst, $src}",
1149*06c3fb27SDimitry Andric                    [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
1150*06c3fb27SDimitry Andric                    XS, OpSize32, Sched<[WriteLZCNT]>;
1151*06c3fb27SDimitry Andric  def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1152*06c3fb27SDimitry Andric                    "lzcnt{l}\t{$src, $dst|$dst, $src}",
1153*06c3fb27SDimitry Andric                    [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
1154*06c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
1155*06c3fb27SDimitry Andric
1156*06c3fb27SDimitry Andric  def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1157*06c3fb27SDimitry Andric                     "lzcnt{q}\t{$src, $dst|$dst, $src}",
1158*06c3fb27SDimitry Andric                     [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
1159*06c3fb27SDimitry Andric                     XS, Sched<[WriteLZCNT]>;
1160*06c3fb27SDimitry Andric  def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1161*06c3fb27SDimitry Andric                     "lzcnt{q}\t{$src, $dst|$dst, $src}",
1162*06c3fb27SDimitry Andric                     [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
1163*06c3fb27SDimitry Andric                      (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
1164*06c3fb27SDimitry Andric}
1165*06c3fb27SDimitry Andric
1166*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1167*06c3fb27SDimitry Andric// BMI Instructions
1168*06c3fb27SDimitry Andric//
1169*06c3fb27SDimitry Andriclet Predicates = [HasBMI], Defs = [EFLAGS] in {
1170*06c3fb27SDimitry Andric  def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
1171*06c3fb27SDimitry Andric                    "tzcnt{w}\t{$src, $dst|$dst, $src}",
1172*06c3fb27SDimitry Andric                    [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
1173*06c3fb27SDimitry Andric                    XS, OpSize16, Sched<[WriteTZCNT]>;
1174*06c3fb27SDimitry Andric  def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
1175*06c3fb27SDimitry Andric                    "tzcnt{w}\t{$src, $dst|$dst, $src}",
1176*06c3fb27SDimitry Andric                    [(set GR16:$dst, (cttz (loadi16 addr:$src))),
1177*06c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
1178*06c3fb27SDimitry Andric
1179*06c3fb27SDimitry Andric  def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
1180*06c3fb27SDimitry Andric                    "tzcnt{l}\t{$src, $dst|$dst, $src}",
1181*06c3fb27SDimitry Andric                    [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
1182*06c3fb27SDimitry Andric                    XS, OpSize32, Sched<[WriteTZCNT]>;
1183*06c3fb27SDimitry Andric  def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
1184*06c3fb27SDimitry Andric                    "tzcnt{l}\t{$src, $dst|$dst, $src}",
1185*06c3fb27SDimitry Andric                    [(set GR32:$dst, (cttz (loadi32 addr:$src))),
1186*06c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
1187*06c3fb27SDimitry Andric
1188*06c3fb27SDimitry Andric  def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
1189*06c3fb27SDimitry Andric                     "tzcnt{q}\t{$src, $dst|$dst, $src}",
1190*06c3fb27SDimitry Andric                     [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
1191*06c3fb27SDimitry Andric                     XS, Sched<[WriteTZCNT]>;
1192*06c3fb27SDimitry Andric  def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
1193*06c3fb27SDimitry Andric                     "tzcnt{q}\t{$src, $dst|$dst, $src}",
1194*06c3fb27SDimitry Andric                     [(set GR64:$dst, (cttz (loadi64 addr:$src))),
1195*06c3fb27SDimitry Andric                      (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
1196*06c3fb27SDimitry Andric}
1197*06c3fb27SDimitry Andric
1198*06c3fb27SDimitry Andricmulticlass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
1199*06c3fb27SDimitry Andric                  RegisterClass RC, X86MemOperand x86memop,
1200*06c3fb27SDimitry Andric                  X86FoldableSchedWrite sched> {
1201*06c3fb27SDimitry Andriclet hasSideEffects = 0 in {
1202*06c3fb27SDimitry Andric  def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
1203*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
1204*06c3fb27SDimitry Andric             T8PS, VEX_4V, Sched<[sched]>;
1205*06c3fb27SDimitry Andric  let mayLoad = 1 in
1206*06c3fb27SDimitry Andric  def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
1207*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
1208*06c3fb27SDimitry Andric             T8PS, VEX_4V, Sched<[sched.Folded]>;
1209*06c3fb27SDimitry Andric}
1210*06c3fb27SDimitry Andric}
1211*06c3fb27SDimitry Andric
1212*06c3fb27SDimitry Andriclet Predicates = [HasBMI], Defs = [EFLAGS] in {
1213*06c3fb27SDimitry Andric  defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>;
1214*06c3fb27SDimitry Andric  defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, REX_W;
1215*06c3fb27SDimitry Andric  defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>;
1216*06c3fb27SDimitry Andric  defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, REX_W;
1217*06c3fb27SDimitry Andric  defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>;
1218*06c3fb27SDimitry Andric  defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, REX_W;
1219*06c3fb27SDimitry Andric}
1220*06c3fb27SDimitry Andric
1221*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1222*06c3fb27SDimitry Andric// Pattern fragments to auto generate BMI instructions.
1223*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1224*06c3fb27SDimitry Andric
1225*06c3fb27SDimitry Andricdef or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
1226*06c3fb27SDimitry Andric                           (X86or_flag node:$lhs, node:$rhs), [{
1227*06c3fb27SDimitry Andric  return hasNoCarryFlagUses(SDValue(N, 1));
1228*06c3fb27SDimitry Andric}]>;
1229*06c3fb27SDimitry Andric
1230*06c3fb27SDimitry Andricdef xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
1231*06c3fb27SDimitry Andric                            (X86xor_flag node:$lhs, node:$rhs), [{
1232*06c3fb27SDimitry Andric  return hasNoCarryFlagUses(SDValue(N, 1));
1233*06c3fb27SDimitry Andric}]>;
1234*06c3fb27SDimitry Andric
1235*06c3fb27SDimitry Andricdef and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs),
1236*06c3fb27SDimitry Andric                            (X86and_flag node:$lhs, node:$rhs), [{
1237*06c3fb27SDimitry Andric  return hasNoCarryFlagUses(SDValue(N, 1));
1238*06c3fb27SDimitry Andric}]>;
1239*06c3fb27SDimitry Andric
1240*06c3fb27SDimitry Andric
1241*06c3fb27SDimitry Andriclet Predicates = [HasBMI] in {
1242*06c3fb27SDimitry Andric  // FIXME(1): patterns for the load versions are not implemented
1243*06c3fb27SDimitry Andric  // FIXME(2): By only matching `add_su` and `ineg_su` we may emit
1244*06c3fb27SDimitry Andric  // extra `mov` instructions if `src` has future uses. It may be better
1245*06c3fb27SDimitry Andric  // to always match if `src` has more users.
1246*06c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (add_su GR32:$src, -1)),
1247*06c3fb27SDimitry Andric            (BLSR32rr GR32:$src)>;
1248*06c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (add_su GR64:$src, -1)),
1249*06c3fb27SDimitry Andric            (BLSR64rr GR64:$src)>;
1250*06c3fb27SDimitry Andric
1251*06c3fb27SDimitry Andric  def : Pat<(xor GR32:$src, (add_su GR32:$src, -1)),
1252*06c3fb27SDimitry Andric            (BLSMSK32rr GR32:$src)>;
1253*06c3fb27SDimitry Andric  def : Pat<(xor GR64:$src, (add_su GR64:$src, -1)),
1254*06c3fb27SDimitry Andric            (BLSMSK64rr GR64:$src)>;
1255*06c3fb27SDimitry Andric
1256*06c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (ineg_su GR32:$src)),
1257*06c3fb27SDimitry Andric            (BLSI32rr GR32:$src)>;
1258*06c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (ineg_su GR64:$src)),
1259*06c3fb27SDimitry Andric            (BLSI64rr GR64:$src)>;
1260*06c3fb27SDimitry Andric
1261*06c3fb27SDimitry Andric  // Versions to match flag producing ops.
1262*06c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
1263*06c3fb27SDimitry Andric            (BLSR32rr GR32:$src)>;
1264*06c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
1265*06c3fb27SDimitry Andric            (BLSR64rr GR64:$src)>;
1266*06c3fb27SDimitry Andric
1267*06c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
1268*06c3fb27SDimitry Andric            (BLSMSK32rr GR32:$src)>;
1269*06c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
1270*06c3fb27SDimitry Andric            (BLSMSK64rr GR64:$src)>;
1271*06c3fb27SDimitry Andric
1272*06c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (ineg_su GR32:$src)),
1273*06c3fb27SDimitry Andric            (BLSI32rr GR32:$src)>;
1274*06c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (ineg_su GR64:$src)),
1275*06c3fb27SDimitry Andric            (BLSI64rr GR64:$src)>;
1276*06c3fb27SDimitry Andric}
1277*06c3fb27SDimitry Andric
1278*06c3fb27SDimitry Andricmulticlass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC,
1279*06c3fb27SDimitry Andric                     X86MemOperand x86memop, SDNode OpNode,
1280*06c3fb27SDimitry Andric                     PatFrag ld_frag, X86FoldableSchedWrite Sched> {
1281*06c3fb27SDimitry Andric  def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1282*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1283*06c3fb27SDimitry Andric             [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
1284*06c3fb27SDimitry Andric             T8PS, VEX, Sched<[Sched]>;
1285*06c3fb27SDimitry Andric  def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
1286*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1287*06c3fb27SDimitry Andric             [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)),
1288*06c3fb27SDimitry Andric              (implicit EFLAGS)]>, T8PS, VEX,
1289*06c3fb27SDimitry Andric             Sched<[Sched.Folded,
1290*06c3fb27SDimitry Andric                    // x86memop:$src1
1291*06c3fb27SDimitry Andric                    ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1292*06c3fb27SDimitry Andric                    ReadDefault,
1293*06c3fb27SDimitry Andric                    // RC:$src2
1294*06c3fb27SDimitry Andric                    Sched.ReadAfterFold]>;
1295*06c3fb27SDimitry Andric}
1296*06c3fb27SDimitry Andric
1297*06c3fb27SDimitry Andriclet Predicates = [HasBMI], Defs = [EFLAGS] in {
1298*06c3fb27SDimitry Andric  defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem,
1299*06c3fb27SDimitry Andric                           X86bextr, loadi32, WriteBEXTR>;
1300*06c3fb27SDimitry Andric  defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem,
1301*06c3fb27SDimitry Andric                           X86bextr, loadi64, WriteBEXTR>, REX_W;
1302*06c3fb27SDimitry Andric}
1303*06c3fb27SDimitry Andric
1304*06c3fb27SDimitry Andricmulticlass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC,
1305*06c3fb27SDimitry Andric                    X86MemOperand x86memop, SDNode Int,
1306*06c3fb27SDimitry Andric                    PatFrag ld_frag, X86FoldableSchedWrite Sched> {
1307*06c3fb27SDimitry Andric  def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1308*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1309*06c3fb27SDimitry Andric             [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
1310*06c3fb27SDimitry Andric             T8PS, VEX, Sched<[Sched]>;
1311*06c3fb27SDimitry Andric  def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
1312*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1313*06c3fb27SDimitry Andric             [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)),
1314*06c3fb27SDimitry Andric              (implicit EFLAGS)]>, T8PS, VEX,
1315*06c3fb27SDimitry Andric             Sched<[Sched.Folded,
1316*06c3fb27SDimitry Andric                    // x86memop:$src1
1317*06c3fb27SDimitry Andric                    ReadDefault, ReadDefault, ReadDefault, ReadDefault,
1318*06c3fb27SDimitry Andric                    ReadDefault,
1319*06c3fb27SDimitry Andric                    // RC:$src2
1320*06c3fb27SDimitry Andric                    Sched.ReadAfterFold]>;
1321*06c3fb27SDimitry Andric}
1322*06c3fb27SDimitry Andric
1323*06c3fb27SDimitry Andriclet Predicates = [HasBMI2], Defs = [EFLAGS] in {
1324*06c3fb27SDimitry Andric  defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem,
1325*06c3fb27SDimitry Andric                         X86bzhi, loadi32, WriteBZHI>;
1326*06c3fb27SDimitry Andric  defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem,
1327*06c3fb27SDimitry Andric                         X86bzhi, loadi64, WriteBZHI>, REX_W;
1328*06c3fb27SDimitry Andric}
1329*06c3fb27SDimitry Andric
1330*06c3fb27SDimitry Andricdef CountTrailingOnes : SDNodeXForm<imm, [{
1331*06c3fb27SDimitry Andric  // Count the trailing ones in the immediate.
1332*06c3fb27SDimitry Andric  return getI8Imm(llvm::countr_one(N->getZExtValue()), SDLoc(N));
1333*06c3fb27SDimitry Andric}]>;
1334*06c3fb27SDimitry Andric
1335*06c3fb27SDimitry Andricdef BEXTRMaskXForm : SDNodeXForm<imm, [{
1336*06c3fb27SDimitry Andric  unsigned Length = llvm::countr_one(N->getZExtValue());
1337*06c3fb27SDimitry Andric  return getI32Imm(Length << 8, SDLoc(N));
1338*06c3fb27SDimitry Andric}]>;
1339*06c3fb27SDimitry Andric
1340*06c3fb27SDimitry Andricdef AndMask64 : ImmLeaf<i64, [{
1341*06c3fb27SDimitry Andric  return isMask_64(Imm) && !isUInt<32>(Imm);
1342*06c3fb27SDimitry Andric}]>;
1343*06c3fb27SDimitry Andric
1344*06c3fb27SDimitry Andric// Use BEXTR for 64-bit 'and' with large immediate 'mask'.
1345*06c3fb27SDimitry Andriclet Predicates = [HasBMI, NoBMI2, NoTBM] in {
1346*06c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
1347*06c3fb27SDimitry Andric            (BEXTR64rr GR64:$src,
1348*06c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
1349*06c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
1350*06c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
1351*06c3fb27SDimitry Andric            (BEXTR64rm addr:$src,
1352*06c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
1353*06c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
1354*06c3fb27SDimitry Andric}
1355*06c3fb27SDimitry Andric
1356*06c3fb27SDimitry Andric// Use BZHI for 64-bit 'and' with large immediate 'mask'.
1357*06c3fb27SDimitry Andriclet Predicates = [HasBMI2, NoTBM] in {
1358*06c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
1359*06c3fb27SDimitry Andric            (BZHI64rr GR64:$src,
1360*06c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1361*06c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
1362*06c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
1363*06c3fb27SDimitry Andric            (BZHI64rm addr:$src,
1364*06c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1365*06c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
1366*06c3fb27SDimitry Andric}
1367*06c3fb27SDimitry Andric
1368*06c3fb27SDimitry Andricmulticlass bmi_pdep_pext<string mnemonic, RegisterClass RC,
1369*06c3fb27SDimitry Andric                         X86MemOperand x86memop, SDNode OpNode,
1370*06c3fb27SDimitry Andric                         PatFrag ld_frag> {
1371*06c3fb27SDimitry Andric  def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
1372*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1373*06c3fb27SDimitry Andric             [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>,
1374*06c3fb27SDimitry Andric             VEX_4V, Sched<[WriteALU]>;
1375*06c3fb27SDimitry Andric  def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
1376*06c3fb27SDimitry Andric             !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
1377*06c3fb27SDimitry Andric             [(set RC:$dst, (OpNode RC:$src1, (ld_frag addr:$src2)))]>,
1378*06c3fb27SDimitry Andric             VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
1379*06c3fb27SDimitry Andric}
1380*06c3fb27SDimitry Andric
1381*06c3fb27SDimitry Andriclet Predicates = [HasBMI2] in {
1382*06c3fb27SDimitry Andric  defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
1383*06c3fb27SDimitry Andric                               X86pdep, loadi32>, T8XD;
1384*06c3fb27SDimitry Andric  defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
1385*06c3fb27SDimitry Andric                               X86pdep, loadi64>, T8XD, REX_W;
1386*06c3fb27SDimitry Andric  defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
1387*06c3fb27SDimitry Andric                               X86pext, loadi32>, T8XS;
1388*06c3fb27SDimitry Andric  defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
1389*06c3fb27SDimitry Andric                               X86pext, loadi64>, T8XS, REX_W;
1390*06c3fb27SDimitry Andric}
1391*06c3fb27SDimitry Andric
1392*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1393*06c3fb27SDimitry Andric// Lightweight Profiling Instructions
1394*06c3fb27SDimitry Andric
1395*06c3fb27SDimitry Andriclet Predicates = [HasLWP], SchedRW = [WriteSystem] in {
1396*06c3fb27SDimitry Andric
1397*06c3fb27SDimitry Andricdef LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
1398*06c3fb27SDimitry Andric               [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
1399*06c3fb27SDimitry Andricdef SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
1400*06c3fb27SDimitry Andric               [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
1401*06c3fb27SDimitry Andric
1402*06c3fb27SDimitry Andricdef LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
1403*06c3fb27SDimitry Andric                 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, REX_W;
1404*06c3fb27SDimitry Andricdef SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
1405*06c3fb27SDimitry Andric                 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, REX_W;
1406*06c3fb27SDimitry Andric
1407*06c3fb27SDimitry Andricmulticlass lwpins_intr<RegisterClass RC> {
1408*06c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
1409*06c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
1410*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>,
1411*06c3fb27SDimitry Andric                 XOP_4V, XOPA;
1412*06c3fb27SDimitry Andric  let mayLoad = 1 in
1413*06c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
1414*06c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
1415*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>,
1416*06c3fb27SDimitry Andric                 XOP_4V, XOPA;
1417*06c3fb27SDimitry Andric}
1418*06c3fb27SDimitry Andric
1419*06c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
1420*06c3fb27SDimitry Andric  defm LWPINS32 : lwpins_intr<GR32>;
1421*06c3fb27SDimitry Andric  defm LWPINS64 : lwpins_intr<GR64>, REX_W;
1422*06c3fb27SDimitry Andric} // EFLAGS
1423*06c3fb27SDimitry Andric
1424*06c3fb27SDimitry Andricmulticlass lwpval_intr<RegisterClass RC, Intrinsic Int> {
1425*06c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
1426*06c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
1427*06c3fb27SDimitry Andric                 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA;
1428*06c3fb27SDimitry Andric  let mayLoad = 1 in
1429*06c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
1430*06c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
1431*06c3fb27SDimitry Andric                 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>,
1432*06c3fb27SDimitry Andric                 XOP_4V, XOPA;
1433*06c3fb27SDimitry Andric}
1434*06c3fb27SDimitry Andric
1435*06c3fb27SDimitry Andricdefm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
1436*06c3fb27SDimitry Andricdefm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, REX_W;
1437*06c3fb27SDimitry Andric
1438*06c3fb27SDimitry Andric} // HasLWP, SchedRW
1439*06c3fb27SDimitry Andric
1440*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1441*06c3fb27SDimitry Andric// MONITORX/MWAITX Instructions
1442*06c3fb27SDimitry Andric//
1443*06c3fb27SDimitry Andriclet SchedRW = [ WriteSystem ] in {
1444*06c3fb27SDimitry Andric  let Uses = [ EAX, ECX, EDX ] in
1445*06c3fb27SDimitry Andric  def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
1446*06c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, Not64BitMode ]>;
1447*06c3fb27SDimitry Andric  let Uses = [ RAX, ECX, EDX ] in
1448*06c3fb27SDimitry Andric  def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
1449*06c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, In64BitMode ]>;
1450*06c3fb27SDimitry Andric
1451*06c3fb27SDimitry Andric  let Uses = [ ECX, EAX, EBX ] in {
1452*06c3fb27SDimitry Andric    def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
1453*06c3fb27SDimitry Andric                    []>, TB, Requires<[ HasMWAITX ]>;
1454*06c3fb27SDimitry Andric  }
1455*06c3fb27SDimitry Andric} // SchedRW
1456*06c3fb27SDimitry Andric
1457*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1458*06c3fb27SDimitry Andric// WAITPKG Instructions
1459*06c3fb27SDimitry Andric//
1460*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
1461*06c3fb27SDimitry Andric  def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
1462*06c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
1463*06c3fb27SDimitry Andric                     XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
1464*06c3fb27SDimitry Andric  def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
1465*06c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
1466*06c3fb27SDimitry Andric                     XS, AdSize32, Requires<[HasWAITPKG]>;
1467*06c3fb27SDimitry Andric  def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
1468*06c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
1469*06c3fb27SDimitry Andric                     XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
1470*06c3fb27SDimitry Andric  let Uses = [EAX, EDX], Defs = [EFLAGS] in {
1471*06c3fb27SDimitry Andric    def UMWAIT : I<0xAE, MRM6r,
1472*06c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "umwait\t$src",
1473*06c3fb27SDimitry Andric                     [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
1474*06c3fb27SDimitry Andric                     XD, Requires<[HasWAITPKG]>;
1475*06c3fb27SDimitry Andric    def TPAUSE : I<0xAE, MRM6r,
1476*06c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "tpause\t$src",
1477*06c3fb27SDimitry Andric                     [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
1478*06c3fb27SDimitry Andric                     PD, Requires<[HasWAITPKG]>;
1479*06c3fb27SDimitry Andric  }
1480*06c3fb27SDimitry Andric} // SchedRW
1481*06c3fb27SDimitry Andric
1482*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1483*06c3fb27SDimitry Andric// MOVDIRI - Move doubleword/quadword as direct store
1484*06c3fb27SDimitry Andric//
1485*06c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
1486*06c3fb27SDimitry Andricdef MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1487*06c3fb27SDimitry Andric                  "movdiri\t{$src, $dst|$dst, $src}",
1488*06c3fb27SDimitry Andric                  [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
1489*06c3fb27SDimitry Andric                 T8PS, Requires<[HasMOVDIRI]>;
1490*06c3fb27SDimitry Andricdef MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1491*06c3fb27SDimitry Andric                   "movdiri\t{$src, $dst|$dst, $src}",
1492*06c3fb27SDimitry Andric                   [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
1493*06c3fb27SDimitry Andric                  T8PS, Requires<[In64BitMode, HasMOVDIRI]>;
1494*06c3fb27SDimitry Andric} // SchedRW
1495*06c3fb27SDimitry Andric
1496*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1497*06c3fb27SDimitry Andric// MOVDIR64B - Move 64 bytes as direct store
1498*06c3fb27SDimitry Andric//
1499*06c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
1500*06c3fb27SDimitry Andricdef MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
1501*06c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}", []>,
1502*06c3fb27SDimitry Andric                   T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
1503*06c3fb27SDimitry Andricdef MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
1504*06c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
1505*06c3fb27SDimitry Andric                    [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
1506*06c3fb27SDimitry Andric                   T8PD, AdSize32, Requires<[HasMOVDIR64B]>;
1507*06c3fb27SDimitry Andricdef MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
1508*06c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
1509*06c3fb27SDimitry Andric                    [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
1510*06c3fb27SDimitry Andric                   T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>;
1511*06c3fb27SDimitry Andric} // SchedRW
1512*06c3fb27SDimitry Andric
1513*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1514*06c3fb27SDimitry Andric// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
1515*06c3fb27SDimitry Andric//
1516*06c3fb27SDimitry Andriclet SchedRW = [WriteStore], Defs = [EFLAGS] in {
1517*06c3fb27SDimitry Andric  def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
1518*06c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
1519*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
1520*06c3fb27SDimitry Andric                 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
1521*06c3fb27SDimitry Andric  def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
1522*06c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
1523*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
1524*06c3fb27SDimitry Andric                 T8XD, AdSize32, Requires<[HasENQCMD]>;
1525*06c3fb27SDimitry Andric  def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
1526*06c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
1527*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
1528*06c3fb27SDimitry Andric                 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
1529*06c3fb27SDimitry Andric
1530*06c3fb27SDimitry Andric  def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
1531*06c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
1532*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
1533*06c3fb27SDimitry Andric                 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
1534*06c3fb27SDimitry Andric  def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
1535*06c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
1536*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
1537*06c3fb27SDimitry Andric                 T8XS, AdSize32, Requires<[HasENQCMD]>;
1538*06c3fb27SDimitry Andric  def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
1539*06c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
1540*06c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
1541*06c3fb27SDimitry Andric                 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
1542*06c3fb27SDimitry Andric}
1543*06c3fb27SDimitry Andric
1544*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1545*06c3fb27SDimitry Andric// CLZERO Instruction
1546*06c3fb27SDimitry Andric//
1547*06c3fb27SDimitry Andriclet SchedRW = [WriteLoad] in {
1548*06c3fb27SDimitry Andric  let Uses = [EAX] in
1549*06c3fb27SDimitry Andric  def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
1550*06c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, Not64BitMode]>;
1551*06c3fb27SDimitry Andric  let Uses = [RAX] in
1552*06c3fb27SDimitry Andric  def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
1553*06c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, In64BitMode]>;
1554*06c3fb27SDimitry Andric} // SchedRW
1555*06c3fb27SDimitry Andric
1556*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1557*06c3fb27SDimitry Andric// INVLPGB Instruction
1558*06c3fb27SDimitry Andric// OPCODE 0F 01 FE
1559*06c3fb27SDimitry Andric//
1560*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
1561*06c3fb27SDimitry Andric  let Uses = [EAX, EDX] in
1562*06c3fb27SDimitry Andric  def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins),
1563*06c3fb27SDimitry Andric                  "invlpgb", []>,
1564*06c3fb27SDimitry Andric                  PS, Requires<[Not64BitMode]>;
1565*06c3fb27SDimitry Andric  let Uses = [RAX, EDX] in
1566*06c3fb27SDimitry Andric  def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins),
1567*06c3fb27SDimitry Andric                  "invlpgb", []>,
1568*06c3fb27SDimitry Andric                  PS, Requires<[In64BitMode]>;
1569*06c3fb27SDimitry Andric} // SchedRW
1570*06c3fb27SDimitry Andric
1571*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1572*06c3fb27SDimitry Andric// TLBSYNC Instruction
1573*06c3fb27SDimitry Andric// OPCODE 0F 01 FF
1574*06c3fb27SDimitry Andric//
1575*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
1576*06c3fb27SDimitry Andric  def TLBSYNC   : I<0x01, MRM_FF, (outs), (ins),
1577*06c3fb27SDimitry Andric                  "tlbsync", []>,
1578*06c3fb27SDimitry Andric                  PS, Requires<[]>;
1579*06c3fb27SDimitry Andric} // SchedRW
1580*06c3fb27SDimitry Andric
1581*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1582*06c3fb27SDimitry Andric// HRESET Instruction
1583*06c3fb27SDimitry Andric//
1584*06c3fb27SDimitry Andriclet Uses = [EAX], SchedRW = [WriteSystem] in
1585*06c3fb27SDimitry Andric  def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>,
1586*06c3fb27SDimitry Andric                   Requires<[HasHRESET]>, TAXS;
1587*06c3fb27SDimitry Andric
1588*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1589*06c3fb27SDimitry Andric// SERIALIZE Instruction
1590*06c3fb27SDimitry Andric//
1591*06c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in
1592*06c3fb27SDimitry Andric  def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize",
1593*06c3fb27SDimitry Andric                    [(int_x86_serialize)]>, PS,
1594*06c3fb27SDimitry Andric                    Requires<[HasSERIALIZE]>;
1595*06c3fb27SDimitry Andric
1596*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1597*06c3fb27SDimitry Andric// TSXLDTRK - TSX Suspend Load Address Tracking
1598*06c3fb27SDimitry Andric//
1599*06c3fb27SDimitry Andriclet Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in {
1600*06c3fb27SDimitry Andric  def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk",
1601*06c3fb27SDimitry Andric                    [(int_x86_xsusldtrk)]>, XD;
1602*06c3fb27SDimitry Andric  def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk",
1603*06c3fb27SDimitry Andric                    [(int_x86_xresldtrk)]>, XD;
1604*06c3fb27SDimitry Andric}
1605*06c3fb27SDimitry Andric
1606*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1607*06c3fb27SDimitry Andric// UINTR Instructions
1608*06c3fb27SDimitry Andric//
1609*06c3fb27SDimitry Andriclet Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in {
1610*06c3fb27SDimitry Andric  def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret",
1611*06c3fb27SDimitry Andric               []>, XS;
1612*06c3fb27SDimitry Andric  def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui",
1613*06c3fb27SDimitry Andric               [(int_x86_clui)]>, XS;
1614*06c3fb27SDimitry Andric  def STUI : I<0x01, MRM_EF, (outs), (ins), "stui",
1615*06c3fb27SDimitry Andric               [(int_x86_stui)]>, XS;
1616*06c3fb27SDimitry Andric
1617*06c3fb27SDimitry Andric  def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg",
1618*06c3fb27SDimitry Andric                   [(int_x86_senduipi GR64:$arg)]>, XS;
1619*06c3fb27SDimitry Andric
1620*06c3fb27SDimitry Andric  let Defs = [EFLAGS] in
1621*06c3fb27SDimitry Andric    def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui",
1622*06c3fb27SDimitry Andric                   [(set EFLAGS, (X86testui))]>, XS;
1623*06c3fb27SDimitry Andric}
1624*06c3fb27SDimitry Andric
1625*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1626*06c3fb27SDimitry Andric// PREFETCHIT0 and PREFETCHIT1 Instructions
1627*06c3fb27SDimitry Andric// prefetch ADDR, RW, Locality, Data
1628*06c3fb27SDimitry Andriclet Predicates = [HasPREFETCHI, In64BitMode], SchedRW = [WriteLoad] in {
1629*06c3fb27SDimitry Andric  def PREFETCHIT0 : I<0x18, MRM7m, (outs), (ins i8mem:$src),
1630*06c3fb27SDimitry Andric    "prefetchit0\t$src", [(prefetch addr:$src, (i32 0), (i32 3), (i32 0))]>, TB;
1631*06c3fb27SDimitry Andric  def PREFETCHIT1 : I<0x18, MRM6m, (outs), (ins i8mem:$src),
1632*06c3fb27SDimitry Andric    "prefetchit1\t$src", [(prefetch addr:$src, (i32 0), (i32 2), (i32 0))]>, TB;
1633*06c3fb27SDimitry Andric}
1634*06c3fb27SDimitry Andric
1635*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1636*06c3fb27SDimitry Andric// CMPCCXADD Instructions
1637*06c3fb27SDimitry Andric//
1638*06c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, mayLoad = 1, mayStore = 1,
1639*06c3fb27SDimitry Andric    Predicates = [HasCMPCCXADD, In64BitMode], Defs = [EFLAGS],
1640*06c3fb27SDimitry Andric    Constraints = "$dstsrc1 = $dst" in {
1641*06c3fb27SDimitry Andricdef CMPCCXADDmr32 : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst),
1642*06c3fb27SDimitry Andric          (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond),
1643*06c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
1644*06c3fb27SDimitry Andric          [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2,
1645*06c3fb27SDimitry Andric            GR32:$dstsrc1, GR32:$src3, timm:$cond))]>,
1646*06c3fb27SDimitry Andric          VEX_4V, T8PD, Sched<[WriteXCHG]>;
1647*06c3fb27SDimitry Andric
1648*06c3fb27SDimitry Andricdef CMPCCXADDmr64 : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst),
1649*06c3fb27SDimitry Andric          (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond),
1650*06c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
1651*06c3fb27SDimitry Andric          [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2,
1652*06c3fb27SDimitry Andric            GR64:$dstsrc1, GR64:$src3, timm:$cond))]>,
1653*06c3fb27SDimitry Andric          VEX_4V, REX_W, T8PD, Sched<[WriteXCHG]>;
1654*06c3fb27SDimitry Andric}
1655*06c3fb27SDimitry Andric
1656*06c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1657*06c3fb27SDimitry Andric// Memory Instructions
1658*06c3fb27SDimitry Andric//
1659*06c3fb27SDimitry Andric
1660*06c3fb27SDimitry Andriclet Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
1661*06c3fb27SDimitry Andricdef CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
1662*06c3fb27SDimitry Andric                   "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
1663*06c3fb27SDimitry Andric
1664*06c3fb27SDimitry Andriclet Predicates = [HasCLWB], SchedRW = [WriteLoad] in
1665*06c3fb27SDimitry Andricdef CLWB       : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
1666*06c3fb27SDimitry Andric                   [(int_x86_clwb addr:$src)]>, PD;
1667*06c3fb27SDimitry Andric
1668*06c3fb27SDimitry Andriclet Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
1669*06c3fb27SDimitry Andricdef CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
1670*06c3fb27SDimitry Andric                   [(int_x86_cldemote addr:$src)]>, PS;
1671