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