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