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