xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/X86InstrMisc.td (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
106c3fb27SDimitry Andric//===-- X86InstrMisc.td - Misc X86 Instruction Definition -*- tablegen -*-===//
206c3fb27SDimitry Andric//
306c3fb27SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric//
706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric//
906c3fb27SDimitry Andric// This file defining the misc X86 instructions.
1006c3fb27SDimitry Andric//
1106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1206c3fb27SDimitry Andric
1306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
1406c3fb27SDimitry Andric// Instruction list.
1506c3fb27SDimitry Andric//
1606c3fb27SDimitry Andric
1706c3fb27SDimitry Andric// Nop
1806c3fb27SDimitry Andriclet hasSideEffects = 0, SchedRW = [WriteNop] in {
1906c3fb27SDimitry Andric  def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>;
2006c3fb27SDimitry Andric  def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero),
2106c3fb27SDimitry Andric                "nop{w}\t$zero", []>, TB, OpSize16;
2206c3fb27SDimitry Andric  def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero),
2306c3fb27SDimitry Andric                "nop{l}\t$zero", []>, TB, OpSize32;
2406c3fb27SDimitry Andric  def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero),
2506c3fb27SDimitry Andric                "nop{q}\t$zero", []>, TB, Requires<[In64BitMode]>;
2606c3fb27SDimitry Andric  // Also allow register so we can assemble/disassemble
2706c3fb27SDimitry Andric  def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero),
2806c3fb27SDimitry Andric                 "nop{w}\t$zero", []>, TB, OpSize16;
2906c3fb27SDimitry Andric  def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero),
3006c3fb27SDimitry Andric                 "nop{l}\t$zero", []>, TB, OpSize32;
3106c3fb27SDimitry Andric  def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero),
3206c3fb27SDimitry Andric                  "nop{q}\t$zero", []>, TB, Requires<[In64BitMode]>;
3306c3fb27SDimitry Andric}
3406c3fb27SDimitry Andric
3506c3fb27SDimitry Andric
3606c3fb27SDimitry Andric// Constructing a stack frame.
3706c3fb27SDimitry Andricdef ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl),
3806c3fb27SDimitry Andric                 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>;
3906c3fb27SDimitry Andric
4006c3fb27SDimitry Andriclet SchedRW = [WriteALU] in {
4106c3fb27SDimitry Andriclet Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in
4206c3fb27SDimitry Andricdef LEAVE    : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
4306c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
4406c3fb27SDimitry Andric
4506c3fb27SDimitry Andriclet Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in
4606c3fb27SDimitry Andricdef LEAVE64  : I<0xC9, RawFrm, (outs), (ins), "leave", []>,
4706c3fb27SDimitry Andric                 Requires<[In64BitMode]>;
4806c3fb27SDimitry Andric} // SchedRW
4906c3fb27SDimitry Andric
5006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
5106c3fb27SDimitry Andric//  Miscellaneous Instructions.
5206c3fb27SDimitry Andric//
5306c3fb27SDimitry Andric
5406c3fb27SDimitry Andriclet isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1,
5506c3fb27SDimitry Andric    SchedRW = [WriteSystem] in
5606c3fb27SDimitry Andric  def Int_eh_sjlj_setup_dispatch
5706c3fb27SDimitry Andric    : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>;
5806c3fb27SDimitry Andric
5906c3fb27SDimitry Andriclet Defs = [ESP], Uses = [ESP], hasSideEffects=0 in {
6006c3fb27SDimitry Andriclet mayLoad = 1, SchedRW = [WriteLoad] in {
6106c3fb27SDimitry Andricdef POP16r  : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
6206c3fb27SDimitry Andric                OpSize16;
6306c3fb27SDimitry Andricdef POP32r  : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
6406c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
6506c3fb27SDimitry Andric// Long form for the disassembler.
6606c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
6706c3fb27SDimitry Andricdef POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>,
6806c3fb27SDimitry Andric                OpSize16;
6906c3fb27SDimitry Andricdef POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>,
7006c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
7106c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
7206c3fb27SDimitry Andric} // mayLoad, SchedRW
7306c3fb27SDimitry Andriclet mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in {
7406c3fb27SDimitry Andricdef POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>,
7506c3fb27SDimitry Andric                OpSize16;
7606c3fb27SDimitry Andricdef POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>,
7706c3fb27SDimitry Andric                OpSize32, Requires<[Not64BitMode]>;
7806c3fb27SDimitry Andric} // mayStore, mayLoad, SchedRW
7906c3fb27SDimitry Andric
8006c3fb27SDimitry Andriclet mayStore = 1, SchedRW = [WriteStore] in {
8106c3fb27SDimitry Andricdef PUSH16r  : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
8206c3fb27SDimitry Andric                 OpSize16;
8306c3fb27SDimitry Andricdef PUSH32r  : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
8406c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
8506c3fb27SDimitry Andric// Long form for the disassembler.
8606c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
8706c3fb27SDimitry Andricdef PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>,
8806c3fb27SDimitry Andric                 OpSize16;
8906c3fb27SDimitry Andricdef PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>,
9006c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
9106c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
9206c3fb27SDimitry Andric
9306c3fb27SDimitry Andricdef PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm),
9406c3fb27SDimitry Andric                   "push{w}\t$imm", []>, OpSize16;
9506c3fb27SDimitry Andricdef PUSH16i  : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm),
9606c3fb27SDimitry Andric                   "push{w}\t$imm", []>, OpSize16;
9706c3fb27SDimitry Andric
9806c3fb27SDimitry Andricdef PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm),
9906c3fb27SDimitry Andric                   "push{l}\t$imm", []>, OpSize32,
10006c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
10106c3fb27SDimitry Andricdef PUSH32i  : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm),
10206c3fb27SDimitry Andric                   "push{l}\t$imm", []>, OpSize32,
10306c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
10406c3fb27SDimitry Andric} // mayStore, SchedRW
10506c3fb27SDimitry Andric
10606c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
10706c3fb27SDimitry Andricdef PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>,
10806c3fb27SDimitry Andric                 OpSize16;
10906c3fb27SDimitry Andricdef PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>,
11006c3fb27SDimitry Andric                 OpSize32, Requires<[Not64BitMode]>;
11106c3fb27SDimitry Andric} // mayLoad, mayStore, SchedRW
11206c3fb27SDimitry Andric
11306c3fb27SDimitry Andric}
11406c3fb27SDimitry Andric
11506c3fb27SDimitry Andriclet isPseudo = 1, mayLoad = 1, mayStore = 1,
11606c3fb27SDimitry Andric    SchedRW = [WriteRMW], Defs = [ESP] in {
11706c3fb27SDimitry Andric  let Uses = [ESP] in
11806c3fb27SDimitry Andric  def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins),
11906c3fb27SDimitry Andric                   [(set GR32:$dst, (int_x86_flags_read_u32))]>,
12006c3fb27SDimitry Andric                Requires<[Not64BitMode]>;
12106c3fb27SDimitry Andric
12206c3fb27SDimitry Andric  let Uses = [RSP] in
12306c3fb27SDimitry Andric  def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins),
12406c3fb27SDimitry Andric                   [(set GR64:$dst, (int_x86_flags_read_u64))]>,
12506c3fb27SDimitry Andric                Requires<[In64BitMode]>;
12606c3fb27SDimitry Andric}
12706c3fb27SDimitry Andric
12806c3fb27SDimitry Andriclet isPseudo = 1, mayLoad = 1, mayStore = 1,
12906c3fb27SDimitry Andric    SchedRW = [WriteRMW] in {
13006c3fb27SDimitry Andric  let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in
13106c3fb27SDimitry Andric  def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src),
13206c3fb27SDimitry Andric                   [(int_x86_flags_write_u32 GR32:$src)]>,
13306c3fb27SDimitry Andric                Requires<[Not64BitMode]>;
13406c3fb27SDimitry Andric
13506c3fb27SDimitry Andric  let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in
13606c3fb27SDimitry Andric  def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src),
13706c3fb27SDimitry Andric                   [(int_x86_flags_write_u64 GR64:$src)]>,
13806c3fb27SDimitry Andric                Requires<[In64BitMode]>;
13906c3fb27SDimitry Andric}
14006c3fb27SDimitry Andric
14106c3fb27SDimitry Andriclet Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0,
14206c3fb27SDimitry Andric    SchedRW = [WriteLoad] in {
14306c3fb27SDimitry Andricdef POPF16   : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16;
14406c3fb27SDimitry Andricdef POPF32   : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32,
14506c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
14606c3fb27SDimitry Andric}
14706c3fb27SDimitry Andric
14806c3fb27SDimitry Andriclet Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0,
14906c3fb27SDimitry Andric    SchedRW = [WriteStore] in {
15006c3fb27SDimitry Andricdef PUSHF16  : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16;
15106c3fb27SDimitry Andricdef PUSHF32  : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32,
15206c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
15306c3fb27SDimitry Andric}
15406c3fb27SDimitry Andric
15506c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP], hasSideEffects=0 in {
15606c3fb27SDimitry Andriclet mayLoad = 1, SchedRW = [WriteLoad] in {
15706c3fb27SDimitry Andricdef POP64r   : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
15806c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
15906c3fb27SDimitry Andric// Long form for the disassembler.
16006c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
16106c3fb27SDimitry Andricdef POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>,
16206c3fb27SDimitry Andric                OpSize32, Requires<[In64BitMode]>;
16306c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
164*5f757f3fSDimitry Andricdef POPP64r  : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "popp\t$reg", []>,
165*5f757f3fSDimitry Andric                 REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
166*5f757f3fSDimitry Andricdef POP2: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
167*5f757f3fSDimitry Andric            "pop2\t{$reg2, $reg1|$reg1, $reg2}",
168*5f757f3fSDimitry Andric            []>, EVEX_4V, EVEX_B, T_MAP4PS;
169*5f757f3fSDimitry Andricdef POP2P: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
170*5f757f3fSDimitry Andric             "pop2p\t{$reg2, $reg1|$reg1, $reg2}",
171*5f757f3fSDimitry Andric             []>, EVEX_4V, EVEX_B, T_MAP4PS, REX_W;
172*5f757f3fSDimitry Andric
17306c3fb27SDimitry Andric} // mayLoad, SchedRW
17406c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in
17506c3fb27SDimitry Andricdef POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>,
17606c3fb27SDimitry Andric                OpSize32, Requires<[In64BitMode]>;
17706c3fb27SDimitry Andriclet mayStore = 1, SchedRW = [WriteStore] in {
17806c3fb27SDimitry Andricdef PUSH64r  : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
17906c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
18006c3fb27SDimitry Andric// Long form for the disassembler.
18106c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1 in {
18206c3fb27SDimitry Andricdef PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>,
18306c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
18406c3fb27SDimitry Andric} // isCodeGenOnly = 1, ForceDisassemble = 1
185*5f757f3fSDimitry Andricdef PUSHP64r  : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "pushp\t$reg", []>,
186*5f757f3fSDimitry Andric                  REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
187*5f757f3fSDimitry Andricdef PUSH2: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
188*5f757f3fSDimitry Andric            "push2\t{$reg2, $reg1|$reg1, $reg2}",
189*5f757f3fSDimitry Andric            []>, EVEX_4V, EVEX_B, T_MAP4PS;
190*5f757f3fSDimitry Andricdef PUSH2P: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
191*5f757f3fSDimitry Andric             "push2p\t{$reg2, $reg1|$reg1, $reg2}",
192*5f757f3fSDimitry Andric             []>, EVEX_4V, EVEX_B, T_MAP4PS, REX_W;
19306c3fb27SDimitry Andric} // mayStore, SchedRW
19406c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in {
19506c3fb27SDimitry Andricdef PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>,
19606c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>;
19706c3fb27SDimitry Andric} // mayLoad, mayStore, SchedRW
19806c3fb27SDimitry Andric}
19906c3fb27SDimitry Andric
20006c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1,
20106c3fb27SDimitry Andric    SchedRW = [WriteStore] in {
20206c3fb27SDimitry Andricdef PUSH64i8   : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm),
20306c3fb27SDimitry Andric                    "push{q}\t$imm", []>, OpSize32,
20406c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
20506c3fb27SDimitry Andricdef PUSH64i32  : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm),
20606c3fb27SDimitry Andric                    "push{q}\t$imm", []>, OpSize32,
20706c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
20806c3fb27SDimitry Andric}
20906c3fb27SDimitry Andric
21006c3fb27SDimitry Andriclet Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in
21106c3fb27SDimitry Andricdef POPF64   : I<0x9D, RawFrm, (outs), (ins), "popfq", []>,
21206c3fb27SDimitry Andric               OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>;
21306c3fb27SDimitry Andriclet Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in
21406c3fb27SDimitry Andricdef PUSHF64    : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>,
21506c3fb27SDimitry Andric                 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>;
21606c3fb27SDimitry Andric
21706c3fb27SDimitry Andriclet Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP],
21806c3fb27SDimitry Andric    mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in {
21906c3fb27SDimitry Andricdef POPA32   : I<0x61, RawFrm, (outs), (ins), "popal", []>,
22006c3fb27SDimitry Andric               OpSize32, Requires<[Not64BitMode]>;
22106c3fb27SDimitry Andricdef POPA16   : I<0x61, RawFrm, (outs), (ins), "popaw", []>,
22206c3fb27SDimitry Andric               OpSize16, Requires<[Not64BitMode]>;
22306c3fb27SDimitry Andric}
22406c3fb27SDimitry Andriclet Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP],
22506c3fb27SDimitry Andric    mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in {
22606c3fb27SDimitry Andricdef PUSHA32  : I<0x60, RawFrm, (outs), (ins), "pushal", []>,
22706c3fb27SDimitry Andric               OpSize32, Requires<[Not64BitMode]>;
22806c3fb27SDimitry Andricdef PUSHA16  : I<0x60, RawFrm, (outs), (ins), "pushaw", []>,
22906c3fb27SDimitry Andric               OpSize16, Requires<[Not64BitMode]>;
23006c3fb27SDimitry Andric}
23106c3fb27SDimitry Andric
23206c3fb27SDimitry Andriclet Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in {
23306c3fb27SDimitry Andric// This instruction is a consequence of BSWAP32r observing operand size. The
23406c3fb27SDimitry Andric// encoding is valid, but the behavior is undefined.
23506c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in
23606c3fb27SDimitry Andricdef BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
23706c3fb27SDimitry Andric                     "bswap{w}\t$dst", []>, OpSize16, TB;
23806c3fb27SDimitry Andric// GR32 = bswap GR32
23906c3fb27SDimitry Andricdef BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
24006c3fb27SDimitry Andric                 "bswap{l}\t$dst",
24106c3fb27SDimitry Andric                 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB;
24206c3fb27SDimitry Andric
24306c3fb27SDimitry Andriclet SchedRW = [WriteBSWAP64] in
24406c3fb27SDimitry Andricdef BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
24506c3fb27SDimitry Andric                  "bswap{q}\t$dst",
24606c3fb27SDimitry Andric                  [(set GR64:$dst, (bswap GR64:$src))]>, TB;
24706c3fb27SDimitry Andric} // Constraints = "$src = $dst", SchedRW
24806c3fb27SDimitry Andric
24906c3fb27SDimitry Andric// Bit scan instructions.
25006c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
25106c3fb27SDimitry Andricdef BSF16rr  : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
25206c3fb27SDimitry Andric                 "bsf{w}\t{$src, $dst|$dst, $src}",
25306c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>,
25406c3fb27SDimitry Andric                  PS, OpSize16, Sched<[WriteBSF]>;
25506c3fb27SDimitry Andricdef BSF16rm  : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
25606c3fb27SDimitry Andric                 "bsf{w}\t{$src, $dst|$dst, $src}",
25706c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>,
25806c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSFLd]>;
25906c3fb27SDimitry Andricdef BSF32rr  : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
26006c3fb27SDimitry Andric                 "bsf{l}\t{$src, $dst|$dst, $src}",
26106c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>,
26206c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSF]>;
26306c3fb27SDimitry Andricdef BSF32rm  : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
26406c3fb27SDimitry Andric                 "bsf{l}\t{$src, $dst|$dst, $src}",
26506c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>,
26606c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSFLd]>;
26706c3fb27SDimitry Andricdef BSF64rr  : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
26806c3fb27SDimitry Andric                  "bsf{q}\t{$src, $dst|$dst, $src}",
26906c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>,
27006c3fb27SDimitry Andric                  PS, Sched<[WriteBSF]>;
27106c3fb27SDimitry Andricdef BSF64rm  : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
27206c3fb27SDimitry Andric                  "bsf{q}\t{$src, $dst|$dst, $src}",
27306c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>,
27406c3fb27SDimitry Andric                  PS, Sched<[WriteBSFLd]>;
27506c3fb27SDimitry Andric
27606c3fb27SDimitry Andricdef BSR16rr  : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
27706c3fb27SDimitry Andric                 "bsr{w}\t{$src, $dst|$dst, $src}",
27806c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>,
27906c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSR]>;
28006c3fb27SDimitry Andricdef BSR16rm  : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
28106c3fb27SDimitry Andric                 "bsr{w}\t{$src, $dst|$dst, $src}",
28206c3fb27SDimitry Andric                 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>,
28306c3fb27SDimitry Andric                 PS, OpSize16, Sched<[WriteBSRLd]>;
28406c3fb27SDimitry Andricdef BSR32rr  : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
28506c3fb27SDimitry Andric                 "bsr{l}\t{$src, $dst|$dst, $src}",
28606c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>,
28706c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSR]>;
28806c3fb27SDimitry Andricdef BSR32rm  : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
28906c3fb27SDimitry Andric                 "bsr{l}\t{$src, $dst|$dst, $src}",
29006c3fb27SDimitry Andric                 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>,
29106c3fb27SDimitry Andric                 PS, OpSize32, Sched<[WriteBSRLd]>;
29206c3fb27SDimitry Andricdef BSR64rr  : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
29306c3fb27SDimitry Andric                  "bsr{q}\t{$src, $dst|$dst, $src}",
29406c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>,
29506c3fb27SDimitry Andric                  PS, Sched<[WriteBSR]>;
29606c3fb27SDimitry Andricdef BSR64rm  : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
29706c3fb27SDimitry Andric                  "bsr{q}\t{$src, $dst|$dst, $src}",
29806c3fb27SDimitry Andric                  [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>,
29906c3fb27SDimitry Andric                  PS, Sched<[WriteBSRLd]>;
30006c3fb27SDimitry Andric} // Defs = [EFLAGS]
30106c3fb27SDimitry Andric
30206c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
30306c3fb27SDimitry Andriclet Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in {
30406c3fb27SDimitry Andricdef MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
30506c3fb27SDimitry Andric              "movsb\t{$src, $dst|$dst, $src}", []>;
30606c3fb27SDimitry Andricdef MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
30706c3fb27SDimitry Andric              "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16;
30806c3fb27SDimitry Andricdef MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
30906c3fb27SDimitry Andric              "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32;
31006c3fb27SDimitry Andricdef MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
31106c3fb27SDimitry Andric               "movsq\t{$src, $dst|$dst, $src}", []>,
31206c3fb27SDimitry Andric               Requires<[In64BitMode]>;
31306c3fb27SDimitry Andric}
31406c3fb27SDimitry Andric
31506c3fb27SDimitry Andriclet Defs = [EDI], Uses = [AL,EDI,DF] in
31606c3fb27SDimitry Andricdef STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst),
31706c3fb27SDimitry Andric              "stosb\t{%al, $dst|$dst, al}", []>;
31806c3fb27SDimitry Andriclet Defs = [EDI], Uses = [AX,EDI,DF] in
31906c3fb27SDimitry Andricdef STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst),
32006c3fb27SDimitry Andric              "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16;
32106c3fb27SDimitry Andriclet Defs = [EDI], Uses = [EAX,EDI,DF] in
32206c3fb27SDimitry Andricdef STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst),
32306c3fb27SDimitry Andric              "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32;
32406c3fb27SDimitry Andriclet Defs = [RDI], Uses = [RAX,RDI,DF] in
32506c3fb27SDimitry Andricdef STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst),
32606c3fb27SDimitry Andric               "stosq\t{%rax, $dst|$dst, rax}", []>,
32706c3fb27SDimitry Andric               Requires<[In64BitMode]>;
32806c3fb27SDimitry Andric
32906c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in
33006c3fb27SDimitry Andricdef SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst),
33106c3fb27SDimitry Andric              "scasb\t{$dst, %al|al, $dst}", []>;
33206c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in
33306c3fb27SDimitry Andricdef SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst),
33406c3fb27SDimitry Andric              "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16;
33506c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in
33606c3fb27SDimitry Andricdef SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst),
33706c3fb27SDimitry Andric              "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32;
33806c3fb27SDimitry Andriclet Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in
33906c3fb27SDimitry Andricdef SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
34006c3fb27SDimitry Andric               "scasq\t{$dst, %rax|rax, $dst}", []>,
34106c3fb27SDimitry Andric               Requires<[In64BitMode]>;
34206c3fb27SDimitry Andric
34306c3fb27SDimitry Andriclet Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in {
34406c3fb27SDimitry Andricdef CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
34506c3fb27SDimitry Andric              "cmpsb\t{$dst, $src|$src, $dst}", []>;
34606c3fb27SDimitry Andricdef CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
34706c3fb27SDimitry Andric              "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16;
34806c3fb27SDimitry Andricdef CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
34906c3fb27SDimitry Andric              "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32;
35006c3fb27SDimitry Andricdef CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
35106c3fb27SDimitry Andric               "cmpsq\t{$dst, $src|$src, $dst}", []>,
35206c3fb27SDimitry Andric               Requires<[In64BitMode]>;
35306c3fb27SDimitry Andric}
35406c3fb27SDimitry Andric} // SchedRW
35506c3fb27SDimitry Andric
35606c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
35706c3fb27SDimitry Andric//  Move Instructions.
35806c3fb27SDimitry Andric//
35906c3fb27SDimitry Andriclet SchedRW = [WriteMove] in {
36006c3fb27SDimitry Andriclet hasSideEffects = 0, isMoveReg = 1 in {
36106c3fb27SDimitry Andricdef MOV8rr  : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src),
36206c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}", []>;
36306c3fb27SDimitry Andricdef MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
36406c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
36506c3fb27SDimitry Andricdef MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
36606c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
36706c3fb27SDimitry Andricdef MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
36806c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}", []>;
36906c3fb27SDimitry Andric}
37006c3fb27SDimitry Andric
37106c3fb27SDimitry Andriclet isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
37206c3fb27SDimitry Andricdef MOV8ri  : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src),
37306c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}",
37406c3fb27SDimitry Andric                   [(set GR8:$dst, imm:$src)]>;
37506c3fb27SDimitry Andricdef MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
37606c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}",
37706c3fb27SDimitry Andric                   [(set GR16:$dst, imm:$src)]>, OpSize16;
37806c3fb27SDimitry Andricdef MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
37906c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}",
38006c3fb27SDimitry Andric                   [(set GR32:$dst, imm:$src)]>, OpSize32;
38106c3fb27SDimitry Andricdef MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
38206c3fb27SDimitry Andric                       "mov{q}\t{$src, $dst|$dst, $src}",
38306c3fb27SDimitry Andric                       [(set GR64:$dst, i64immSExt32:$src)]>;
38406c3fb27SDimitry Andric}
38506c3fb27SDimitry Andriclet isReMaterializable = 1, isMoveImm = 1 in {
38606c3fb27SDimitry Andricdef MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
38706c3fb27SDimitry Andric                    "movabs{q}\t{$src, $dst|$dst, $src}",
38806c3fb27SDimitry Andric                    [(set GR64:$dst, imm:$src)]>;
38906c3fb27SDimitry Andric}
39006c3fb27SDimitry Andric
39106c3fb27SDimitry Andric// Longer forms that use a ModR/M byte. Needed for disassembler
39206c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in {
39306c3fb27SDimitry Andricdef MOV8ri_alt  : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src),
39406c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}", []>;
39506c3fb27SDimitry Andricdef MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src),
39606c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
39706c3fb27SDimitry Andricdef MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src),
39806c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
39906c3fb27SDimitry Andric}
40006c3fb27SDimitry Andric} // SchedRW
40106c3fb27SDimitry Andric
40206c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
40306c3fb27SDimitry Andricdef MOV8mi  : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src),
40406c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}",
40506c3fb27SDimitry Andric                   [(store (i8 imm_su:$src), addr:$dst)]>;
40606c3fb27SDimitry Andricdef MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src),
40706c3fb27SDimitry Andric                   "mov{w}\t{$src, $dst|$dst, $src}",
40806c3fb27SDimitry Andric                   [(store (i16 imm_su:$src), addr:$dst)]>, OpSize16;
40906c3fb27SDimitry Andricdef MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src),
41006c3fb27SDimitry Andric                   "mov{l}\t{$src, $dst|$dst, $src}",
41106c3fb27SDimitry Andric                   [(store (i32 imm_su:$src), addr:$dst)]>, OpSize32;
41206c3fb27SDimitry Andricdef MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src),
41306c3fb27SDimitry Andric                       "mov{q}\t{$src, $dst|$dst, $src}",
41406c3fb27SDimitry Andric                       [(store i64immSExt32_su:$src, addr:$dst)]>,
41506c3fb27SDimitry Andric                       Requires<[In64BitMode]>;
41606c3fb27SDimitry Andric} // SchedRW
41706c3fb27SDimitry Andric
41806c3fb27SDimitry Andricdef : Pat<(i32 relocImm:$src), (MOV32ri relocImm:$src)>;
41906c3fb27SDimitry Andricdef : Pat<(i64 relocImm:$src), (MOV64ri relocImm:$src)>;
42006c3fb27SDimitry Andric
42106c3fb27SDimitry Andricdef : Pat<(store (i8 relocImm8_su:$src), addr:$dst),
42206c3fb27SDimitry Andric          (MOV8mi addr:$dst, relocImm8_su:$src)>;
42306c3fb27SDimitry Andricdef : Pat<(store (i16 relocImm16_su:$src), addr:$dst),
42406c3fb27SDimitry Andric          (MOV16mi addr:$dst, relocImm16_su:$src)>;
42506c3fb27SDimitry Andricdef : Pat<(store (i32 relocImm32_su:$src), addr:$dst),
42606c3fb27SDimitry Andric          (MOV32mi addr:$dst, relocImm32_su:$src)>;
42706c3fb27SDimitry Andricdef : Pat<(store (i64 i64relocImmSExt32_su:$src), addr:$dst),
42806c3fb27SDimitry Andric          (MOV64mi32 addr:$dst, i64immSExt32_su:$src)>;
42906c3fb27SDimitry Andric
43006c3fb27SDimitry Andriclet hasSideEffects = 0 in {
43106c3fb27SDimitry Andric
43206c3fb27SDimitry Andric/// Memory offset versions of moves. The immediate is an address mode sized
43306c3fb27SDimitry Andric/// offset from the segment base.
43406c3fb27SDimitry Andriclet SchedRW = [WriteALU] in {
43506c3fb27SDimitry Andriclet mayLoad = 1 in {
43606c3fb27SDimitry Andriclet Defs = [AL] in
43706c3fb27SDimitry Andricdef MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src),
43806c3fb27SDimitry Andric                    "mov{b}\t{$src, %al|al, $src}", []>,
43906c3fb27SDimitry Andric                    AdSize32;
44006c3fb27SDimitry Andriclet Defs = [AX] in
44106c3fb27SDimitry Andricdef MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src),
44206c3fb27SDimitry Andric                     "mov{w}\t{$src, %ax|ax, $src}", []>,
44306c3fb27SDimitry Andric                     OpSize16, AdSize32;
44406c3fb27SDimitry Andriclet Defs = [EAX] in
44506c3fb27SDimitry Andricdef MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src),
44606c3fb27SDimitry Andric                     "mov{l}\t{$src, %eax|eax, $src}", []>,
44706c3fb27SDimitry Andric                     OpSize32, AdSize32;
44806c3fb27SDimitry Andriclet Defs = [RAX] in
44906c3fb27SDimitry Andricdef MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src),
45006c3fb27SDimitry Andric                      "mov{q}\t{$src, %rax|rax, $src}", []>,
45106c3fb27SDimitry Andric                      AdSize32;
45206c3fb27SDimitry Andric
45306c3fb27SDimitry Andriclet Defs = [AL] in
45406c3fb27SDimitry Andricdef MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src),
45506c3fb27SDimitry Andric                    "mov{b}\t{$src, %al|al, $src}", []>, AdSize16;
45606c3fb27SDimitry Andriclet Defs = [AX] in
45706c3fb27SDimitry Andricdef MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src),
45806c3fb27SDimitry Andric                     "mov{w}\t{$src, %ax|ax, $src}", []>,
45906c3fb27SDimitry Andric                     OpSize16, AdSize16;
46006c3fb27SDimitry Andriclet Defs = [EAX] in
46106c3fb27SDimitry Andricdef MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src),
46206c3fb27SDimitry Andric                     "mov{l}\t{$src, %eax|eax, $src}", []>,
46306c3fb27SDimitry Andric                     AdSize16, OpSize32;
46406c3fb27SDimitry Andric} // mayLoad
46506c3fb27SDimitry Andriclet mayStore = 1 in {
46606c3fb27SDimitry Andriclet Uses = [AL] in
46706c3fb27SDimitry Andricdef MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst),
46806c3fb27SDimitry Andric                    "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32;
46906c3fb27SDimitry Andriclet Uses = [AX] in
47006c3fb27SDimitry Andricdef MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst),
47106c3fb27SDimitry Andric                     "mov{w}\t{%ax, $dst|$dst, ax}", []>,
47206c3fb27SDimitry Andric                     OpSize16, AdSize32;
47306c3fb27SDimitry Andriclet Uses = [EAX] in
47406c3fb27SDimitry Andricdef MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst),
47506c3fb27SDimitry Andric                     "mov{l}\t{%eax, $dst|$dst, eax}", []>,
47606c3fb27SDimitry Andric                     OpSize32, AdSize32;
47706c3fb27SDimitry Andriclet Uses = [RAX] in
47806c3fb27SDimitry Andricdef MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst),
47906c3fb27SDimitry Andric                      "mov{q}\t{%rax, $dst|$dst, rax}", []>,
48006c3fb27SDimitry Andric                      AdSize32;
48106c3fb27SDimitry Andric
48206c3fb27SDimitry Andriclet Uses = [AL] in
48306c3fb27SDimitry Andricdef MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst),
48406c3fb27SDimitry Andric                    "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16;
48506c3fb27SDimitry Andriclet Uses = [AX] in
48606c3fb27SDimitry Andricdef MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst),
48706c3fb27SDimitry Andric                     "mov{w}\t{%ax, $dst|$dst, ax}", []>,
48806c3fb27SDimitry Andric                     OpSize16, AdSize16;
48906c3fb27SDimitry Andriclet Uses = [EAX] in
49006c3fb27SDimitry Andricdef MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst),
49106c3fb27SDimitry Andric                     "mov{l}\t{%eax, $dst|$dst, eax}", []>,
49206c3fb27SDimitry Andric                     OpSize32, AdSize16;
49306c3fb27SDimitry Andric} // mayStore
49406c3fb27SDimitry Andric
49506c3fb27SDimitry Andric// These forms all have full 64-bit absolute addresses in their instructions
49606c3fb27SDimitry Andric// and use the movabs mnemonic to indicate this specific form.
49706c3fb27SDimitry Andriclet mayLoad = 1 in {
49806c3fb27SDimitry Andriclet Defs = [AL] in
49906c3fb27SDimitry Andricdef MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src),
50006c3fb27SDimitry Andric                    "movabs{b}\t{$src, %al|al, $src}", []>,
50106c3fb27SDimitry Andric                    AdSize64;
50206c3fb27SDimitry Andriclet Defs = [AX] in
50306c3fb27SDimitry Andricdef MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src),
50406c3fb27SDimitry Andric                     "movabs{w}\t{$src, %ax|ax, $src}", []>,
50506c3fb27SDimitry Andric                     OpSize16, AdSize64;
50606c3fb27SDimitry Andriclet Defs = [EAX] in
50706c3fb27SDimitry Andricdef MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src),
50806c3fb27SDimitry Andric                     "movabs{l}\t{$src, %eax|eax, $src}", []>,
50906c3fb27SDimitry Andric                     OpSize32, AdSize64;
51006c3fb27SDimitry Andriclet Defs = [RAX] in
51106c3fb27SDimitry Andricdef MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src),
51206c3fb27SDimitry Andric                     "movabs{q}\t{$src, %rax|rax, $src}", []>,
51306c3fb27SDimitry Andric                     AdSize64;
51406c3fb27SDimitry Andric} // mayLoad
51506c3fb27SDimitry Andric
51606c3fb27SDimitry Andriclet mayStore = 1 in {
51706c3fb27SDimitry Andriclet Uses = [AL] in
51806c3fb27SDimitry Andricdef MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst),
51906c3fb27SDimitry Andric                    "movabs{b}\t{%al, $dst|$dst, al}", []>,
52006c3fb27SDimitry Andric                    AdSize64;
52106c3fb27SDimitry Andriclet Uses = [AX] in
52206c3fb27SDimitry Andricdef MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst),
52306c3fb27SDimitry Andric                     "movabs{w}\t{%ax, $dst|$dst, ax}", []>,
52406c3fb27SDimitry Andric                     OpSize16, AdSize64;
52506c3fb27SDimitry Andriclet Uses = [EAX] in
52606c3fb27SDimitry Andricdef MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst),
52706c3fb27SDimitry Andric                     "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
52806c3fb27SDimitry Andric                     OpSize32, AdSize64;
52906c3fb27SDimitry Andriclet Uses = [RAX] in
53006c3fb27SDimitry Andricdef MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst),
53106c3fb27SDimitry Andric                     "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
53206c3fb27SDimitry Andric                     AdSize64;
53306c3fb27SDimitry Andric} // mayStore
53406c3fb27SDimitry Andric} // SchedRW
53506c3fb27SDimitry Andric} // hasSideEffects = 0
53606c3fb27SDimitry Andric
53706c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0,
53806c3fb27SDimitry Andric    SchedRW = [WriteMove], isMoveReg = 1 in {
53906c3fb27SDimitry Andricdef MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src),
54006c3fb27SDimitry Andric                   "mov{b}\t{$src, $dst|$dst, $src}", []>;
54106c3fb27SDimitry Andricdef MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
54206c3fb27SDimitry Andric                    "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16;
54306c3fb27SDimitry Andricdef MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
54406c3fb27SDimitry Andric                    "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32;
54506c3fb27SDimitry Andricdef MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
54606c3fb27SDimitry Andric                     "mov{q}\t{$src, $dst|$dst, $src}", []>;
54706c3fb27SDimitry Andric}
54806c3fb27SDimitry Andric
54906c3fb27SDimitry Andriclet canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in {
55006c3fb27SDimitry Andricdef MOV8rm  : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src),
55106c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}",
55206c3fb27SDimitry Andric                [(set GR8:$dst, (loadi8 addr:$src))]>;
55306c3fb27SDimitry Andricdef MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
55406c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}",
55506c3fb27SDimitry Andric                [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16;
55606c3fb27SDimitry Andricdef MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
55706c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}",
55806c3fb27SDimitry Andric                [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32;
55906c3fb27SDimitry Andricdef MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
56006c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}",
56106c3fb27SDimitry Andric                 [(set GR64:$dst, (load addr:$src))]>;
56206c3fb27SDimitry Andric}
56306c3fb27SDimitry Andric
56406c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
56506c3fb27SDimitry Andricdef MOV8mr  : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src),
56606c3fb27SDimitry Andric                "mov{b}\t{$src, $dst|$dst, $src}",
56706c3fb27SDimitry Andric                [(store GR8:$src, addr:$dst)]>;
56806c3fb27SDimitry Andricdef MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
56906c3fb27SDimitry Andric                "mov{w}\t{$src, $dst|$dst, $src}",
57006c3fb27SDimitry Andric                [(store GR16:$src, addr:$dst)]>, OpSize16;
57106c3fb27SDimitry Andricdef MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
57206c3fb27SDimitry Andric                "mov{l}\t{$src, $dst|$dst, $src}",
57306c3fb27SDimitry Andric                [(store GR32:$src, addr:$dst)]>, OpSize32;
57406c3fb27SDimitry Andricdef MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
57506c3fb27SDimitry Andric                 "mov{q}\t{$src, $dst|$dst, $src}",
57606c3fb27SDimitry Andric                 [(store GR64:$src, addr:$dst)]>;
57706c3fb27SDimitry Andric} // SchedRW
57806c3fb27SDimitry Andric
57906c3fb27SDimitry Andric// Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so
58006c3fb27SDimitry Andric// that they can be used for copying and storing h registers, which can't be
58106c3fb27SDimitry Andric// encoded when a REX prefix is present.
58206c3fb27SDimitry Andriclet isCodeGenOnly = 1 in {
58306c3fb27SDimitry Andriclet hasSideEffects = 0, isMoveReg = 1 in
58406c3fb27SDimitry Andricdef MOV8rr_NOREX : I<0x88, MRMDestReg,
58506c3fb27SDimitry Andric                     (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src),
58606c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
58706c3fb27SDimitry Andric                   Sched<[WriteMove]>;
58806c3fb27SDimitry Andriclet mayStore = 1, hasSideEffects = 0 in
58906c3fb27SDimitry Andricdef MOV8mr_NOREX : I<0x88, MRMDestMem,
59006c3fb27SDimitry Andric                     (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src),
59106c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
59206c3fb27SDimitry Andric                     Sched<[WriteStore]>;
59306c3fb27SDimitry Andriclet mayLoad = 1, hasSideEffects = 0,
59406c3fb27SDimitry Andric    canFoldAsLoad = 1, isReMaterializable = 1 in
59506c3fb27SDimitry Andricdef MOV8rm_NOREX : I<0x8A, MRMSrcMem,
59606c3fb27SDimitry Andric                     (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src),
59706c3fb27SDimitry Andric                     "mov{b}\t{$src, $dst|$dst, $src}", []>,
59806c3fb27SDimitry Andric                     Sched<[WriteLoad]>;
59906c3fb27SDimitry Andric}
60006c3fb27SDimitry Andric
60106c3fb27SDimitry Andric
60206c3fb27SDimitry Andric// Condition code ops, incl. set if equal/not equal/...
60306c3fb27SDimitry Andriclet SchedRW = [WriteLAHFSAHF] in {
60406c3fb27SDimitry Andriclet Defs = [EFLAGS], Uses = [AH], hasSideEffects = 0 in
60506c3fb27SDimitry Andricdef SAHF     : I<0x9E, RawFrm, (outs),  (ins), "sahf", []>,  // flags = AH
60606c3fb27SDimitry Andric                 Requires<[HasLAHFSAHF]>;
60706c3fb27SDimitry Andriclet Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in
60806c3fb27SDimitry Andricdef LAHF     : I<0x9F, RawFrm, (outs),  (ins), "lahf", []>,  // AH = flags
60906c3fb27SDimitry Andric               Requires<[HasLAHFSAHF]>;
61006c3fb27SDimitry Andric} // SchedRW
61106c3fb27SDimitry Andric
61206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
61306c3fb27SDimitry Andric// Bit tests instructions: BT, BTS, BTR, BTC.
61406c3fb27SDimitry Andric
61506c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
61606c3fb27SDimitry Andriclet SchedRW = [WriteBitTest] in {
61706c3fb27SDimitry Andricdef BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2),
61806c3fb27SDimitry Andric               "bt{w}\t{$src2, $src1|$src1, $src2}",
61906c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>,
62006c3fb27SDimitry Andric               OpSize16, TB;
62106c3fb27SDimitry Andricdef BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2),
62206c3fb27SDimitry Andric               "bt{l}\t{$src2, $src1|$src1, $src2}",
62306c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>,
62406c3fb27SDimitry Andric               OpSize32, TB;
62506c3fb27SDimitry Andricdef BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2),
62606c3fb27SDimitry Andric               "bt{q}\t{$src2, $src1|$src1, $src2}",
62706c3fb27SDimitry Andric               [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB;
62806c3fb27SDimitry Andric} // SchedRW
62906c3fb27SDimitry Andric
63006c3fb27SDimitry Andric// Unlike with the register+register form, the memory+register form of the
63106c3fb27SDimitry Andric// bt instruction does not ignore the high bits of the index. From ISel's
63206c3fb27SDimitry Andric// perspective, this is pretty bizarre. Make these instructions disassembly
63306c3fb27SDimitry Andric// only for now. These instructions are also slow on modern CPUs so that's
63406c3fb27SDimitry Andric// another reason to avoid generating them.
63506c3fb27SDimitry Andric
63606c3fb27SDimitry Andriclet mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in {
63706c3fb27SDimitry Andric  def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
63806c3fb27SDimitry Andric                 "bt{w}\t{$src2, $src1|$src1, $src2}",
63906c3fb27SDimitry Andric                 []>, OpSize16, TB;
64006c3fb27SDimitry Andric  def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
64106c3fb27SDimitry Andric                 "bt{l}\t{$src2, $src1|$src1, $src2}",
64206c3fb27SDimitry Andric                 []>, OpSize32, TB;
64306c3fb27SDimitry Andric  def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
64406c3fb27SDimitry Andric                 "bt{q}\t{$src2, $src1|$src1, $src2}",
64506c3fb27SDimitry Andric                  []>, TB;
64606c3fb27SDimitry Andric}
64706c3fb27SDimitry Andric
64806c3fb27SDimitry Andriclet SchedRW = [WriteBitTest] in {
64906c3fb27SDimitry Andricdef BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2),
65006c3fb27SDimitry Andric                "bt{w}\t{$src2, $src1|$src1, $src2}",
65106c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>,
65206c3fb27SDimitry Andric                OpSize16, TB;
65306c3fb27SDimitry Andricdef BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2),
65406c3fb27SDimitry Andric                "bt{l}\t{$src2, $src1|$src1, $src2}",
65506c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>,
65606c3fb27SDimitry Andric                OpSize32, TB;
65706c3fb27SDimitry Andricdef BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2),
65806c3fb27SDimitry Andric                "bt{q}\t{$src2, $src1|$src1, $src2}",
65906c3fb27SDimitry Andric                [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB;
66006c3fb27SDimitry Andric} // SchedRW
66106c3fb27SDimitry Andric
66206c3fb27SDimitry Andric// Note that these instructions aren't slow because that only applies when the
66306c3fb27SDimitry Andric// other operand is in a register. When it's an immediate, bt is still fast.
66406c3fb27SDimitry Andriclet SchedRW = [WriteBitTestImmLd] in {
66506c3fb27SDimitry Andricdef BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
66606c3fb27SDimitry Andric                  "bt{w}\t{$src2, $src1|$src1, $src2}",
66706c3fb27SDimitry Andric                  [(set EFLAGS, (X86bt (loadi16 addr:$src1),
66806c3fb27SDimitry Andric                                       imm:$src2))]>,
66906c3fb27SDimitry Andric                  OpSize16, TB;
67006c3fb27SDimitry Andricdef BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
67106c3fb27SDimitry Andric                  "bt{l}\t{$src2, $src1|$src1, $src2}",
67206c3fb27SDimitry Andric                  [(set EFLAGS, (X86bt (loadi32 addr:$src1),
67306c3fb27SDimitry Andric                                       imm:$src2))]>,
67406c3fb27SDimitry Andric                  OpSize32, TB;
67506c3fb27SDimitry Andricdef BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
67606c3fb27SDimitry Andric                "bt{q}\t{$src2, $src1|$src1, $src2}",
67706c3fb27SDimitry Andric                [(set EFLAGS, (X86bt (loadi64 addr:$src1),
67806c3fb27SDimitry Andric                                     imm:$src2))]>, TB,
67906c3fb27SDimitry Andric                Requires<[In64BitMode]>;
68006c3fb27SDimitry Andric} // SchedRW
68106c3fb27SDimitry Andric
68206c3fb27SDimitry Andriclet hasSideEffects = 0 in {
68306c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
68406c3fb27SDimitry Andricdef BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
68506c3fb27SDimitry Andric                "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
68606c3fb27SDimitry Andric                OpSize16, TB;
68706c3fb27SDimitry Andricdef BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
68806c3fb27SDimitry Andric                "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
68906c3fb27SDimitry Andric                OpSize32, TB;
69006c3fb27SDimitry Andricdef BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
69106c3fb27SDimitry Andric                 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
69206c3fb27SDimitry Andric} // SchedRW
69306c3fb27SDimitry Andric
69406c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
69506c3fb27SDimitry Andricdef BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
69606c3fb27SDimitry Andric                "btc{w}\t{$src2, $src1|$src1, $src2}", []>,
69706c3fb27SDimitry Andric                OpSize16, TB;
69806c3fb27SDimitry Andricdef BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
69906c3fb27SDimitry Andric                "btc{l}\t{$src2, $src1|$src1, $src2}", []>,
70006c3fb27SDimitry Andric                OpSize32, TB;
70106c3fb27SDimitry Andricdef BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
70206c3fb27SDimitry Andric                 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
70306c3fb27SDimitry Andric}
70406c3fb27SDimitry Andric
70506c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
70606c3fb27SDimitry Andricdef BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
70706c3fb27SDimitry Andric                    "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
70806c3fb27SDimitry Andricdef BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
70906c3fb27SDimitry Andric                    "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
71006c3fb27SDimitry Andricdef BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
71106c3fb27SDimitry Andric                    "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
71206c3fb27SDimitry Andric} // SchedRW
71306c3fb27SDimitry Andric
71406c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
71506c3fb27SDimitry Andricdef BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
71606c3fb27SDimitry Andric                    "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
71706c3fb27SDimitry Andricdef BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
71806c3fb27SDimitry Andric                    "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
71906c3fb27SDimitry Andricdef BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
72006c3fb27SDimitry Andric                    "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
72106c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
72206c3fb27SDimitry Andric}
72306c3fb27SDimitry Andric
72406c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
72506c3fb27SDimitry Andricdef BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
72606c3fb27SDimitry Andric                "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
72706c3fb27SDimitry Andric                OpSize16, TB;
72806c3fb27SDimitry Andricdef BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
72906c3fb27SDimitry Andric                "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
73006c3fb27SDimitry Andric                OpSize32, TB;
73106c3fb27SDimitry Andricdef BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
73206c3fb27SDimitry Andric                 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
73306c3fb27SDimitry Andric} // SchedRW
73406c3fb27SDimitry Andric
73506c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
73606c3fb27SDimitry Andricdef BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
73706c3fb27SDimitry Andric                "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
73806c3fb27SDimitry Andric                OpSize16, TB;
73906c3fb27SDimitry Andricdef BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
74006c3fb27SDimitry Andric                "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
74106c3fb27SDimitry Andric                OpSize32, TB;
74206c3fb27SDimitry Andricdef BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
74306c3fb27SDimitry Andric                 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
74406c3fb27SDimitry Andric}
74506c3fb27SDimitry Andric
74606c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
74706c3fb27SDimitry Andricdef BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
74806c3fb27SDimitry Andric                    "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
74906c3fb27SDimitry Andric                    OpSize16, TB;
75006c3fb27SDimitry Andricdef BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
75106c3fb27SDimitry Andric                    "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
75206c3fb27SDimitry Andric                    OpSize32, TB;
75306c3fb27SDimitry Andricdef BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
75406c3fb27SDimitry Andric                    "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
75506c3fb27SDimitry Andric} // SchedRW
75606c3fb27SDimitry Andric
75706c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
75806c3fb27SDimitry Andricdef BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
75906c3fb27SDimitry Andric                    "btr{w}\t{$src2, $src1|$src1, $src2}", []>,
76006c3fb27SDimitry Andric                    OpSize16, TB;
76106c3fb27SDimitry Andricdef BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
76206c3fb27SDimitry Andric                    "btr{l}\t{$src2, $src1|$src1, $src2}", []>,
76306c3fb27SDimitry Andric                    OpSize32, TB;
76406c3fb27SDimitry Andricdef BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
76506c3fb27SDimitry Andric                    "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
76606c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
76706c3fb27SDimitry Andric}
76806c3fb27SDimitry Andric
76906c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
77006c3fb27SDimitry Andricdef BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2),
77106c3fb27SDimitry Andric                "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
77206c3fb27SDimitry Andric                OpSize16, TB;
77306c3fb27SDimitry Andricdef BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2),
77406c3fb27SDimitry Andric                "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
77506c3fb27SDimitry Andric              OpSize32, TB;
77606c3fb27SDimitry Andricdef BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2),
77706c3fb27SDimitry Andric               "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
77806c3fb27SDimitry Andric} // SchedRW
77906c3fb27SDimitry Andric
78006c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in {
78106c3fb27SDimitry Andricdef BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2),
78206c3fb27SDimitry Andric              "bts{w}\t{$src2, $src1|$src1, $src2}", []>,
78306c3fb27SDimitry Andric              OpSize16, TB;
78406c3fb27SDimitry Andricdef BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2),
78506c3fb27SDimitry Andric              "bts{l}\t{$src2, $src1|$src1, $src2}", []>,
78606c3fb27SDimitry Andric              OpSize32, TB;
78706c3fb27SDimitry Andricdef BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2),
78806c3fb27SDimitry Andric                 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
78906c3fb27SDimitry Andric}
79006c3fb27SDimitry Andric
79106c3fb27SDimitry Andriclet SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in {
79206c3fb27SDimitry Andricdef BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2),
79306c3fb27SDimitry Andric                    "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
79406c3fb27SDimitry Andricdef BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2),
79506c3fb27SDimitry Andric                    "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
79606c3fb27SDimitry Andricdef BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2),
79706c3fb27SDimitry Andric                    "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
79806c3fb27SDimitry Andric} // SchedRW
79906c3fb27SDimitry Andric
80006c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in {
80106c3fb27SDimitry Andricdef BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2),
80206c3fb27SDimitry Andric                    "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB;
80306c3fb27SDimitry Andricdef BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2),
80406c3fb27SDimitry Andric                    "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB;
80506c3fb27SDimitry Andricdef BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2),
80606c3fb27SDimitry Andric                    "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB,
80706c3fb27SDimitry Andric                    Requires<[In64BitMode]>;
80806c3fb27SDimitry Andric}
80906c3fb27SDimitry Andric} // hasSideEffects = 0
81006c3fb27SDimitry Andric} // Defs = [EFLAGS]
81106c3fb27SDimitry Andric
81206c3fb27SDimitry Andric
81306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
81406c3fb27SDimitry Andric// Atomic support
81506c3fb27SDimitry Andric//
81606c3fb27SDimitry Andric
81706c3fb27SDimitry Andric// Atomic swap. These are just normal xchg instructions. But since a memory
81806c3fb27SDimitry Andric// operand is referenced, the atomicity is ensured.
81906c3fb27SDimitry Andricmulticlass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> {
82006c3fb27SDimitry Andric  let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in {
82106c3fb27SDimitry Andric    def NAME#8rm  : I<opc8, MRMSrcMem, (outs GR8:$dst),
82206c3fb27SDimitry Andric                      (ins GR8:$val, i8mem:$ptr),
82306c3fb27SDimitry Andric                      !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"),
82406c3fb27SDimitry Andric                      [(set
82506c3fb27SDimitry Andric                         GR8:$dst,
82606c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>;
82706c3fb27SDimitry Andric    def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst),
82806c3fb27SDimitry Andric                      (ins GR16:$val, i16mem:$ptr),
82906c3fb27SDimitry Andric                      !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"),
83006c3fb27SDimitry Andric                      [(set
83106c3fb27SDimitry Andric                         GR16:$dst,
83206c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>,
83306c3fb27SDimitry Andric                      OpSize16;
83406c3fb27SDimitry Andric    def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst),
83506c3fb27SDimitry Andric                      (ins GR32:$val, i32mem:$ptr),
83606c3fb27SDimitry Andric                      !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"),
83706c3fb27SDimitry Andric                      [(set
83806c3fb27SDimitry Andric                         GR32:$dst,
83906c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>,
84006c3fb27SDimitry Andric                      OpSize32;
84106c3fb27SDimitry Andric    def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst),
84206c3fb27SDimitry Andric                       (ins GR64:$val, i64mem:$ptr),
84306c3fb27SDimitry Andric                       !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"),
84406c3fb27SDimitry Andric                       [(set
84506c3fb27SDimitry Andric                         GR64:$dst,
84606c3fb27SDimitry Andric                         (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>;
84706c3fb27SDimitry Andric  }
84806c3fb27SDimitry Andric}
84906c3fb27SDimitry Andric
85006c3fb27SDimitry Andricdefm XCHG    : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">;
85106c3fb27SDimitry Andric
85206c3fb27SDimitry Andric// Swap between registers.
85306c3fb27SDimitry Andriclet SchedRW = [WriteXCHG] in {
85406c3fb27SDimitry Andriclet Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in {
85506c3fb27SDimitry Andricdef XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2),
85606c3fb27SDimitry Andric                (ins GR8:$src1, GR8:$src2),
85706c3fb27SDimitry Andric                "xchg{b}\t{$src2, $src1|$src1, $src2}", []>;
85806c3fb27SDimitry Andricdef XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2),
85906c3fb27SDimitry Andric                 (ins GR16:$src1, GR16:$src2),
86006c3fb27SDimitry Andric                 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>,
86106c3fb27SDimitry Andric                 OpSize16;
86206c3fb27SDimitry Andricdef XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2),
86306c3fb27SDimitry Andric                 (ins GR32:$src1, GR32:$src2),
86406c3fb27SDimitry Andric                 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>,
86506c3fb27SDimitry Andric                 OpSize32;
86606c3fb27SDimitry Andricdef XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2),
86706c3fb27SDimitry Andric                  (ins GR64:$src1 ,GR64:$src2),
86806c3fb27SDimitry Andric                  "xchg{q}\t{$src2, $src1|$src1, $src2}", []>;
86906c3fb27SDimitry Andric}
87006c3fb27SDimitry Andric
87106c3fb27SDimitry Andric// Swap between EAX and other registers.
87206c3fb27SDimitry Andriclet Constraints = "$src = $dst", hasSideEffects = 0 in {
87306c3fb27SDimitry Andriclet Uses = [AX], Defs = [AX] in
87406c3fb27SDimitry Andricdef XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src),
87506c3fb27SDimitry Andric                  "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16;
87606c3fb27SDimitry Andriclet Uses = [EAX], Defs = [EAX] in
87706c3fb27SDimitry Andricdef XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src),
87806c3fb27SDimitry Andric                  "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32;
87906c3fb27SDimitry Andriclet Uses = [RAX], Defs = [RAX] in
88006c3fb27SDimitry Andricdef XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src),
88106c3fb27SDimitry Andric                  "xchg{q}\t{$src, %rax|rax, $src}", []>;
88206c3fb27SDimitry Andric}
88306c3fb27SDimitry Andric} // SchedRW
88406c3fb27SDimitry Andric
88506c3fb27SDimitry Andriclet hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2",
88606c3fb27SDimitry Andric    Defs = [EFLAGS], SchedRW = [WriteXCHG] in {
88706c3fb27SDimitry Andricdef XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2),
88806c3fb27SDimitry Andric                (ins GR8:$src1, GR8:$src2),
88906c3fb27SDimitry Andric                "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB;
89006c3fb27SDimitry Andricdef XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2),
89106c3fb27SDimitry Andric                 (ins GR16:$src1, GR16:$src2),
89206c3fb27SDimitry Andric                 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16;
89306c3fb27SDimitry Andricdef XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2),
89406c3fb27SDimitry Andric                  (ins GR32:$src1, GR32:$src2),
89506c3fb27SDimitry Andric                 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32;
89606c3fb27SDimitry Andricdef XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2),
89706c3fb27SDimitry Andric                  (ins GR64:$src1, GR64:$src2),
89806c3fb27SDimitry Andric                  "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB;
89906c3fb27SDimitry Andric} // SchedRW
90006c3fb27SDimitry Andric
90106c3fb27SDimitry Andriclet mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst",
90206c3fb27SDimitry Andric    Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in {
90306c3fb27SDimitry Andricdef XADD8rm   : I<0xC0, MRMSrcMem, (outs GR8:$dst),
90406c3fb27SDimitry Andric                  (ins GR8:$val, i8mem:$ptr),
90506c3fb27SDimitry Andric                 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB;
90606c3fb27SDimitry Andricdef XADD16rm  : I<0xC1, MRMSrcMem, (outs GR16:$dst),
90706c3fb27SDimitry Andric                  (ins GR16:$val, i16mem:$ptr),
90806c3fb27SDimitry Andric                 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB,
90906c3fb27SDimitry Andric                 OpSize16;
91006c3fb27SDimitry Andricdef XADD32rm  : I<0xC1, MRMSrcMem, (outs GR32:$dst),
91106c3fb27SDimitry Andric                  (ins GR32:$val, i32mem:$ptr),
91206c3fb27SDimitry Andric                 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB,
91306c3fb27SDimitry Andric                 OpSize32;
91406c3fb27SDimitry Andricdef XADD64rm  : RI<0xC1, MRMSrcMem, (outs GR64:$dst),
91506c3fb27SDimitry Andric                   (ins GR64:$val, i64mem:$ptr),
91606c3fb27SDimitry Andric                   "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB;
91706c3fb27SDimitry Andric
91806c3fb27SDimitry Andric}
91906c3fb27SDimitry Andric
92006c3fb27SDimitry Andriclet SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in {
92106c3fb27SDimitry Andriclet Defs = [AL, EFLAGS], Uses = [AL] in
92206c3fb27SDimitry Andricdef CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src),
92306c3fb27SDimitry Andric                   "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB;
92406c3fb27SDimitry Andriclet Defs = [AX, EFLAGS], Uses = [AX] in
92506c3fb27SDimitry Andricdef CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
92606c3fb27SDimitry Andric                    "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16;
92706c3fb27SDimitry Andriclet Defs = [EAX, EFLAGS], Uses = [EAX] in
92806c3fb27SDimitry Andricdef CMPXCHG32rr  : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src),
92906c3fb27SDimitry Andric                     "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32;
93006c3fb27SDimitry Andriclet Defs = [RAX, EFLAGS], Uses = [RAX] in
93106c3fb27SDimitry Andricdef CMPXCHG64rr  : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src),
93206c3fb27SDimitry Andric                      "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
93306c3fb27SDimitry Andric} // SchedRW, hasSideEffects
93406c3fb27SDimitry Andric
93506c3fb27SDimitry Andriclet SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1,
93606c3fb27SDimitry Andric    hasSideEffects = 0 in {
93706c3fb27SDimitry Andriclet Defs = [AL, EFLAGS], Uses = [AL] in
93806c3fb27SDimitry Andricdef CMPXCHG8rm   : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src),
93906c3fb27SDimitry Andric                     "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB;
94006c3fb27SDimitry Andriclet Defs = [AX, EFLAGS], Uses = [AX] in
94106c3fb27SDimitry Andricdef CMPXCHG16rm  : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
94206c3fb27SDimitry Andric                     "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16;
94306c3fb27SDimitry Andriclet Defs = [EAX, EFLAGS], Uses = [EAX] in
94406c3fb27SDimitry Andricdef CMPXCHG32rm  : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
94506c3fb27SDimitry Andric                     "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32;
94606c3fb27SDimitry Andriclet Defs = [RAX, EFLAGS], Uses = [RAX] in
94706c3fb27SDimitry Andricdef CMPXCHG64rm  : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
94806c3fb27SDimitry Andric                      "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB;
94906c3fb27SDimitry Andric
95006c3fb27SDimitry Andriclet Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in
95106c3fb27SDimitry Andricdef CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst),
95206c3fb27SDimitry Andric                  "cmpxchg8b\t$dst", []>, TB, Requires<[HasCX8]>;
95306c3fb27SDimitry Andric
95406c3fb27SDimitry Andriclet Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in
95506c3fb27SDimitry Andric// NOTE: In64BitMode check needed for the AssemblerPredicate.
95606c3fb27SDimitry Andricdef CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
95706c3fb27SDimitry Andric                    "cmpxchg16b\t$dst", []>,
95806c3fb27SDimitry Andric                    TB, Requires<[HasCX16,In64BitMode]>;
95906c3fb27SDimitry Andric} // SchedRW, mayLoad, mayStore, hasSideEffects
96006c3fb27SDimitry Andric
96106c3fb27SDimitry Andric
96206c3fb27SDimitry Andric// Lock instruction prefix
96306c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in
96406c3fb27SDimitry Andricdef LOCK_PREFIX : I<0xF0, PrefixByte, (outs),  (ins), "lock", []>;
96506c3fb27SDimitry Andric
96606c3fb27SDimitry Andriclet SchedRW = [WriteNop] in {
96706c3fb27SDimitry Andric
96806c3fb27SDimitry Andric// Rex64 instruction prefix
96906c3fb27SDimitry Andricdef REX64_PREFIX : I<0x48, PrefixByte, (outs),  (ins), "rex64", []>,
97006c3fb27SDimitry Andric                     Requires<[In64BitMode]>;
97106c3fb27SDimitry Andric
97206c3fb27SDimitry Andric// Data16 instruction prefix
97306c3fb27SDimitry Andricdef DATA16_PREFIX : I<0x66, PrefixByte, (outs),  (ins), "data16", []>;
97406c3fb27SDimitry Andric} // SchedRW
97506c3fb27SDimitry Andric
97606c3fb27SDimitry Andric// Repeat string operation instruction prefixes
97706c3fb27SDimitry Andriclet Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
97806c3fb27SDimitry Andric// Repeat (used with INS, OUTS, MOVS, LODS and STOS)
97906c3fb27SDimitry Andricdef REP_PREFIX : I<0xF3, PrefixByte, (outs),  (ins), "rep", []>;
98006c3fb27SDimitry Andric// Repeat while not equal (used with CMPS and SCAS)
98106c3fb27SDimitry Andricdef REPNE_PREFIX : I<0xF2, PrefixByte, (outs),  (ins), "repne", []>;
98206c3fb27SDimitry Andric}
98306c3fb27SDimitry Andric
98406c3fb27SDimitry Andric// String manipulation instructions
98506c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
98606c3fb27SDimitry Andriclet Defs = [AL,ESI], Uses = [ESI,DF] in
98706c3fb27SDimitry Andricdef LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src),
98806c3fb27SDimitry Andric              "lodsb\t{$src, %al|al, $src}", []>;
98906c3fb27SDimitry Andriclet Defs = [AX,ESI], Uses = [ESI,DF] in
99006c3fb27SDimitry Andricdef LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src),
99106c3fb27SDimitry Andric              "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16;
99206c3fb27SDimitry Andriclet Defs = [EAX,ESI], Uses = [ESI,DF] in
99306c3fb27SDimitry Andricdef LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src),
99406c3fb27SDimitry Andric              "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32;
99506c3fb27SDimitry Andriclet Defs = [RAX,ESI], Uses = [ESI,DF] in
99606c3fb27SDimitry Andricdef LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src),
99706c3fb27SDimitry Andric               "lodsq\t{$src, %rax|rax, $src}", []>,
99806c3fb27SDimitry Andric               Requires<[In64BitMode]>;
99906c3fb27SDimitry Andric}
100006c3fb27SDimitry Andric
100106c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
100206c3fb27SDimitry Andriclet Defs = [ESI], Uses = [DX,ESI,DF] in {
100306c3fb27SDimitry Andricdef OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src),
100406c3fb27SDimitry Andric             "outsb\t{$src, %dx|dx, $src}", []>;
100506c3fb27SDimitry Andricdef OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src),
100606c3fb27SDimitry Andric              "outsw\t{$src, %dx|dx, $src}", []>, OpSize16;
100706c3fb27SDimitry Andricdef OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src),
100806c3fb27SDimitry Andric              "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32;
100906c3fb27SDimitry Andric}
101006c3fb27SDimitry Andric
101106c3fb27SDimitry Andriclet Defs = [EDI], Uses = [DX,EDI,DF] in {
101206c3fb27SDimitry Andricdef INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst),
101306c3fb27SDimitry Andric             "insb\t{%dx, $dst|$dst, dx}", []>;
101406c3fb27SDimitry Andricdef INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst),
101506c3fb27SDimitry Andric             "insw\t{%dx, $dst|$dst, dx}", []>,  OpSize16;
101606c3fb27SDimitry Andricdef INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst),
101706c3fb27SDimitry Andric             "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32;
101806c3fb27SDimitry Andric}
101906c3fb27SDimitry Andric}
102006c3fb27SDimitry Andric
102106c3fb27SDimitry Andric// EFLAGS management instructions.
102206c3fb27SDimitry Andriclet SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in {
102306c3fb27SDimitry Andricdef CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>;
102406c3fb27SDimitry Andricdef STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>;
102506c3fb27SDimitry Andricdef CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>;
102606c3fb27SDimitry Andric}
102706c3fb27SDimitry Andric
102806c3fb27SDimitry Andric// DF management instructions.
102906c3fb27SDimitry Andriclet SchedRW = [WriteALU], Defs = [DF] in {
103006c3fb27SDimitry Andricdef CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>;
103106c3fb27SDimitry Andricdef STD : I<0xFD, RawFrm, (outs), (ins), "std", []>;
103206c3fb27SDimitry Andric}
103306c3fb27SDimitry Andric
103406c3fb27SDimitry Andric// Table lookup instructions
103506c3fb27SDimitry Andriclet Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in
103606c3fb27SDimitry Andricdef XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>;
103706c3fb27SDimitry Andric
103806c3fb27SDimitry Andriclet SchedRW = [WriteMicrocoded] in {
103906c3fb27SDimitry Andric// ASCII Adjust After Addition
104006c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
104106c3fb27SDimitry Andricdef AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>,
104206c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
104306c3fb27SDimitry Andric
104406c3fb27SDimitry Andric// ASCII Adjust AX Before Division
104506c3fb27SDimitry Andriclet Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in
104606c3fb27SDimitry Andricdef AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src),
104706c3fb27SDimitry Andric                 "aad\t$src", []>, Requires<[Not64BitMode]>;
104806c3fb27SDimitry Andric
104906c3fb27SDimitry Andric// ASCII Adjust AX After Multiply
105006c3fb27SDimitry Andriclet Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in
105106c3fb27SDimitry Andricdef AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src),
105206c3fb27SDimitry Andric                 "aam\t$src", []>, Requires<[Not64BitMode]>;
105306c3fb27SDimitry Andric
105406c3fb27SDimitry Andric// ASCII Adjust AL After Subtraction - sets
105506c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in
105606c3fb27SDimitry Andricdef AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>,
105706c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
105806c3fb27SDimitry Andric
105906c3fb27SDimitry Andric// Decimal Adjust AL after Addition
106006c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
106106c3fb27SDimitry Andricdef DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>,
106206c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
106306c3fb27SDimitry Andric
106406c3fb27SDimitry Andric// Decimal Adjust AL after Subtraction
106506c3fb27SDimitry Andriclet Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in
106606c3fb27SDimitry Andricdef DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>,
106706c3fb27SDimitry Andric            Requires<[Not64BitMode]>;
106806c3fb27SDimitry Andric} // SchedRW
106906c3fb27SDimitry Andric
107006c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
107106c3fb27SDimitry Andric// Check Array Index Against Bounds
107206c3fb27SDimitry Andric// Note: "bound" does not have reversed operands in at&t syntax.
107306c3fb27SDimitry Andricdef BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
107406c3fb27SDimitry Andric                   "bound\t$dst, $src", []>, OpSize16,
107506c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
107606c3fb27SDimitry Andricdef BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
107706c3fb27SDimitry Andric                   "bound\t$dst, $src", []>, OpSize32,
107806c3fb27SDimitry Andric                   Requires<[Not64BitMode]>;
107906c3fb27SDimitry Andric
108006c3fb27SDimitry Andric// Adjust RPL Field of Segment Selector
108106c3fb27SDimitry Andricdef ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src),
108206c3fb27SDimitry Andric                 "arpl\t{$src, $dst|$dst, $src}", []>,
108306c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
108406c3fb27SDimitry Andriclet mayStore = 1 in
108506c3fb27SDimitry Andricdef ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
108606c3fb27SDimitry Andric                 "arpl\t{$src, $dst|$dst, $src}", []>,
108706c3fb27SDimitry Andric                 Requires<[Not64BitMode]>;
108806c3fb27SDimitry Andric} // SchedRW
108906c3fb27SDimitry Andric
109006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
109106c3fb27SDimitry Andric// MOVBE Instructions
109206c3fb27SDimitry Andric//
109306c3fb27SDimitry Andriclet Predicates = [HasMOVBE] in {
109406c3fb27SDimitry Andric  let SchedRW = [WriteALULd] in {
109506c3fb27SDimitry Andric  def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
109606c3fb27SDimitry Andric                    "movbe{w}\t{$src, $dst|$dst, $src}",
109706c3fb27SDimitry Andric                    [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>,
109806c3fb27SDimitry Andric                    OpSize16, T8PS;
109906c3fb27SDimitry Andric  def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
110006c3fb27SDimitry Andric                    "movbe{l}\t{$src, $dst|$dst, $src}",
110106c3fb27SDimitry Andric                    [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>,
110206c3fb27SDimitry Andric                    OpSize32, T8PS;
110306c3fb27SDimitry Andric  def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
110406c3fb27SDimitry Andric                     "movbe{q}\t{$src, $dst|$dst, $src}",
110506c3fb27SDimitry Andric                     [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>,
110606c3fb27SDimitry Andric                     T8PS;
110706c3fb27SDimitry Andric  }
110806c3fb27SDimitry Andric  let SchedRW = [WriteStore] in {
110906c3fb27SDimitry Andric  def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src),
111006c3fb27SDimitry Andric                    "movbe{w}\t{$src, $dst|$dst, $src}",
111106c3fb27SDimitry Andric                    [(store (bswap GR16:$src), addr:$dst)]>,
111206c3fb27SDimitry Andric                    OpSize16, T8PS;
111306c3fb27SDimitry Andric  def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
111406c3fb27SDimitry Andric                    "movbe{l}\t{$src, $dst|$dst, $src}",
111506c3fb27SDimitry Andric                    [(store (bswap GR32:$src), addr:$dst)]>,
111606c3fb27SDimitry Andric                    OpSize32, T8PS;
111706c3fb27SDimitry Andric  def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
111806c3fb27SDimitry Andric                     "movbe{q}\t{$src, $dst|$dst, $src}",
111906c3fb27SDimitry Andric                     [(store (bswap GR64:$src), addr:$dst)]>,
112006c3fb27SDimitry Andric                     T8PS;
112106c3fb27SDimitry Andric  }
112206c3fb27SDimitry Andric}
112306c3fb27SDimitry Andric
112406c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
112506c3fb27SDimitry Andric// RDRAND Instruction
112606c3fb27SDimitry Andric//
112706c3fb27SDimitry Andriclet Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
112806c3fb27SDimitry Andric  def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
112906c3fb27SDimitry Andric                    "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
113006c3fb27SDimitry Andric                    OpSize16, PS;
113106c3fb27SDimitry Andric  def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
113206c3fb27SDimitry Andric                    "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
113306c3fb27SDimitry Andric                    OpSize32, PS;
113406c3fb27SDimitry Andric  def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
113506c3fb27SDimitry Andric                     "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
113606c3fb27SDimitry Andric                     PS;
113706c3fb27SDimitry Andric}
113806c3fb27SDimitry Andric
113906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
114006c3fb27SDimitry Andric// RDSEED Instruction
114106c3fb27SDimitry Andric//
114206c3fb27SDimitry Andriclet Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
114306c3fb27SDimitry Andric  def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
114406c3fb27SDimitry Andric                    [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS;
114506c3fb27SDimitry Andric  def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
114606c3fb27SDimitry Andric                    [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS;
114706c3fb27SDimitry Andric  def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
114806c3fb27SDimitry Andric                     [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS;
114906c3fb27SDimitry Andric}
115006c3fb27SDimitry Andric
115106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
115206c3fb27SDimitry Andric// LZCNT Instruction
115306c3fb27SDimitry Andric//
115406c3fb27SDimitry Andriclet Predicates = [HasLZCNT], Defs = [EFLAGS] in {
115506c3fb27SDimitry Andric  def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
115606c3fb27SDimitry Andric                    "lzcnt{w}\t{$src, $dst|$dst, $src}",
115706c3fb27SDimitry Andric                    [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>,
115806c3fb27SDimitry Andric                    XS, OpSize16, Sched<[WriteLZCNT]>;
115906c3fb27SDimitry Andric  def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
116006c3fb27SDimitry Andric                    "lzcnt{w}\t{$src, $dst|$dst, $src}",
116106c3fb27SDimitry Andric                    [(set GR16:$dst, (ctlz (loadi16 addr:$src))),
116206c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>;
116306c3fb27SDimitry Andric
116406c3fb27SDimitry Andric  def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
116506c3fb27SDimitry Andric                    "lzcnt{l}\t{$src, $dst|$dst, $src}",
116606c3fb27SDimitry Andric                    [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>,
116706c3fb27SDimitry Andric                    XS, OpSize32, Sched<[WriteLZCNT]>;
116806c3fb27SDimitry Andric  def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
116906c3fb27SDimitry Andric                    "lzcnt{l}\t{$src, $dst|$dst, $src}",
117006c3fb27SDimitry Andric                    [(set GR32:$dst, (ctlz (loadi32 addr:$src))),
117106c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>;
117206c3fb27SDimitry Andric
117306c3fb27SDimitry Andric  def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
117406c3fb27SDimitry Andric                     "lzcnt{q}\t{$src, $dst|$dst, $src}",
117506c3fb27SDimitry Andric                     [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>,
117606c3fb27SDimitry Andric                     XS, Sched<[WriteLZCNT]>;
117706c3fb27SDimitry Andric  def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
117806c3fb27SDimitry Andric                     "lzcnt{q}\t{$src, $dst|$dst, $src}",
117906c3fb27SDimitry Andric                     [(set GR64:$dst, (ctlz (loadi64 addr:$src))),
118006c3fb27SDimitry Andric                      (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>;
118106c3fb27SDimitry Andric}
118206c3fb27SDimitry Andric
118306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
118406c3fb27SDimitry Andric// BMI Instructions
118506c3fb27SDimitry Andric//
118606c3fb27SDimitry Andriclet Predicates = [HasBMI], Defs = [EFLAGS] in {
118706c3fb27SDimitry Andric  def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src),
118806c3fb27SDimitry Andric                    "tzcnt{w}\t{$src, $dst|$dst, $src}",
118906c3fb27SDimitry Andric                    [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>,
119006c3fb27SDimitry Andric                    XS, OpSize16, Sched<[WriteTZCNT]>;
119106c3fb27SDimitry Andric  def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src),
119206c3fb27SDimitry Andric                    "tzcnt{w}\t{$src, $dst|$dst, $src}",
119306c3fb27SDimitry Andric                    [(set GR16:$dst, (cttz (loadi16 addr:$src))),
119406c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>;
119506c3fb27SDimitry Andric
119606c3fb27SDimitry Andric  def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src),
119706c3fb27SDimitry Andric                    "tzcnt{l}\t{$src, $dst|$dst, $src}",
119806c3fb27SDimitry Andric                    [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>,
119906c3fb27SDimitry Andric                    XS, OpSize32, Sched<[WriteTZCNT]>;
120006c3fb27SDimitry Andric  def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src),
120106c3fb27SDimitry Andric                    "tzcnt{l}\t{$src, $dst|$dst, $src}",
120206c3fb27SDimitry Andric                    [(set GR32:$dst, (cttz (loadi32 addr:$src))),
120306c3fb27SDimitry Andric                     (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>;
120406c3fb27SDimitry Andric
120506c3fb27SDimitry Andric  def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src),
120606c3fb27SDimitry Andric                     "tzcnt{q}\t{$src, $dst|$dst, $src}",
120706c3fb27SDimitry Andric                     [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>,
120806c3fb27SDimitry Andric                     XS, Sched<[WriteTZCNT]>;
120906c3fb27SDimitry Andric  def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src),
121006c3fb27SDimitry Andric                     "tzcnt{q}\t{$src, $dst|$dst, $src}",
121106c3fb27SDimitry Andric                     [(set GR64:$dst, (cttz (loadi64 addr:$src))),
121206c3fb27SDimitry Andric                      (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>;
121306c3fb27SDimitry Andric}
121406c3fb27SDimitry Andric
121506c3fb27SDimitry Andricmulticlass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM,
121606c3fb27SDimitry Andric                  RegisterClass RC, X86MemOperand x86memop,
1217*5f757f3fSDimitry Andric                  X86FoldableSchedWrite sched, string Suffix = ""> {
121806c3fb27SDimitry Andriclet hasSideEffects = 0 in {
1219*5f757f3fSDimitry Andric  def rr#Suffix : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src),
122006c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
122106c3fb27SDimitry Andric                  T8PS, VEX_4V, Sched<[sched]>;
122206c3fb27SDimitry Andric  let mayLoad = 1 in
1223*5f757f3fSDimitry Andric  def rm#Suffix : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src),
122406c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>,
122506c3fb27SDimitry Andric                  T8PS, VEX_4V, Sched<[sched.Folded]>;
122606c3fb27SDimitry Andric}
122706c3fb27SDimitry Andric}
122806c3fb27SDimitry Andric
1229*5f757f3fSDimitry Andriclet Predicates = [HasBMI, NoEGPR], Defs = [EFLAGS] in {
123006c3fb27SDimitry Andric  defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>;
123106c3fb27SDimitry Andric  defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, REX_W;
123206c3fb27SDimitry Andric  defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>;
123306c3fb27SDimitry Andric  defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, REX_W;
123406c3fb27SDimitry Andric  defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>;
123506c3fb27SDimitry Andric  defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, REX_W;
123606c3fb27SDimitry Andric}
123706c3fb27SDimitry Andric
1238*5f757f3fSDimitry Andriclet Predicates = [HasBMI, HasEGPR], Defs = [EFLAGS] in {
1239*5f757f3fSDimitry Andric  defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS, "_EVEX">, EVEX;
1240*5f757f3fSDimitry Andric  defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS, "_EVEX">, REX_W, EVEX;
1241*5f757f3fSDimitry Andric  defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS, "_EVEX">, EVEX;
1242*5f757f3fSDimitry Andric  defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS, "_EVEX">, REX_W, EVEX;
1243*5f757f3fSDimitry Andric  defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS, "_EVEX">, EVEX;
1244*5f757f3fSDimitry Andric  defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS, "_EVEX">, REX_W, EVEX;
1245*5f757f3fSDimitry Andric}
124606c3fb27SDimitry Andric
124706c3fb27SDimitry Andriclet Predicates = [HasBMI] in {
124806c3fb27SDimitry Andric  // FIXME(1): patterns for the load versions are not implemented
124906c3fb27SDimitry Andric  // FIXME(2): By only matching `add_su` and `ineg_su` we may emit
125006c3fb27SDimitry Andric  // extra `mov` instructions if `src` has future uses. It may be better
125106c3fb27SDimitry Andric  // to always match if `src` has more users.
125206c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (add_su GR32:$src, -1)),
125306c3fb27SDimitry Andric            (BLSR32rr GR32:$src)>;
125406c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (add_su GR64:$src, -1)),
125506c3fb27SDimitry Andric            (BLSR64rr GR64:$src)>;
125606c3fb27SDimitry Andric
125706c3fb27SDimitry Andric  def : Pat<(xor GR32:$src, (add_su GR32:$src, -1)),
125806c3fb27SDimitry Andric            (BLSMSK32rr GR32:$src)>;
125906c3fb27SDimitry Andric  def : Pat<(xor GR64:$src, (add_su GR64:$src, -1)),
126006c3fb27SDimitry Andric            (BLSMSK64rr GR64:$src)>;
126106c3fb27SDimitry Andric
126206c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (ineg_su GR32:$src)),
126306c3fb27SDimitry Andric            (BLSI32rr GR32:$src)>;
126406c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (ineg_su GR64:$src)),
126506c3fb27SDimitry Andric            (BLSI64rr GR64:$src)>;
126606c3fb27SDimitry Andric
126706c3fb27SDimitry Andric  // Versions to match flag producing ops.
126806c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
126906c3fb27SDimitry Andric            (BLSR32rr GR32:$src)>;
127006c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
127106c3fb27SDimitry Andric            (BLSR64rr GR64:$src)>;
127206c3fb27SDimitry Andric
127306c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
127406c3fb27SDimitry Andric            (BLSMSK32rr GR32:$src)>;
127506c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
127606c3fb27SDimitry Andric            (BLSMSK64rr GR64:$src)>;
127706c3fb27SDimitry Andric
127806c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (ineg_su GR32:$src)),
127906c3fb27SDimitry Andric            (BLSI32rr GR32:$src)>;
128006c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (ineg_su GR64:$src)),
128106c3fb27SDimitry Andric            (BLSI64rr GR64:$src)>;
128206c3fb27SDimitry Andric}
128306c3fb27SDimitry Andric
1284*5f757f3fSDimitry Andricmulticlass bmi4VOp3_base<bits<8> opc, string mnemonic, RegisterClass RC,
1285*5f757f3fSDimitry Andric                         X86MemOperand x86memop, SDPatternOperator OpNode,
1286*5f757f3fSDimitry Andric                         PatFrag ld_frag, X86FoldableSchedWrite Sched,
1287*5f757f3fSDimitry Andric                         string Suffix = ""> {
1288*5f757f3fSDimitry Andric  def rr#Suffix : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
128906c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
129006c3fb27SDimitry Andric                    [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>,
129106c3fb27SDimitry Andric                  T8PS, VEX, Sched<[Sched]>;
1292*5f757f3fSDimitry Andriclet mayLoad = 1 in
1293*5f757f3fSDimitry Andric  def rm#Suffix : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
129406c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
129506c3fb27SDimitry Andric                    [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)),
129606c3fb27SDimitry Andric                     (implicit EFLAGS)]>, T8PS, VEX,
129706c3fb27SDimitry Andric                  Sched<[Sched.Folded,
129806c3fb27SDimitry Andric                         // x86memop:$src1
129906c3fb27SDimitry Andric                         ReadDefault, ReadDefault, ReadDefault, ReadDefault,
130006c3fb27SDimitry Andric                         ReadDefault,
130106c3fb27SDimitry Andric                         // RC:$src2
130206c3fb27SDimitry Andric                         Sched.ReadAfterFold]>;
130306c3fb27SDimitry Andric}
130406c3fb27SDimitry Andric
1305*5f757f3fSDimitry Andriclet Predicates = [HasBMI, NoEGPR], Defs = [EFLAGS] in {
1306*5f757f3fSDimitry Andric  defm BEXTR32 : bmi4VOp3_base<0xF7, "bextr{l}", GR32, i32mem,
130706c3fb27SDimitry Andric                               X86bextr, loadi32, WriteBEXTR>;
1308*5f757f3fSDimitry Andric  defm BEXTR64 : bmi4VOp3_base<0xF7, "bextr{q}", GR64, i64mem,
130906c3fb27SDimitry Andric                               X86bextr, loadi64, WriteBEXTR>, REX_W;
131006c3fb27SDimitry Andric}
1311*5f757f3fSDimitry Andriclet Predicates = [HasBMI2, NoEGPR], Defs = [EFLAGS] in {
1312*5f757f3fSDimitry Andric  defm BZHI32 : bmi4VOp3_base<0xF5, "bzhi{l}", GR32, i32mem,
131306c3fb27SDimitry Andric                              X86bzhi, loadi32, WriteBZHI>;
1314*5f757f3fSDimitry Andric  defm BZHI64 : bmi4VOp3_base<0xF5, "bzhi{q}", GR64, i64mem,
131506c3fb27SDimitry Andric                              X86bzhi, loadi64, WriteBZHI>, REX_W;
131606c3fb27SDimitry Andric}
1317*5f757f3fSDimitry Andriclet Predicates = [HasBMI, HasEGPR], Defs = [EFLAGS] in {
1318*5f757f3fSDimitry Andric  defm BEXTR32 : bmi4VOp3_base<0xF7, "bextr{l}", GR32, i32mem,
1319*5f757f3fSDimitry Andric                               X86bextr, loadi32, WriteBEXTR, "_EVEX">, EVEX;
1320*5f757f3fSDimitry Andric  defm BEXTR64 : bmi4VOp3_base<0xF7, "bextr{q}", GR64, i64mem,
1321*5f757f3fSDimitry Andric                               X86bextr, loadi64, WriteBEXTR, "_EVEX">, EVEX, REX_W;
1322*5f757f3fSDimitry Andric}
1323*5f757f3fSDimitry Andriclet Predicates = [HasBMI2, HasEGPR], Defs = [EFLAGS] in {
1324*5f757f3fSDimitry Andric  defm BZHI32 : bmi4VOp3_base<0xF5, "bzhi{l}", GR32, i32mem,
1325*5f757f3fSDimitry Andric                              X86bzhi, loadi32, WriteBZHI, "_EVEX">, EVEX;
1326*5f757f3fSDimitry Andric  defm BZHI64 : bmi4VOp3_base<0xF5, "bzhi{q}", GR64, i64mem,
1327*5f757f3fSDimitry Andric                              X86bzhi, loadi64, WriteBZHI, "_EVEX">, EVEX, REX_W;
1328*5f757f3fSDimitry Andric}
132906c3fb27SDimitry Andric
133006c3fb27SDimitry Andricdef CountTrailingOnes : SDNodeXForm<imm, [{
133106c3fb27SDimitry Andric  // Count the trailing ones in the immediate.
133206c3fb27SDimitry Andric  return getI8Imm(llvm::countr_one(N->getZExtValue()), SDLoc(N));
133306c3fb27SDimitry Andric}]>;
133406c3fb27SDimitry Andric
133506c3fb27SDimitry Andricdef BEXTRMaskXForm : SDNodeXForm<imm, [{
133606c3fb27SDimitry Andric  unsigned Length = llvm::countr_one(N->getZExtValue());
133706c3fb27SDimitry Andric  return getI32Imm(Length << 8, SDLoc(N));
133806c3fb27SDimitry Andric}]>;
133906c3fb27SDimitry Andric
134006c3fb27SDimitry Andricdef AndMask64 : ImmLeaf<i64, [{
134106c3fb27SDimitry Andric  return isMask_64(Imm) && !isUInt<32>(Imm);
134206c3fb27SDimitry Andric}]>;
134306c3fb27SDimitry Andric
134406c3fb27SDimitry Andric// Use BEXTR for 64-bit 'and' with large immediate 'mask'.
134506c3fb27SDimitry Andriclet Predicates = [HasBMI, NoBMI2, NoTBM] in {
134606c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
134706c3fb27SDimitry Andric            (BEXTR64rr GR64:$src,
134806c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
134906c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
135006c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
135106c3fb27SDimitry Andric            (BEXTR64rm addr:$src,
135206c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
135306c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
135406c3fb27SDimitry Andric}
135506c3fb27SDimitry Andric
135606c3fb27SDimitry Andric// Use BZHI for 64-bit 'and' with large immediate 'mask'.
135706c3fb27SDimitry Andriclet Predicates = [HasBMI2, NoTBM] in {
135806c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
135906c3fb27SDimitry Andric            (BZHI64rr GR64:$src,
136006c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
136106c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
136206c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
136306c3fb27SDimitry Andric            (BZHI64rm addr:$src,
136406c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
136506c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
136606c3fb27SDimitry Andric}
136706c3fb27SDimitry Andric
136806c3fb27SDimitry Andricmulticlass bmi_pdep_pext<string mnemonic, RegisterClass RC,
1369*5f757f3fSDimitry Andric                         X86MemOperand x86memop, SDPatternOperator OpNode,
1370*5f757f3fSDimitry Andric                         PatFrag ld_frag, string Suffix = ""> {
1371*5f757f3fSDimitry Andric  def rr#Suffix : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2),
137206c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
137306c3fb27SDimitry Andric                    [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>,
137406c3fb27SDimitry Andric                  VEX_4V, Sched<[WriteALU]>;
1375*5f757f3fSDimitry Andric  def rm#Suffix : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2),
137606c3fb27SDimitry Andric                    !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"),
137706c3fb27SDimitry Andric                    [(set RC:$dst, (OpNode RC:$src1, (ld_frag addr:$src2)))]>,
137806c3fb27SDimitry Andric                  VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
137906c3fb27SDimitry Andric}
138006c3fb27SDimitry Andric
1381*5f757f3fSDimitry Andriclet Predicates = [HasBMI2, NoEGPR] in {
138206c3fb27SDimitry Andric  defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
138306c3fb27SDimitry Andric                               X86pdep, loadi32>, T8XD;
138406c3fb27SDimitry Andric  defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
138506c3fb27SDimitry Andric                               X86pdep, loadi64>, T8XD, REX_W;
138606c3fb27SDimitry Andric  defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
138706c3fb27SDimitry Andric                               X86pext, loadi32>, T8XS;
138806c3fb27SDimitry Andric  defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
138906c3fb27SDimitry Andric                               X86pext, loadi64>, T8XS, REX_W;
139006c3fb27SDimitry Andric}
139106c3fb27SDimitry Andric
1392*5f757f3fSDimitry Andriclet Predicates = [HasBMI2, HasEGPR] in {
1393*5f757f3fSDimitry Andric  defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem,
1394*5f757f3fSDimitry Andric                               X86pdep, loadi32, "_EVEX">, T8XD, EVEX;
1395*5f757f3fSDimitry Andric  defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem,
1396*5f757f3fSDimitry Andric                               X86pdep, loadi64, "_EVEX">, T8XD, REX_W, EVEX;
1397*5f757f3fSDimitry Andric  defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem,
1398*5f757f3fSDimitry Andric                               X86pext, loadi32, "_EVEX">, T8XS, EVEX;
1399*5f757f3fSDimitry Andric  defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem,
1400*5f757f3fSDimitry Andric                               X86pext, loadi64, "_EVEX">, T8XS, REX_W, EVEX;
1401*5f757f3fSDimitry Andric}
1402*5f757f3fSDimitry Andric
140306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
140406c3fb27SDimitry Andric// Lightweight Profiling Instructions
140506c3fb27SDimitry Andric
140606c3fb27SDimitry Andriclet Predicates = [HasLWP], SchedRW = [WriteSystem] in {
140706c3fb27SDimitry Andric
140806c3fb27SDimitry Andricdef LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
140906c3fb27SDimitry Andric               [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
141006c3fb27SDimitry Andricdef SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
141106c3fb27SDimitry Andric               [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
141206c3fb27SDimitry Andric
141306c3fb27SDimitry Andricdef LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
141406c3fb27SDimitry Andric                 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, REX_W;
141506c3fb27SDimitry Andricdef SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
141606c3fb27SDimitry Andric                 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, REX_W;
141706c3fb27SDimitry Andric
141806c3fb27SDimitry Andricmulticlass lwpins_intr<RegisterClass RC> {
141906c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
142006c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
142106c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>,
142206c3fb27SDimitry Andric                 XOP_4V, XOPA;
142306c3fb27SDimitry Andric  let mayLoad = 1 in
142406c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
142506c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
142606c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>,
142706c3fb27SDimitry Andric                 XOP_4V, XOPA;
142806c3fb27SDimitry Andric}
142906c3fb27SDimitry Andric
143006c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
143106c3fb27SDimitry Andric  defm LWPINS32 : lwpins_intr<GR32>;
143206c3fb27SDimitry Andric  defm LWPINS64 : lwpins_intr<GR64>, REX_W;
143306c3fb27SDimitry Andric} // EFLAGS
143406c3fb27SDimitry Andric
143506c3fb27SDimitry Andricmulticlass lwpval_intr<RegisterClass RC, Intrinsic Int> {
143606c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
143706c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
143806c3fb27SDimitry Andric                 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA;
143906c3fb27SDimitry Andric  let mayLoad = 1 in
144006c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
144106c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
144206c3fb27SDimitry Andric                 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>,
144306c3fb27SDimitry Andric                 XOP_4V, XOPA;
144406c3fb27SDimitry Andric}
144506c3fb27SDimitry Andric
144606c3fb27SDimitry Andricdefm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
144706c3fb27SDimitry Andricdefm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, REX_W;
144806c3fb27SDimitry Andric
144906c3fb27SDimitry Andric} // HasLWP, SchedRW
145006c3fb27SDimitry Andric
145106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
145206c3fb27SDimitry Andric// MONITORX/MWAITX Instructions
145306c3fb27SDimitry Andric//
145406c3fb27SDimitry Andriclet SchedRW = [ WriteSystem ] in {
145506c3fb27SDimitry Andric  let Uses = [ EAX, ECX, EDX ] in
145606c3fb27SDimitry Andric  def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
145706c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, Not64BitMode ]>;
145806c3fb27SDimitry Andric  let Uses = [ RAX, ECX, EDX ] in
145906c3fb27SDimitry Andric  def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
146006c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, In64BitMode ]>;
146106c3fb27SDimitry Andric
146206c3fb27SDimitry Andric  let Uses = [ ECX, EAX, EBX ] in {
146306c3fb27SDimitry Andric    def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
146406c3fb27SDimitry Andric                    []>, TB, Requires<[ HasMWAITX ]>;
146506c3fb27SDimitry Andric  }
146606c3fb27SDimitry Andric} // SchedRW
146706c3fb27SDimitry Andric
146806c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
146906c3fb27SDimitry Andric// WAITPKG Instructions
147006c3fb27SDimitry Andric//
147106c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
147206c3fb27SDimitry Andric  def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
147306c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
147406c3fb27SDimitry Andric                     XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
147506c3fb27SDimitry Andric  def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
147606c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
147706c3fb27SDimitry Andric                     XS, AdSize32, Requires<[HasWAITPKG]>;
147806c3fb27SDimitry Andric  def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
147906c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
148006c3fb27SDimitry Andric                     XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
148106c3fb27SDimitry Andric  let Uses = [EAX, EDX], Defs = [EFLAGS] in {
148206c3fb27SDimitry Andric    def UMWAIT : I<0xAE, MRM6r,
148306c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "umwait\t$src",
148406c3fb27SDimitry Andric                     [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
148506c3fb27SDimitry Andric                     XD, Requires<[HasWAITPKG]>;
148606c3fb27SDimitry Andric    def TPAUSE : I<0xAE, MRM6r,
148706c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "tpause\t$src",
148806c3fb27SDimitry Andric                     [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
148906c3fb27SDimitry Andric                     PD, Requires<[HasWAITPKG]>;
149006c3fb27SDimitry Andric  }
149106c3fb27SDimitry Andric} // SchedRW
149206c3fb27SDimitry Andric
149306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
149406c3fb27SDimitry Andric// MOVDIRI - Move doubleword/quadword as direct store
149506c3fb27SDimitry Andric//
149606c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
149706c3fb27SDimitry Andricdef MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
149806c3fb27SDimitry Andric                  "movdiri\t{$src, $dst|$dst, $src}",
149906c3fb27SDimitry Andric                  [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
1500*5f757f3fSDimitry Andric                 T8PS, Requires<[HasMOVDIRI, NoEGPR]>;
150106c3fb27SDimitry Andricdef MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
150206c3fb27SDimitry Andric                   "movdiri\t{$src, $dst|$dst, $src}",
150306c3fb27SDimitry Andric                   [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
1504*5f757f3fSDimitry Andric                  T8PS, Requires<[In64BitMode, HasMOVDIRI, NoEGPR]>;
1505*5f757f3fSDimitry Andricdef MOVDIRI32_EVEX : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
1506*5f757f3fSDimitry Andric                       "movdiri\t{$src, $dst|$dst, $src}",
1507*5f757f3fSDimitry Andric                       [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
1508*5f757f3fSDimitry Andric                     EVEX_NoCD8, T_MAP4PS, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>;
1509*5f757f3fSDimitry Andricdef MOVDIRI64_EVEX : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
1510*5f757f3fSDimitry Andric                        "movdiri\t{$src, $dst|$dst, $src}",
1511*5f757f3fSDimitry Andric                        [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
1512*5f757f3fSDimitry Andric                     EVEX_NoCD8, T_MAP4PS, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>;
151306c3fb27SDimitry Andric} // SchedRW
151406c3fb27SDimitry Andric
151506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
151606c3fb27SDimitry Andric// MOVDIR64B - Move 64 bytes as direct store
151706c3fb27SDimitry Andric//
151806c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
151906c3fb27SDimitry Andricdef MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
152006c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}", []>,
152106c3fb27SDimitry Andric                   T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
152206c3fb27SDimitry Andricdef MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
152306c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
152406c3fb27SDimitry Andric                    [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
1525*5f757f3fSDimitry Andric                   T8PD, AdSize32, Requires<[HasMOVDIR64B, NoEGPR]>;
152606c3fb27SDimitry Andricdef MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
152706c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
152806c3fb27SDimitry Andric                    [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
1529*5f757f3fSDimitry Andric                   T8PD, AdSize64, Requires<[HasMOVDIR64B, NoEGPR, In64BitMode]>;
1530*5f757f3fSDimitry Andricdef MOVDIR64B32_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
1531*5f757f3fSDimitry Andric                         "movdir64b\t{$src, $dst|$dst, $src}",
1532*5f757f3fSDimitry Andric                         [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
1533*5f757f3fSDimitry Andric                       EVEX_NoCD8, T_MAP4PD, AdSize32, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>;
1534*5f757f3fSDimitry Andricdef MOVDIR64B64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
1535*5f757f3fSDimitry Andric                         "movdir64b\t{$src, $dst|$dst, $src}",
1536*5f757f3fSDimitry Andric                         [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
1537*5f757f3fSDimitry Andric                       EVEX_NoCD8, T_MAP4PD, AdSize64, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>;
153806c3fb27SDimitry Andric} // SchedRW
153906c3fb27SDimitry Andric
154006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
154106c3fb27SDimitry Andric// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
154206c3fb27SDimitry Andric//
154306c3fb27SDimitry Andriclet SchedRW = [WriteStore], Defs = [EFLAGS] in {
154406c3fb27SDimitry Andric  def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
154506c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
154606c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
154706c3fb27SDimitry Andric                 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
154806c3fb27SDimitry Andric  def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
154906c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
155006c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
155106c3fb27SDimitry Andric                 T8XD, AdSize32, Requires<[HasENQCMD]>;
155206c3fb27SDimitry Andric  def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
155306c3fb27SDimitry Andric                 "enqcmd\t{$src, $dst|$dst, $src}",
155406c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
155506c3fb27SDimitry Andric                 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
155606c3fb27SDimitry Andric
155706c3fb27SDimitry Andric  def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src),
155806c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
155906c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
156006c3fb27SDimitry Andric                 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
156106c3fb27SDimitry Andric  def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src),
156206c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
156306c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
156406c3fb27SDimitry Andric                 T8XS, AdSize32, Requires<[HasENQCMD]>;
156506c3fb27SDimitry Andric  def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src),
156606c3fb27SDimitry Andric                 "enqcmds\t{$src, $dst|$dst, $src}",
156706c3fb27SDimitry Andric                 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
156806c3fb27SDimitry Andric                 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>;
156906c3fb27SDimitry Andric}
157006c3fb27SDimitry Andric
157106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
157206c3fb27SDimitry Andric// CLZERO Instruction
157306c3fb27SDimitry Andric//
157406c3fb27SDimitry Andriclet SchedRW = [WriteLoad] in {
157506c3fb27SDimitry Andric  let Uses = [EAX] in
157606c3fb27SDimitry Andric  def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
157706c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, Not64BitMode]>;
157806c3fb27SDimitry Andric  let Uses = [RAX] in
157906c3fb27SDimitry Andric  def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
158006c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, In64BitMode]>;
158106c3fb27SDimitry Andric} // SchedRW
158206c3fb27SDimitry Andric
158306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
158406c3fb27SDimitry Andric// INVLPGB Instruction
158506c3fb27SDimitry Andric// OPCODE 0F 01 FE
158606c3fb27SDimitry Andric//
158706c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
158806c3fb27SDimitry Andric  let Uses = [EAX, EDX] in
158906c3fb27SDimitry Andric  def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins),
159006c3fb27SDimitry Andric                  "invlpgb", []>,
159106c3fb27SDimitry Andric                  PS, Requires<[Not64BitMode]>;
159206c3fb27SDimitry Andric  let Uses = [RAX, EDX] in
159306c3fb27SDimitry Andric  def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins),
159406c3fb27SDimitry Andric                  "invlpgb", []>,
159506c3fb27SDimitry Andric                  PS, Requires<[In64BitMode]>;
159606c3fb27SDimitry Andric} // SchedRW
159706c3fb27SDimitry Andric
159806c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
159906c3fb27SDimitry Andric// TLBSYNC Instruction
160006c3fb27SDimitry Andric// OPCODE 0F 01 FF
160106c3fb27SDimitry Andric//
160206c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
160306c3fb27SDimitry Andric  def TLBSYNC   : I<0x01, MRM_FF, (outs), (ins),
160406c3fb27SDimitry Andric                  "tlbsync", []>,
160506c3fb27SDimitry Andric                  PS, Requires<[]>;
160606c3fb27SDimitry Andric} // SchedRW
160706c3fb27SDimitry Andric
160806c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
160906c3fb27SDimitry Andric// HRESET Instruction
161006c3fb27SDimitry Andric//
161106c3fb27SDimitry Andriclet Uses = [EAX], SchedRW = [WriteSystem] in
161206c3fb27SDimitry Andric  def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>,
161306c3fb27SDimitry Andric                   Requires<[HasHRESET]>, TAXS;
161406c3fb27SDimitry Andric
161506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
161606c3fb27SDimitry Andric// SERIALIZE Instruction
161706c3fb27SDimitry Andric//
161806c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in
161906c3fb27SDimitry Andric  def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize",
162006c3fb27SDimitry Andric                    [(int_x86_serialize)]>, PS,
162106c3fb27SDimitry Andric                    Requires<[HasSERIALIZE]>;
162206c3fb27SDimitry Andric
162306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
162406c3fb27SDimitry Andric// TSXLDTRK - TSX Suspend Load Address Tracking
162506c3fb27SDimitry Andric//
162606c3fb27SDimitry Andriclet Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in {
162706c3fb27SDimitry Andric  def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk",
162806c3fb27SDimitry Andric                    [(int_x86_xsusldtrk)]>, XD;
162906c3fb27SDimitry Andric  def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk",
163006c3fb27SDimitry Andric                    [(int_x86_xresldtrk)]>, XD;
163106c3fb27SDimitry Andric}
163206c3fb27SDimitry Andric
163306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
163406c3fb27SDimitry Andric// UINTR Instructions
163506c3fb27SDimitry Andric//
163606c3fb27SDimitry Andriclet Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in {
163706c3fb27SDimitry Andric  def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret",
163806c3fb27SDimitry Andric               []>, XS;
163906c3fb27SDimitry Andric  def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui",
164006c3fb27SDimitry Andric               [(int_x86_clui)]>, XS;
164106c3fb27SDimitry Andric  def STUI : I<0x01, MRM_EF, (outs), (ins), "stui",
164206c3fb27SDimitry Andric               [(int_x86_stui)]>, XS;
164306c3fb27SDimitry Andric
164406c3fb27SDimitry Andric  def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg",
164506c3fb27SDimitry Andric                   [(int_x86_senduipi GR64:$arg)]>, XS;
164606c3fb27SDimitry Andric
164706c3fb27SDimitry Andric  let Defs = [EFLAGS] in
164806c3fb27SDimitry Andric    def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui",
164906c3fb27SDimitry Andric                   [(set EFLAGS, (X86testui))]>, XS;
165006c3fb27SDimitry Andric}
165106c3fb27SDimitry Andric
165206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
165306c3fb27SDimitry Andric// PREFETCHIT0 and PREFETCHIT1 Instructions
165406c3fb27SDimitry Andric// prefetch ADDR, RW, Locality, Data
165506c3fb27SDimitry Andriclet Predicates = [HasPREFETCHI, In64BitMode], SchedRW = [WriteLoad] in {
165606c3fb27SDimitry Andric  def PREFETCHIT0 : I<0x18, MRM7m, (outs), (ins i8mem:$src),
165706c3fb27SDimitry Andric    "prefetchit0\t$src", [(prefetch addr:$src, (i32 0), (i32 3), (i32 0))]>, TB;
165806c3fb27SDimitry Andric  def PREFETCHIT1 : I<0x18, MRM6m, (outs), (ins i8mem:$src),
165906c3fb27SDimitry Andric    "prefetchit1\t$src", [(prefetch addr:$src, (i32 0), (i32 2), (i32 0))]>, TB;
166006c3fb27SDimitry Andric}
166106c3fb27SDimitry Andric
166206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
166306c3fb27SDimitry Andric// CMPCCXADD Instructions
166406c3fb27SDimitry Andric//
166506c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, mayLoad = 1, mayStore = 1,
166606c3fb27SDimitry Andric    Predicates = [HasCMPCCXADD, In64BitMode], Defs = [EFLAGS],
166706c3fb27SDimitry Andric    Constraints = "$dstsrc1 = $dst" in {
166806c3fb27SDimitry Andricdef CMPCCXADDmr32 : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst),
166906c3fb27SDimitry Andric          (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond),
167006c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
167106c3fb27SDimitry Andric          [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2,
167206c3fb27SDimitry Andric            GR32:$dstsrc1, GR32:$src3, timm:$cond))]>,
167306c3fb27SDimitry Andric          VEX_4V, T8PD, Sched<[WriteXCHG]>;
167406c3fb27SDimitry Andric
167506c3fb27SDimitry Andricdef CMPCCXADDmr64 : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst),
167606c3fb27SDimitry Andric          (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond),
167706c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
167806c3fb27SDimitry Andric          [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2,
167906c3fb27SDimitry Andric            GR64:$dstsrc1, GR64:$src3, timm:$cond))]>,
168006c3fb27SDimitry Andric          VEX_4V, REX_W, T8PD, Sched<[WriteXCHG]>;
168106c3fb27SDimitry Andric}
168206c3fb27SDimitry Andric
168306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
168406c3fb27SDimitry Andric// Memory Instructions
168506c3fb27SDimitry Andric//
168606c3fb27SDimitry Andric
168706c3fb27SDimitry Andriclet Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
168806c3fb27SDimitry Andricdef CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
168906c3fb27SDimitry Andric                   "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD;
169006c3fb27SDimitry Andric
169106c3fb27SDimitry Andriclet Predicates = [HasCLWB], SchedRW = [WriteLoad] in
169206c3fb27SDimitry Andricdef CLWB       : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
169306c3fb27SDimitry Andric                   [(int_x86_clwb addr:$src)]>, PD;
169406c3fb27SDimitry Andric
169506c3fb27SDimitry Andriclet Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
169606c3fb27SDimitry Andricdef CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
169706c3fb27SDimitry Andric                   [(int_x86_cldemote addr:$src)]>, PS;
1698