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] 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 # "_8") 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 # "_16") 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 # "_32") 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 # "_64") 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// 1093let Predicates = [HasMOVBE] in { 1094 let SchedRW = [WriteALULd] in { 1095 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1096 "movbe{w}\t{$src, $dst|$dst, $src}", 1097 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>, 1098 OpSize16, T8; 1099 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1100 "movbe{l}\t{$src, $dst|$dst, $src}", 1101 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>, 1102 OpSize32, T8; 1103 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1104 "movbe{q}\t{$src, $dst|$dst, $src}", 1105 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>, 1106 T8; 1107 } 1108 let SchedRW = [WriteStore] in { 1109 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 1110 "movbe{w}\t{$src, $dst|$dst, $src}", 1111 [(store (bswap GR16:$src), addr:$dst)]>, 1112 OpSize16, T8; 1113 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 1114 "movbe{l}\t{$src, $dst|$dst, $src}", 1115 [(store (bswap GR32:$src), addr:$dst)]>, 1116 OpSize32, T8; 1117 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 1118 "movbe{q}\t{$src, $dst|$dst, $src}", 1119 [(store (bswap GR64:$src), addr:$dst)]>, 1120 T8; 1121 } 1122} 1123 1124//===----------------------------------------------------------------------===// 1125// RDRAND Instruction 1126// 1127let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 1128 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins), 1129 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>, 1130 OpSize16, TB; 1131 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins), 1132 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>, 1133 OpSize32, TB; 1134 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins), 1135 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>, 1136 TB; 1137} 1138 1139//===----------------------------------------------------------------------===// 1140// RDSEED Instruction 1141// 1142let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 1143 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst", 1144 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, TB; 1145 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst", 1146 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, TB; 1147 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst", 1148 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, TB; 1149} 1150 1151//===----------------------------------------------------------------------===// 1152// LZCNT Instruction 1153// 1154let Predicates = [HasLZCNT], Defs = [EFLAGS] in { 1155 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1156 "lzcnt{w}\t{$src, $dst|$dst, $src}", 1157 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, 1158 TB, XS, OpSize16, Sched<[WriteLZCNT]>; 1159 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1160 "lzcnt{w}\t{$src, $dst|$dst, $src}", 1161 [(set GR16:$dst, (ctlz (loadi16 addr:$src))), 1162 (implicit EFLAGS)]>, TB, XS, OpSize16, Sched<[WriteLZCNTLd]>; 1163 1164 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1165 "lzcnt{l}\t{$src, $dst|$dst, $src}", 1166 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, 1167 TB, XS, OpSize32, Sched<[WriteLZCNT]>; 1168 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1169 "lzcnt{l}\t{$src, $dst|$dst, $src}", 1170 [(set GR32:$dst, (ctlz (loadi32 addr:$src))), 1171 (implicit EFLAGS)]>, TB, XS, OpSize32, Sched<[WriteLZCNTLd]>; 1172 1173 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1174 "lzcnt{q}\t{$src, $dst|$dst, $src}", 1175 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>, 1176 TB, XS, Sched<[WriteLZCNT]>; 1177 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1178 "lzcnt{q}\t{$src, $dst|$dst, $src}", 1179 [(set GR64:$dst, (ctlz (loadi64 addr:$src))), 1180 (implicit EFLAGS)]>, TB, XS, Sched<[WriteLZCNTLd]>; 1181} 1182 1183//===----------------------------------------------------------------------===// 1184// BMI Instructions 1185// 1186let Predicates = [HasBMI], Defs = [EFLAGS] in { 1187 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1188 "tzcnt{w}\t{$src, $dst|$dst, $src}", 1189 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, 1190 TB, XS, OpSize16, Sched<[WriteTZCNT]>; 1191 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1192 "tzcnt{w}\t{$src, $dst|$dst, $src}", 1193 [(set GR16:$dst, (cttz (loadi16 addr:$src))), 1194 (implicit EFLAGS)]>, TB, XS, OpSize16, Sched<[WriteTZCNTLd]>; 1195 1196 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1197 "tzcnt{l}\t{$src, $dst|$dst, $src}", 1198 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, 1199 TB, XS, OpSize32, Sched<[WriteTZCNT]>; 1200 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1201 "tzcnt{l}\t{$src, $dst|$dst, $src}", 1202 [(set GR32:$dst, (cttz (loadi32 addr:$src))), 1203 (implicit EFLAGS)]>, TB, XS, OpSize32, Sched<[WriteTZCNTLd]>; 1204 1205 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1206 "tzcnt{q}\t{$src, $dst|$dst, $src}", 1207 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>, 1208 TB, XS, Sched<[WriteTZCNT]>; 1209 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1210 "tzcnt{q}\t{$src, $dst|$dst, $src}", 1211 [(set GR64:$dst, (cttz (loadi64 addr:$src))), 1212 (implicit EFLAGS)]>, TB, XS, Sched<[WriteTZCNTLd]>; 1213} 1214 1215multiclass Bls<string m, Format RegMRM, Format MemMRM, X86TypeInfo t, string Suffix = ""> { 1216 let SchedRW = [WriteBLS] in { 1217 def rr#Suffix : UnaryOpR<0xF3, RegMRM, m, unaryop_ndd_args, t, 1218 (outs t.RegClass:$dst), []>, T8, VVVV; 1219 } 1220 1221 let SchedRW = [WriteBLS.Folded] in 1222 def rm#Suffix : UnaryOpM<0xF3, MemMRM, m, unaryop_ndd_args, t, 1223 (outs t.RegClass:$dst), []>, T8, VVVV; 1224} 1225 1226let Predicates = [HasBMI], Defs = [EFLAGS] in { 1227 defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32>, VEX; 1228 defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64>, VEX; 1229 defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32>, VEX; 1230 defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64>, VEX; 1231 defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32>, VEX; 1232 defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64>, VEX; 1233} 1234 1235let Predicates = [HasBMI, In64BitMode], Defs = [EFLAGS] in { 1236 defm BLSR32 : Bls<"blsr", MRM1r, MRM1m, Xi32, "_EVEX">, EVEX; 1237 defm BLSR64 : Bls<"blsr", MRM1r, MRM1m, Xi64, "_EVEX">, EVEX; 1238 defm BLSMSK32 : Bls<"blsmsk", MRM2r, MRM2m, Xi32, "_EVEX">, EVEX; 1239 defm BLSMSK64 : Bls<"blsmsk", MRM2r, MRM2m, Xi64, "_EVEX">, EVEX; 1240 defm BLSI32 : Bls<"blsi", MRM3r, MRM3m, Xi32, "_EVEX">, EVEX; 1241 defm BLSI64 : Bls<"blsi", MRM3r, MRM3m, Xi64, "_EVEX">, EVEX; 1242} 1243 1244let Predicates = [HasBMI] in { 1245 // FIXME(1): patterns for the load versions are not implemented 1246 // FIXME(2): By only matching `add_su` and `ineg_su` we may emit 1247 // extra `mov` instructions if `src` has future uses. It may be better 1248 // to always match if `src` has more users. 1249 def : Pat<(and GR32:$src, (add_su GR32:$src, -1)), 1250 (BLSR32rr GR32:$src)>; 1251 def : Pat<(and GR64:$src, (add_su GR64:$src, -1)), 1252 (BLSR64rr GR64:$src)>; 1253 1254 def : Pat<(xor GR32:$src, (add_su GR32:$src, -1)), 1255 (BLSMSK32rr GR32:$src)>; 1256 def : Pat<(xor GR64:$src, (add_su GR64:$src, -1)), 1257 (BLSMSK64rr GR64:$src)>; 1258 1259 def : Pat<(and GR32:$src, (ineg_su GR32:$src)), 1260 (BLSI32rr GR32:$src)>; 1261 def : Pat<(and GR64:$src, (ineg_su GR64:$src)), 1262 (BLSI64rr GR64:$src)>; 1263 1264 // Versions to match flag producing ops. 1265 def : Pat<(and_flag_nocf GR32:$src, (add_su GR32:$src, -1)), 1266 (BLSR32rr GR32:$src)>; 1267 def : Pat<(and_flag_nocf GR64:$src, (add_su GR64:$src, -1)), 1268 (BLSR64rr GR64:$src)>; 1269 1270 def : Pat<(xor_flag_nocf GR32:$src, (add_su GR32:$src, -1)), 1271 (BLSMSK32rr GR32:$src)>; 1272 def : Pat<(xor_flag_nocf GR64:$src, (add_su GR64:$src, -1)), 1273 (BLSMSK64rr GR64:$src)>; 1274 1275 def : Pat<(and_flag_nocf GR32:$src, (ineg_su GR32:$src)), 1276 (BLSI32rr GR32:$src)>; 1277 def : Pat<(and_flag_nocf GR64:$src, (ineg_su GR64:$src)), 1278 (BLSI64rr GR64:$src)>; 1279} 1280 1281multiclass Bmi4VOp3<bits<8> o, string m, X86TypeInfo t, SDPatternOperator node, 1282 X86FoldableSchedWrite sched, string Suffix = ""> { 1283 let SchedRW = [sched], Form = MRMSrcReg4VOp3 in 1284 def rr#Suffix : BinOpRR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst), 1285 [(set t.RegClass:$dst, EFLAGS, 1286 (node t.RegClass:$src1, t.RegClass:$src2))]>, T8; 1287 let SchedRW = [sched.Folded, 1288 ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault, 1289 sched.ReadAfterFold], Form = MRMSrcMem4VOp3 in 1290 def rm#Suffix : BinOpMR<o, m, binop_ndd_args, t, (outs t.RegClass:$dst), 1291 [(set t.RegClass:$dst, EFLAGS, (node (t.LoadNode addr:$src1), 1292 t.RegClass:$src2))]>, T8; 1293} 1294 1295let Predicates = [HasBMI, NoEGPR], Defs = [EFLAGS] in { 1296 defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, X86bextr, WriteBEXTR>, VEX; 1297 defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, X86bextr, WriteBEXTR>, VEX; 1298} 1299let Predicates = [HasBMI2, NoEGPR], Defs = [EFLAGS] in { 1300 defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, X86bzhi, WriteBZHI>, VEX; 1301 defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, X86bzhi, WriteBZHI>, VEX; 1302} 1303let Predicates = [HasBMI, HasEGPR, In64BitMode], Defs = [EFLAGS] in { 1304 defm BEXTR32 : Bmi4VOp3<0xF7, "bextr", Xi32, X86bextr, WriteBEXTR, "_EVEX">, EVEX; 1305 defm BEXTR64 : Bmi4VOp3<0xF7, "bextr", Xi64, X86bextr, WriteBEXTR, "_EVEX">, EVEX; 1306} 1307let Predicates = [HasBMI2, HasEGPR, In64BitMode], Defs = [EFLAGS] in { 1308 defm BZHI32 : Bmi4VOp3<0xF5, "bzhi", Xi32, X86bzhi, WriteBZHI, "_EVEX">, EVEX; 1309 defm BZHI64 : Bmi4VOp3<0xF5, "bzhi", Xi64, X86bzhi, WriteBZHI, "_EVEX">, EVEX; 1310} 1311 1312def CountTrailingOnes : SDNodeXForm<imm, [{ 1313 // Count the trailing ones in the immediate. 1314 return getI8Imm(llvm::countr_one(N->getZExtValue()), SDLoc(N)); 1315}]>; 1316 1317def BEXTRMaskXForm : SDNodeXForm<imm, [{ 1318 unsigned Length = llvm::countr_one(N->getZExtValue()); 1319 return getI32Imm(Length << 8, SDLoc(N)); 1320}]>; 1321 1322def AndMask64 : ImmLeaf<i64, [{ 1323 return isMask_64(Imm) && !isUInt<32>(Imm); 1324}]>; 1325 1326// Use BEXTR for 64-bit 'and' with large immediate 'mask'. 1327let Predicates = [HasBMI, NoBMI2, NoTBM] in { 1328 def : Pat<(and GR64:$src, AndMask64:$mask), 1329 (BEXTR64rr GR64:$src, 1330 (SUBREG_TO_REG (i64 0), 1331 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 1332 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 1333 (BEXTR64rm addr:$src, 1334 (SUBREG_TO_REG (i64 0), 1335 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 1336} 1337 1338// Use BZHI for 64-bit 'and' with large immediate 'mask'. 1339let Predicates = [HasBMI2, NoTBM] in { 1340 def : Pat<(and GR64:$src, AndMask64:$mask), 1341 (BZHI64rr GR64:$src, 1342 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1343 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 1344 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 1345 (BZHI64rm addr:$src, 1346 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 1347 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 1348} 1349 1350multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC, 1351 X86MemOperand x86memop, SDPatternOperator OpNode, 1352 PatFrag ld_frag, string Suffix = ""> { 1353 def rr#Suffix : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2), 1354 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 1355 [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>, 1356 NoCD8, VVVV, Sched<[WriteALU]>; 1357 def rm#Suffix : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2), 1358 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 1359 [(set RC:$dst, (OpNode RC:$src1, (ld_frag addr:$src2)))]>, 1360 NoCD8, VVVV, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>; 1361} 1362 1363let Predicates = [HasBMI2, NoEGPR] in { 1364 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem, 1365 X86pdep, loadi32>, T8, XD, VEX; 1366 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem, 1367 X86pdep, loadi64>, T8, XD, REX_W, VEX; 1368 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem, 1369 X86pext, loadi32>, T8, XS, VEX; 1370 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem, 1371 X86pext, loadi64>, T8, XS, REX_W, VEX; 1372} 1373 1374let Predicates = [HasBMI2, HasEGPR] in { 1375 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem, 1376 X86pdep, loadi32, "_EVEX">, T8, XD, EVEX; 1377 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem, 1378 X86pdep, loadi64, "_EVEX">, T8, XD, REX_W, EVEX; 1379 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem, 1380 X86pext, loadi32, "_EVEX">, T8, XS, EVEX; 1381 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem, 1382 X86pext, loadi64, "_EVEX">, T8, XS, REX_W, EVEX; 1383} 1384 1385//===----------------------------------------------------------------------===// 1386// Lightweight Profiling Instructions 1387 1388let Predicates = [HasLWP], SchedRW = [WriteSystem] in { 1389 1390def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src", 1391 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9; 1392def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst", 1393 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9; 1394 1395def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src", 1396 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, REX_W; 1397def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst", 1398 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, REX_W; 1399 1400multiclass lwpins_intr<RegisterClass RC> { 1401 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 1402 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 1403 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>, 1404 XOP, VVVV, XOPA; 1405 let mayLoad = 1 in 1406 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 1407 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 1408 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>, 1409 XOP, VVVV, XOPA; 1410} 1411 1412let Defs = [EFLAGS] in { 1413 defm LWPINS32 : lwpins_intr<GR32>; 1414 defm LWPINS64 : lwpins_intr<GR64>, REX_W; 1415} // EFLAGS 1416 1417multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> { 1418 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 1419 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 1420 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP, VVVV, XOPA; 1421 let mayLoad = 1 in 1422 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 1423 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 1424 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>, 1425 XOP, VVVV, XOPA; 1426} 1427 1428defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>; 1429defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, REX_W; 1430 1431} // HasLWP, SchedRW 1432 1433//===----------------------------------------------------------------------===// 1434// MONITORX/MWAITX Instructions 1435// 1436let SchedRW = [ WriteSystem ] in { 1437 let Uses = [ EAX, ECX, EDX ] in 1438 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 1439 TB, Requires<[ HasMWAITX, Not64BitMode ]>; 1440 let Uses = [ RAX, ECX, EDX ] in 1441 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 1442 TB, Requires<[ HasMWAITX, In64BitMode ]>; 1443 1444 let Uses = [ ECX, EAX, EBX ] in { 1445 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", 1446 []>, TB, Requires<[ HasMWAITX ]>; 1447 } 1448} // SchedRW 1449 1450//===----------------------------------------------------------------------===// 1451// WAITPKG Instructions 1452// 1453let SchedRW = [WriteSystem] in { 1454 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src), 1455 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>, 1456 TB, XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>; 1457 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src), 1458 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>, 1459 TB, XS, AdSize32, Requires<[HasWAITPKG]>; 1460 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src), 1461 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>, 1462 TB, XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>; 1463 let Uses = [EAX, EDX], Defs = [EFLAGS] in { 1464 def UMWAIT : I<0xAE, MRM6r, 1465 (outs), (ins GR32orGR64:$src), "umwait\t$src", 1466 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>, 1467 TB, XD, Requires<[HasWAITPKG]>; 1468 def TPAUSE : I<0xAE, MRM6r, 1469 (outs), (ins GR32orGR64:$src), "tpause\t$src", 1470 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>, 1471 TB, PD, Requires<[HasWAITPKG]>; 1472 } 1473} // SchedRW 1474 1475//===----------------------------------------------------------------------===// 1476// MOVDIRI - Move doubleword/quadword as direct store 1477// 1478let SchedRW = [WriteStore] in { 1479def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 1480 "movdiri\t{$src, $dst|$dst, $src}", 1481 [(int_x86_directstore32 addr:$dst, GR32:$src)]>, 1482 T8, Requires<[HasMOVDIRI, NoEGPR]>; 1483def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 1484 "movdiri\t{$src, $dst|$dst, $src}", 1485 [(int_x86_directstore64 addr:$dst, GR64:$src)]>, 1486 T8, Requires<[In64BitMode, HasMOVDIRI, NoEGPR]>; 1487def MOVDIRI32_EVEX : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 1488 "movdiri\t{$src, $dst|$dst, $src}", 1489 [(int_x86_directstore32 addr:$dst, GR32:$src)]>, 1490 EVEX, NoCD8, T_MAP4, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>; 1491def MOVDIRI64_EVEX : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 1492 "movdiri\t{$src, $dst|$dst, $src}", 1493 [(int_x86_directstore64 addr:$dst, GR64:$src)]>, 1494 EVEX, NoCD8, T_MAP4, Requires<[In64BitMode, HasMOVDIRI, HasEGPR]>; 1495} // SchedRW 1496 1497//===----------------------------------------------------------------------===// 1498// MOVDIR64B - Move 64 bytes as direct store 1499// 1500let SchedRW = [WriteStore] in { 1501def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem_GR16:$src), 1502 "movdir64b\t{$src, $dst|$dst, $src}", []>, 1503 T8, PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>; 1504def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src), 1505 "movdir64b\t{$src, $dst|$dst, $src}", 1506 [(int_x86_movdir64b GR32:$dst, addr:$src)]>, 1507 T8, PD, AdSize32, Requires<[HasMOVDIR64B, NoEGPR]>; 1508def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src), 1509 "movdir64b\t{$src, $dst|$dst, $src}", 1510 [(int_x86_movdir64b GR64:$dst, addr:$src)]>, 1511 T8, PD, AdSize64, Requires<[HasMOVDIR64B, NoEGPR, In64BitMode]>; 1512def MOVDIR64B32_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem_GR32:$src), 1513 "movdir64b\t{$src, $dst|$dst, $src}", 1514 [(int_x86_movdir64b GR32:$dst, addr:$src)]>, 1515 EVEX, NoCD8, T_MAP4, PD, AdSize32, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>; 1516def MOVDIR64B64_EVEX : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem_GR64:$src), 1517 "movdir64b\t{$src, $dst|$dst, $src}", 1518 [(int_x86_movdir64b GR64:$dst, addr:$src)]>, 1519 EVEX, NoCD8, T_MAP4, PD, AdSize64, Requires<[HasMOVDIR64B, HasEGPR, In64BitMode]>; 1520} // SchedRW 1521 1522//===----------------------------------------------------------------------===// 1523// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity 1524// 1525let SchedRW = [WriteStore], Defs = [EFLAGS] in { 1526 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 1527 "enqcmd\t{$src, $dst|$dst, $src}", 1528 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>, 1529 T8, XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 1530 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 1531 "enqcmd\t{$src, $dst|$dst, $src}", 1532 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>, 1533 T8, XD, AdSize32, Requires<[HasENQCMD]>; 1534 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 1535 "enqcmd\t{$src, $dst|$dst, $src}", 1536 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>, 1537 T8, XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 1538 1539 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 1540 "enqcmds\t{$src, $dst|$dst, $src}", 1541 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>, 1542 T8, XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 1543 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 1544 "enqcmds\t{$src, $dst|$dst, $src}", 1545 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>, 1546 T8, XS, AdSize32, Requires<[HasENQCMD]>; 1547 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 1548 "enqcmds\t{$src, $dst|$dst, $src}", 1549 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>, 1550 T8, XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 1551} 1552 1553//===----------------------------------------------------------------------===// 1554// CLZERO Instruction 1555// 1556let SchedRW = [WriteLoad] in { 1557 let Uses = [EAX] in 1558 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 1559 TB, Requires<[HasCLZERO, Not64BitMode]>; 1560 let Uses = [RAX] in 1561 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 1562 TB, Requires<[HasCLZERO, In64BitMode]>; 1563} // SchedRW 1564 1565//===----------------------------------------------------------------------===// 1566// INVLPGB Instruction 1567// OPCODE 0F 01 FE 1568// 1569let SchedRW = [WriteSystem] in { 1570 let Uses = [EAX, EDX] in 1571 def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins), 1572 "invlpgb", []>, 1573 TB, Requires<[Not64BitMode]>; 1574 let Uses = [RAX, EDX] in 1575 def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins), 1576 "invlpgb", []>, 1577 TB, Requires<[In64BitMode]>; 1578} // SchedRW 1579 1580//===----------------------------------------------------------------------===// 1581// TLBSYNC Instruction 1582// OPCODE 0F 01 FF 1583// 1584let SchedRW = [WriteSystem] in { 1585 def TLBSYNC : I<0x01, MRM_FF, (outs), (ins), 1586 "tlbsync", []>, 1587 TB, Requires<[]>; 1588} // SchedRW 1589 1590//===----------------------------------------------------------------------===// 1591// HRESET Instruction 1592// 1593let Uses = [EAX], SchedRW = [WriteSystem] in 1594 def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>, 1595 Requires<[HasHRESET]>, TA, XS; 1596 1597//===----------------------------------------------------------------------===// 1598// SERIALIZE Instruction 1599// 1600let SchedRW = [WriteSystem] in 1601 def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize", 1602 [(int_x86_serialize)]>, TB, 1603 Requires<[HasSERIALIZE]>; 1604 1605//===----------------------------------------------------------------------===// 1606// TSXLDTRK - TSX Suspend Load Address Tracking 1607// 1608let Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in { 1609 def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk", 1610 [(int_x86_xsusldtrk)]>, TB, XD; 1611 def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk", 1612 [(int_x86_xresldtrk)]>, TB, XD; 1613} 1614 1615//===----------------------------------------------------------------------===// 1616// UINTR Instructions 1617// 1618let Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in { 1619 def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret", 1620 []>, TB, XS; 1621 def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui", 1622 [(int_x86_clui)]>, TB, XS; 1623 def STUI : I<0x01, MRM_EF, (outs), (ins), "stui", 1624 [(int_x86_stui)]>, TB, XS; 1625 1626 def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg", 1627 [(int_x86_senduipi GR64:$arg)]>, TB, XS; 1628 1629 let Defs = [EFLAGS] in 1630 def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui", 1631 [(set EFLAGS, (X86testui))]>, TB, XS; 1632} 1633 1634//===----------------------------------------------------------------------===// 1635// PREFETCHIT0 and PREFETCHIT1 Instructions 1636// prefetch ADDR, RW, Locality, Data 1637let Predicates = [HasPREFETCHI, In64BitMode], SchedRW = [WriteLoad] in { 1638 def PREFETCHIT0 : I<0x18, MRM7m, (outs), (ins i8mem:$src), 1639 "prefetchit0\t$src", [(prefetch addr:$src, (i32 0), (i32 3), (i32 0))]>, TB; 1640 def PREFETCHIT1 : I<0x18, MRM6m, (outs), (ins i8mem:$src), 1641 "prefetchit1\t$src", [(prefetch addr:$src, (i32 0), (i32 2), (i32 0))]>, TB; 1642} 1643 1644//===----------------------------------------------------------------------===// 1645// CMPCCXADD Instructions 1646// 1647let isCodeGenOnly = 1, ForceDisassemble = 1, mayLoad = 1, mayStore = 1, 1648 Defs = [EFLAGS], Constraints = "$dstsrc1 = $dst" in { 1649let Predicates = [HasCMPCCXADD, NoEGPR, In64BitMode] in { 1650def CMPCCXADDmr32 : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst), 1651 (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond), 1652 "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}", 1653 [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2, 1654 GR32:$dstsrc1, GR32:$src3, timm:$cond))]>, 1655 VEX, VVVV, T8, PD, Sched<[WriteXCHG]>; 1656 1657def CMPCCXADDmr64 : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst), 1658 (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond), 1659 "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}", 1660 [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2, 1661 GR64:$dstsrc1, GR64:$src3, timm:$cond))]>, 1662 VEX, VVVV, REX_W, T8, PD, Sched<[WriteXCHG]>; 1663} 1664 1665let Predicates = [HasCMPCCXADD, HasEGPR, In64BitMode] in { 1666def CMPCCXADDmr32_EVEX : I<0xe0, MRMDestMem4VOp3CC, (outs GR32:$dst), 1667 (ins GR32:$dstsrc1, i32mem:$dstsrc2, GR32:$src3, ccode:$cond), 1668 "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}", 1669 [(set GR32:$dst, (X86cmpccxadd addr:$dstsrc2, 1670 GR32:$dstsrc1, GR32:$src3, timm:$cond))]>, 1671 EVEX, VVVV, NoCD8, T8, PD, Sched<[WriteXCHG]>; 1672 1673def CMPCCXADDmr64_EVEX : I<0xe0, MRMDestMem4VOp3CC, (outs GR64:$dst), 1674 (ins GR64:$dstsrc1, i64mem:$dstsrc2, GR64:$src3, ccode:$cond), 1675 "cmp${cond}xadd\t{$src3, $dst, $dstsrc2|$dstsrc2, $dst, $src3}", 1676 [(set GR64:$dst, (X86cmpccxadd addr:$dstsrc2, 1677 GR64:$dstsrc1, GR64:$src3, timm:$cond))]>, 1678 EVEX, VVVV, NoCD8, REX_W, T8, PD, Sched<[WriteXCHG]>; 1679} 1680} 1681 1682//===----------------------------------------------------------------------===// 1683// Memory Instructions 1684// 1685 1686let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in 1687def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src), 1688 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, TB, PD; 1689 1690let Predicates = [HasCLWB], SchedRW = [WriteLoad] in 1691def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", 1692 [(int_x86_clwb addr:$src)]>, TB, PD; 1693 1694let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in 1695def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src", 1696 [(int_x86_cldemote addr:$src)]>, TB; 1697