1//===-- X86InstrInfo.td - Main 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 describes the X86 instruction set, defining the instructions, and 10// properties of the instructions which are needed for code generation, machine 11// code emission, and analysis. 12// 13//===----------------------------------------------------------------------===// 14 15//===----------------------------------------------------------------------===// 16// X86 specific DAG Nodes. 17// 18 19def SDTX86CmpTest : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisInt<1>, 20 SDTCisSameAs<1, 2>]>; 21def SDTX86FCmp : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, SDTCisFP<1>, 22 SDTCisSameAs<1, 2>]>; 23 24def SDTX86Cmov : SDTypeProfile<1, 4, 25 [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, 26 SDTCisVT<3, i8>, SDTCisVT<4, i32>]>; 27 28// Unary and binary operator instructions that set EFLAGS as a side-effect. 29def SDTUnaryArithWithFlags : SDTypeProfile<2, 1, 30 [SDTCisSameAs<0, 2>, 31 SDTCisInt<0>, SDTCisVT<1, i32>]>; 32 33def SDTBinaryArithWithFlags : SDTypeProfile<2, 2, 34 [SDTCisSameAs<0, 2>, 35 SDTCisSameAs<0, 3>, 36 SDTCisInt<0>, SDTCisVT<1, i32>]>; 37 38// SDTBinaryArithWithFlagsInOut - RES1, EFLAGS = op LHS, RHS, EFLAGS 39def SDTBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, 40 [SDTCisSameAs<0, 2>, 41 SDTCisSameAs<0, 3>, 42 SDTCisInt<0>, 43 SDTCisVT<1, i32>, 44 SDTCisVT<4, i32>]>; 45// RES1, RES2, FLAGS = op LHS, RHS 46def SDT2ResultBinaryArithWithFlags : SDTypeProfile<3, 2, 47 [SDTCisSameAs<0, 1>, 48 SDTCisSameAs<0, 2>, 49 SDTCisSameAs<0, 3>, 50 SDTCisInt<0>, SDTCisVT<1, i32>]>; 51def SDTX86BrCond : SDTypeProfile<0, 3, 52 [SDTCisVT<0, OtherVT>, 53 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 54 55def SDTX86SetCC : SDTypeProfile<1, 2, 56 [SDTCisVT<0, i8>, 57 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 58def SDTX86SetCC_C : SDTypeProfile<1, 2, 59 [SDTCisInt<0>, 60 SDTCisVT<1, i8>, SDTCisVT<2, i32>]>; 61 62def SDTX86sahf : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i8>]>; 63 64def SDTX86rdrand : SDTypeProfile<2, 0, [SDTCisInt<0>, SDTCisVT<1, i32>]>; 65 66def SDTX86rdpkru : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; 67def SDTX86wrpkru : SDTypeProfile<0, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>, 68 SDTCisVT<2, i32>]>; 69 70def SDTX86cas : SDTypeProfile<0, 3, [SDTCisPtrTy<0>, SDTCisInt<1>, 71 SDTCisVT<2, i8>]>; 72def SDTX86cas8pair : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; 73def SDTX86cas16pair : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i64>]>; 74 75def SDTLockBinaryArithWithFlags : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, 76 SDTCisPtrTy<1>, 77 SDTCisInt<2>]>; 78 79def SDTLockUnaryArithWithFlags : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, 80 SDTCisPtrTy<1>]>; 81 82def SDTX86Ret : SDTypeProfile<0, -1, [SDTCisVT<0, i32>]>; 83 84def SDT_X86CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, 85 SDTCisVT<1, i32>]>; 86def SDT_X86CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, 87 SDTCisVT<1, i32>]>; 88 89def SDT_X86Call : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 90 91def SDT_X86NtBrind : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>; 92 93def SDT_X86VASTART_SAVE_XMM_REGS : SDTypeProfile<0, -1, [SDTCisVT<0, i8>, 94 SDTCisPtrTy<1>]>; 95 96def SDT_X86VAARG : SDTypeProfile<1, -1, [SDTCisPtrTy<0>, 97 SDTCisPtrTy<1>, 98 SDTCisVT<2, i32>, 99 SDTCisVT<3, i8>, 100 SDTCisVT<4, i32>]>; 101 102def SDTX86RepStr : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>; 103 104def SDTX86Void : SDTypeProfile<0, 0, []>; 105 106def SDTX86Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>; 107 108def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 109 110def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 111 112def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 113 114def SDT_X86DYN_ALLOCA : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; 115 116def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 117 118def SDT_X86PROBED_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>; 119 120def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 121 122def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>; 123 124def SDT_X86MEMBARRIER : SDTypeProfile<0, 0, []>; 125 126def SDT_X86ENQCMD : SDTypeProfile<1, 2, [SDTCisVT<0, i32>, 127 SDTCisPtrTy<1>, SDTCisSameAs<1, 2>]>; 128 129def SDT_X86AESENCDECKL : SDTypeProfile<2, 2, [SDTCisVT<0, v2i64>, 130 SDTCisVT<1, i32>, 131 SDTCisVT<2, v2i64>, 132 SDTCisPtrTy<3>]>; 133 134def X86MemBarrier : SDNode<"X86ISD::MEMBARRIER", SDT_X86MEMBARRIER, 135 [SDNPHasChain,SDNPSideEffect]>; 136def X86MFence : SDNode<"X86ISD::MFENCE", SDT_X86MEMBARRIER, 137 [SDNPHasChain]>; 138 139 140def X86bsf : SDNode<"X86ISD::BSF", SDTUnaryArithWithFlags>; 141def X86bsr : SDNode<"X86ISD::BSR", SDTUnaryArithWithFlags>; 142def X86fshl : SDNode<"X86ISD::FSHL", SDTIntShiftDOp>; 143def X86fshr : SDNode<"X86ISD::FSHR", SDTIntShiftDOp>; 144 145def X86cmp : SDNode<"X86ISD::CMP" , SDTX86CmpTest>; 146def X86fcmp : SDNode<"X86ISD::FCMP", SDTX86FCmp>; 147def X86strict_fcmp : SDNode<"X86ISD::STRICT_FCMP", SDTX86FCmp, [SDNPHasChain]>; 148def X86strict_fcmps : SDNode<"X86ISD::STRICT_FCMPS", SDTX86FCmp, [SDNPHasChain]>; 149def X86bt : SDNode<"X86ISD::BT", SDTX86CmpTest>; 150 151def X86cmov : SDNode<"X86ISD::CMOV", SDTX86Cmov>; 152def X86brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond, 153 [SDNPHasChain]>; 154def X86setcc : SDNode<"X86ISD::SETCC", SDTX86SetCC>; 155def X86setcc_c : SDNode<"X86ISD::SETCC_CARRY", SDTX86SetCC_C>; 156 157def X86rdrand : SDNode<"X86ISD::RDRAND", SDTX86rdrand, 158 [SDNPHasChain, SDNPSideEffect]>; 159 160def X86rdseed : SDNode<"X86ISD::RDSEED", SDTX86rdrand, 161 [SDNPHasChain, SDNPSideEffect]>; 162 163def X86rdpkru : SDNode<"X86ISD::RDPKRU", SDTX86rdpkru, 164 [SDNPHasChain, SDNPSideEffect]>; 165def X86wrpkru : SDNode<"X86ISD::WRPKRU", SDTX86wrpkru, 166 [SDNPHasChain, SDNPSideEffect]>; 167 168def X86cas : SDNode<"X86ISD::LCMPXCHG_DAG", SDTX86cas, 169 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 170 SDNPMayLoad, SDNPMemOperand]>; 171def X86cas8 : SDNode<"X86ISD::LCMPXCHG8_DAG", SDTX86cas8pair, 172 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 173 SDNPMayLoad, SDNPMemOperand]>; 174def X86cas16 : SDNode<"X86ISD::LCMPXCHG16_DAG", SDTX86cas16pair, 175 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 176 SDNPMayLoad, SDNPMemOperand]>; 177 178def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86Ret, 179 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 180def X86iret : SDNode<"X86ISD::IRET", SDTX86Ret, 181 [SDNPHasChain, SDNPOptInGlue]>; 182 183def X86vastart_save_xmm_regs : 184 SDNode<"X86ISD::VASTART_SAVE_XMM_REGS", 185 SDT_X86VASTART_SAVE_XMM_REGS, 186 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPVariadic]>; 187def X86vaarg64 : 188 SDNode<"X86ISD::VAARG_64", SDT_X86VAARG, 189 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 190 SDNPMemOperand]>; 191def X86vaargx32 : 192 SDNode<"X86ISD::VAARG_X32", SDT_X86VAARG, 193 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 194 SDNPMemOperand]>; 195def X86callseq_start : 196 SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart, 197 [SDNPHasChain, SDNPOutGlue]>; 198def X86callseq_end : 199 SDNode<"ISD::CALLSEQ_END", SDT_X86CallSeqEnd, 200 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 201 202def X86call : SDNode<"X86ISD::CALL", SDT_X86Call, 203 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 204 SDNPVariadic]>; 205 206def X86call_rvmarker : SDNode<"X86ISD::CALL_RVMARKER", SDT_X86Call, 207 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 208 SDNPVariadic]>; 209 210 211def X86NoTrackCall : SDNode<"X86ISD::NT_CALL", SDT_X86Call, 212 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 213 SDNPVariadic]>; 214def X86NoTrackBrind : SDNode<"X86ISD::NT_BRIND", SDT_X86NtBrind, 215 [SDNPHasChain]>; 216 217def X86rep_stos: SDNode<"X86ISD::REP_STOS", SDTX86RepStr, 218 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore]>; 219def X86rep_movs: SDNode<"X86ISD::REP_MOVS", SDTX86RepStr, 220 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, SDNPMayStore, 221 SDNPMayLoad]>; 222 223def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>; 224def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>; 225 226def X86RecoverFrameAlloc : SDNode<"ISD::LOCAL_RECOVER", 227 SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, 228 SDTCisInt<1>]>>; 229 230def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR, 231 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 232 233def X86tlsbaseaddr : SDNode<"X86ISD::TLSBASEADDR", SDT_X86TLSBASEADDR, 234 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 235 236def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET, 237 [SDNPHasChain]>; 238 239def X86eh_sjlj_setjmp : SDNode<"X86ISD::EH_SJLJ_SETJMP", 240 SDTypeProfile<1, 1, [SDTCisInt<0>, 241 SDTCisPtrTy<1>]>, 242 [SDNPHasChain, SDNPSideEffect]>; 243def X86eh_sjlj_longjmp : SDNode<"X86ISD::EH_SJLJ_LONGJMP", 244 SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>, 245 [SDNPHasChain, SDNPSideEffect]>; 246def X86eh_sjlj_setup_dispatch : SDNode<"X86ISD::EH_SJLJ_SETUP_DISPATCH", 247 SDTypeProfile<0, 0, []>, 248 [SDNPHasChain, SDNPSideEffect]>; 249 250def X86tcret : SDNode<"X86ISD::TC_RETURN", SDT_X86TCRET, 251 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 252 253def X86add_flag : SDNode<"X86ISD::ADD", SDTBinaryArithWithFlags, 254 [SDNPCommutative]>; 255def X86sub_flag : SDNode<"X86ISD::SUB", SDTBinaryArithWithFlags>; 256def X86smul_flag : SDNode<"X86ISD::SMUL", SDTBinaryArithWithFlags, 257 [SDNPCommutative]>; 258def X86umul_flag : SDNode<"X86ISD::UMUL", SDT2ResultBinaryArithWithFlags, 259 [SDNPCommutative]>; 260def X86adc_flag : SDNode<"X86ISD::ADC", SDTBinaryArithWithFlagsInOut>; 261def X86sbb_flag : SDNode<"X86ISD::SBB", SDTBinaryArithWithFlagsInOut>; 262 263def X86or_flag : SDNode<"X86ISD::OR", SDTBinaryArithWithFlags, 264 [SDNPCommutative]>; 265def X86xor_flag : SDNode<"X86ISD::XOR", SDTBinaryArithWithFlags, 266 [SDNPCommutative]>; 267def X86and_flag : SDNode<"X86ISD::AND", SDTBinaryArithWithFlags, 268 [SDNPCommutative]>; 269 270def X86lock_add : SDNode<"X86ISD::LADD", SDTLockBinaryArithWithFlags, 271 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 272 SDNPMemOperand]>; 273def X86lock_sub : SDNode<"X86ISD::LSUB", SDTLockBinaryArithWithFlags, 274 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 275 SDNPMemOperand]>; 276def X86lock_or : SDNode<"X86ISD::LOR", SDTLockBinaryArithWithFlags, 277 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 278 SDNPMemOperand]>; 279def X86lock_xor : SDNode<"X86ISD::LXOR", SDTLockBinaryArithWithFlags, 280 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 281 SDNPMemOperand]>; 282def X86lock_and : SDNode<"X86ISD::LAND", SDTLockBinaryArithWithFlags, 283 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, 284 SDNPMemOperand]>; 285 286def X86bextr : SDNode<"X86ISD::BEXTR", SDTIntBinOp>; 287def X86bextri : SDNode<"X86ISD::BEXTRI", SDTIntBinOp>; 288 289def X86bzhi : SDNode<"X86ISD::BZHI", SDTIntBinOp>; 290 291def X86pdep : SDNode<"X86ISD::PDEP", SDTIntBinOp>; 292def X86pext : SDNode<"X86ISD::PEXT", SDTIntBinOp>; 293 294def X86mul_imm : SDNode<"X86ISD::MUL_IMM", SDTIntBinOp>; 295 296def X86DynAlloca : SDNode<"X86ISD::DYN_ALLOCA", SDT_X86DYN_ALLOCA, 297 [SDNPHasChain, SDNPOutGlue]>; 298 299def X86SegAlloca : SDNode<"X86ISD::SEG_ALLOCA", SDT_X86SEG_ALLOCA, 300 [SDNPHasChain]>; 301 302def X86ProbedAlloca : SDNode<"X86ISD::PROBED_ALLOCA", SDT_X86PROBED_ALLOCA, 303 [SDNPHasChain]>; 304 305def X86TLSCall : SDNode<"X86ISD::TLSCALL", SDT_X86TLSCALL, 306 [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; 307 308def X86lwpins : SDNode<"X86ISD::LWPINS", 309 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 310 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 311 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPSideEffect]>; 312 313def X86umwait : SDNode<"X86ISD::UMWAIT", 314 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 315 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 316 [SDNPHasChain, SDNPSideEffect]>; 317 318def X86tpause : SDNode<"X86ISD::TPAUSE", 319 SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisInt<1>, 320 SDTCisVT<2, i32>, SDTCisVT<3, i32>]>, 321 [SDNPHasChain, SDNPSideEffect]>; 322 323def X86enqcmd : SDNode<"X86ISD::ENQCMD", SDT_X86ENQCMD, 324 [SDNPHasChain, SDNPSideEffect]>; 325def X86enqcmds : SDNode<"X86ISD::ENQCMDS", SDT_X86ENQCMD, 326 [SDNPHasChain, SDNPSideEffect]>; 327def X86testui : SDNode<"X86ISD::TESTUI", 328 SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>, 329 [SDNPHasChain, SDNPSideEffect]>; 330 331def X86aesenc128kl : SDNode<"X86ISD::AESENC128KL", SDT_X86AESENCDECKL, 332 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 333 SDNPMemOperand]>; 334def X86aesdec128kl : SDNode<"X86ISD::AESDEC128KL", SDT_X86AESENCDECKL, 335 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 336 SDNPMemOperand]>; 337def X86aesenc256kl : SDNode<"X86ISD::AESENC256KL", SDT_X86AESENCDECKL, 338 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 339 SDNPMemOperand]>; 340def X86aesdec256kl : SDNode<"X86ISD::AESDEC256KL", SDT_X86AESENCDECKL, 341 [SDNPHasChain, SDNPMayLoad, SDNPSideEffect, 342 SDNPMemOperand]>; 343 344//===----------------------------------------------------------------------===// 345// X86 Operand Definitions. 346// 347 348// A version of ptr_rc which excludes SP, ESP, and RSP. This is used for 349// the index operand of an address, to conform to x86 encoding restrictions. 350def ptr_rc_nosp : PointerLikeRegClass<1>; 351 352// *mem - Operand definitions for the funky X86 addressing mode operands. 353// 354def X86MemAsmOperand : AsmOperandClass { 355 let Name = "Mem"; 356} 357let RenderMethod = "addMemOperands", SuperClasses = [X86MemAsmOperand] in { 358 def X86Mem8AsmOperand : AsmOperandClass { let Name = "Mem8"; } 359 def X86Mem16AsmOperand : AsmOperandClass { let Name = "Mem16"; } 360 def X86Mem32AsmOperand : AsmOperandClass { let Name = "Mem32"; } 361 def X86Mem64AsmOperand : AsmOperandClass { let Name = "Mem64"; } 362 def X86Mem80AsmOperand : AsmOperandClass { let Name = "Mem80"; } 363 def X86Mem128AsmOperand : AsmOperandClass { let Name = "Mem128"; } 364 def X86Mem256AsmOperand : AsmOperandClass { let Name = "Mem256"; } 365 def X86Mem512AsmOperand : AsmOperandClass { let Name = "Mem512"; } 366 // Gather mem operands 367 def X86Mem64_RC128Operand : AsmOperandClass { let Name = "Mem64_RC128"; } 368 def X86Mem128_RC128Operand : AsmOperandClass { let Name = "Mem128_RC128"; } 369 def X86Mem256_RC128Operand : AsmOperandClass { let Name = "Mem256_RC128"; } 370 def X86Mem128_RC256Operand : AsmOperandClass { let Name = "Mem128_RC256"; } 371 def X86Mem256_RC256Operand : AsmOperandClass { let Name = "Mem256_RC256"; } 372 373 def X86Mem64_RC128XOperand : AsmOperandClass { let Name = "Mem64_RC128X"; } 374 def X86Mem128_RC128XOperand : AsmOperandClass { let Name = "Mem128_RC128X"; } 375 def X86Mem256_RC128XOperand : AsmOperandClass { let Name = "Mem256_RC128X"; } 376 def X86Mem128_RC256XOperand : AsmOperandClass { let Name = "Mem128_RC256X"; } 377 def X86Mem256_RC256XOperand : AsmOperandClass { let Name = "Mem256_RC256X"; } 378 def X86Mem512_RC256XOperand : AsmOperandClass { let Name = "Mem512_RC256X"; } 379 def X86Mem256_RC512Operand : AsmOperandClass { let Name = "Mem256_RC512"; } 380 def X86Mem512_RC512Operand : AsmOperandClass { let Name = "Mem512_RC512"; } 381 382 def X86SibMemOperand : AsmOperandClass { let Name = "SibMem"; } 383} 384 385def X86AbsMemAsmOperand : AsmOperandClass { 386 let Name = "AbsMem"; 387 let SuperClasses = [X86MemAsmOperand]; 388} 389 390class X86MemOperand<string printMethod, 391 AsmOperandClass parserMatchClass = X86MemAsmOperand, 392 int size = 0> : Operand<iPTR> { 393 let PrintMethod = printMethod; 394 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG); 395 let ParserMatchClass = parserMatchClass; 396 let OperandType = "OPERAND_MEMORY"; 397 int Size = size; 398} 399 400// Gather mem operands 401class X86VMemOperand<RegisterClass RC, string printMethod, 402 AsmOperandClass parserMatchClass, int size = 0> 403 : X86MemOperand<printMethod, parserMatchClass, size> { 404 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG); 405} 406 407def anymem : X86MemOperand<"printMemReference">; 408def X86any_fcmp : PatFrags<(ops node:$lhs, node:$rhs), 409 [(X86strict_fcmp node:$lhs, node:$rhs), 410 (X86fcmp node:$lhs, node:$rhs)]>; 411 412// FIXME: Right now we allow any size during parsing, but we might want to 413// restrict to only unsized memory. 414def opaquemem : X86MemOperand<"printMemReference">; 415 416def sibmem: X86MemOperand<"printMemReference", X86SibMemOperand>; 417 418def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8>; 419def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand, 16>; 420def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand, 32>; 421def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64>; 422def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand, 128>; 423def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand, 256>; 424def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand, 512>; 425def f16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand, 16>; 426def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand, 32>; 427def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand, 64>; 428def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand, 80>; 429def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand, 128>; 430def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand, 256>; 431def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand, 512>; 432 433// Gather mem operands 434def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand, 64>; 435def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand, 128>; 436def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand, 256>; 437def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand, 128>; 438def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand, 256>; 439 440def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand, 64>; 441def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand, 128>; 442def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand, 256>; 443def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand, 128>; 444def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand, 256>; 445def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand, 512>; 446def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand, 256>; 447def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand, 512>; 448 449// A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead 450// of a plain GPR, so that it doesn't potentially require a REX prefix. 451def ptr_rc_norex : PointerLikeRegClass<2>; 452def ptr_rc_norex_nosp : PointerLikeRegClass<3>; 453 454def i8mem_NOREX : X86MemOperand<"printbytemem", X86Mem8AsmOperand, 8> { 455 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm, 456 SEGMENT_REG); 457} 458 459// GPRs available for tailcall. 460// It represents GR32_TC, GR64_TC or GR64_TCW64. 461def ptr_rc_tailcall : PointerLikeRegClass<4>; 462 463// Special i32mem for addresses of load folding tail calls. These are not 464// allowed to use callee-saved registers since they must be scheduled 465// after callee-saved register are popped. 466def i32mem_TC : Operand<i32> { 467 let PrintMethod = "printdwordmem"; 468 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, ptr_rc_tailcall, 469 i32imm, SEGMENT_REG); 470 let ParserMatchClass = X86Mem32AsmOperand; 471 let OperandType = "OPERAND_MEMORY"; 472} 473 474// Special i64mem for addresses of load folding tail calls. These are not 475// allowed to use callee-saved registers since they must be scheduled 476// after callee-saved register are popped. 477def i64mem_TC : Operand<i64> { 478 let PrintMethod = "printqwordmem"; 479 let MIOperandInfo = (ops ptr_rc_tailcall, i8imm, 480 ptr_rc_tailcall, i32imm, SEGMENT_REG); 481 let ParserMatchClass = X86Mem64AsmOperand; 482 let OperandType = "OPERAND_MEMORY"; 483} 484 485// Special parser to detect 16-bit mode to select 16-bit displacement. 486def X86AbsMem16AsmOperand : AsmOperandClass { 487 let Name = "AbsMem16"; 488 let RenderMethod = "addAbsMemOperands"; 489 let SuperClasses = [X86AbsMemAsmOperand]; 490} 491 492// Branch targets print as pc-relative values. 493class BranchTargetOperand<ValueType ty> : Operand<ty> { 494 let OperandType = "OPERAND_PCREL"; 495 let PrintMethod = "printPCRelImm"; 496 let ParserMatchClass = X86AbsMemAsmOperand; 497} 498 499def i32imm_brtarget : BranchTargetOperand<i32>; 500def i16imm_brtarget : BranchTargetOperand<i16>; 501 502// 64-bits but only 32 bits are significant, and those bits are treated as being 503// pc relative. 504def i64i32imm_brtarget : BranchTargetOperand<i64>; 505 506def brtarget : BranchTargetOperand<OtherVT>; 507def brtarget8 : BranchTargetOperand<OtherVT>; 508def brtarget16 : BranchTargetOperand<OtherVT> { 509 let ParserMatchClass = X86AbsMem16AsmOperand; 510} 511def brtarget32 : BranchTargetOperand<OtherVT>; 512 513let RenderMethod = "addSrcIdxOperands" in { 514 def X86SrcIdx8Operand : AsmOperandClass { 515 let Name = "SrcIdx8"; 516 let SuperClasses = [X86Mem8AsmOperand]; 517 } 518 def X86SrcIdx16Operand : AsmOperandClass { 519 let Name = "SrcIdx16"; 520 let SuperClasses = [X86Mem16AsmOperand]; 521 } 522 def X86SrcIdx32Operand : AsmOperandClass { 523 let Name = "SrcIdx32"; 524 let SuperClasses = [X86Mem32AsmOperand]; 525 } 526 def X86SrcIdx64Operand : AsmOperandClass { 527 let Name = "SrcIdx64"; 528 let SuperClasses = [X86Mem64AsmOperand]; 529 } 530} // RenderMethod = "addSrcIdxOperands" 531 532let RenderMethod = "addDstIdxOperands" in { 533 def X86DstIdx8Operand : AsmOperandClass { 534 let Name = "DstIdx8"; 535 let SuperClasses = [X86Mem8AsmOperand]; 536 } 537 def X86DstIdx16Operand : AsmOperandClass { 538 let Name = "DstIdx16"; 539 let SuperClasses = [X86Mem16AsmOperand]; 540 } 541 def X86DstIdx32Operand : AsmOperandClass { 542 let Name = "DstIdx32"; 543 let SuperClasses = [X86Mem32AsmOperand]; 544 } 545 def X86DstIdx64Operand : AsmOperandClass { 546 let Name = "DstIdx64"; 547 let SuperClasses = [X86Mem64AsmOperand]; 548 } 549} // RenderMethod = "addDstIdxOperands" 550 551let RenderMethod = "addMemOffsOperands" in { 552 def X86MemOffs16_8AsmOperand : AsmOperandClass { 553 let Name = "MemOffs16_8"; 554 let SuperClasses = [X86Mem8AsmOperand]; 555 } 556 def X86MemOffs16_16AsmOperand : AsmOperandClass { 557 let Name = "MemOffs16_16"; 558 let SuperClasses = [X86Mem16AsmOperand]; 559 } 560 def X86MemOffs16_32AsmOperand : AsmOperandClass { 561 let Name = "MemOffs16_32"; 562 let SuperClasses = [X86Mem32AsmOperand]; 563 } 564 def X86MemOffs32_8AsmOperand : AsmOperandClass { 565 let Name = "MemOffs32_8"; 566 let SuperClasses = [X86Mem8AsmOperand]; 567 } 568 def X86MemOffs32_16AsmOperand : AsmOperandClass { 569 let Name = "MemOffs32_16"; 570 let SuperClasses = [X86Mem16AsmOperand]; 571 } 572 def X86MemOffs32_32AsmOperand : AsmOperandClass { 573 let Name = "MemOffs32_32"; 574 let SuperClasses = [X86Mem32AsmOperand]; 575 } 576 def X86MemOffs32_64AsmOperand : AsmOperandClass { 577 let Name = "MemOffs32_64"; 578 let SuperClasses = [X86Mem64AsmOperand]; 579 } 580 def X86MemOffs64_8AsmOperand : AsmOperandClass { 581 let Name = "MemOffs64_8"; 582 let SuperClasses = [X86Mem8AsmOperand]; 583 } 584 def X86MemOffs64_16AsmOperand : AsmOperandClass { 585 let Name = "MemOffs64_16"; 586 let SuperClasses = [X86Mem16AsmOperand]; 587 } 588 def X86MemOffs64_32AsmOperand : AsmOperandClass { 589 let Name = "MemOffs64_32"; 590 let SuperClasses = [X86Mem32AsmOperand]; 591 } 592 def X86MemOffs64_64AsmOperand : AsmOperandClass { 593 let Name = "MemOffs64_64"; 594 let SuperClasses = [X86Mem64AsmOperand]; 595 } 596} // RenderMethod = "addMemOffsOperands" 597 598class X86SrcIdxOperand<string printMethod, AsmOperandClass parserMatchClass> 599 : X86MemOperand<printMethod, parserMatchClass> { 600 let MIOperandInfo = (ops ptr_rc, SEGMENT_REG); 601} 602 603class X86DstIdxOperand<string printMethod, AsmOperandClass parserMatchClass> 604 : X86MemOperand<printMethod, parserMatchClass> { 605 let MIOperandInfo = (ops ptr_rc); 606} 607 608def srcidx8 : X86SrcIdxOperand<"printSrcIdx8", X86SrcIdx8Operand>; 609def srcidx16 : X86SrcIdxOperand<"printSrcIdx16", X86SrcIdx16Operand>; 610def srcidx32 : X86SrcIdxOperand<"printSrcIdx32", X86SrcIdx32Operand>; 611def srcidx64 : X86SrcIdxOperand<"printSrcIdx64", X86SrcIdx64Operand>; 612def dstidx8 : X86DstIdxOperand<"printDstIdx8", X86DstIdx8Operand>; 613def dstidx16 : X86DstIdxOperand<"printDstIdx16", X86DstIdx16Operand>; 614def dstidx32 : X86DstIdxOperand<"printDstIdx32", X86DstIdx32Operand>; 615def dstidx64 : X86DstIdxOperand<"printDstIdx64", X86DstIdx64Operand>; 616 617class X86MemOffsOperand<Operand immOperand, string printMethod, 618 AsmOperandClass parserMatchClass> 619 : X86MemOperand<printMethod, parserMatchClass> { 620 let MIOperandInfo = (ops immOperand, SEGMENT_REG); 621} 622 623def offset16_8 : X86MemOffsOperand<i16imm, "printMemOffs8", 624 X86MemOffs16_8AsmOperand>; 625def offset16_16 : X86MemOffsOperand<i16imm, "printMemOffs16", 626 X86MemOffs16_16AsmOperand>; 627def offset16_32 : X86MemOffsOperand<i16imm, "printMemOffs32", 628 X86MemOffs16_32AsmOperand>; 629def offset32_8 : X86MemOffsOperand<i32imm, "printMemOffs8", 630 X86MemOffs32_8AsmOperand>; 631def offset32_16 : X86MemOffsOperand<i32imm, "printMemOffs16", 632 X86MemOffs32_16AsmOperand>; 633def offset32_32 : X86MemOffsOperand<i32imm, "printMemOffs32", 634 X86MemOffs32_32AsmOperand>; 635def offset32_64 : X86MemOffsOperand<i32imm, "printMemOffs64", 636 X86MemOffs32_64AsmOperand>; 637def offset64_8 : X86MemOffsOperand<i64imm, "printMemOffs8", 638 X86MemOffs64_8AsmOperand>; 639def offset64_16 : X86MemOffsOperand<i64imm, "printMemOffs16", 640 X86MemOffs64_16AsmOperand>; 641def offset64_32 : X86MemOffsOperand<i64imm, "printMemOffs32", 642 X86MemOffs64_32AsmOperand>; 643def offset64_64 : X86MemOffsOperand<i64imm, "printMemOffs64", 644 X86MemOffs64_64AsmOperand>; 645 646def ccode : Operand<i8> { 647 let PrintMethod = "printCondCode"; 648 let OperandNamespace = "X86"; 649 let OperandType = "OPERAND_COND_CODE"; 650} 651 652class ImmSExtAsmOperandClass : AsmOperandClass { 653 let SuperClasses = [ImmAsmOperand]; 654 let RenderMethod = "addImmOperands"; 655} 656 657def X86GR32orGR64AsmOperand : AsmOperandClass { 658 let Name = "GR32orGR64"; 659} 660def GR32orGR64 : RegisterOperand<GR32> { 661 let ParserMatchClass = X86GR32orGR64AsmOperand; 662} 663 664def X86GR16orGR32orGR64AsmOperand : AsmOperandClass { 665 let Name = "GR16orGR32orGR64"; 666} 667def GR16orGR32orGR64 : RegisterOperand<GR16> { 668 let ParserMatchClass = X86GR16orGR32orGR64AsmOperand; 669} 670 671def AVX512RCOperand : AsmOperandClass { 672 let Name = "AVX512RC"; 673} 674def AVX512RC : Operand<i32> { 675 let PrintMethod = "printRoundingControl"; 676 let OperandNamespace = "X86"; 677 let OperandType = "OPERAND_ROUNDING_CONTROL"; 678 let ParserMatchClass = AVX512RCOperand; 679} 680 681// Sign-extended immediate classes. We don't need to define the full lattice 682// here because there is no instruction with an ambiguity between ImmSExti64i32 683// and ImmSExti32i8. 684// 685// The strange ranges come from the fact that the assembler always works with 686// 64-bit immediates, but for a 16-bit target value we want to accept both "-1" 687// (which will be a -1ULL), and "0xFF" (-1 in 16-bits). 688 689// [0, 0x7FFFFFFF] | 690// [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF] 691def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass { 692 let Name = "ImmSExti64i32"; 693} 694 695// [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] | 696// [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] 697def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass { 698 let Name = "ImmSExti16i8"; 699 let SuperClasses = [ImmSExti64i32AsmOperand]; 700} 701 702// [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] | 703// [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] 704def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass { 705 let Name = "ImmSExti32i8"; 706} 707 708// [0, 0x0000007F] | 709// [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] 710def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass { 711 let Name = "ImmSExti64i8"; 712 let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand, 713 ImmSExti64i32AsmOperand]; 714} 715 716// 4-bit immediate used by some XOP instructions 717// [0, 0xF] 718def ImmUnsignedi4AsmOperand : AsmOperandClass { 719 let Name = "ImmUnsignedi4"; 720 let RenderMethod = "addImmOperands"; 721 let DiagnosticType = "InvalidImmUnsignedi4"; 722} 723 724// Unsigned immediate used by SSE/AVX instructions 725// [0, 0xFF] 726// [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] 727def ImmUnsignedi8AsmOperand : AsmOperandClass { 728 let Name = "ImmUnsignedi8"; 729 let RenderMethod = "addImmOperands"; 730} 731 732// A couple of more descriptive operand definitions. 733// 16-bits but only 8 bits are significant. 734def i16i8imm : Operand<i16> { 735 let ParserMatchClass = ImmSExti16i8AsmOperand; 736 let OperandType = "OPERAND_IMMEDIATE"; 737} 738// 32-bits but only 8 bits are significant. 739def i32i8imm : Operand<i32> { 740 let ParserMatchClass = ImmSExti32i8AsmOperand; 741 let OperandType = "OPERAND_IMMEDIATE"; 742} 743 744// 64-bits but only 32 bits are significant. 745def i64i32imm : Operand<i64> { 746 let ParserMatchClass = ImmSExti64i32AsmOperand; 747 let OperandType = "OPERAND_IMMEDIATE"; 748} 749 750// 64-bits but only 8 bits are significant. 751def i64i8imm : Operand<i64> { 752 let ParserMatchClass = ImmSExti64i8AsmOperand; 753 let OperandType = "OPERAND_IMMEDIATE"; 754} 755 756// Unsigned 4-bit immediate used by some XOP instructions. 757def u4imm : Operand<i8> { 758 let PrintMethod = "printU8Imm"; 759 let ParserMatchClass = ImmUnsignedi4AsmOperand; 760 let OperandType = "OPERAND_IMMEDIATE"; 761} 762 763// Unsigned 8-bit immediate used by SSE/AVX instructions. 764def u8imm : Operand<i8> { 765 let PrintMethod = "printU8Imm"; 766 let ParserMatchClass = ImmUnsignedi8AsmOperand; 767 let OperandType = "OPERAND_IMMEDIATE"; 768} 769 770// 16-bit immediate but only 8-bits are significant and they are unsigned. 771// Used by BT instructions. 772def i16u8imm : Operand<i16> { 773 let PrintMethod = "printU8Imm"; 774 let ParserMatchClass = ImmUnsignedi8AsmOperand; 775 let OperandType = "OPERAND_IMMEDIATE"; 776} 777 778// 32-bit immediate but only 8-bits are significant and they are unsigned. 779// Used by some SSE/AVX instructions that use intrinsics. 780def i32u8imm : Operand<i32> { 781 let PrintMethod = "printU8Imm"; 782 let ParserMatchClass = ImmUnsignedi8AsmOperand; 783 let OperandType = "OPERAND_IMMEDIATE"; 784} 785 786// 64-bit immediate but only 8-bits are significant and they are unsigned. 787// Used by BT instructions. 788def i64u8imm : Operand<i64> { 789 let PrintMethod = "printU8Imm"; 790 let ParserMatchClass = ImmUnsignedi8AsmOperand; 791 let OperandType = "OPERAND_IMMEDIATE"; 792} 793 794def lea64_32mem : Operand<i32> { 795 let PrintMethod = "printMemReference"; 796 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG); 797 let ParserMatchClass = X86MemAsmOperand; 798} 799 800// Memory operands that use 64-bit pointers in both ILP32 and LP64. 801def lea64mem : Operand<i64> { 802 let PrintMethod = "printMemReference"; 803 let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm, SEGMENT_REG); 804 let ParserMatchClass = X86MemAsmOperand; 805} 806 807let RenderMethod = "addMaskPairOperands" in { 808 def VK1PairAsmOperand : AsmOperandClass { let Name = "VK1Pair"; } 809 def VK2PairAsmOperand : AsmOperandClass { let Name = "VK2Pair"; } 810 def VK4PairAsmOperand : AsmOperandClass { let Name = "VK4Pair"; } 811 def VK8PairAsmOperand : AsmOperandClass { let Name = "VK8Pair"; } 812 def VK16PairAsmOperand : AsmOperandClass { let Name = "VK16Pair"; } 813} 814 815def VK1Pair : RegisterOperand<VK1PAIR, "printVKPair"> { 816 let ParserMatchClass = VK1PairAsmOperand; 817} 818 819def VK2Pair : RegisterOperand<VK2PAIR, "printVKPair"> { 820 let ParserMatchClass = VK2PairAsmOperand; 821} 822 823def VK4Pair : RegisterOperand<VK4PAIR, "printVKPair"> { 824 let ParserMatchClass = VK4PairAsmOperand; 825} 826 827def VK8Pair : RegisterOperand<VK8PAIR, "printVKPair"> { 828 let ParserMatchClass = VK8PairAsmOperand; 829} 830 831def VK16Pair : RegisterOperand<VK16PAIR, "printVKPair"> { 832 let ParserMatchClass = VK16PairAsmOperand; 833} 834 835//===----------------------------------------------------------------------===// 836// X86 Complex Pattern Definitions. 837// 838 839// Define X86-specific addressing mode. 840def addr : ComplexPattern<iPTR, 5, "selectAddr", [], [SDNPWantParent]>; 841def lea32addr : ComplexPattern<i32, 5, "selectLEAAddr", 842 [add, sub, mul, X86mul_imm, shl, or, xor, frameindex], 843 []>; 844// In 64-bit mode 32-bit LEAs can use RIP-relative addressing. 845def lea64_32addr : ComplexPattern<i32, 5, "selectLEA64_32Addr", 846 [add, sub, mul, X86mul_imm, shl, or, xor, 847 frameindex, X86WrapperRIP], 848 []>; 849 850def tls32addr : ComplexPattern<i32, 5, "selectTLSADDRAddr", 851 [tglobaltlsaddr], []>; 852 853def tls32baseaddr : ComplexPattern<i32, 5, "selectTLSADDRAddr", 854 [tglobaltlsaddr], []>; 855 856def lea64addr : ComplexPattern<i64, 5, "selectLEAAddr", 857 [add, sub, mul, X86mul_imm, shl, or, xor, frameindex, 858 X86WrapperRIP], []>; 859 860def tls64addr : ComplexPattern<i64, 5, "selectTLSADDRAddr", 861 [tglobaltlsaddr], []>; 862 863def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr", 864 [tglobaltlsaddr], []>; 865 866def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>; 867 868// A relocatable immediate is an operand that can be relocated by the linker to 869// an immediate, such as a regular symbol in non-PIC code. 870def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", 871 [X86Wrapper], [], 0>; 872 873//===----------------------------------------------------------------------===// 874// X86 Instruction Predicate Definitions. 875def TruePredicate : Predicate<"true">; 876 877def HasCMOV : Predicate<"Subtarget->canUseCMOV()">; 878def NoCMOV : Predicate<"!Subtarget->canUseCMOV()">; 879 880def HasMMX : Predicate<"Subtarget->hasMMX()">; 881def Has3DNow : Predicate<"Subtarget->hasThreeDNow()">; 882def Has3DNowA : Predicate<"Subtarget->hasThreeDNowA()">; 883def HasSSE1 : Predicate<"Subtarget->hasSSE1()">; 884def UseSSE1 : Predicate<"Subtarget->hasSSE1() && !Subtarget->hasAVX()">; 885def HasSSE2 : Predicate<"Subtarget->hasSSE2()">; 886def UseSSE2 : Predicate<"Subtarget->hasSSE2() && !Subtarget->hasAVX()">; 887def HasSSE3 : Predicate<"Subtarget->hasSSE3()">; 888def UseSSE3 : Predicate<"Subtarget->hasSSE3() && !Subtarget->hasAVX()">; 889def HasSSSE3 : Predicate<"Subtarget->hasSSSE3()">; 890def UseSSSE3 : Predicate<"Subtarget->hasSSSE3() && !Subtarget->hasAVX()">; 891def HasSSE41 : Predicate<"Subtarget->hasSSE41()">; 892def NoSSE41 : Predicate<"!Subtarget->hasSSE41()">; 893def UseSSE41 : Predicate<"Subtarget->hasSSE41() && !Subtarget->hasAVX()">; 894def HasSSE42 : Predicate<"Subtarget->hasSSE42()">; 895def UseSSE42 : Predicate<"Subtarget->hasSSE42() && !Subtarget->hasAVX()">; 896def HasSSE4A : Predicate<"Subtarget->hasSSE4A()">; 897def NoAVX : Predicate<"!Subtarget->hasAVX()">; 898def HasAVX : Predicate<"Subtarget->hasAVX()">; 899def HasAVX2 : Predicate<"Subtarget->hasAVX2()">; 900def HasAVX1Only : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX2()">; 901def HasAVX512 : Predicate<"Subtarget->hasAVX512()">; 902def UseAVX : Predicate<"Subtarget->hasAVX() && !Subtarget->hasAVX512()">; 903def UseAVX2 : Predicate<"Subtarget->hasAVX2() && !Subtarget->hasAVX512()">; 904def NoAVX512 : Predicate<"!Subtarget->hasAVX512()">; 905def HasCDI : Predicate<"Subtarget->hasCDI()">; 906def HasVPOPCNTDQ : Predicate<"Subtarget->hasVPOPCNTDQ()">; 907def HasPFI : Predicate<"Subtarget->hasPFI()">; 908def HasERI : Predicate<"Subtarget->hasERI()">; 909def HasDQI : Predicate<"Subtarget->hasDQI()">; 910def NoDQI : Predicate<"!Subtarget->hasDQI()">; 911def HasBWI : Predicate<"Subtarget->hasBWI()">; 912def NoBWI : Predicate<"!Subtarget->hasBWI()">; 913def HasVLX : Predicate<"Subtarget->hasVLX()">; 914def NoVLX : Predicate<"!Subtarget->hasVLX()">; 915def NoVLX_Or_NoBWI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasBWI()">; 916def NoVLX_Or_NoDQI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasDQI()">; 917def PKU : Predicate<"Subtarget->hasPKU()">; 918def HasVNNI : Predicate<"Subtarget->hasVNNI()">; 919def HasVP2INTERSECT : Predicate<"Subtarget->hasVP2INTERSECT()">; 920def HasBF16 : Predicate<"Subtarget->hasBF16()">; 921def HasFP16 : Predicate<"Subtarget->hasFP16()">; 922def HasAVXVNNI : Predicate <"Subtarget->hasAVXVNNI()">; 923def NoVLX_Or_NoVNNI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVNNI()">; 924 925def HasBITALG : Predicate<"Subtarget->hasBITALG()">; 926def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">; 927def HasAES : Predicate<"Subtarget->hasAES()">; 928def HasVAES : Predicate<"Subtarget->hasVAES()">; 929def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">; 930def HasFXSR : Predicate<"Subtarget->hasFXSR()">; 931def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">; 932def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">; 933def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">; 934def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">; 935def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">; 936def NoVLX_Or_NoVPCLMULQDQ : 937 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">; 938def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">; 939def HasGFNI : Predicate<"Subtarget->hasGFNI()">; 940def HasFMA : Predicate<"Subtarget->hasFMA()">; 941def HasFMA4 : Predicate<"Subtarget->hasFMA4()">; 942def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">; 943def HasXOP : Predicate<"Subtarget->hasXOP()">; 944def HasTBM : Predicate<"Subtarget->hasTBM()">; 945def NoTBM : Predicate<"!Subtarget->hasTBM()">; 946def HasLWP : Predicate<"Subtarget->hasLWP()">; 947def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">; 948def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">; 949def HasF16C : Predicate<"Subtarget->hasF16C()">; 950def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">; 951def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">; 952def HasBMI : Predicate<"Subtarget->hasBMI()">; 953def HasBMI2 : Predicate<"Subtarget->hasBMI2()">; 954def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">; 955def HasVBMI : Predicate<"Subtarget->hasVBMI()">; 956def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">; 957def HasIFMA : Predicate<"Subtarget->hasIFMA()">; 958def HasRTM : Predicate<"Subtarget->hasRTM()">; 959def HasADX : Predicate<"Subtarget->hasADX()">; 960def HasSHA : Predicate<"Subtarget->hasSHA()">; 961def HasSGX : Predicate<"Subtarget->hasSGX()">; 962def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">; 963def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">; 964def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">; 965def HasPrefetchW : Predicate<"Subtarget->hasPrefetchW()">; 966def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">; 967def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">; 968def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">; 969def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">; 970def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">; 971def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">; 972def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">; 973def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">; 974def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">; 975def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">; 976def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">; 977def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">; 978def HasCLWB : Predicate<"Subtarget->hasCLWB()">; 979def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">; 980def HasRDPID : Predicate<"Subtarget->hasRDPID()">; 981def HasRDPRU : Predicate<"Subtarget->hasRDPRU()">; 982def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">; 983def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">; 984def HasCX8 : Predicate<"Subtarget->hasCX8()">; 985def HasCX16 : Predicate<"Subtarget->hasCX16()">; 986def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">; 987def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">; 988def HasKL : Predicate<"Subtarget->hasKL()">; 989def HasWIDEKL : Predicate<"Subtarget->hasWIDEKL()">; 990def HasHRESET : Predicate<"Subtarget->hasHRESET()">; 991def HasSERIALIZE : Predicate<"Subtarget->hasSERIALIZE()">; 992def HasTSXLDTRK : Predicate<"Subtarget->hasTSXLDTRK()">; 993def HasAMXTILE : Predicate<"Subtarget->hasAMXTILE()">; 994def HasAMXBF16 : Predicate<"Subtarget->hasAMXBF16()">; 995def HasAMXINT8 : Predicate<"Subtarget->hasAMXINT8()">; 996def HasUINTR : Predicate<"Subtarget->hasUINTR()">; 997def HasCRC32 : Predicate<"Subtarget->hasCRC32()">; 998def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, 999 AssemblerPredicate<(all_of (not Is64Bit)), "Not 64-bit mode">; 1000def In64BitMode : Predicate<"Subtarget->is64Bit()">, 1001 AssemblerPredicate<(all_of Is64Bit), "64-bit mode">; 1002def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">; 1003def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">; 1004def In16BitMode : Predicate<"Subtarget->is16Bit()">, 1005 AssemblerPredicate<(all_of Is16Bit), "16-bit mode">; 1006def Not16BitMode : Predicate<"!Subtarget->is16Bit()">, 1007 AssemblerPredicate<(all_of (not Is16Bit)), "Not 16-bit mode">; 1008def In32BitMode : Predicate<"Subtarget->is32Bit()">, 1009 AssemblerPredicate<(all_of Is32Bit), "32-bit mode">; 1010def IsWin64 : Predicate<"Subtarget->isTargetWin64()">; 1011def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">; 1012def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||" 1013 "Subtarget->getFrameLowering()->hasFP(*MF)"> { 1014 let RecomputePerFunction = 1; 1015} 1016def IsPS : Predicate<"Subtarget->isTargetPS()">; 1017def NotPS : Predicate<"!Subtarget->isTargetPS()">; 1018def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; 1019def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; 1020def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">; 1021def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">; 1022def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||" 1023 "TM.getCodeModel() == CodeModel::Kernel">; 1024def IsNotPIC : Predicate<"!TM.isPositionIndependent()">; 1025 1026// We could compute these on a per-module basis but doing so requires accessing 1027// the Function object through the <Target>Subtarget and objections were raised 1028// to that (see post-commit review comments for r301750). 1029let RecomputePerFunction = 1 in { 1030 def OptForSize : Predicate<"shouldOptForSize(MF)">; 1031 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">; 1032 def OptForSpeed : Predicate<"!shouldOptForSize(MF)">; 1033 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || " 1034 "shouldOptForSize(MF)">; 1035 def NoSSE41_Or_OptForSize : Predicate<"shouldOptForSize(MF) || " 1036 "!Subtarget->hasSSE41()">; 1037} 1038 1039def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">; 1040def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">; 1041def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">; 1042def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">; 1043def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">; 1044def HasERMSB : Predicate<"Subtarget->hasERMSB()">; 1045def HasFSRM : Predicate<"Subtarget->hasFSRM()">; 1046def HasMFence : Predicate<"Subtarget->hasMFence()">; 1047def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">; 1048def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">; 1049 1050//===----------------------------------------------------------------------===// 1051// X86 Instruction Format Definitions. 1052// 1053 1054include "X86InstrFormats.td" 1055 1056//===----------------------------------------------------------------------===// 1057// Pattern fragments. 1058// 1059 1060// X86 specific condition code. These correspond to CondCode in 1061// X86InstrInfo.h. They must be kept in synch. 1062def X86_COND_O : PatLeaf<(i8 0)>; 1063def X86_COND_NO : PatLeaf<(i8 1)>; 1064def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C 1065def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC 1066def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z 1067def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ 1068def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA 1069def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE 1070def X86_COND_S : PatLeaf<(i8 8)>; 1071def X86_COND_NS : PatLeaf<(i8 9)>; 1072def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE 1073def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO 1074def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE 1075def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL 1076def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG 1077def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE 1078 1079def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>; 1080def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>; 1081def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>; 1082def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 1083def i64timmSExt32 : TImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 1084 1085def i16relocImmSExt8 : PatLeaf<(i16 relocImm), [{ 1086 return isSExtAbsoluteSymbolRef(8, N); 1087}]>; 1088def i32relocImmSExt8 : PatLeaf<(i32 relocImm), [{ 1089 return isSExtAbsoluteSymbolRef(8, N); 1090}]>; 1091def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{ 1092 return isSExtAbsoluteSymbolRef(8, N); 1093}]>; 1094def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{ 1095 return isSExtAbsoluteSymbolRef(32, N); 1096}]>; 1097 1098// If we have multiple users of an immediate, it's much smaller to reuse 1099// the register, rather than encode the immediate in every instruction. 1100// This has the risk of increasing register pressure from stretched live 1101// ranges, however, the immediates should be trivial to rematerialize by 1102// the RA in the event of high register pressure. 1103// TODO : This is currently enabled for stores and binary ops. There are more 1104// cases for which this can be enabled, though this catches the bulk of the 1105// issues. 1106// TODO2 : This should really also be enabled under O2, but there's currently 1107// an issue with RA where we don't pull the constants into their users 1108// when we rematerialize them. I'll follow-up on enabling O2 after we fix that 1109// issue. 1110// TODO3 : This is currently limited to single basic blocks (DAG creation 1111// pulls block immediates to the top and merges them if necessary). 1112// Eventually, it would be nice to allow ConstantHoisting to merge constants 1113// globally for potentially added savings. 1114// 1115def imm_su : PatLeaf<(imm), [{ 1116 return !shouldAvoidImmediateInstFormsForSize(N); 1117}]>; 1118def i64immSExt32_su : PatLeaf<(i64immSExt32), [{ 1119 return !shouldAvoidImmediateInstFormsForSize(N); 1120}]>; 1121 1122def relocImm8_su : PatLeaf<(i8 relocImm), [{ 1123 return !shouldAvoidImmediateInstFormsForSize(N); 1124}]>; 1125def relocImm16_su : PatLeaf<(i16 relocImm), [{ 1126 return !shouldAvoidImmediateInstFormsForSize(N); 1127}]>; 1128def relocImm32_su : PatLeaf<(i32 relocImm), [{ 1129 return !shouldAvoidImmediateInstFormsForSize(N); 1130}]>; 1131 1132def i16relocImmSExt8_su : PatLeaf<(i16relocImmSExt8), [{ 1133 return !shouldAvoidImmediateInstFormsForSize(N); 1134}]>; 1135def i32relocImmSExt8_su : PatLeaf<(i32relocImmSExt8), [{ 1136 return !shouldAvoidImmediateInstFormsForSize(N); 1137}]>; 1138def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{ 1139 return !shouldAvoidImmediateInstFormsForSize(N); 1140}]>; 1141def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{ 1142 return !shouldAvoidImmediateInstFormsForSize(N); 1143}]>; 1144 1145def i16immSExt8_su : PatLeaf<(i16immSExt8), [{ 1146 return !shouldAvoidImmediateInstFormsForSize(N); 1147}]>; 1148def i32immSExt8_su : PatLeaf<(i32immSExt8), [{ 1149 return !shouldAvoidImmediateInstFormsForSize(N); 1150}]>; 1151def i64immSExt8_su : PatLeaf<(i64immSExt8), [{ 1152 return !shouldAvoidImmediateInstFormsForSize(N); 1153}]>; 1154 1155// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit 1156// unsigned field. 1157def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>; 1158 1159def i64immZExt32SExt8 : ImmLeaf<i64, [{ 1160 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm)); 1161}]>; 1162 1163// Helper fragments for loads. 1164 1165// It's safe to fold a zextload/extload from i1 as a regular i8 load. The 1166// upper bits are guaranteed to be zero and we were going to emit a MOV8rm 1167// which might get folded during peephole anyway. 1168def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{ 1169 LoadSDNode *LD = cast<LoadSDNode>(N); 1170 ISD::LoadExtType ExtType = LD->getExtensionType(); 1171 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD || 1172 ExtType == ISD::ZEXTLOAD; 1173}]>; 1174 1175// It's always safe to treat a anyext i16 load as a i32 load if the i16 is 1176// known to be 32-bit aligned or better. Ditto for i8 to i16. 1177def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{ 1178 LoadSDNode *LD = cast<LoadSDNode>(N); 1179 ISD::LoadExtType ExtType = LD->getExtensionType(); 1180 if (ExtType == ISD::NON_EXTLOAD) 1181 return true; 1182 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 1183 return LD->getAlignment() >= 2 && LD->isSimple(); 1184 return false; 1185}]>; 1186 1187def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{ 1188 LoadSDNode *LD = cast<LoadSDNode>(N); 1189 ISD::LoadExtType ExtType = LD->getExtensionType(); 1190 if (ExtType == ISD::NON_EXTLOAD) 1191 return true; 1192 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 1193 return LD->getAlignment() >= 4 && LD->isSimple(); 1194 return false; 1195}]>; 1196 1197def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>; 1198def loadf16 : PatFrag<(ops node:$ptr), (f16 (load node:$ptr))>; 1199def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>; 1200def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>; 1201def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>; 1202def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>; 1203def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 1204 LoadSDNode *Ld = cast<LoadSDNode>(N); 1205 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); 1206}]>; 1207def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 1208 LoadSDNode *Ld = cast<LoadSDNode>(N); 1209 return Subtarget->hasSSEUnalignedMem() || 1210 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); 1211}]>; 1212 1213def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>; 1214def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>; 1215def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>; 1216def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>; 1217def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>; 1218def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>; 1219 1220def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>; 1221def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>; 1222def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>; 1223def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; 1224def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>; 1225def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>; 1226def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>; 1227def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>; 1228def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>; 1229def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>; 1230 1231def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>; 1232def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>; 1233def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>; 1234def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>; 1235def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>; 1236def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>; 1237def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>; 1238def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>; 1239def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>; 1240 1241// We can treat an i8/i16 extending load to i64 as a 32 bit load if its known 1242// to be 4 byte aligned or better. 1243def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{ 1244 LoadSDNode *LD = cast<LoadSDNode>(N); 1245 ISD::LoadExtType ExtType = LD->getExtensionType(); 1246 if (ExtType != ISD::EXTLOAD) 1247 return false; 1248 if (LD->getMemoryVT() == MVT::i32) 1249 return true; 1250 1251 return LD->getAlignment() >= 4 && LD->isSimple(); 1252}]>; 1253 1254 1255// An 'and' node with a single use. 1256def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 1257 return N->hasOneUse(); 1258}]>; 1259// An 'srl' node with a single use. 1260def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{ 1261 return N->hasOneUse(); 1262}]>; 1263// An 'trunc' node with a single use. 1264def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{ 1265 return N->hasOneUse(); 1266}]>; 1267 1268//===----------------------------------------------------------------------===// 1269// Instruction list. 1270// 1271 1272// Nop 1273let hasSideEffects = 0, SchedRW = [WriteNop] in { 1274 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>; 1275 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero), 1276 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable; 1277 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero), 1278 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable; 1279 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero), 1280 "nop{q}\t$zero", []>, TB, NotMemoryFoldable, 1281 Requires<[In64BitMode]>; 1282 // Also allow register so we can assemble/disassemble 1283 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero), 1284 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable; 1285 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero), 1286 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable; 1287 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero), 1288 "nop{q}\t$zero", []>, TB, NotMemoryFoldable, 1289 Requires<[In64BitMode]>; 1290} 1291 1292 1293// Constructing a stack frame. 1294def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl), 1295 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>; 1296 1297let SchedRW = [WriteALU] in { 1298let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in 1299def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>, 1300 Requires<[Not64BitMode]>; 1301 1302let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in 1303def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>, 1304 Requires<[In64BitMode]>; 1305} // SchedRW 1306 1307//===----------------------------------------------------------------------===// 1308// Miscellaneous Instructions. 1309// 1310 1311let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1, 1312 SchedRW = [WriteSystem] in 1313 def Int_eh_sjlj_setup_dispatch 1314 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>; 1315 1316let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in { 1317let mayLoad = 1, SchedRW = [WriteLoad] in { 1318def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>, 1319 OpSize16; 1320def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>, 1321 OpSize32, Requires<[Not64BitMode]>; 1322// Long form for the disassembler. 1323let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1324def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>, 1325 OpSize16, NotMemoryFoldable; 1326def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>, 1327 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable; 1328} // isCodeGenOnly = 1, ForceDisassemble = 1 1329} // mayLoad, SchedRW 1330let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in { 1331def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>, 1332 OpSize16; 1333def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>, 1334 OpSize32, Requires<[Not64BitMode]>; 1335} // mayStore, mayLoad, SchedRW 1336 1337let mayStore = 1, SchedRW = [WriteStore] in { 1338def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>, 1339 OpSize16; 1340def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>, 1341 OpSize32, Requires<[Not64BitMode]>; 1342// Long form for the disassembler. 1343let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1344def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>, 1345 OpSize16, NotMemoryFoldable; 1346def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>, 1347 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable; 1348} // isCodeGenOnly = 1, ForceDisassemble = 1 1349 1350def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm), 1351 "push{w}\t$imm", []>, OpSize16; 1352def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), 1353 "push{w}\t$imm", []>, OpSize16; 1354 1355def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm), 1356 "push{l}\t$imm", []>, OpSize32, 1357 Requires<[Not64BitMode]>; 1358def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), 1359 "push{l}\t$imm", []>, OpSize32, 1360 Requires<[Not64BitMode]>; 1361} // mayStore, SchedRW 1362 1363let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in { 1364def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>, 1365 OpSize16; 1366def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>, 1367 OpSize32, Requires<[Not64BitMode]>; 1368} // mayLoad, mayStore, SchedRW 1369 1370} 1371 1372let mayLoad = 1, mayStore = 1, usesCustomInserter = 1, 1373 SchedRW = [WriteRMW], Defs = [ESP] in { 1374 let Uses = [ESP] in 1375 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins), 1376 [(set GR32:$dst, (int_x86_flags_read_u32))]>, 1377 Requires<[Not64BitMode]>; 1378 1379 let Uses = [RSP] in 1380 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins), 1381 [(set GR64:$dst, (int_x86_flags_read_u64))]>, 1382 Requires<[In64BitMode]>; 1383} 1384 1385let mayLoad = 1, mayStore = 1, usesCustomInserter = 1, 1386 SchedRW = [WriteRMW] in { 1387 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in 1388 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src), 1389 [(int_x86_flags_write_u32 GR32:$src)]>, 1390 Requires<[Not64BitMode]>; 1391 1392 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in 1393 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src), 1394 [(int_x86_flags_write_u64 GR64:$src)]>, 1395 Requires<[In64BitMode]>; 1396} 1397 1398let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0, 1399 SchedRW = [WriteLoad] in { 1400def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16; 1401def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32, 1402 Requires<[Not64BitMode]>; 1403} 1404 1405let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0, 1406 SchedRW = [WriteStore] in { 1407def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16; 1408def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32, 1409 Requires<[Not64BitMode]>; 1410} 1411 1412let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in { 1413let mayLoad = 1, SchedRW = [WriteLoad] in { 1414def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>, 1415 OpSize32, Requires<[In64BitMode]>; 1416// Long form for the disassembler. 1417let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1418def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>, 1419 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable; 1420} // isCodeGenOnly = 1, ForceDisassemble = 1 1421} // mayLoad, SchedRW 1422let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in 1423def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>, 1424 OpSize32, Requires<[In64BitMode]>; 1425let mayStore = 1, SchedRW = [WriteStore] in { 1426def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>, 1427 OpSize32, Requires<[In64BitMode]>; 1428// Long form for the disassembler. 1429let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1430def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>, 1431 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable; 1432} // isCodeGenOnly = 1, ForceDisassemble = 1 1433} // mayStore, SchedRW 1434let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in { 1435def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>, 1436 OpSize32, Requires<[In64BitMode]>; 1437} // mayLoad, mayStore, SchedRW 1438} 1439 1440let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1, 1441 SchedRW = [WriteStore] in { 1442def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm), 1443 "push{q}\t$imm", []>, OpSize32, 1444 Requires<[In64BitMode]>; 1445def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm), 1446 "push{q}\t$imm", []>, OpSize32, 1447 Requires<[In64BitMode]>; 1448} 1449 1450let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in 1451def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, 1452 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>; 1453let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in 1454def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>, 1455 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>; 1456 1457let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP], 1458 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in { 1459def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>, 1460 OpSize32, Requires<[Not64BitMode]>; 1461def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>, 1462 OpSize16, Requires<[Not64BitMode]>; 1463} 1464let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], 1465 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in { 1466def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>, 1467 OpSize32, Requires<[Not64BitMode]>; 1468def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>, 1469 OpSize16, Requires<[Not64BitMode]>; 1470} 1471 1472let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in { 1473// This instruction is a consequence of BSWAP32r observing operand size. The 1474// encoding is valid, but the behavior is undefined. 1475let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 1476def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src), 1477 "bswap{w}\t$dst", []>, OpSize16, TB; 1478// GR32 = bswap GR32 1479def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src), 1480 "bswap{l}\t$dst", 1481 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB; 1482 1483let SchedRW = [WriteBSWAP64] in 1484def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), 1485 "bswap{q}\t$dst", 1486 [(set GR64:$dst, (bswap GR64:$src))]>, TB; 1487} // Constraints = "$src = $dst", SchedRW 1488 1489// Bit scan instructions. 1490let Defs = [EFLAGS] in { 1491def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1492 "bsf{w}\t{$src, $dst|$dst, $src}", 1493 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>, 1494 PS, OpSize16, Sched<[WriteBSF]>; 1495def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1496 "bsf{w}\t{$src, $dst|$dst, $src}", 1497 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>, 1498 PS, OpSize16, Sched<[WriteBSFLd]>; 1499def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1500 "bsf{l}\t{$src, $dst|$dst, $src}", 1501 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>, 1502 PS, OpSize32, Sched<[WriteBSF]>; 1503def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1504 "bsf{l}\t{$src, $dst|$dst, $src}", 1505 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>, 1506 PS, OpSize32, Sched<[WriteBSFLd]>; 1507def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1508 "bsf{q}\t{$src, $dst|$dst, $src}", 1509 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>, 1510 PS, Sched<[WriteBSF]>; 1511def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1512 "bsf{q}\t{$src, $dst|$dst, $src}", 1513 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>, 1514 PS, Sched<[WriteBSFLd]>; 1515 1516def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1517 "bsr{w}\t{$src, $dst|$dst, $src}", 1518 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>, 1519 PS, OpSize16, Sched<[WriteBSR]>; 1520def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1521 "bsr{w}\t{$src, $dst|$dst, $src}", 1522 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>, 1523 PS, OpSize16, Sched<[WriteBSRLd]>; 1524def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1525 "bsr{l}\t{$src, $dst|$dst, $src}", 1526 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>, 1527 PS, OpSize32, Sched<[WriteBSR]>; 1528def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1529 "bsr{l}\t{$src, $dst|$dst, $src}", 1530 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>, 1531 PS, OpSize32, Sched<[WriteBSRLd]>; 1532def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1533 "bsr{q}\t{$src, $dst|$dst, $src}", 1534 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>, 1535 PS, Sched<[WriteBSR]>; 1536def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1537 "bsr{q}\t{$src, $dst|$dst, $src}", 1538 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>, 1539 PS, Sched<[WriteBSRLd]>; 1540} // Defs = [EFLAGS] 1541 1542let SchedRW = [WriteMicrocoded] in { 1543let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in { 1544def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src), 1545 "movsb\t{$src, $dst|$dst, $src}", []>; 1546def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src), 1547 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16; 1548def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src), 1549 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32; 1550def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src), 1551 "movsq\t{$src, $dst|$dst, $src}", []>, 1552 Requires<[In64BitMode]>; 1553} 1554 1555let Defs = [EDI], Uses = [AL,EDI,DF] in 1556def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst), 1557 "stosb\t{%al, $dst|$dst, al}", []>; 1558let Defs = [EDI], Uses = [AX,EDI,DF] in 1559def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst), 1560 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16; 1561let Defs = [EDI], Uses = [EAX,EDI,DF] in 1562def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst), 1563 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32; 1564let Defs = [RDI], Uses = [RAX,RDI,DF] in 1565def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst), 1566 "stosq\t{%rax, $dst|$dst, rax}", []>, 1567 Requires<[In64BitMode]>; 1568 1569let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in 1570def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst), 1571 "scasb\t{$dst, %al|al, $dst}", []>; 1572let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in 1573def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst), 1574 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16; 1575let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in 1576def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst), 1577 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32; 1578let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in 1579def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst), 1580 "scasq\t{$dst, %rax|rax, $dst}", []>, 1581 Requires<[In64BitMode]>; 1582 1583let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in { 1584def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src), 1585 "cmpsb\t{$dst, $src|$src, $dst}", []>; 1586def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src), 1587 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16; 1588def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src), 1589 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32; 1590def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src), 1591 "cmpsq\t{$dst, $src|$src, $dst}", []>, 1592 Requires<[In64BitMode]>; 1593} 1594} // SchedRW 1595 1596//===----------------------------------------------------------------------===// 1597// Move Instructions. 1598// 1599let SchedRW = [WriteMove] in { 1600let hasSideEffects = 0, isMoveReg = 1 in { 1601def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src), 1602 "mov{b}\t{$src, $dst|$dst, $src}", []>; 1603def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 1604 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16; 1605def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), 1606 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32; 1607def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), 1608 "mov{q}\t{$src, $dst|$dst, $src}", []>; 1609} 1610 1611let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { 1612def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src), 1613 "mov{b}\t{$src, $dst|$dst, $src}", 1614 [(set GR8:$dst, imm:$src)]>; 1615def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src), 1616 "mov{w}\t{$src, $dst|$dst, $src}", 1617 [(set GR16:$dst, imm:$src)]>, OpSize16; 1618def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src), 1619 "mov{l}\t{$src, $dst|$dst, $src}", 1620 [(set GR32:$dst, imm:$src)]>, OpSize32; 1621def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src), 1622 "mov{q}\t{$src, $dst|$dst, $src}", 1623 [(set GR64:$dst, i64immSExt32:$src)]>; 1624} 1625let isReMaterializable = 1, isMoveImm = 1 in { 1626def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src), 1627 "movabs{q}\t{$src, $dst|$dst, $src}", 1628 [(set GR64:$dst, imm:$src)]>; 1629} 1630 1631// Longer forms that use a ModR/M byte. Needed for disassembler 1632let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in { 1633def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src), 1634 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1635 FoldGenData<"MOV8ri">; 1636def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src), 1637 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16, 1638 FoldGenData<"MOV16ri">; 1639def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src), 1640 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32, 1641 FoldGenData<"MOV32ri">; 1642} 1643} // SchedRW 1644 1645let SchedRW = [WriteStore] in { 1646def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src), 1647 "mov{b}\t{$src, $dst|$dst, $src}", 1648 [(store (i8 imm_su:$src), addr:$dst)]>; 1649def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src), 1650 "mov{w}\t{$src, $dst|$dst, $src}", 1651 [(store (i16 imm_su:$src), addr:$dst)]>, OpSize16; 1652def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src), 1653 "mov{l}\t{$src, $dst|$dst, $src}", 1654 [(store (i32 imm_su:$src), addr:$dst)]>, OpSize32; 1655def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src), 1656 "mov{q}\t{$src, $dst|$dst, $src}", 1657 [(store i64immSExt32_su:$src, addr:$dst)]>, 1658 Requires<[In64BitMode]>; 1659} // SchedRW 1660 1661def : Pat<(i32 relocImm:$src), (MOV32ri relocImm:$src)>; 1662def : Pat<(i64 relocImm:$src), (MOV64ri relocImm:$src)>; 1663 1664def : Pat<(store (i8 relocImm8_su:$src), addr:$dst), 1665 (MOV8mi addr:$dst, relocImm8_su:$src)>; 1666def : Pat<(store (i16 relocImm16_su:$src), addr:$dst), 1667 (MOV16mi addr:$dst, relocImm16_su:$src)>; 1668def : Pat<(store (i32 relocImm32_su:$src), addr:$dst), 1669 (MOV32mi addr:$dst, relocImm32_su:$src)>; 1670def : Pat<(store (i64 i64relocImmSExt32_su:$src), addr:$dst), 1671 (MOV64mi32 addr:$dst, i64immSExt32_su:$src)>; 1672 1673let hasSideEffects = 0 in { 1674 1675/// Memory offset versions of moves. The immediate is an address mode sized 1676/// offset from the segment base. 1677let SchedRW = [WriteALU] in { 1678let mayLoad = 1 in { 1679let Defs = [AL] in 1680def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src), 1681 "mov{b}\t{$src, %al|al, $src}", []>, 1682 AdSize32; 1683let Defs = [AX] in 1684def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src), 1685 "mov{w}\t{$src, %ax|ax, $src}", []>, 1686 OpSize16, AdSize32; 1687let Defs = [EAX] in 1688def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src), 1689 "mov{l}\t{$src, %eax|eax, $src}", []>, 1690 OpSize32, AdSize32; 1691let Defs = [RAX] in 1692def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src), 1693 "mov{q}\t{$src, %rax|rax, $src}", []>, 1694 AdSize32; 1695 1696let Defs = [AL] in 1697def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src), 1698 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16; 1699let Defs = [AX] in 1700def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src), 1701 "mov{w}\t{$src, %ax|ax, $src}", []>, 1702 OpSize16, AdSize16; 1703let Defs = [EAX] in 1704def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src), 1705 "mov{l}\t{$src, %eax|eax, $src}", []>, 1706 AdSize16, OpSize32; 1707} // mayLoad 1708let mayStore = 1 in { 1709let Uses = [AL] in 1710def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst), 1711 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32; 1712let Uses = [AX] in 1713def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst), 1714 "mov{w}\t{%ax, $dst|$dst, ax}", []>, 1715 OpSize16, AdSize32; 1716let Uses = [EAX] in 1717def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst), 1718 "mov{l}\t{%eax, $dst|$dst, eax}", []>, 1719 OpSize32, AdSize32; 1720let Uses = [RAX] in 1721def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst), 1722 "mov{q}\t{%rax, $dst|$dst, rax}", []>, 1723 AdSize32; 1724 1725let Uses = [AL] in 1726def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst), 1727 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16; 1728let Uses = [AX] in 1729def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst), 1730 "mov{w}\t{%ax, $dst|$dst, ax}", []>, 1731 OpSize16, AdSize16; 1732let Uses = [EAX] in 1733def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst), 1734 "mov{l}\t{%eax, $dst|$dst, eax}", []>, 1735 OpSize32, AdSize16; 1736} // mayStore 1737 1738// These forms all have full 64-bit absolute addresses in their instructions 1739// and use the movabs mnemonic to indicate this specific form. 1740let mayLoad = 1 in { 1741let Defs = [AL] in 1742def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src), 1743 "movabs{b}\t{$src, %al|al, $src}", []>, 1744 AdSize64; 1745let Defs = [AX] in 1746def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src), 1747 "movabs{w}\t{$src, %ax|ax, $src}", []>, 1748 OpSize16, AdSize64; 1749let Defs = [EAX] in 1750def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src), 1751 "movabs{l}\t{$src, %eax|eax, $src}", []>, 1752 OpSize32, AdSize64; 1753let Defs = [RAX] in 1754def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src), 1755 "movabs{q}\t{$src, %rax|rax, $src}", []>, 1756 AdSize64; 1757} // mayLoad 1758 1759let mayStore = 1 in { 1760let Uses = [AL] in 1761def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst), 1762 "movabs{b}\t{%al, $dst|$dst, al}", []>, 1763 AdSize64; 1764let Uses = [AX] in 1765def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst), 1766 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, 1767 OpSize16, AdSize64; 1768let Uses = [EAX] in 1769def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst), 1770 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, 1771 OpSize32, AdSize64; 1772let Uses = [RAX] in 1773def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst), 1774 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, 1775 AdSize64; 1776} // mayStore 1777} // SchedRW 1778} // hasSideEffects = 0 1779 1780let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, 1781 SchedRW = [WriteMove], isMoveReg = 1 in { 1782def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src), 1783 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1784 FoldGenData<"MOV8rr">; 1785def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1786 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16, 1787 FoldGenData<"MOV16rr">; 1788def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1789 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32, 1790 FoldGenData<"MOV32rr">; 1791def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1792 "mov{q}\t{$src, $dst|$dst, $src}", []>, 1793 FoldGenData<"MOV64rr">; 1794} 1795 1796// Reversed version with ".s" suffix for GAS compatibility. 1797def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}", 1798 (MOV8rr_REV GR8:$dst, GR8:$src), 0>; 1799def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}", 1800 (MOV16rr_REV GR16:$dst, GR16:$src), 0>; 1801def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}", 1802 (MOV32rr_REV GR32:$dst, GR32:$src), 0>; 1803def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}", 1804 (MOV64rr_REV GR64:$dst, GR64:$src), 0>; 1805def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1806 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">; 1807def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1808 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">; 1809def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1810 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">; 1811def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1812 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">; 1813 1814let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in { 1815def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src), 1816 "mov{b}\t{$src, $dst|$dst, $src}", 1817 [(set GR8:$dst, (loadi8 addr:$src))]>; 1818def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1819 "mov{w}\t{$src, $dst|$dst, $src}", 1820 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16; 1821def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1822 "mov{l}\t{$src, $dst|$dst, $src}", 1823 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32; 1824def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1825 "mov{q}\t{$src, $dst|$dst, $src}", 1826 [(set GR64:$dst, (load addr:$src))]>; 1827} 1828 1829let SchedRW = [WriteStore] in { 1830def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src), 1831 "mov{b}\t{$src, $dst|$dst, $src}", 1832 [(store GR8:$src, addr:$dst)]>; 1833def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 1834 "mov{w}\t{$src, $dst|$dst, $src}", 1835 [(store GR16:$src, addr:$dst)]>, OpSize16; 1836def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 1837 "mov{l}\t{$src, $dst|$dst, $src}", 1838 [(store GR32:$src, addr:$dst)]>, OpSize32; 1839def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 1840 "mov{q}\t{$src, $dst|$dst, $src}", 1841 [(store GR64:$src, addr:$dst)]>; 1842} // SchedRW 1843 1844// Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so 1845// that they can be used for copying and storing h registers, which can't be 1846// encoded when a REX prefix is present. 1847let isCodeGenOnly = 1 in { 1848let hasSideEffects = 0, isMoveReg = 1 in 1849def MOV8rr_NOREX : I<0x88, MRMDestReg, 1850 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src), 1851 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1852 Sched<[WriteMove]>; 1853let mayStore = 1, hasSideEffects = 0 in 1854def MOV8mr_NOREX : I<0x88, MRMDestMem, 1855 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src), 1856 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1857 Sched<[WriteStore]>; 1858let mayLoad = 1, hasSideEffects = 0, 1859 canFoldAsLoad = 1, isReMaterializable = 1 in 1860def MOV8rm_NOREX : I<0x8A, MRMSrcMem, 1861 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src), 1862 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1863 Sched<[WriteLoad]>; 1864} 1865 1866 1867// Condition code ops, incl. set if equal/not equal/... 1868let SchedRW = [WriteLAHFSAHF] in { 1869let Defs = [EFLAGS], Uses = [AH], hasSideEffects = 0 in 1870def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>, // flags = AH 1871 Requires<[HasLAHFSAHF]>; 1872let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in 1873def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags 1874 Requires<[HasLAHFSAHF]>; 1875} // SchedRW 1876 1877//===----------------------------------------------------------------------===// 1878// Bit tests instructions: BT, BTS, BTR, BTC. 1879 1880let Defs = [EFLAGS] in { 1881let SchedRW = [WriteBitTest] in { 1882def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), 1883 "bt{w}\t{$src2, $src1|$src1, $src2}", 1884 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>, 1885 OpSize16, TB, NotMemoryFoldable; 1886def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2), 1887 "bt{l}\t{$src2, $src1|$src1, $src2}", 1888 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>, 1889 OpSize32, TB, NotMemoryFoldable; 1890def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), 1891 "bt{q}\t{$src2, $src1|$src1, $src2}", 1892 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB, 1893 NotMemoryFoldable; 1894} // SchedRW 1895 1896// Unlike with the register+register form, the memory+register form of the 1897// bt instruction does not ignore the high bits of the index. From ISel's 1898// perspective, this is pretty bizarre. Make these instructions disassembly 1899// only for now. These instructions are also slow on modern CPUs so that's 1900// another reason to avoid generating them. 1901 1902let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in { 1903 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 1904 "bt{w}\t{$src2, $src1|$src1, $src2}", 1905 []>, OpSize16, TB, NotMemoryFoldable; 1906 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 1907 "bt{l}\t{$src2, $src1|$src1, $src2}", 1908 []>, OpSize32, TB, NotMemoryFoldable; 1909 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 1910 "bt{q}\t{$src2, $src1|$src1, $src2}", 1911 []>, TB, NotMemoryFoldable; 1912} 1913 1914let SchedRW = [WriteBitTest] in { 1915def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2), 1916 "bt{w}\t{$src2, $src1|$src1, $src2}", 1917 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>, 1918 OpSize16, TB; 1919def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2), 1920 "bt{l}\t{$src2, $src1|$src1, $src2}", 1921 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>, 1922 OpSize32, TB; 1923def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2), 1924 "bt{q}\t{$src2, $src1|$src1, $src2}", 1925 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB; 1926} // SchedRW 1927 1928// Note that these instructions aren't slow because that only applies when the 1929// other operand is in a register. When it's an immediate, bt is still fast. 1930let SchedRW = [WriteBitTestImmLd] in { 1931def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 1932 "bt{w}\t{$src2, $src1|$src1, $src2}", 1933 [(set EFLAGS, (X86bt (loadi16 addr:$src1), 1934 imm:$src2))]>, 1935 OpSize16, TB; 1936def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 1937 "bt{l}\t{$src2, $src1|$src1, $src2}", 1938 [(set EFLAGS, (X86bt (loadi32 addr:$src1), 1939 imm:$src2))]>, 1940 OpSize32, TB; 1941def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 1942 "bt{q}\t{$src2, $src1|$src1, $src2}", 1943 [(set EFLAGS, (X86bt (loadi64 addr:$src1), 1944 imm:$src2))]>, TB, 1945 Requires<[In64BitMode]>; 1946} // SchedRW 1947 1948let hasSideEffects = 0 in { 1949let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1950def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 1951 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, 1952 OpSize16, TB, NotMemoryFoldable; 1953def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 1954 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, 1955 OpSize32, TB, NotMemoryFoldable; 1956def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 1957 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1958 NotMemoryFoldable; 1959} // SchedRW 1960 1961let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 1962def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 1963 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, 1964 OpSize16, TB, NotMemoryFoldable; 1965def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 1966 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, 1967 OpSize32, TB, NotMemoryFoldable; 1968def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 1969 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1970 NotMemoryFoldable; 1971} 1972 1973let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1974def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 1975 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 1976def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 1977 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 1978def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 1979 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 1980} // SchedRW 1981 1982let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 1983def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 1984 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 1985def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 1986 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 1987def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 1988 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1989 Requires<[In64BitMode]>; 1990} 1991 1992let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1993def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 1994 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 1995 OpSize16, TB, NotMemoryFoldable; 1996def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 1997 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 1998 OpSize32, TB, NotMemoryFoldable; 1999def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 2000 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2001 NotMemoryFoldable; 2002} // SchedRW 2003 2004let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 2005def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 2006 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2007 OpSize16, TB, NotMemoryFoldable; 2008def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 2009 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2010 OpSize32, TB, NotMemoryFoldable; 2011def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 2012 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2013 NotMemoryFoldable; 2014} 2015 2016let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2017def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 2018 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2019 OpSize16, TB; 2020def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 2021 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2022 OpSize32, TB; 2023def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 2024 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2025} // SchedRW 2026 2027let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 2028def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 2029 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2030 OpSize16, TB; 2031def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 2032 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2033 OpSize32, TB; 2034def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 2035 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2036 Requires<[In64BitMode]>; 2037} 2038 2039let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2040def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 2041 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, 2042 OpSize16, TB, NotMemoryFoldable; 2043def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 2044 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, 2045 OpSize32, TB, NotMemoryFoldable; 2046def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 2047 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2048 NotMemoryFoldable; 2049} // SchedRW 2050 2051let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 2052def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 2053 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, 2054 OpSize16, TB, NotMemoryFoldable; 2055def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 2056 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, 2057 OpSize32, TB, NotMemoryFoldable; 2058def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 2059 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2060 NotMemoryFoldable; 2061} 2062 2063let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2064def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 2065 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 2066def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 2067 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 2068def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 2069 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2070} // SchedRW 2071 2072let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 2073def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 2074 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 2075def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 2076 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 2077def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 2078 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2079 Requires<[In64BitMode]>; 2080} 2081} // hasSideEffects = 0 2082} // Defs = [EFLAGS] 2083 2084 2085//===----------------------------------------------------------------------===// 2086// Atomic support 2087// 2088 2089// Atomic swap. These are just normal xchg instructions. But since a memory 2090// operand is referenced, the atomicity is ensured. 2091multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> { 2092 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in { 2093 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst), 2094 (ins GR8:$val, i8mem:$ptr), 2095 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"), 2096 [(set 2097 GR8:$dst, 2098 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>; 2099 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst), 2100 (ins GR16:$val, i16mem:$ptr), 2101 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"), 2102 [(set 2103 GR16:$dst, 2104 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>, 2105 OpSize16; 2106 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst), 2107 (ins GR32:$val, i32mem:$ptr), 2108 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"), 2109 [(set 2110 GR32:$dst, 2111 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>, 2112 OpSize32; 2113 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst), 2114 (ins GR64:$val, i64mem:$ptr), 2115 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"), 2116 [(set 2117 GR64:$dst, 2118 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>; 2119 } 2120} 2121 2122defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable; 2123 2124// Swap between registers. 2125let SchedRW = [WriteXCHG] in { 2126let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in { 2127def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2), 2128 (ins GR8:$src1, GR8:$src2), 2129 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable; 2130def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2), 2131 (ins GR16:$src1, GR16:$src2), 2132 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>, 2133 OpSize16, NotMemoryFoldable; 2134def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2), 2135 (ins GR32:$src1, GR32:$src2), 2136 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>, 2137 OpSize32, NotMemoryFoldable; 2138def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2), 2139 (ins GR64:$src1 ,GR64:$src2), 2140 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable; 2141} 2142 2143// Swap between EAX and other registers. 2144let Constraints = "$src = $dst", hasSideEffects = 0 in { 2145let Uses = [AX], Defs = [AX] in 2146def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src), 2147 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16; 2148let Uses = [EAX], Defs = [EAX] in 2149def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src), 2150 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32; 2151let Uses = [RAX], Defs = [RAX] in 2152def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), 2153 "xchg{q}\t{$src, %rax|rax, $src}", []>; 2154} 2155} // SchedRW 2156 2157let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2", 2158 Defs = [EFLAGS], SchedRW = [WriteXCHG] in { 2159def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2), 2160 (ins GR8:$src1, GR8:$src2), 2161 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB; 2162def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2), 2163 (ins GR16:$src1, GR16:$src2), 2164 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16; 2165def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2), 2166 (ins GR32:$src1, GR32:$src2), 2167 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32; 2168def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2), 2169 (ins GR64:$src1, GR64:$src2), 2170 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2171} // SchedRW 2172 2173let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst", 2174 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in { 2175def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst), 2176 (ins GR8:$val, i8mem:$ptr), 2177 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB; 2178def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst), 2179 (ins GR16:$val, i16mem:$ptr), 2180 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB, 2181 OpSize16; 2182def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst), 2183 (ins GR32:$val, i32mem:$ptr), 2184 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB, 2185 OpSize32; 2186def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst), 2187 (ins GR64:$val, i64mem:$ptr), 2188 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB; 2189 2190} 2191 2192let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in { 2193let Defs = [AL, EFLAGS], Uses = [AL] in 2194def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src), 2195 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB, 2196 NotMemoryFoldable; 2197let Defs = [AX, EFLAGS], Uses = [AX] in 2198def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 2199 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, 2200 NotMemoryFoldable; 2201let Defs = [EAX, EFLAGS], Uses = [EAX] in 2202def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), 2203 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, 2204 NotMemoryFoldable; 2205let Defs = [RAX, EFLAGS], Uses = [RAX] in 2206def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), 2207 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB, 2208 NotMemoryFoldable; 2209} // SchedRW, hasSideEffects 2210 2211let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1, 2212 hasSideEffects = 0 in { 2213let Defs = [AL, EFLAGS], Uses = [AL] in 2214def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src), 2215 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB, 2216 NotMemoryFoldable; 2217let Defs = [AX, EFLAGS], Uses = [AX] in 2218def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2219 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, 2220 NotMemoryFoldable; 2221let Defs = [EAX, EFLAGS], Uses = [EAX] in 2222def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2223 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, 2224 NotMemoryFoldable; 2225let Defs = [RAX, EFLAGS], Uses = [RAX] in 2226def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2227 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB, 2228 NotMemoryFoldable; 2229 2230let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in 2231def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst), 2232 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCX8]>; 2233 2234let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in 2235// NOTE: In64BitMode check needed for the AssemblerPredicate. 2236def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst), 2237 "cmpxchg16b\t$dst", []>, 2238 TB, Requires<[HasCX16,In64BitMode]>; 2239} // SchedRW, mayLoad, mayStore, hasSideEffects 2240 2241 2242// Lock instruction prefix 2243let SchedRW = [WriteMicrocoded] in 2244def LOCK_PREFIX : I<0xF0, PrefixByte, (outs), (ins), "lock", []>; 2245 2246let SchedRW = [WriteNop] in { 2247 2248// Rex64 instruction prefix 2249def REX64_PREFIX : I<0x48, PrefixByte, (outs), (ins), "rex64", []>, 2250 Requires<[In64BitMode]>; 2251 2252// Data16 instruction prefix 2253def DATA16_PREFIX : I<0x66, PrefixByte, (outs), (ins), "data16", []>; 2254} // SchedRW 2255 2256// Repeat string operation instruction prefixes 2257let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in { 2258// Repeat (used with INS, OUTS, MOVS, LODS and STOS) 2259def REP_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "rep", []>; 2260// Repeat while not equal (used with CMPS and SCAS) 2261def REPNE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "repne", []>; 2262} 2263 2264// String manipulation instructions 2265let SchedRW = [WriteMicrocoded] in { 2266let Defs = [AL,ESI], Uses = [ESI,DF] in 2267def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src), 2268 "lodsb\t{$src, %al|al, $src}", []>; 2269let Defs = [AX,ESI], Uses = [ESI,DF] in 2270def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src), 2271 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16; 2272let Defs = [EAX,ESI], Uses = [ESI,DF] in 2273def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src), 2274 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32; 2275let Defs = [RAX,ESI], Uses = [ESI,DF] in 2276def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src), 2277 "lodsq\t{$src, %rax|rax, $src}", []>, 2278 Requires<[In64BitMode]>; 2279} 2280 2281let SchedRW = [WriteSystem] in { 2282let Defs = [ESI], Uses = [DX,ESI,DF] in { 2283def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src), 2284 "outsb\t{$src, %dx|dx, $src}", []>; 2285def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src), 2286 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16; 2287def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src), 2288 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32; 2289} 2290 2291let Defs = [EDI], Uses = [DX,EDI,DF] in { 2292def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst), 2293 "insb\t{%dx, $dst|$dst, dx}", []>; 2294def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst), 2295 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16; 2296def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst), 2297 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32; 2298} 2299} 2300 2301// EFLAGS management instructions. 2302let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in { 2303def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>; 2304def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>; 2305def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>; 2306} 2307 2308// DF management instructions. 2309let SchedRW = [WriteALU], Defs = [DF] in { 2310def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>; 2311def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>; 2312} 2313 2314// Table lookup instructions 2315let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in 2316def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>; 2317 2318let SchedRW = [WriteMicrocoded] in { 2319// ASCII Adjust After Addition 2320let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2321def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>, 2322 Requires<[Not64BitMode]>; 2323 2324// ASCII Adjust AX Before Division 2325let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2326def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src), 2327 "aad\t$src", []>, Requires<[Not64BitMode]>; 2328 2329// ASCII Adjust AX After Multiply 2330let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2331def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src), 2332 "aam\t$src", []>, Requires<[Not64BitMode]>; 2333 2334// ASCII Adjust AL After Subtraction - sets 2335let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2336def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>, 2337 Requires<[Not64BitMode]>; 2338 2339// Decimal Adjust AL after Addition 2340let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in 2341def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>, 2342 Requires<[Not64BitMode]>; 2343 2344// Decimal Adjust AL after Subtraction 2345let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in 2346def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>, 2347 Requires<[Not64BitMode]>; 2348} // SchedRW 2349 2350let SchedRW = [WriteSystem] in { 2351// Check Array Index Against Bounds 2352// Note: "bound" does not have reversed operands in at&t syntax. 2353def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2354 "bound\t$dst, $src", []>, OpSize16, 2355 Requires<[Not64BitMode]>; 2356def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2357 "bound\t$dst, $src", []>, OpSize32, 2358 Requires<[Not64BitMode]>; 2359 2360// Adjust RPL Field of Segment Selector 2361def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 2362 "arpl\t{$src, $dst|$dst, $src}", []>, 2363 Requires<[Not64BitMode]>, NotMemoryFoldable; 2364let mayStore = 1 in 2365def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2366 "arpl\t{$src, $dst|$dst, $src}", []>, 2367 Requires<[Not64BitMode]>, NotMemoryFoldable; 2368} // SchedRW 2369 2370//===----------------------------------------------------------------------===// 2371// MOVBE Instructions 2372// 2373let Predicates = [HasMOVBE] in { 2374 let SchedRW = [WriteALULd] in { 2375 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2376 "movbe{w}\t{$src, $dst|$dst, $src}", 2377 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>, 2378 OpSize16, T8PS; 2379 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2380 "movbe{l}\t{$src, $dst|$dst, $src}", 2381 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>, 2382 OpSize32, T8PS; 2383 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2384 "movbe{q}\t{$src, $dst|$dst, $src}", 2385 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>, 2386 T8PS; 2387 } 2388 let SchedRW = [WriteStore] in { 2389 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2390 "movbe{w}\t{$src, $dst|$dst, $src}", 2391 [(store (bswap GR16:$src), addr:$dst)]>, 2392 OpSize16, T8PS; 2393 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2394 "movbe{l}\t{$src, $dst|$dst, $src}", 2395 [(store (bswap GR32:$src), addr:$dst)]>, 2396 OpSize32, T8PS; 2397 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2398 "movbe{q}\t{$src, $dst|$dst, $src}", 2399 [(store (bswap GR64:$src), addr:$dst)]>, 2400 T8PS; 2401 } 2402} 2403 2404//===----------------------------------------------------------------------===// 2405// RDRAND Instruction 2406// 2407let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 2408 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins), 2409 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>, 2410 OpSize16, PS; 2411 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins), 2412 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>, 2413 OpSize32, PS; 2414 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins), 2415 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>, 2416 PS; 2417} 2418 2419//===----------------------------------------------------------------------===// 2420// RDSEED Instruction 2421// 2422let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 2423 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst", 2424 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS; 2425 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst", 2426 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS; 2427 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst", 2428 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS; 2429} 2430 2431//===----------------------------------------------------------------------===// 2432// LZCNT Instruction 2433// 2434let Predicates = [HasLZCNT], Defs = [EFLAGS] in { 2435 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 2436 "lzcnt{w}\t{$src, $dst|$dst, $src}", 2437 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, 2438 XS, OpSize16, Sched<[WriteLZCNT]>; 2439 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2440 "lzcnt{w}\t{$src, $dst|$dst, $src}", 2441 [(set GR16:$dst, (ctlz (loadi16 addr:$src))), 2442 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>; 2443 2444 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 2445 "lzcnt{l}\t{$src, $dst|$dst, $src}", 2446 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, 2447 XS, OpSize32, Sched<[WriteLZCNT]>; 2448 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2449 "lzcnt{l}\t{$src, $dst|$dst, $src}", 2450 [(set GR32:$dst, (ctlz (loadi32 addr:$src))), 2451 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>; 2452 2453 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 2454 "lzcnt{q}\t{$src, $dst|$dst, $src}", 2455 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>, 2456 XS, Sched<[WriteLZCNT]>; 2457 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2458 "lzcnt{q}\t{$src, $dst|$dst, $src}", 2459 [(set GR64:$dst, (ctlz (loadi64 addr:$src))), 2460 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>; 2461} 2462 2463//===----------------------------------------------------------------------===// 2464// BMI Instructions 2465// 2466let Predicates = [HasBMI], Defs = [EFLAGS] in { 2467 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 2468 "tzcnt{w}\t{$src, $dst|$dst, $src}", 2469 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, 2470 XS, OpSize16, Sched<[WriteTZCNT]>; 2471 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2472 "tzcnt{w}\t{$src, $dst|$dst, $src}", 2473 [(set GR16:$dst, (cttz (loadi16 addr:$src))), 2474 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>; 2475 2476 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 2477 "tzcnt{l}\t{$src, $dst|$dst, $src}", 2478 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, 2479 XS, OpSize32, Sched<[WriteTZCNT]>; 2480 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2481 "tzcnt{l}\t{$src, $dst|$dst, $src}", 2482 [(set GR32:$dst, (cttz (loadi32 addr:$src))), 2483 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>; 2484 2485 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 2486 "tzcnt{q}\t{$src, $dst|$dst, $src}", 2487 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>, 2488 XS, Sched<[WriteTZCNT]>; 2489 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2490 "tzcnt{q}\t{$src, $dst|$dst, $src}", 2491 [(set GR64:$dst, (cttz (loadi64 addr:$src))), 2492 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>; 2493} 2494 2495multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM, 2496 RegisterClass RC, X86MemOperand x86memop, 2497 X86FoldableSchedWrite sched> { 2498let hasSideEffects = 0 in { 2499 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src), 2500 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, 2501 T8PS, VEX_4V, Sched<[sched]>; 2502 let mayLoad = 1 in 2503 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src), 2504 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, 2505 T8PS, VEX_4V, Sched<[sched.Folded]>; 2506} 2507} 2508 2509let Predicates = [HasBMI], Defs = [EFLAGS] in { 2510 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>; 2511 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, VEX_W; 2512 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>; 2513 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, VEX_W; 2514 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>; 2515 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, VEX_W; 2516} 2517 2518//===----------------------------------------------------------------------===// 2519// Pattern fragments to auto generate BMI instructions. 2520//===----------------------------------------------------------------------===// 2521 2522def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2523 (X86or_flag node:$lhs, node:$rhs), [{ 2524 return hasNoCarryFlagUses(SDValue(N, 1)); 2525}]>; 2526 2527def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2528 (X86xor_flag node:$lhs, node:$rhs), [{ 2529 return hasNoCarryFlagUses(SDValue(N, 1)); 2530}]>; 2531 2532def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2533 (X86and_flag node:$lhs, node:$rhs), [{ 2534 return hasNoCarryFlagUses(SDValue(N, 1)); 2535}]>; 2536 2537let Predicates = [HasBMI] in { 2538 // FIXME: patterns for the load versions are not implemented 2539 def : Pat<(and GR32:$src, (add GR32:$src, -1)), 2540 (BLSR32rr GR32:$src)>; 2541 def : Pat<(and GR64:$src, (add GR64:$src, -1)), 2542 (BLSR64rr GR64:$src)>; 2543 2544 def : Pat<(xor GR32:$src, (add GR32:$src, -1)), 2545 (BLSMSK32rr GR32:$src)>; 2546 def : Pat<(xor GR64:$src, (add GR64:$src, -1)), 2547 (BLSMSK64rr GR64:$src)>; 2548 2549 def : Pat<(and GR32:$src, (ineg GR32:$src)), 2550 (BLSI32rr GR32:$src)>; 2551 def : Pat<(and GR64:$src, (ineg GR64:$src)), 2552 (BLSI64rr GR64:$src)>; 2553 2554 // Versions to match flag producing ops. 2555 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)), 2556 (BLSR32rr GR32:$src)>; 2557 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)), 2558 (BLSR64rr GR64:$src)>; 2559 2560 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)), 2561 (BLSMSK32rr GR32:$src)>; 2562 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)), 2563 (BLSMSK64rr GR64:$src)>; 2564 2565 def : Pat<(and_flag_nocf GR32:$src, (ineg GR32:$src)), 2566 (BLSI32rr GR32:$src)>; 2567 def : Pat<(and_flag_nocf GR64:$src, (ineg GR64:$src)), 2568 (BLSI64rr GR64:$src)>; 2569} 2570 2571multiclass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC, 2572 X86MemOperand x86memop, SDNode OpNode, 2573 PatFrag ld_frag, X86FoldableSchedWrite Sched> { 2574 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2575 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2576 [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>, 2577 T8PS, VEX, Sched<[Sched]>; 2578 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2), 2579 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2580 [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)), 2581 (implicit EFLAGS)]>, T8PS, VEX, 2582 Sched<[Sched.Folded, 2583 // x86memop:$src1 2584 ReadDefault, ReadDefault, ReadDefault, ReadDefault, 2585 ReadDefault, 2586 // RC:$src2 2587 Sched.ReadAfterFold]>; 2588} 2589 2590let Predicates = [HasBMI], Defs = [EFLAGS] in { 2591 defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem, 2592 X86bextr, loadi32, WriteBEXTR>; 2593 defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem, 2594 X86bextr, loadi64, WriteBEXTR>, VEX_W; 2595} 2596 2597multiclass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC, 2598 X86MemOperand x86memop, SDNode Int, 2599 PatFrag ld_frag, X86FoldableSchedWrite Sched> { 2600 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2601 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2602 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>, 2603 T8PS, VEX, Sched<[Sched]>; 2604 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2), 2605 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2606 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)), 2607 (implicit EFLAGS)]>, T8PS, VEX, 2608 Sched<[Sched.Folded, 2609 // x86memop:$src1 2610 ReadDefault, ReadDefault, ReadDefault, ReadDefault, 2611 ReadDefault, 2612 // RC:$src2 2613 Sched.ReadAfterFold]>; 2614} 2615 2616let Predicates = [HasBMI2], Defs = [EFLAGS] in { 2617 defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem, 2618 X86bzhi, loadi32, WriteBZHI>; 2619 defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem, 2620 X86bzhi, loadi64, WriteBZHI>, VEX_W; 2621} 2622 2623def CountTrailingOnes : SDNodeXForm<imm, [{ 2624 // Count the trailing ones in the immediate. 2625 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N)); 2626}]>; 2627 2628def BEXTRMaskXForm : SDNodeXForm<imm, [{ 2629 unsigned Length = countTrailingOnes(N->getZExtValue()); 2630 return getI32Imm(Length << 8, SDLoc(N)); 2631}]>; 2632 2633def AndMask64 : ImmLeaf<i64, [{ 2634 return isMask_64(Imm) && !isUInt<32>(Imm); 2635}]>; 2636 2637// Use BEXTR for 64-bit 'and' with large immediate 'mask'. 2638let Predicates = [HasBMI, NoBMI2, NoTBM] in { 2639 def : Pat<(and GR64:$src, AndMask64:$mask), 2640 (BEXTR64rr GR64:$src, 2641 (SUBREG_TO_REG (i64 0), 2642 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 2643 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2644 (BEXTR64rm addr:$src, 2645 (SUBREG_TO_REG (i64 0), 2646 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 2647} 2648 2649// Use BZHI for 64-bit 'and' with large immediate 'mask'. 2650let Predicates = [HasBMI2, NoTBM] in { 2651 def : Pat<(and GR64:$src, AndMask64:$mask), 2652 (BZHI64rr GR64:$src, 2653 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2654 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 2655 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2656 (BZHI64rm addr:$src, 2657 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2658 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 2659} 2660 2661multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC, 2662 X86MemOperand x86memop, SDNode OpNode, 2663 PatFrag ld_frag> { 2664 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2665 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2666 [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>, 2667 VEX_4V, Sched<[WriteALU]>; 2668 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2), 2669 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2670 [(set RC:$dst, (OpNode RC:$src1, (ld_frag addr:$src2)))]>, 2671 VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>; 2672} 2673 2674let Predicates = [HasBMI2] in { 2675 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem, 2676 X86pdep, loadi32>, T8XD; 2677 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem, 2678 X86pdep, loadi64>, T8XD, VEX_W; 2679 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem, 2680 X86pext, loadi32>, T8XS; 2681 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem, 2682 X86pext, loadi64>, T8XS, VEX_W; 2683} 2684 2685//===----------------------------------------------------------------------===// 2686// TBM Instructions 2687// 2688let Predicates = [HasTBM], Defs = [EFLAGS] in { 2689 2690multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr, 2691 X86MemOperand x86memop, PatFrag ld_frag, 2692 SDNode OpNode, Operand immtype, 2693 SDPatternOperator immoperator, 2694 X86FoldableSchedWrite Sched> { 2695 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl), 2696 !strconcat(OpcodeStr, 2697 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 2698 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>, 2699 XOP, XOPA, Sched<[Sched]>; 2700 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst), 2701 (ins x86memop:$src1, immtype:$cntl), 2702 !strconcat(OpcodeStr, 2703 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 2704 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>, 2705 XOP, XOPA, Sched<[Sched.Folded]>; 2706} 2707 2708defm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32, 2709 X86bextri, i32imm, timm, WriteBEXTR>; 2710let ImmT = Imm32S in 2711defm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64, 2712 X86bextri, i64i32imm, 2713 i64timmSExt32, WriteBEXTR>, VEX_W; 2714 2715multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem, 2716 RegisterClass RC, string OpcodeStr, 2717 X86MemOperand x86memop, X86FoldableSchedWrite Sched> { 2718let hasSideEffects = 0 in { 2719 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src), 2720 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 2721 XOP_4V, XOP9, Sched<[Sched]>; 2722 let mayLoad = 1 in 2723 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src), 2724 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 2725 XOP_4V, XOP9, Sched<[Sched.Folded]>; 2726} 2727} 2728 2729multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr, 2730 X86FoldableSchedWrite Sched, 2731 Format FormReg, Format FormMem> { 2732 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}", 2733 i32mem, Sched>; 2734 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}", 2735 i64mem, Sched>, VEX_W; 2736} 2737 2738defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>; 2739defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>; 2740defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>; 2741defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>; 2742defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>; 2743defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>; 2744defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>; 2745defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>; 2746defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>; 2747} // HasTBM, EFLAGS 2748 2749// Use BEXTRI for 64-bit 'and' with large immediate 'mask'. 2750let Predicates = [HasTBM] in { 2751 def : Pat<(and GR64:$src, AndMask64:$mask), 2752 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>; 2753 2754 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2755 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>; 2756} 2757 2758//===----------------------------------------------------------------------===// 2759// Lightweight Profiling Instructions 2760 2761let Predicates = [HasLWP], SchedRW = [WriteSystem] in { 2762 2763def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src", 2764 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9; 2765def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst", 2766 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9; 2767 2768def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src", 2769 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, VEX_W; 2770def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst", 2771 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, VEX_W; 2772 2773multiclass lwpins_intr<RegisterClass RC> { 2774 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 2775 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2776 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>, 2777 XOP_4V, XOPA; 2778 let mayLoad = 1 in 2779 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 2780 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2781 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>, 2782 XOP_4V, XOPA; 2783} 2784 2785let Defs = [EFLAGS] in { 2786 defm LWPINS32 : lwpins_intr<GR32>; 2787 defm LWPINS64 : lwpins_intr<GR64>, VEX_W; 2788} // EFLAGS 2789 2790multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> { 2791 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 2792 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2793 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA; 2794 let mayLoad = 1 in 2795 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 2796 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2797 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>, 2798 XOP_4V, XOPA; 2799} 2800 2801defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>; 2802defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W; 2803 2804} // HasLWP, SchedRW 2805 2806//===----------------------------------------------------------------------===// 2807// MONITORX/MWAITX Instructions 2808// 2809let SchedRW = [ WriteSystem ] in { 2810 let Uses = [ EAX, ECX, EDX ] in 2811 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 2812 TB, Requires<[ HasMWAITX, Not64BitMode ]>; 2813 let Uses = [ RAX, ECX, EDX ] in 2814 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 2815 TB, Requires<[ HasMWAITX, In64BitMode ]>; 2816 2817 let Uses = [ ECX, EAX, EBX ] in { 2818 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", 2819 []>, TB, Requires<[ HasMWAITX ]>; 2820 } 2821} // SchedRW 2822 2823def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>, 2824 Requires<[ Not64BitMode ]>; 2825def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>, 2826 Requires<[ In64BitMode ]>; 2827 2828def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORX32rrr)>, 2829 Requires<[ Not64BitMode ]>; 2830def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORX64rrr)>, 2831 Requires<[ In64BitMode ]>; 2832 2833//===----------------------------------------------------------------------===// 2834// WAITPKG Instructions 2835// 2836let SchedRW = [WriteSystem] in { 2837 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src), 2838 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>, 2839 XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>; 2840 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src), 2841 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>, 2842 XS, AdSize32, Requires<[HasWAITPKG]>; 2843 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src), 2844 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>, 2845 XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>; 2846 let Uses = [EAX, EDX], Defs = [EFLAGS] in { 2847 def UMWAIT : I<0xAE, MRM6r, 2848 (outs), (ins GR32orGR64:$src), "umwait\t$src", 2849 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>, 2850 XD, Requires<[HasWAITPKG]>; 2851 def TPAUSE : I<0xAE, MRM6r, 2852 (outs), (ins GR32orGR64:$src), "tpause\t$src", 2853 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>, 2854 PD, Requires<[HasWAITPKG]>; 2855 } 2856} // SchedRW 2857 2858//===----------------------------------------------------------------------===// 2859// MOVDIRI - Move doubleword/quadword as direct store 2860// 2861let SchedRW = [WriteStore] in { 2862def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2863 "movdiri\t{$src, $dst|$dst, $src}", 2864 [(int_x86_directstore32 addr:$dst, GR32:$src)]>, 2865 T8PS, Requires<[HasMOVDIRI]>; 2866def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2867 "movdiri\t{$src, $dst|$dst, $src}", 2868 [(int_x86_directstore64 addr:$dst, GR64:$src)]>, 2869 T8PS, Requires<[In64BitMode, HasMOVDIRI]>; 2870} // SchedRW 2871 2872//===----------------------------------------------------------------------===// 2873// MOVDIR64B - Move 64 bytes as direct store 2874// 2875let SchedRW = [WriteStore] in { 2876def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2877 "movdir64b\t{$src, $dst|$dst, $src}", []>, 2878 T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>; 2879def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2880 "movdir64b\t{$src, $dst|$dst, $src}", 2881 [(int_x86_movdir64b GR32:$dst, addr:$src)]>, 2882 T8PD, AdSize32, Requires<[HasMOVDIR64B]>; 2883def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2884 "movdir64b\t{$src, $dst|$dst, $src}", 2885 [(int_x86_movdir64b GR64:$dst, addr:$src)]>, 2886 T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>; 2887} // SchedRW 2888 2889//===----------------------------------------------------------------------===// 2890// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity 2891// 2892let SchedRW = [WriteStore], Defs = [EFLAGS] in { 2893 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2894 "enqcmd\t{$src, $dst|$dst, $src}", 2895 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>, 2896 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 2897 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2898 "enqcmd\t{$src, $dst|$dst, $src}", 2899 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>, 2900 T8XD, AdSize32, Requires<[HasENQCMD]>; 2901 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2902 "enqcmd\t{$src, $dst|$dst, $src}", 2903 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>, 2904 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 2905 2906 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2907 "enqcmds\t{$src, $dst|$dst, $src}", 2908 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>, 2909 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 2910 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2911 "enqcmds\t{$src, $dst|$dst, $src}", 2912 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>, 2913 T8XS, AdSize32, Requires<[HasENQCMD]>; 2914 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2915 "enqcmds\t{$src, $dst|$dst, $src}", 2916 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>, 2917 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 2918} 2919 2920//===----------------------------------------------------------------------===// 2921// CLZERO Instruction 2922// 2923let SchedRW = [WriteLoad] in { 2924 let Uses = [EAX] in 2925 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 2926 TB, Requires<[HasCLZERO, Not64BitMode]>; 2927 let Uses = [RAX] in 2928 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 2929 TB, Requires<[HasCLZERO, In64BitMode]>; 2930} // SchedRW 2931 2932def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>; 2933def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>; 2934 2935//===----------------------------------------------------------------------===// 2936// INVLPGB Instruction 2937// OPCODE 0F 01 FE 2938// 2939let SchedRW = [WriteSystem] in { 2940 let Uses = [EAX, EDX] in 2941 def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins), 2942 "invlpgb", []>, 2943 PS, Requires<[Not64BitMode]>; 2944 let Uses = [RAX, EDX] in 2945 def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins), 2946 "invlpgb", []>, 2947 PS, Requires<[In64BitMode]>; 2948} // SchedRW 2949 2950def : InstAlias<"invlpgb\t{%eax, %edx|eax, edx}", (INVLPGB32)>, Requires<[Not64BitMode]>; 2951def : InstAlias<"invlpgb\t{%rax, %edx|rax, edx}", (INVLPGB64)>, Requires<[In64BitMode]>; 2952 2953//===----------------------------------------------------------------------===// 2954// TLBSYNC Instruction 2955// OPCODE 0F 01 FF 2956// 2957let SchedRW = [WriteSystem] in { 2958 def TLBSYNC : I<0x01, MRM_FF, (outs), (ins), 2959 "tlbsync", []>, 2960 PS, Requires<[]>; 2961} // SchedRW 2962 2963//===----------------------------------------------------------------------===// 2964// HRESET Instruction 2965// 2966let Uses = [EAX], SchedRW = [WriteSystem] in 2967 def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>, 2968 Requires<[HasHRESET]>, TAXS; 2969 2970//===----------------------------------------------------------------------===// 2971// SERIALIZE Instruction 2972// 2973let SchedRW = [WriteSystem] in 2974 def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize", 2975 [(int_x86_serialize)]>, PS, 2976 Requires<[HasSERIALIZE]>; 2977 2978//===----------------------------------------------------------------------===// 2979// TSXLDTRK - TSX Suspend Load Address Tracking 2980// 2981let Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in { 2982 def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk", 2983 [(int_x86_xsusldtrk)]>, XD; 2984 def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk", 2985 [(int_x86_xresldtrk)]>, XD; 2986} 2987 2988//===----------------------------------------------------------------------===// 2989// UINTR Instructions 2990// 2991let Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in { 2992 def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret", 2993 []>, XS; 2994 def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui", 2995 [(int_x86_clui)]>, XS; 2996 def STUI : I<0x01, MRM_EF, (outs), (ins), "stui", 2997 [(int_x86_stui)]>, XS; 2998 2999 def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg", 3000 [(int_x86_senduipi GR64:$arg)]>, XS; 3001 3002 let Defs = [EFLAGS] in 3003 def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui", 3004 [(set EFLAGS, (X86testui))]>, XS; 3005} 3006 3007//===----------------------------------------------------------------------===// 3008// Pattern fragments to auto generate TBM instructions. 3009//===----------------------------------------------------------------------===// 3010 3011let Predicates = [HasTBM] in { 3012 // FIXME: patterns for the load versions are not implemented 3013 def : Pat<(and GR32:$src, (add GR32:$src, 1)), 3014 (BLCFILL32rr GR32:$src)>; 3015 def : Pat<(and GR64:$src, (add GR64:$src, 1)), 3016 (BLCFILL64rr GR64:$src)>; 3017 3018 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))), 3019 (BLCI32rr GR32:$src)>; 3020 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))), 3021 (BLCI64rr GR64:$src)>; 3022 3023 // Extra patterns because opt can optimize the above patterns to this. 3024 def : Pat<(or GR32:$src, (sub -2, GR32:$src)), 3025 (BLCI32rr GR32:$src)>; 3026 def : Pat<(or GR64:$src, (sub -2, GR64:$src)), 3027 (BLCI64rr GR64:$src)>; 3028 3029 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)), 3030 (BLCIC32rr GR32:$src)>; 3031 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)), 3032 (BLCIC64rr GR64:$src)>; 3033 3034 def : Pat<(xor GR32:$src, (add GR32:$src, 1)), 3035 (BLCMSK32rr GR32:$src)>; 3036 def : Pat<(xor GR64:$src, (add GR64:$src, 1)), 3037 (BLCMSK64rr GR64:$src)>; 3038 3039 def : Pat<(or GR32:$src, (add GR32:$src, 1)), 3040 (BLCS32rr GR32:$src)>; 3041 def : Pat<(or GR64:$src, (add GR64:$src, 1)), 3042 (BLCS64rr GR64:$src)>; 3043 3044 def : Pat<(or GR32:$src, (add GR32:$src, -1)), 3045 (BLSFILL32rr GR32:$src)>; 3046 def : Pat<(or GR64:$src, (add GR64:$src, -1)), 3047 (BLSFILL64rr GR64:$src)>; 3048 3049 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)), 3050 (BLSIC32rr GR32:$src)>; 3051 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)), 3052 (BLSIC64rr GR64:$src)>; 3053 3054 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)), 3055 (T1MSKC32rr GR32:$src)>; 3056 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)), 3057 (T1MSKC64rr GR64:$src)>; 3058 3059 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)), 3060 (TZMSK32rr GR32:$src)>; 3061 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)), 3062 (TZMSK64rr GR64:$src)>; 3063 3064 // Patterns to match flag producing ops. 3065 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, 1)), 3066 (BLCFILL32rr GR32:$src)>; 3067 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, 1)), 3068 (BLCFILL64rr GR64:$src)>; 3069 3070 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))), 3071 (BLCI32rr GR32:$src)>; 3072 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))), 3073 (BLCI64rr GR64:$src)>; 3074 3075 // Extra patterns because opt can optimize the above patterns to this. 3076 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)), 3077 (BLCI32rr GR32:$src)>; 3078 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)), 3079 (BLCI64rr GR64:$src)>; 3080 3081 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 3082 (BLCIC32rr GR32:$src)>; 3083 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 3084 (BLCIC64rr GR64:$src)>; 3085 3086 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)), 3087 (BLCMSK32rr GR32:$src)>; 3088 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)), 3089 (BLCMSK64rr GR64:$src)>; 3090 3091 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)), 3092 (BLCS32rr GR32:$src)>; 3093 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)), 3094 (BLCS64rr GR64:$src)>; 3095 3096 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)), 3097 (BLSFILL32rr GR32:$src)>; 3098 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)), 3099 (BLSFILL64rr GR64:$src)>; 3100 3101 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 3102 (BLSIC32rr GR32:$src)>; 3103 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 3104 (BLSIC64rr GR64:$src)>; 3105 3106 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 3107 (T1MSKC32rr GR32:$src)>; 3108 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 3109 (T1MSKC64rr GR64:$src)>; 3110 3111 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 3112 (TZMSK32rr GR32:$src)>; 3113 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 3114 (TZMSK64rr GR64:$src)>; 3115} // HasTBM 3116 3117//===----------------------------------------------------------------------===// 3118// Memory Instructions 3119// 3120 3121let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in 3122def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src), 3123 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD; 3124 3125let Predicates = [HasCLWB], SchedRW = [WriteLoad] in 3126def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", 3127 [(int_x86_clwb addr:$src)]>, PD; 3128 3129let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in 3130def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src", 3131 [(int_x86_cldemote addr:$src)]>, PS; 3132 3133//===----------------------------------------------------------------------===// 3134// Subsystems. 3135//===----------------------------------------------------------------------===// 3136 3137include "X86InstrArithmetic.td" 3138include "X86InstrCMovSetCC.td" 3139include "X86InstrExtension.td" 3140include "X86InstrControl.td" 3141include "X86InstrShiftRotate.td" 3142 3143// X87 Floating Point Stack. 3144include "X86InstrFPStack.td" 3145 3146// SIMD support (SSE, MMX and AVX) 3147include "X86InstrFragmentsSIMD.td" 3148 3149// FMA - Fused Multiply-Add support (requires FMA) 3150include "X86InstrFMA.td" 3151 3152// XOP 3153include "X86InstrXOP.td" 3154 3155// SSE, MMX and 3DNow! vector support. 3156include "X86InstrSSE.td" 3157include "X86InstrAVX512.td" 3158include "X86InstrMMX.td" 3159include "X86Instr3DNow.td" 3160 3161include "X86InstrVMX.td" 3162include "X86InstrSVM.td" 3163include "X86InstrSNP.td" 3164 3165include "X86InstrTSX.td" 3166include "X86InstrSGX.td" 3167 3168include "X86InstrTDX.td" 3169 3170// Key Locker instructions 3171include "X86InstrKL.td" 3172 3173// AMX instructions 3174include "X86InstrAMX.td" 3175 3176// System instructions. 3177include "X86InstrSystem.td" 3178 3179// Compiler Pseudo Instructions and Pat Patterns 3180include "X86InstrCompiler.td" 3181include "X86InstrVecCompiler.td" 3182 3183//===----------------------------------------------------------------------===// 3184// Assembler Mnemonic Aliases 3185//===----------------------------------------------------------------------===// 3186 3187def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>; 3188def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>; 3189def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>; 3190 3191def : MnemonicAlias<"cbw", "cbtw", "att">; 3192def : MnemonicAlias<"cwde", "cwtl", "att">; 3193def : MnemonicAlias<"cwd", "cwtd", "att">; 3194def : MnemonicAlias<"cdq", "cltd", "att">; 3195def : MnemonicAlias<"cdqe", "cltq", "att">; 3196def : MnemonicAlias<"cqo", "cqto", "att">; 3197 3198// In 64-bit mode lret maps to lretl; it is not ambiguous with lretq. 3199def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>; 3200def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>; 3201 3202def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>; 3203def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>; 3204 3205def : MnemonicAlias<"loopz", "loope">; 3206def : MnemonicAlias<"loopnz", "loopne">; 3207 3208def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>; 3209def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>; 3210def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>; 3211def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>; 3212def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>; 3213def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>; 3214def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>; 3215def : MnemonicAlias<"popfd", "popfl", "att">; 3216def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In32BitMode]>; 3217def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In64BitMode]>; 3218 3219// FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in 3220// all modes. However: "push (addr)" and "push $42" should default to 3221// pushl/pushq depending on the current mode. Similar for "pop %bx" 3222def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>; 3223def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>; 3224def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>; 3225def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>; 3226def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>; 3227def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>; 3228def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>; 3229def : MnemonicAlias<"pushfd", "pushfl", "att">; 3230def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In32BitMode]>; 3231def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In64BitMode]>; 3232 3233def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>; 3234def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>; 3235def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>; 3236def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>; 3237def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>; 3238def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>; 3239 3240def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>; 3241def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>; 3242def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>; 3243def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>; 3244 3245def : MnemonicAlias<"repe", "rep">; 3246def : MnemonicAlias<"repz", "rep">; 3247def : MnemonicAlias<"repnz", "repne">; 3248 3249def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>; 3250def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>; 3251def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>; 3252 3253// Apply 'ret' behavior to 'retn' 3254def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>; 3255def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>; 3256def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>; 3257def : MnemonicAlias<"retn", "ret", "intel">; 3258 3259def : MnemonicAlias<"sal", "shl", "intel">; 3260def : MnemonicAlias<"salb", "shlb", "att">; 3261def : MnemonicAlias<"salw", "shlw", "att">; 3262def : MnemonicAlias<"sall", "shll", "att">; 3263def : MnemonicAlias<"salq", "shlq", "att">; 3264 3265def : MnemonicAlias<"smovb", "movsb", "att">; 3266def : MnemonicAlias<"smovw", "movsw", "att">; 3267def : MnemonicAlias<"smovl", "movsl", "att">; 3268def : MnemonicAlias<"smovq", "movsq", "att">; 3269 3270def : MnemonicAlias<"ud2a", "ud2", "att">; 3271def : MnemonicAlias<"ud2bw", "ud1w", "att">; 3272def : MnemonicAlias<"ud2bl", "ud1l", "att">; 3273def : MnemonicAlias<"ud2bq", "ud1q", "att">; 3274def : MnemonicAlias<"verrw", "verr", "att">; 3275 3276// MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release' 3277def : MnemonicAlias<"acquire", "xacquire", "intel">; 3278def : MnemonicAlias<"release", "xrelease", "intel">; 3279 3280// System instruction aliases. 3281def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>; 3282def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>; 3283def : MnemonicAlias<"sysret", "sysretl", "att">; 3284def : MnemonicAlias<"sysexit", "sysexitl", "att">; 3285 3286def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>; 3287def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>; 3288def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>; 3289def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>; 3290def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>; 3291def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>; 3292def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>; 3293def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>; 3294def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>; 3295def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>; 3296def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>; 3297def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>; 3298def : MnemonicAlias<"lgdt", "lgdtw", "intel">, Requires<[In16BitMode]>; 3299def : MnemonicAlias<"lgdt", "lgdtd", "intel">, Requires<[In32BitMode]>; 3300def : MnemonicAlias<"lidt", "lidtw", "intel">, Requires<[In16BitMode]>; 3301def : MnemonicAlias<"lidt", "lidtd", "intel">, Requires<[In32BitMode]>; 3302def : MnemonicAlias<"sgdt", "sgdtw", "intel">, Requires<[In16BitMode]>; 3303def : MnemonicAlias<"sgdt", "sgdtd", "intel">, Requires<[In32BitMode]>; 3304def : MnemonicAlias<"sidt", "sidtw", "intel">, Requires<[In16BitMode]>; 3305def : MnemonicAlias<"sidt", "sidtd", "intel">, Requires<[In32BitMode]>; 3306 3307 3308// Floating point stack aliases. 3309def : MnemonicAlias<"fcmovz", "fcmove", "att">; 3310def : MnemonicAlias<"fcmova", "fcmovnbe", "att">; 3311def : MnemonicAlias<"fcmovnae", "fcmovb", "att">; 3312def : MnemonicAlias<"fcmovna", "fcmovbe", "att">; 3313def : MnemonicAlias<"fcmovae", "fcmovnb", "att">; 3314def : MnemonicAlias<"fcomip", "fcompi">; 3315def : MnemonicAlias<"fildq", "fildll", "att">; 3316def : MnemonicAlias<"fistpq", "fistpll", "att">; 3317def : MnemonicAlias<"fisttpq", "fisttpll", "att">; 3318def : MnemonicAlias<"fldcww", "fldcw", "att">; 3319def : MnemonicAlias<"fnstcww", "fnstcw", "att">; 3320def : MnemonicAlias<"fnstsww", "fnstsw", "att">; 3321def : MnemonicAlias<"fucomip", "fucompi">; 3322def : MnemonicAlias<"fwait", "wait">; 3323 3324def : MnemonicAlias<"fxsaveq", "fxsave64", "att">; 3325def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">; 3326def : MnemonicAlias<"xsaveq", "xsave64", "att">; 3327def : MnemonicAlias<"xrstorq", "xrstor64", "att">; 3328def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">; 3329def : MnemonicAlias<"xrstorsq", "xrstors64", "att">; 3330def : MnemonicAlias<"xsavecq", "xsavec64", "att">; 3331def : MnemonicAlias<"xsavesq", "xsaves64", "att">; 3332 3333class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond, 3334 string VariantName> 3335 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix), 3336 !strconcat(Prefix, NewCond, Suffix), VariantName>; 3337 3338/// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of 3339/// MnemonicAlias's that canonicalize the condition code in a mnemonic, for 3340/// example "setz" -> "sete". 3341multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix, 3342 string V = ""> { 3343 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb 3344 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete 3345 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe 3346 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae 3347 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae 3348 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle 3349 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge 3350 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne 3351 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp 3352 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp 3353 3354 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb 3355 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta 3356 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl 3357 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg 3358} 3359 3360// Aliases for set<CC> 3361defm : IntegerCondCodeMnemonicAlias<"set", "">; 3362// Aliases for j<CC> 3363defm : IntegerCondCodeMnemonicAlias<"j", "">; 3364// Aliases for cmov<CC>{w,l,q} 3365defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">; 3366defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">; 3367defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">; 3368// No size suffix for intel-style asm. 3369defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">; 3370 3371 3372//===----------------------------------------------------------------------===// 3373// Assembler Instruction Aliases 3374//===----------------------------------------------------------------------===// 3375 3376// aad/aam default to base 10 if no operand is specified. 3377def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>; 3378def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>; 3379 3380// Disambiguate the mem/imm form of bt-without-a-suffix as btl. 3381// Likewise for btc/btr/bts. 3382def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}", 3383 (BT32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3384def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}", 3385 (BTC32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3386def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}", 3387 (BTR32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3388def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}", 3389 (BTS32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3390 3391// clr aliases. 3392def : InstAlias<"clr{b}\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>; 3393def : InstAlias<"clr{w}\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>; 3394def : InstAlias<"clr{l}\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>; 3395def : InstAlias<"clr{q}\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>; 3396 3397// lods aliases. Accept the destination being omitted because it's implicit 3398// in the mnemonic, or the mnemonic suffix being omitted because it's implicit 3399// in the destination. 3400def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>; 3401def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>; 3402def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>; 3403def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>; 3404def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>; 3405def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>; 3406def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>; 3407def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>; 3408def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0, "intel">; 3409def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0, "intel">; 3410def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0, "intel">; 3411def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3412 3413 3414// stos aliases. Accept the source being omitted because it's implicit in 3415// the mnemonic, or the mnemonic suffix being omitted because it's implicit 3416// in the source. 3417def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>; 3418def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>; 3419def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>; 3420def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3421def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>; 3422def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>; 3423def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>; 3424def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3425def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0, "intel">; 3426def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0, "intel">; 3427def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0, "intel">; 3428def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>; 3429 3430 3431// scas aliases. Accept the destination being omitted because it's implicit 3432// in the mnemonic, or the mnemonic suffix being omitted because it's implicit 3433// in the destination. 3434def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>; 3435def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>; 3436def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>; 3437def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3438def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>; 3439def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>; 3440def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>; 3441def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3442def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0, "intel">; 3443def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0, "intel">; 3444def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0, "intel">; 3445def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>; 3446 3447// cmps aliases. Mnemonic suffix being omitted because it's implicit 3448// in the destination. 3449def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0, "intel">; 3450def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0, "intel">; 3451def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0, "intel">; 3452def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3453 3454// movs aliases. Mnemonic suffix being omitted because it's implicit 3455// in the destination. 3456def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0, "intel">; 3457def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0, "intel">; 3458def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0, "intel">; 3459def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3460 3461// div and idiv aliases for explicit A register. 3462def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>; 3463def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>; 3464def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>; 3465def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>; 3466def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>; 3467def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>; 3468def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>; 3469def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>; 3470def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>; 3471def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>; 3472def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>; 3473def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>; 3474def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>; 3475def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>; 3476def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>; 3477def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>; 3478 3479 3480 3481// Various unary fpstack operations default to operating on ST1. 3482// For example, "fxch" -> "fxch %st(1)" 3483def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>; 3484def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>; 3485def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>; 3486def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>; 3487def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>; 3488def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>; 3489def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>; 3490def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>; 3491def : InstAlias<"fxch", (XCH_F ST1), 0>; 3492def : InstAlias<"fcom", (COM_FST0r ST1), 0>; 3493def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>; 3494def : InstAlias<"fcomi", (COM_FIr ST1), 0>; 3495def : InstAlias<"fcompi", (COM_FIPr ST1), 0>; 3496def : InstAlias<"fucom", (UCOM_Fr ST1), 0>; 3497def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>; 3498def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>; 3499def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>; 3500 3501// Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op. 3502// For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate 3503// instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with 3504// gas. 3505multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> { 3506 def : InstAlias<!strconcat(Mnemonic, "\t$op"), 3507 (Inst RSTi:$op), EmitAlias>; 3508 def : InstAlias<!strconcat(Mnemonic, "\t{%st, %st|st, st}"), 3509 (Inst ST0), EmitAlias>; 3510} 3511 3512defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>; 3513defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>; 3514defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>; 3515defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>; 3516defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>; 3517defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>; 3518defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>; 3519defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>; 3520defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>; 3521defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>; 3522defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>; 3523defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>; 3524defm : FpUnaryAlias<"fcomi", COM_FIr, 0>; 3525defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>; 3526defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>; 3527defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>; 3528 3529 3530// Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they 3531// commute. We also allow fdiv[r]p/fsubrp even though they don't commute, 3532// solely because gas supports it. 3533def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>; 3534def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>; 3535def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>; 3536def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>; 3537def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>; 3538def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>; 3539 3540def : InstAlias<"fnstsw" , (FNSTSW16r), 0>; 3541 3542// lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but 3543// this is compatible with what GAS does. 3544def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>; 3545def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>; 3546def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>; 3547def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>; 3548def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>; 3549def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>; 3550def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaquemem:$dst), 0>, Requires<[In16BitMode]>; 3551def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaquemem:$dst), 0>, Requires<[In16BitMode]>; 3552 3553def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0, "att">, Requires<[In64BitMode]>; 3554def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0, "att">, Requires<[In32BitMode]>; 3555def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0, "att">, Requires<[In16BitMode]>; 3556 3557 3558// "imul <imm>, B" is an alias for "imul <imm>, B, B". 3559def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>; 3560def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>; 3561def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>; 3562def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>; 3563def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>; 3564def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>; 3565 3566// ins aliases. Accept the mnemonic suffix being omitted because it's implicit 3567// in the destination. 3568def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0, "intel">; 3569def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0, "intel">; 3570def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0, "intel">; 3571 3572// outs aliases. Accept the mnemonic suffix being omitted because it's implicit 3573// in the source. 3574def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0, "intel">; 3575def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0, "intel">; 3576def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0, "intel">; 3577 3578// inb %dx -> inb %al, %dx 3579def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>; 3580def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>; 3581def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>; 3582def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>; 3583def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>; 3584def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>; 3585 3586 3587// jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp 3588def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>; 3589def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>; 3590def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>; 3591def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>; 3592def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3593def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3594def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3595def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3596 3597// Match 'movq <largeimm>, <reg>' as an alias for movabsq. 3598def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>; 3599 3600// Match 'movd GR64, MMX' as an alias for movq to be compatible with gas, 3601// which supports this due to an old AMD documentation bug when 64-bit mode was 3602// created. 3603def : InstAlias<"movd\t{$src, $dst|$dst, $src}", 3604 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>; 3605def : InstAlias<"movd\t{$src, $dst|$dst, $src}", 3606 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>; 3607 3608// movsx aliases 3609def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0, "att">; 3610def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0, "att">; 3611def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0, "att">; 3612def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0, "att">; 3613def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0, "att">; 3614def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0, "att">; 3615def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0, "att">; 3616 3617// movzx aliases 3618def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0, "att">; 3619def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0, "att">; 3620def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0, "att">; 3621def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0, "att">; 3622def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0, "att">; 3623def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0, "att">; 3624// Note: No GR32->GR64 movzx form. 3625 3626// outb %dx -> outb %al, %dx 3627def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>; 3628def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>; 3629def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>; 3630def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>; 3631def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>; 3632def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>; 3633 3634// 'sldt <mem>' can be encoded with either sldtw or sldtq with the same 3635// effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity 3636// errors, since its encoding is the most compact. 3637def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>; 3638 3639// shld/shrd op,op -> shld op, op, CL 3640def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>; 3641def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>; 3642def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>; 3643def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>; 3644def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>; 3645def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>; 3646 3647def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>; 3648def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>; 3649def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>; 3650def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>; 3651def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>; 3652def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>; 3653 3654/* FIXME: This is disabled because the asm matcher is currently incapable of 3655 * matching a fixed immediate like $1. 3656// "shl X, $1" is an alias for "shl X". 3657multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> { 3658 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"), 3659 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>; 3660 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"), 3661 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>; 3662 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"), 3663 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>; 3664 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"), 3665 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>; 3666 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"), 3667 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>; 3668 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"), 3669 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>; 3670 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"), 3671 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>; 3672 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"), 3673 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>; 3674} 3675 3676defm : ShiftRotateByOneAlias<"rcl", "RCL">; 3677defm : ShiftRotateByOneAlias<"rcr", "RCR">; 3678defm : ShiftRotateByOneAlias<"rol", "ROL">; 3679defm : ShiftRotateByOneAlias<"ror", "ROR">; 3680FIXME */ 3681 3682// test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms. 3683def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}", 3684 (TEST8mr i8mem :$mem, GR8 :$val), 0>; 3685def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}", 3686 (TEST16mr i16mem:$mem, GR16:$val), 0>; 3687def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}", 3688 (TEST32mr i32mem:$mem, GR32:$val), 0>; 3689def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}", 3690 (TEST64mr i64mem:$mem, GR64:$val), 0>; 3691 3692// xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms. 3693def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}", 3694 (XCHG8rm GR8 :$val, i8mem :$mem), 0>; 3695def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}", 3696 (XCHG16rm GR16:$val, i16mem:$mem), 0>; 3697def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}", 3698 (XCHG32rm GR32:$val, i32mem:$mem), 0>; 3699def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}", 3700 (XCHG64rm GR64:$val, i64mem:$mem), 0>; 3701 3702// xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms. 3703def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>; 3704def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>; 3705def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>; 3706 3707// In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we 3708// would get by default because it's defined as NOP. But xchg %eax, %eax implies 3709// implicit zeroing of the upper 32 bits. So alias to the longer encoding. 3710def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}", 3711 (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>; 3712 3713// xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this 3714// we emit an unneeded REX.w prefix. 3715def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>; 3716 3717// These aliases exist to get the parser to prioritize matching 8-bit 3718// immediate encodings over matching the implicit ax/eax/rax encodings. By 3719// explicitly mentioning the A register here, these entries will be ordered 3720// first due to the more explicit immediate type. 3721def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>; 3722def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>; 3723def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>; 3724def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>; 3725def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>; 3726def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>; 3727def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>; 3728def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>; 3729 3730def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>; 3731def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>; 3732def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>; 3733def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>; 3734def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>; 3735def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>; 3736def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>; 3737def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>; 3738 3739def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>; 3740def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>; 3741def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>; 3742def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>; 3743def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>; 3744def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>; 3745def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>; 3746def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>; 3747