xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/X86/X86InstrMisc.td (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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
1645f757f3fSDimitry Andricdef POPP64r  : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "popp\t$reg", []>,
1655f757f3fSDimitry Andric                 REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
1665f757f3fSDimitry Andricdef POP2: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
1675f757f3fSDimitry Andric            "pop2\t{$reg2, $reg1|$reg1, $reg2}",
168cb14a3feSDimitry Andric            []>, EVEX, VVVV, EVEX_B, T_MAP4;
1695f757f3fSDimitry Andricdef POP2P: I<0x8F, MRM0r, (outs GR64:$reg1, GR64:$reg2), (ins),
1705f757f3fSDimitry Andric             "pop2p\t{$reg2, $reg1|$reg1, $reg2}",
171cb14a3feSDimitry Andric             []>, EVEX, VVVV, EVEX_B, T_MAP4, REX_W;
1725f757f3fSDimitry 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
1855f757f3fSDimitry Andricdef PUSHP64r  : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "pushp\t$reg", []>,
1865f757f3fSDimitry Andric                  REX_W, ExplicitREX2Prefix, Requires<[In64BitMode]>;
1875f757f3fSDimitry Andricdef PUSH2: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
1885f757f3fSDimitry Andric            "push2\t{$reg2, $reg1|$reg1, $reg2}",
189cb14a3feSDimitry Andric            []>, EVEX, VVVV, EVEX_B, T_MAP4;
1905f757f3fSDimitry Andricdef PUSH2P: I<0xFF, MRM6r, (outs), (ins GR64:$reg1, GR64:$reg2),
1915f757f3fSDimitry Andric             "push2p\t{$reg2, $reg1|$reg1, $reg2}",
192cb14a3feSDimitry Andric             []>, EVEX, VVVV, EVEX_B, T_MAP4, 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
232*0fca6ea1SDimitry Andriclet Constraints = "$src = $dst", SchedRW = [WriteBSWAP32], Predicates = [NoNDD_Or_NoMOVBE] 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))]>,
254cb14a3feSDimitry Andric                  TB, 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)))]>,
258cb14a3feSDimitry Andric                 TB, 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))]>,
262cb14a3feSDimitry Andric                 TB, 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)))]>,
266cb14a3feSDimitry Andric                 TB, 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))]>,
270cb14a3feSDimitry Andric                  TB, 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)))]>,
274cb14a3feSDimitry Andric                  TB, 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))]>,
279cb14a3feSDimitry Andric                 TB, 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)))]>,
283cb14a3feSDimitry Andric                 TB, 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))]>,
287cb14a3feSDimitry Andric                 TB, 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)))]>,
291cb14a3feSDimitry Andric                 TB, 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))]>,
295cb14a3feSDimitry Andric                  TB, 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)))]>,
299cb14a3feSDimitry Andric                  TB, 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,
826*0fca6ea1SDimitry Andric                         (!cast<PatFrag>(frag # "_i8") 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,
832*0fca6ea1SDimitry Andric                         (!cast<PatFrag>(frag # "_i16") 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,
839*0fca6ea1SDimitry Andric                         (!cast<PatFrag>(frag # "_i32") 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,
846*0fca6ea1SDimitry Andric                         (!cast<PatFrag>(frag # "_i64") 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//
1093*0fca6ea1SDimitry Andricmulticlass Movbe<bits<8> o, X86TypeInfo t, string suffix = ""> {
1094*0fca6ea1SDimitry Andric  def rm#suffix : ITy<o, MRMSrcMem, t, (outs t.RegClass:$dst),
1095*0fca6ea1SDimitry Andric                      (ins t.MemOperand:$src1), "movbe", unaryop_ndd_args,
1096*0fca6ea1SDimitry Andric                      [(set t.RegClass:$dst, (bswap (t.LoadNode addr:$src1)))]>,
1097*0fca6ea1SDimitry Andric                  Sched<[WriteALULd]>;
1098*0fca6ea1SDimitry Andric  def mr#suffix : ITy<!add(o, 1), MRMDestMem, t, (outs),
1099*0fca6ea1SDimitry Andric                      (ins t.MemOperand:$dst, t.RegClass:$src1),
1100*0fca6ea1SDimitry Andric                      "movbe", unaryop_ndd_args,
1101*0fca6ea1SDimitry Andric                      [(store (bswap t.RegClass:$src1), addr:$dst)]>,
1102*0fca6ea1SDimitry Andric                  Sched<[WriteStore]>;
110306c3fb27SDimitry Andric}
1104*0fca6ea1SDimitry Andric
1105*0fca6ea1SDimitry Andriclet Predicates = [HasMOVBE, NoEGPR] in {
1106*0fca6ea1SDimitry Andric  defm MOVBE16 : Movbe<0xF0, Xi16>, OpSize16, T8;
1107*0fca6ea1SDimitry Andric  defm MOVBE32 : Movbe<0xF0, Xi32>, OpSize32, T8;
1108*0fca6ea1SDimitry Andric  defm MOVBE64 : Movbe<0xF0, Xi64>, T8;
110906c3fb27SDimitry Andric}
1110*0fca6ea1SDimitry Andric
1111*0fca6ea1SDimitry Andriclet Predicates = [HasMOVBE, HasEGPR, In64BitMode] in {
1112*0fca6ea1SDimitry Andric  defm MOVBE16 : Movbe<0x60, Xi16, "_EVEX">, EVEX, T_MAP4, PD;
1113*0fca6ea1SDimitry Andric  defm MOVBE32 : Movbe<0x60, Xi32, "_EVEX">, EVEX, T_MAP4;
1114*0fca6ea1SDimitry Andric  defm MOVBE64 : Movbe<0x60, Xi64, "_EVEX">, EVEX, T_MAP4;
1115*0fca6ea1SDimitry Andric}
1116*0fca6ea1SDimitry Andric
1117*0fca6ea1SDimitry Andricmulticlass Movberr<X86TypeInfo t> {
1118*0fca6ea1SDimitry Andric  def rr : ITy<0x61, MRMDestReg, t, (outs t.RegClass:$dst),
1119*0fca6ea1SDimitry Andric               (ins t.RegClass:$src1), "movbe", unaryop_ndd_args,
1120*0fca6ea1SDimitry Andric               [(set t.RegClass:$dst, (bswap t.RegClass:$src1))]>,
1121*0fca6ea1SDimitry Andric           EVEX, T_MAP4;
1122*0fca6ea1SDimitry Andric  def rr_REV : ITy<0x60, MRMSrcReg, t, (outs t.RegClass:$dst),
1123*0fca6ea1SDimitry Andric                   (ins t.RegClass:$src1), "movbe", unaryop_ndd_args, []>,
1124*0fca6ea1SDimitry Andric               EVEX, T_MAP4, DisassembleOnly;
1125*0fca6ea1SDimitry Andric}
1126*0fca6ea1SDimitry Andriclet SchedRW = [WriteALU], Predicates = [HasMOVBE, HasNDD, In64BitMode] in {
1127*0fca6ea1SDimitry Andric  defm MOVBE16 : Movberr<Xi16>, PD;
1128*0fca6ea1SDimitry Andric  defm MOVBE32 : Movberr<Xi32>;
1129*0fca6ea1SDimitry Andric  defm MOVBE64 : Movberr<Xi64>;
113006c3fb27SDimitry Andric}
113106c3fb27SDimitry Andric
113206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
113306c3fb27SDimitry Andric// RDRAND Instruction
113406c3fb27SDimitry Andric//
113506c3fb27SDimitry Andriclet Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
113606c3fb27SDimitry Andric  def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins),
113706c3fb27SDimitry Andric                    "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>,
1138cb14a3feSDimitry Andric                    OpSize16, TB;
113906c3fb27SDimitry Andric  def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins),
114006c3fb27SDimitry Andric                    "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>,
1141cb14a3feSDimitry Andric                    OpSize32, TB;
114206c3fb27SDimitry Andric  def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins),
114306c3fb27SDimitry Andric                     "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>,
1144cb14a3feSDimitry Andric                     TB;
114506c3fb27SDimitry Andric}
114606c3fb27SDimitry Andric
114706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
114806c3fb27SDimitry Andric// RDSEED Instruction
114906c3fb27SDimitry Andric//
115006c3fb27SDimitry Andriclet Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in {
115106c3fb27SDimitry Andric  def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst",
1152cb14a3feSDimitry Andric                    [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB;
115306c3fb27SDimitry Andric  def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst",
1154cb14a3feSDimitry Andric                    [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB;
115506c3fb27SDimitry Andric  def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst",
1156cb14a3feSDimitry Andric                     [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB;
115706c3fb27SDimitry Andric}
115806c3fb27SDimitry Andric
115906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
116006c3fb27SDimitry Andric// LZCNT Instruction
116106c3fb27SDimitry Andric//
1162*0fca6ea1SDimitry Andricmulticlass Lzcnt<bits<8> o, string m, SDPatternOperator node, X86TypeInfo t,
1163*0fca6ea1SDimitry Andric                 SchedWrite schedrr, SchedWrite schedrm, string suffix = ""> {
1164*0fca6ea1SDimitry Andric  def rr#suffix : ITy<o, MRMSrcReg, t, (outs t.RegClass:$dst),
1165*0fca6ea1SDimitry Andric                      (ins t.RegClass:$src1), m, unaryop_ndd_args,
1166*0fca6ea1SDimitry Andric                      [(set t.RegClass:$dst, (node t.RegClass:$src1)),
1167*0fca6ea1SDimitry Andric                                              (implicit EFLAGS)]>,
1168*0fca6ea1SDimitry Andric                  TB, Sched<[schedrr]>;
1169*0fca6ea1SDimitry Andric  let mayLoad = 1 in
1170*0fca6ea1SDimitry Andric    def rm#suffix : ITy<o, MRMSrcMem, t, (outs t.RegClass:$dst),
1171*0fca6ea1SDimitry Andric                        (ins t.MemOperand:$src1), m, unaryop_ndd_args,
1172*0fca6ea1SDimitry Andric                        [(set t.RegClass:$dst, (node (t.LoadNode addr:$src1))),
1173*0fca6ea1SDimitry Andric                                                (implicit EFLAGS)]>,
1174*0fca6ea1SDimitry Andric                    TB, Sched<[schedrm]>;
117506c3fb27SDimitry Andric}
117606c3fb27SDimitry Andric
1177*0fca6ea1SDimitry Andriclet Predicates = [HasLZCNT], Defs = [EFLAGS] in {
1178*0fca6ea1SDimitry Andric  defm LZCNT16 : Lzcnt<0xBD, "lzcnt", ctlz, Xi16, WriteLZCNT, WriteLZCNTLd>, OpSize16, XS;
1179*0fca6ea1SDimitry Andric  defm LZCNT32 : Lzcnt<0xBD, "lzcnt", ctlz, Xi32, WriteLZCNT, WriteLZCNTLd>, OpSize32, XS;
1180*0fca6ea1SDimitry Andric  defm LZCNT64 : Lzcnt<0xBD, "lzcnt", ctlz, Xi64, WriteLZCNT, WriteLZCNTLd>, XS;
1181*0fca6ea1SDimitry Andric
1182*0fca6ea1SDimitry Andric  defm LZCNT16 : Lzcnt<0xF5, "lzcnt", null_frag, Xi16, WriteLZCNT, WriteLZCNTLd, "_EVEX">, PL, PD;
1183*0fca6ea1SDimitry Andric  defm LZCNT32 : Lzcnt<0xF5, "lzcnt", null_frag, Xi32, WriteLZCNT, WriteLZCNTLd, "_EVEX">, PL;
1184*0fca6ea1SDimitry Andric  defm LZCNT64 : Lzcnt<0xF5, "lzcnt", null_frag, Xi64, WriteLZCNT, WriteLZCNTLd, "_EVEX">, PL;
1185*0fca6ea1SDimitry Andric}
1186*0fca6ea1SDimitry Andric
1187*0fca6ea1SDimitry Andricdefm LZCNT16 : Lzcnt<0xF5, "lzcnt", null_frag, Xi16, WriteLZCNT, WriteLZCNTLd, "_NF">, NF, PD;
1188*0fca6ea1SDimitry Andricdefm LZCNT32 : Lzcnt<0xF5, "lzcnt", null_frag, Xi32, WriteLZCNT, WriteLZCNTLd, "_NF">, NF;
1189*0fca6ea1SDimitry Andricdefm LZCNT64 : Lzcnt<0xF5, "lzcnt", null_frag, Xi64, WriteLZCNT, WriteLZCNTLd, "_NF">, NF;
1190*0fca6ea1SDimitry Andric
119106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
119206c3fb27SDimitry Andric// BMI Instructions
119306c3fb27SDimitry Andric//
119406c3fb27SDimitry Andriclet Predicates = [HasBMI], Defs = [EFLAGS] in {
1195*0fca6ea1SDimitry Andric  defm TZCNT16 : Lzcnt<0xBC, "tzcnt", cttz, Xi16, WriteTZCNT, WriteTZCNTLd>, OpSize16, XS;
1196*0fca6ea1SDimitry Andric  defm TZCNT32 : Lzcnt<0xBC, "tzcnt", cttz, Xi32, WriteTZCNT, WriteTZCNTLd>, OpSize32, XS;
1197*0fca6ea1SDimitry Andric  defm TZCNT64 : Lzcnt<0xBC, "tzcnt", cttz, Xi64, WriteTZCNT, WriteTZCNTLd>, XS;
119806c3fb27SDimitry Andric
1199*0fca6ea1SDimitry Andric  defm TZCNT16 : Lzcnt<0xF4, "tzcnt", null_frag, Xi16, WriteTZCNT, WriteTZCNTLd, "_EVEX">, PL, PD;
1200*0fca6ea1SDimitry Andric  defm TZCNT32 : Lzcnt<0xF4, "tzcnt", null_frag, Xi32, WriteTZCNT, WriteTZCNTLd, "_EVEX">, PL;
1201*0fca6ea1SDimitry Andric  defm TZCNT64 : Lzcnt<0xF4, "tzcnt", null_frag, Xi64, WriteTZCNT, WriteTZCNTLd, "_EVEX">, PL;
120206c3fb27SDimitry Andric}
120306c3fb27SDimitry Andric
1204*0fca6ea1SDimitry Andricdefm TZCNT16 : Lzcnt<0xF4, "tzcnt", null_frag, Xi16, WriteTZCNT, WriteTZCNTLd, "_NF">, NF, PD;
1205*0fca6ea1SDimitry Andricdefm TZCNT32 : Lzcnt<0xF4, "tzcnt", null_frag, Xi32, WriteTZCNT, WriteTZCNTLd, "_NF">, NF;
1206*0fca6ea1SDimitry Andricdefm TZCNT64 : Lzcnt<0xF4, "tzcnt", null_frag, Xi64, WriteTZCNT, WriteTZCNTLd, "_NF">, NF;
1207*0fca6ea1SDimitry Andric
12081db9f3b2SDimitry Andricmulticlass Bls<string m, Format RegMRM, Format MemMRM, X86TypeInfo t, string Suffix = ""> {
12091db9f3b2SDimitry Andric  let SchedRW = [WriteBLS] in {
12101db9f3b2SDimitry Andric    def rr#Suffix : UnaryOpR<0xF3, RegMRM, m, unaryop_ndd_args, t,
12111db9f3b2SDimitry Andric                             (outs t.RegClass:$dst), []>, T8, VVVV;
121206c3fb27SDimitry Andric  }
121306c3fb27SDimitry Andric
12141db9f3b2SDimitry Andric  let SchedRW = [WriteBLS.Folded] in
12151db9f3b2SDimitry Andric    def rm#Suffix : UnaryOpM<0xF3, MemMRM, m, unaryop_ndd_args, t,
12161db9f3b2SDimitry Andric                             (outs t.RegClass:$dst), []>, T8, VVVV;
121706c3fb27SDimitry Andric}
121806c3fb27SDimitry Andric
1219*0fca6ea1SDimitry Andriclet Defs = [EFLAGS] in {
12201db9f3b2SDimitry Andric  defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32>, VEX;
12211db9f3b2SDimitry Andric  defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64>, VEX;
12221db9f3b2SDimitry Andric  defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32>, VEX;
12231db9f3b2SDimitry Andric  defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64>, VEX;
12241db9f3b2SDimitry Andric  defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32>, VEX;
12251db9f3b2SDimitry Andric  defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64>, VEX;
12261db9f3b2SDimitry Andric}
12271db9f3b2SDimitry Andric
1228*0fca6ea1SDimitry Andriclet Predicates = [In64BitMode], Defs = [EFLAGS] in {
12291db9f3b2SDimitry Andric  defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32, "_EVEX">, EVEX;
12301db9f3b2SDimitry Andric  defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64, "_EVEX">, EVEX;
12311db9f3b2SDimitry Andric  defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32, "_EVEX">, EVEX;
12321db9f3b2SDimitry Andric  defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64, "_EVEX">, EVEX;
12331db9f3b2SDimitry Andric  defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32, "_EVEX">, EVEX;
12341db9f3b2SDimitry Andric  defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64, "_EVEX">, EVEX;
12355f757f3fSDimitry Andric}
123606c3fb27SDimitry Andric
1237*0fca6ea1SDimitry Andriclet Predicates = [In64BitMode] in {
1238*0fca6ea1SDimitry Andric  defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32, "_NF">, EVEX, EVEX_NF;
1239*0fca6ea1SDimitry Andric  defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64, "_NF">, EVEX, EVEX_NF;
1240*0fca6ea1SDimitry Andric  defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32, "_NF">, EVEX, EVEX_NF;
1241*0fca6ea1SDimitry Andric  defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64, "_NF">, EVEX, EVEX_NF;
1242*0fca6ea1SDimitry Andric  defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32, "_NF">, EVEX, EVEX_NF;
1243*0fca6ea1SDimitry Andric  defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64, "_NF">, EVEX, EVEX_NF;
1244*0fca6ea1SDimitry Andric}
1245*0fca6ea1SDimitry Andric
12467a6dacacSDimitry Andricmulticlass Bls_Pats<string suffix> {
124706c3fb27SDimitry Andric  // FIXME(1): patterns for the load versions are not implemented
124806c3fb27SDimitry Andric  // FIXME(2): By only matching `add_su` and `ineg_su` we may emit
124906c3fb27SDimitry Andric  // extra `mov` instructions if `src` has future uses. It may be better
125006c3fb27SDimitry Andric  // to always match if `src` has more users.
125106c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (add_su GR32:$src, -1)),
12527a6dacacSDimitry Andric            (!cast<Instruction>(BLSR32rr#suffix) GR32:$src)>;
125306c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (add_su GR64:$src, -1)),
12547a6dacacSDimitry Andric            (!cast<Instruction>(BLSR64rr#suffix) GR64:$src)>;
125506c3fb27SDimitry Andric
125606c3fb27SDimitry Andric  def : Pat<(xor GR32:$src, (add_su GR32:$src, -1)),
12577a6dacacSDimitry Andric            (!cast<Instruction>(BLSMSK32rr#suffix) GR32:$src)>;
125806c3fb27SDimitry Andric  def : Pat<(xor GR64:$src, (add_su GR64:$src, -1)),
12597a6dacacSDimitry Andric            (!cast<Instruction>(BLSMSK64rr#suffix) GR64:$src)>;
126006c3fb27SDimitry Andric
126106c3fb27SDimitry Andric  def : Pat<(and GR32:$src, (ineg_su GR32:$src)),
12627a6dacacSDimitry Andric            (!cast<Instruction>(BLSI32rr#suffix) GR32:$src)>;
126306c3fb27SDimitry Andric  def : Pat<(and GR64:$src, (ineg_su GR64:$src)),
12647a6dacacSDimitry Andric            (!cast<Instruction>(BLSI64rr#suffix) GR64:$src)>;
126506c3fb27SDimitry Andric
126606c3fb27SDimitry Andric  // Versions to match flag producing ops.
126706c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
12687a6dacacSDimitry Andric            (!cast<Instruction>(BLSR32rr#suffix) GR32:$src)>;
126906c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
12707a6dacacSDimitry Andric            (!cast<Instruction>(BLSR64rr#suffix) GR64:$src)>;
127106c3fb27SDimitry Andric
127206c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR32:$src, (add_su GR32:$src, -1)),
12737a6dacacSDimitry Andric            (!cast<Instruction>(BLSMSK32rr#suffix) GR32:$src)>;
127406c3fb27SDimitry Andric  def : Pat<(xor_flag_nocf GR64:$src, (add_su GR64:$src, -1)),
12757a6dacacSDimitry Andric            (!cast<Instruction>(BLSMSK64rr#suffix) GR64:$src)>;
127606c3fb27SDimitry Andric
127706c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR32:$src, (ineg_su GR32:$src)),
12787a6dacacSDimitry Andric            (!cast<Instruction>(BLSI32rr#suffix) GR32:$src)>;
127906c3fb27SDimitry Andric  def : Pat<(and_flag_nocf GR64:$src, (ineg_su GR64:$src)),
12807a6dacacSDimitry Andric            (!cast<Instruction>(BLSI64rr#suffix) GR64:$src)>;
128106c3fb27SDimitry Andric}
128206c3fb27SDimitry Andric
12837a6dacacSDimitry Andriclet Predicates = [HasBMI, NoEGPR] in
12847a6dacacSDimitry Andric  defm : Bls_Pats<"">;
12857a6dacacSDimitry Andric
12867a6dacacSDimitry Andriclet Predicates = [HasBMI, HasEGPR] in
12877a6dacacSDimitry Andric  defm : Bls_Pats<"_EVEX">;
12887a6dacacSDimitry Andric
12891db9f3b2SDimitry Andricmulticlass Bmi4VOp3<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node,
12901db9f3b2SDimitry Andric                    X86FoldableSchedWrite sched, string Suffix = ""> {
12911db9f3b2SDimitry Andric  let SchedRW = [sched], Form = MRMSrcReg4VOp3 in
12921db9f3b2SDimitry Andric    def rr#Suffix : BinOpRR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
12931db9f3b2SDimitry Andric                            [(set t.RegClass:$dst, EFLAGS,
12941db9f3b2SDimitry Andric                             (node t.RegClass:$src1, t.RegClass:$src2))]>, T8;
12951db9f3b2SDimitry Andric  let SchedRW = [sched.Folded,
12961db9f3b2SDimitry Andric                 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
12971db9f3b2SDimitry Andric                 sched.ReadAfterFold], Form =  MRMSrcMem4VOp3 in
12981db9f3b2SDimitry Andric    def rm#Suffix : BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst),
12991db9f3b2SDimitry Andric                            [(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1),
13001db9f3b2SDimitry Andric                             t.RegClass:$src2))]>, T8;
130106c3fb27SDimitry Andric}
130206c3fb27SDimitry Andric
13035f757f3fSDimitry Andriclet Predicates = [HasBMI, NoEGPR], Defs = [EFLAGS] in {
13041db9f3b2SDimitry Andric  defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, X86bextr, WriteBEXTR>, VEX;
13051db9f3b2SDimitry Andric  defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, X86bextr, WriteBEXTR>, VEX;
130606c3fb27SDimitry Andric}
13075f757f3fSDimitry Andriclet Predicates = [HasBMI2, NoEGPR], Defs = [EFLAGS] in {
13081db9f3b2SDimitry Andric  defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, X86bzhi, WriteBZHI>, VEX;
13091db9f3b2SDimitry Andric  defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, X86bzhi, WriteBZHI>, VEX;
131006c3fb27SDimitry Andric}
13111db9f3b2SDimitry Andriclet Predicates = [HasBMI, HasEGPR, In64BitMode], Defs = [EFLAGS] in {
13121db9f3b2SDimitry Andric  defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, X86bextr, WriteBEXTR, "_EVEX">, EVEX;
13131db9f3b2SDimitry Andric  defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, X86bextr, WriteBEXTR, "_EVEX">, EVEX;
13145f757f3fSDimitry Andric}
13151db9f3b2SDimitry Andriclet Predicates = [HasBMI2, HasEGPR, In64BitMode], Defs = [EFLAGS] in {
13161db9f3b2SDimitry Andric  defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, X86bzhi, WriteBZHI, "_EVEX">, EVEX;
13171db9f3b2SDimitry Andric  defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, X86bzhi, WriteBZHI, "_EVEX">, EVEX;
13185f757f3fSDimitry Andric}
131906c3fb27SDimitry Andric
1320*0fca6ea1SDimitry Andriclet Predicates = [In64BitMode] in {
1321*0fca6ea1SDimitry Andric  defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, null_frag, WriteBEXTR, "_NF">, EVEX, EVEX_NF;
1322*0fca6ea1SDimitry Andric  defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, null_frag, WriteBEXTR, "_NF">, EVEX, EVEX_NF;
1323*0fca6ea1SDimitry Andric  defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, null_frag, WriteBZHI, "_NF">, EVEX, EVEX_NF;
1324*0fca6ea1SDimitry Andric  defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, null_frag, WriteBZHI, "_NF">, EVEX, EVEX_NF;
1325*0fca6ea1SDimitry Andric}
1326*0fca6ea1SDimitry Andric
132706c3fb27SDimitry Andricdef CountTrailingOnes : SDNodeXForm<imm, [{
132806c3fb27SDimitry Andric  // Count the trailing ones in the immediate.
132906c3fb27SDimitry Andric  return getI8Imm(llvm::countr_one(N->getZExtValue()), SDLoc(N));
133006c3fb27SDimitry Andric}]>;
133106c3fb27SDimitry Andric
133206c3fb27SDimitry Andricdef BEXTRMaskXForm : SDNodeXForm<imm, [{
133306c3fb27SDimitry Andric  unsigned Length = llvm::countr_one(N->getZExtValue());
133406c3fb27SDimitry Andric  return getI32Imm(Length << 8, SDLoc(N));
133506c3fb27SDimitry Andric}]>;
133606c3fb27SDimitry Andric
133706c3fb27SDimitry Andricdef AndMask64 : ImmLeaf<i64, [{
133806c3fb27SDimitry Andric  return isMask_64(Imm) && !isUInt<32>(Imm);
133906c3fb27SDimitry Andric}]>;
134006c3fb27SDimitry Andric
134106c3fb27SDimitry Andric// Use BEXTR for 64-bit 'and' with large immediate 'mask'.
13427a6dacacSDimitry Andriclet Predicates = [HasBMI, NoBMI2, NoTBM, NoEGPR] in {
134306c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
134406c3fb27SDimitry Andric            (BEXTR64rr GR64:$src,
134506c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
134606c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
134706c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
134806c3fb27SDimitry Andric            (BEXTR64rm addr:$src,
134906c3fb27SDimitry Andric              (SUBREG_TO_REG (i64 0),
135006c3fb27SDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
135106c3fb27SDimitry Andric}
135206c3fb27SDimitry Andric
13537a6dacacSDimitry Andriclet Predicates = [HasBMI, NoBMI2, NoTBM, HasEGPR] in {
13547a6dacacSDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
13557a6dacacSDimitry Andric            (BEXTR64rr_EVEX GR64:$src,
13567a6dacacSDimitry Andric              (SUBREG_TO_REG (i64 0),
13577a6dacacSDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
13587a6dacacSDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
13597a6dacacSDimitry Andric            (BEXTR64rm_EVEX addr:$src,
13607a6dacacSDimitry Andric              (SUBREG_TO_REG (i64 0),
13617a6dacacSDimitry Andric                             (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>;
13627a6dacacSDimitry Andric}
13637a6dacacSDimitry Andric
136406c3fb27SDimitry Andric// Use BZHI for 64-bit 'and' with large immediate 'mask'.
13657a6dacacSDimitry Andriclet Predicates = [HasBMI2, NoTBM, NoEGPR] in {
136606c3fb27SDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
136706c3fb27SDimitry Andric            (BZHI64rr GR64:$src,
136806c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
136906c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
137006c3fb27SDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
137106c3fb27SDimitry Andric            (BZHI64rm addr:$src,
137206c3fb27SDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
137306c3fb27SDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
137406c3fb27SDimitry Andric}
137506c3fb27SDimitry Andric
13767a6dacacSDimitry Andriclet Predicates = [HasBMI2, NoTBM, HasEGPR] in {
13777a6dacacSDimitry Andric  def : Pat<(and GR64:$src, AndMask64:$mask),
13787a6dacacSDimitry Andric            (BZHI64rr_EVEX GR64:$src,
13797a6dacacSDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
13807a6dacacSDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
13817a6dacacSDimitry Andric  def : Pat<(and (loadi64 addr:$src), AndMask64:$mask),
13827a6dacacSDimitry Andric            (BZHI64rm_EVEX addr:$src,
13837a6dacacSDimitry Andric              (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
13847a6dacacSDimitry Andric                             (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>;
13857a6dacacSDimitry Andric}
13867a6dacacSDimitry Andric
13877a6dacacSDimitry Andricmulticlass PdepPext<string m, X86TypeInfo t, SDPatternOperator node,
13887a6dacacSDimitry Andric                    string suffix = ""> {
13897a6dacacSDimitry Andric  def rr#suffix : ITy<0xF5, MRMSrcReg, t, (outs t.RegClass:$dst),
13907a6dacacSDimitry Andric                      (ins t.RegClass:$src1, t.RegClass:$src2), m, binop_ndd_args,
13917a6dacacSDimitry Andric                      [(set t.RegClass:$dst, (node t.RegClass:$src1, t.RegClass:$src2))]>,
13927a6dacacSDimitry Andric                  T8, VVVV, Sched<[WriteALU]>;
13937a6dacacSDimitry Andric  def rm#suffix : ITy<0xF5, MRMSrcMem, t, (outs t.RegClass:$dst),
13947a6dacacSDimitry Andric                      (ins t.RegClass:$src1, t.MemOperand:$src2), m, binop_ndd_args,
13957a6dacacSDimitry Andric                      [(set t.RegClass:$dst, (node t.RegClass:$src1, (t.LoadNode addr:$src2)))]>,
13967a6dacacSDimitry Andric                  T8, VVVV, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>;
139706c3fb27SDimitry Andric}
139806c3fb27SDimitry Andric
13995f757f3fSDimitry Andriclet Predicates = [HasBMI2, NoEGPR] in {
14007a6dacacSDimitry Andric  defm PDEP32 : PdepPext<"pdep", Xi32, X86pdep>, XD, VEX;
14017a6dacacSDimitry Andric  defm PDEP64 : PdepPext<"pdep", Xi64, X86pdep>, XD, REX_W, VEX;
14027a6dacacSDimitry Andric  defm PEXT32 : PdepPext<"pext", Xi32, X86pext>, XS, VEX;
14037a6dacacSDimitry Andric  defm PEXT64 : PdepPext<"pext", Xi64, X86pext>, XS, REX_W, VEX;
140406c3fb27SDimitry Andric}
140506c3fb27SDimitry Andric
14065f757f3fSDimitry Andriclet Predicates = [HasBMI2, HasEGPR] in {
14077a6dacacSDimitry Andric  defm PDEP32 : PdepPext<"pdep", Xi32, X86pdep, "_EVEX">, XD, EVEX;
14087a6dacacSDimitry Andric  defm PDEP64 : PdepPext<"pdep", Xi64, X86pdep, "_EVEX">, XD, REX_W, EVEX;
14097a6dacacSDimitry Andric  defm PEXT32 : PdepPext<"pext", Xi32, X86pext, "_EVEX">, XS, EVEX;
14107a6dacacSDimitry Andric  defm PEXT64 : PdepPext<"pext", Xi64, X86pext, "_EVEX">, XS, REX_W, EVEX;
14115f757f3fSDimitry Andric}
14125f757f3fSDimitry Andric
141306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
141406c3fb27SDimitry Andric// Lightweight Profiling Instructions
141506c3fb27SDimitry Andric
141606c3fb27SDimitry Andriclet Predicates = [HasLWP], SchedRW = [WriteSystem] in {
141706c3fb27SDimitry Andric
141806c3fb27SDimitry Andricdef LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src",
141906c3fb27SDimitry Andric               [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9;
142006c3fb27SDimitry Andricdef SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst",
142106c3fb27SDimitry Andric               [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9;
142206c3fb27SDimitry Andric
142306c3fb27SDimitry Andricdef LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src",
142406c3fb27SDimitry Andric                 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, REX_W;
142506c3fb27SDimitry Andricdef SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst",
142606c3fb27SDimitry Andric                 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, REX_W;
142706c3fb27SDimitry Andric
142806c3fb27SDimitry Andricmulticlass lwpins_intr<RegisterClass RC> {
142906c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
143006c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
143106c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>,
1432cb14a3feSDimitry Andric                 XOP, VVVV, XOPA;
143306c3fb27SDimitry Andric  let mayLoad = 1 in
143406c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
143506c3fb27SDimitry Andric                 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
143606c3fb27SDimitry Andric                 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>,
1437cb14a3feSDimitry Andric                 XOP, VVVV, XOPA;
143806c3fb27SDimitry Andric}
143906c3fb27SDimitry Andric
144006c3fb27SDimitry Andriclet Defs = [EFLAGS] in {
144106c3fb27SDimitry Andric  defm LWPINS32 : lwpins_intr<GR32>;
144206c3fb27SDimitry Andric  defm LWPINS64 : lwpins_intr<GR64>, REX_W;
144306c3fb27SDimitry Andric} // EFLAGS
144406c3fb27SDimitry Andric
144506c3fb27SDimitry Andricmulticlass lwpval_intr<RegisterClass RC, Intrinsic Int> {
144606c3fb27SDimitry Andric  def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl),
144706c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
1448cb14a3feSDimitry Andric                 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP, VVVV, XOPA;
144906c3fb27SDimitry Andric  let mayLoad = 1 in
145006c3fb27SDimitry Andric  def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl),
145106c3fb27SDimitry Andric                 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}",
145206c3fb27SDimitry Andric                 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>,
1453cb14a3feSDimitry Andric                 XOP, VVVV, XOPA;
145406c3fb27SDimitry Andric}
145506c3fb27SDimitry Andric
145606c3fb27SDimitry Andricdefm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>;
145706c3fb27SDimitry Andricdefm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, REX_W;
145806c3fb27SDimitry Andric
145906c3fb27SDimitry Andric} // HasLWP, SchedRW
146006c3fb27SDimitry Andric
146106c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
146206c3fb27SDimitry Andric// MONITORX/MWAITX Instructions
146306c3fb27SDimitry Andric//
146406c3fb27SDimitry Andriclet SchedRW = [ WriteSystem ] in {
146506c3fb27SDimitry Andric  let Uses = [ EAX, ECX, EDX ] in
146606c3fb27SDimitry Andric  def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
146706c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, Not64BitMode ]>;
146806c3fb27SDimitry Andric  let Uses = [ RAX, ECX, EDX ] in
146906c3fb27SDimitry Andric  def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>,
147006c3fb27SDimitry Andric                      TB, Requires<[ HasMWAITX, In64BitMode ]>;
147106c3fb27SDimitry Andric
147206c3fb27SDimitry Andric  let Uses = [ ECX, EAX, EBX ] in {
147306c3fb27SDimitry Andric    def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx",
147406c3fb27SDimitry Andric                    []>, TB, Requires<[ HasMWAITX ]>;
147506c3fb27SDimitry Andric  }
147606c3fb27SDimitry Andric} // SchedRW
147706c3fb27SDimitry Andric
147806c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
147906c3fb27SDimitry Andric// WAITPKG Instructions
148006c3fb27SDimitry Andric//
148106c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
148206c3fb27SDimitry Andric  def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src),
148306c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>,
1484cb14a3feSDimitry Andric                     TB, XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>;
148506c3fb27SDimitry Andric  def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src),
148606c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>,
1487cb14a3feSDimitry Andric                     TB, XS, AdSize32, Requires<[HasWAITPKG]>;
148806c3fb27SDimitry Andric  def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src),
148906c3fb27SDimitry Andric                     "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>,
1490cb14a3feSDimitry Andric                     TB, XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>;
149106c3fb27SDimitry Andric  let Uses = [EAX, EDX], Defs = [EFLAGS] in {
149206c3fb27SDimitry Andric    def UMWAIT : I<0xAE, MRM6r,
149306c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "umwait\t$src",
149406c3fb27SDimitry Andric                     [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>,
1495cb14a3feSDimitry Andric                     TB, XD, Requires<[HasWAITPKG]>;
149606c3fb27SDimitry Andric    def TPAUSE : I<0xAE, MRM6r,
149706c3fb27SDimitry Andric                     (outs), (ins GR32orGR64:$src), "tpause\t$src",
149806c3fb27SDimitry Andric                     [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>,
1499cb14a3feSDimitry Andric                     TB, PD, Requires<[HasWAITPKG]>;
150006c3fb27SDimitry Andric  }
150106c3fb27SDimitry Andric} // SchedRW
150206c3fb27SDimitry Andric
150306c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
150406c3fb27SDimitry Andric// MOVDIRI - Move doubleword/quadword as direct store
150506c3fb27SDimitry Andric//
150606c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
150706c3fb27SDimitry Andricdef MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
150806c3fb27SDimitry Andric                  "movdiri\t{$src, $dst|$dst, $src}",
150906c3fb27SDimitry Andric                  [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
1510cb14a3feSDimitry Andric                 T8, Requires<[HasMOVDIRI, NoEGPR]>;
151106c3fb27SDimitry Andricdef MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
151206c3fb27SDimitry Andric                   "movdiri\t{$src, $dst|$dst, $src}",
151306c3fb27SDimitry Andric                   [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
1514cb14a3feSDimitry Andric                  T8, Requires<[In64BitMode, HasMOVDIRI, NoEGPR]>;
15155f757f3fSDimitry Andricdef MOVDIRI32_EVEX : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src),
15165f757f3fSDimitry Andric                       "movdiri\t{$src, $dst|$dst, $src}",
15175f757f3fSDimitry Andric                       [(int_x86_directstore32 addr:$dst, GR32:$src)]>,
1518cb14a3feSDimitry Andric                     EVEX, NoCD8, T_MAP4, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>;
15195f757f3fSDimitry Andricdef MOVDIRI64_EVEX : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src),
15205f757f3fSDimitry Andric                        "movdiri\t{$src, $dst|$dst, $src}",
15215f757f3fSDimitry Andric                        [(int_x86_directstore64 addr:$dst, GR64:$src)]>,
1522cb14a3feSDimitry Andric                     EVEX, NoCD8, T_MAP4, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>;
152306c3fb27SDimitry Andric} // SchedRW
152406c3fb27SDimitry Andric
152506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
152606c3fb27SDimitry Andric// MOVDIR64B - Move 64 bytes as direct store
152706c3fb27SDimitry Andric//
152806c3fb27SDimitry Andriclet SchedRW = [WriteStore] in {
152906c3fb27SDimitry Andricdef MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
153006c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}", []>,
1531cb14a3feSDimitry Andric                   T8, PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>;
153206c3fb27SDimitry Andricdef MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
153306c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
153406c3fb27SDimitry Andric                    [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
1535cb14a3feSDimitry Andric                   T8, PD, AdSize32, Requires<[HasMOVDIR64B, NoEGPR]>;
153606c3fb27SDimitry Andricdef MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
153706c3fb27SDimitry Andric                    "movdir64b\t{$src, $dst|$dst, $src}",
153806c3fb27SDimitry Andric                    [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
1539cb14a3feSDimitry Andric                   T8, PD, AdSize64, Requires<[HasMOVDIR64B, NoEGPR, In64BitMode]>;
15405f757f3fSDimitry Andricdef MOVDIR64B32_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
15415f757f3fSDimitry Andric                         "movdir64b\t{$src, $dst|$dst, $src}",
15425f757f3fSDimitry Andric                         [(int_x86_movdir64b GR32:$dst, addr:$src)]>,
1543cb14a3feSDimitry Andric                       EVEX, NoCD8, T_MAP4, PD, AdSize32, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>;
15445f757f3fSDimitry Andricdef MOVDIR64B64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
15455f757f3fSDimitry Andric                         "movdir64b\t{$src, $dst|$dst, $src}",
15465f757f3fSDimitry Andric                         [(int_x86_movdir64b GR64:$dst, addr:$src)]>,
1547cb14a3feSDimitry Andric                       EVEX, NoCD8, T_MAP4, PD, AdSize64, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>;
154806c3fb27SDimitry Andric} // SchedRW
154906c3fb27SDimitry Andric
155006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
155106c3fb27SDimitry Andric// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity
155206c3fb27SDimitry Andric//
1553*0fca6ea1SDimitry Andricmulticlass Enqcmds<string suffix> {
1554*0fca6ea1SDimitry Andric  def ENQCMD32#suffix : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
1555*0fca6ea1SDimitry Andric                          "enqcmd\t{$src, $dst|$dst, $src}",
1556*0fca6ea1SDimitry Andric                          [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>,
1557*0fca6ea1SDimitry Andric                        NoCD8, XD, AdSize32;
1558*0fca6ea1SDimitry Andric  def ENQCMD64#suffix : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
1559*0fca6ea1SDimitry Andric                          "enqcmd\t{$src, $dst|$dst, $src}",
1560*0fca6ea1SDimitry Andric                          [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>,
1561*0fca6ea1SDimitry Andric                        NoCD8, XD, AdSize64;
1562*0fca6ea1SDimitry Andric
1563*0fca6ea1SDimitry Andric  def ENQCMDS32#suffix : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src),
1564*0fca6ea1SDimitry Andric                           "enqcmds\t{$src, $dst|$dst, $src}",
1565*0fca6ea1SDimitry Andric                           [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>,
1566*0fca6ea1SDimitry Andric                         NoCD8, XS, AdSize32;
1567*0fca6ea1SDimitry Andric  def ENQCMDS64#suffix : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src),
1568*0fca6ea1SDimitry Andric                          "enqcmds\t{$src, $dst|$dst, $src}",
1569*0fca6ea1SDimitry Andric                          [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>,
1570*0fca6ea1SDimitry Andric                         NoCD8, XS, AdSize64;
1571*0fca6ea1SDimitry Andric}
1572*0fca6ea1SDimitry Andric
157306c3fb27SDimitry Andriclet SchedRW = [WriteStore], Defs = [EFLAGS] in {
1574297eecfbSDimitry Andric  def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
157506c3fb27SDimitry Andric                   "enqcmd\t{$src, $dst|$dst, $src}",
157606c3fb27SDimitry Andric                   [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>,
1577cb14a3feSDimitry Andric                 T8, XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
1578297eecfbSDimitry Andric  def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src),
157906c3fb27SDimitry Andric                    "enqcmds\t{$src, $dst|$dst, $src}",
158006c3fb27SDimitry Andric                    [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>,
1581cb14a3feSDimitry Andric                  T8, XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>;
1582*0fca6ea1SDimitry Andric
1583*0fca6ea1SDimitry Andric  defm "" : Enqcmds<"">, T8, Requires<[HasENQCMD, NoEGPR]>;
1584*0fca6ea1SDimitry Andric  defm "" : Enqcmds<"_EVEX">, EVEX, T_MAP4, Requires<[HasENQCMD, HasEGPR, In64BitMode]>;
1585*0fca6ea1SDimitry Andric
158606c3fb27SDimitry Andric}
158706c3fb27SDimitry Andric
158806c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
158906c3fb27SDimitry Andric// CLZERO Instruction
159006c3fb27SDimitry Andric//
159106c3fb27SDimitry Andriclet SchedRW = [WriteLoad] in {
159206c3fb27SDimitry Andric  let Uses = [EAX] in
159306c3fb27SDimitry Andric  def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
159406c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, Not64BitMode]>;
159506c3fb27SDimitry Andric  let Uses = [RAX] in
159606c3fb27SDimitry Andric  def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>,
159706c3fb27SDimitry Andric                  TB, Requires<[HasCLZERO, In64BitMode]>;
159806c3fb27SDimitry Andric} // SchedRW
159906c3fb27SDimitry Andric
160006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
160106c3fb27SDimitry Andric// INVLPGB Instruction
160206c3fb27SDimitry Andric// OPCODE 0F 01 FE
160306c3fb27SDimitry Andric//
160406c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
160506c3fb27SDimitry Andric  let Uses = [EAX, EDX] in
160606c3fb27SDimitry Andric  def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins),
160706c3fb27SDimitry Andric                  "invlpgb", []>,
1608cb14a3feSDimitry Andric                  TB, Requires<[Not64BitMode]>;
160906c3fb27SDimitry Andric  let Uses = [RAX, EDX] in
161006c3fb27SDimitry Andric  def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins),
161106c3fb27SDimitry Andric                  "invlpgb", []>,
1612cb14a3feSDimitry Andric                  TB, Requires<[In64BitMode]>;
161306c3fb27SDimitry Andric} // SchedRW
161406c3fb27SDimitry Andric
161506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
161606c3fb27SDimitry Andric// TLBSYNC Instruction
161706c3fb27SDimitry Andric// OPCODE 0F 01 FF
161806c3fb27SDimitry Andric//
161906c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in {
162006c3fb27SDimitry Andric  def TLBSYNC   : I<0x01, MRM_FF, (outs), (ins),
162106c3fb27SDimitry Andric                  "tlbsync", []>,
1622cb14a3feSDimitry Andric                  TB, Requires<[]>;
162306c3fb27SDimitry Andric} // SchedRW
162406c3fb27SDimitry Andric
162506c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
162606c3fb27SDimitry Andric// HRESET Instruction
162706c3fb27SDimitry Andric//
162806c3fb27SDimitry Andriclet Uses = [EAX], SchedRW = [WriteSystem] in
162906c3fb27SDimitry Andric  def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>,
1630cb14a3feSDimitry Andric                   Requires<[HasHRESET]>, TA, XS;
163106c3fb27SDimitry Andric
163206c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
163306c3fb27SDimitry Andric// SERIALIZE Instruction
163406c3fb27SDimitry Andric//
163506c3fb27SDimitry Andriclet SchedRW = [WriteSystem] in
163606c3fb27SDimitry Andric  def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize",
1637cb14a3feSDimitry Andric                    [(int_x86_serialize)]>, TB,
163806c3fb27SDimitry Andric                    Requires<[HasSERIALIZE]>;
163906c3fb27SDimitry Andric
164006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
164106c3fb27SDimitry Andric// TSXLDTRK - TSX Suspend Load Address Tracking
164206c3fb27SDimitry Andric//
164306c3fb27SDimitry Andriclet Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in {
164406c3fb27SDimitry Andric  def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk",
1645cb14a3feSDimitry Andric                    [(int_x86_xsusldtrk)]>, TB, XD;
164606c3fb27SDimitry Andric  def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk",
1647cb14a3feSDimitry Andric                    [(int_x86_xresldtrk)]>, TB, XD;
164806c3fb27SDimitry Andric}
164906c3fb27SDimitry Andric
165006c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
165106c3fb27SDimitry Andric// UINTR Instructions
165206c3fb27SDimitry Andric//
165306c3fb27SDimitry Andriclet Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in {
165406c3fb27SDimitry Andric  def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret",
1655cb14a3feSDimitry Andric               []>, TB, XS;
165606c3fb27SDimitry Andric  def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui",
1657cb14a3feSDimitry Andric               [(int_x86_clui)]>, TB, XS;
165806c3fb27SDimitry Andric  def STUI : I<0x01, MRM_EF, (outs), (ins), "stui",
1659cb14a3feSDimitry Andric               [(int_x86_stui)]>, TB, XS;
166006c3fb27SDimitry Andric
166106c3fb27SDimitry Andric  def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg",
1662cb14a3feSDimitry Andric                   [(int_x86_senduipi GR64:$arg)]>, TB, XS;
166306c3fb27SDimitry Andric
166406c3fb27SDimitry Andric  let Defs = [EFLAGS] in
166506c3fb27SDimitry Andric    def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui",
1666cb14a3feSDimitry Andric                   [(set EFLAGS, (X86testui))]>, TB, XS;
166706c3fb27SDimitry Andric}
166806c3fb27SDimitry Andric
166906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
167006c3fb27SDimitry Andric// PREFETCHIT0 and PREFETCHIT1 Instructions
167106c3fb27SDimitry Andric// prefetch ADDR, RW, Locality, Data
167206c3fb27SDimitry Andriclet Predicates = [HasPREFETCHI, In64BitMode], SchedRW = [WriteLoad] in {
167306c3fb27SDimitry Andric  def PREFETCHIT0 : I<0x18, MRM7m, (outs), (ins i8mem:$src),
167406c3fb27SDimitry Andric    "prefetchit0\t$src", [(prefetch addr:$src, (i32 0), (i32 3), (i32 0))]>, TB;
167506c3fb27SDimitry Andric  def PREFETCHIT1 : I<0x18, MRM6m, (outs), (ins i8mem:$src),
167606c3fb27SDimitry Andric    "prefetchit1\t$src", [(prefetch addr:$src, (i32 0), (i32 2), (i32 0))]>, TB;
167706c3fb27SDimitry Andric}
167806c3fb27SDimitry Andric
167906c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
168006c3fb27SDimitry Andric// CMPCCXADD Instructions
168106c3fb27SDimitry Andric//
168206c3fb27SDimitry Andriclet isCodeGenOnly = 1, ForceDisassemble = 1, mayLoad = 1, mayStore = 1,
1683cb14a3feSDimitry Andric    Defs = [EFLAGS], Constraints = "$dstsrc1 = $dst" in {
1684cb14a3feSDimitry Andriclet Predicates = [HasCMPCCXADD, NoEGPR, In64BitMode] in {
168506c3fb27SDimitry Andricdef CMPCCXADDmr32 : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst),
168606c3fb27SDimitry Andric          (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond),
168706c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
168806c3fb27SDimitry Andric          [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2,
168906c3fb27SDimitry Andric            GR32:$dstsrc1, GR32:$src3, timm:$cond))]>,
1690cb14a3feSDimitry Andric          VEX, VVVV, T8, PD, Sched<[WriteXCHG]>;
169106c3fb27SDimitry Andric
169206c3fb27SDimitry Andricdef CMPCCXADDmr64 : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst),
169306c3fb27SDimitry Andric          (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond),
169406c3fb27SDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
169506c3fb27SDimitry Andric          [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2,
169606c3fb27SDimitry Andric            GR64:$dstsrc1, GR64:$src3, timm:$cond))]>,
1697cb14a3feSDimitry Andric          VEX, VVVV, REX_W, T8, PD, Sched<[WriteXCHG]>;
1698cb14a3feSDimitry Andric}
1699cb14a3feSDimitry Andric
1700cb14a3feSDimitry Andriclet Predicates = [HasCMPCCXADD, HasEGPR, In64BitMode] in {
1701cb14a3feSDimitry Andricdef CMPCCXADDmr32_EVEX : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst),
1702cb14a3feSDimitry Andric          (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond),
1703cb14a3feSDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
1704cb14a3feSDimitry Andric          [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2,
1705cb14a3feSDimitry Andric            GR32:$dstsrc1, GR32:$src3, timm:$cond))]>,
1706cb14a3feSDimitry Andric          EVEX, VVVV, NoCD8, T8, PD, Sched<[WriteXCHG]>;
1707cb14a3feSDimitry Andric
1708cb14a3feSDimitry Andricdef CMPCCXADDmr64_EVEX : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst),
1709cb14a3feSDimitry Andric          (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond),
1710cb14a3feSDimitry Andric          "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}",
1711cb14a3feSDimitry Andric          [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2,
1712cb14a3feSDimitry Andric            GR64:$dstsrc1, GR64:$src3, timm:$cond))]>,
1713cb14a3feSDimitry Andric          EVEX, VVVV, NoCD8, REX_W, T8, PD, Sched<[WriteXCHG]>;
1714cb14a3feSDimitry Andric}
171506c3fb27SDimitry Andric}
171606c3fb27SDimitry Andric
171706c3fb27SDimitry Andric//===----------------------------------------------------------------------===//
171806c3fb27SDimitry Andric// Memory Instructions
171906c3fb27SDimitry Andric//
172006c3fb27SDimitry Andric
172106c3fb27SDimitry Andriclet Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in
172206c3fb27SDimitry Andricdef CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src),
1723cb14a3feSDimitry Andric                   "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, TB, PD;
172406c3fb27SDimitry Andric
172506c3fb27SDimitry Andriclet Predicates = [HasCLWB], SchedRW = [WriteLoad] in
172606c3fb27SDimitry Andricdef CLWB       : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src",
1727cb14a3feSDimitry Andric                   [(int_x86_clwb addr:$src)]>, TB, PD;
172806c3fb27SDimitry Andric
172906c3fb27SDimitry Andriclet Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in
173006c3fb27SDimitry Andricdef CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src",
1731cb14a3feSDimitry Andric                   [(int_x86_cldemote addr:$src)]>, TB;
1732