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_X86WIN_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 X86WinAlloca : SDNode<"X86ISD::WIN_ALLOCA", SDT_X86WIN_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> : Operand<iPTR> { 392 let PrintMethod = printMethod; 393 let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, SEGMENT_REG); 394 let ParserMatchClass = parserMatchClass; 395 let OperandType = "OPERAND_MEMORY"; 396} 397 398// Gather mem operands 399class X86VMemOperand<RegisterClass RC, string printMethod, 400 AsmOperandClass parserMatchClass> 401 : X86MemOperand<printMethod, parserMatchClass> { 402 let MIOperandInfo = (ops ptr_rc, i8imm, RC, i32imm, SEGMENT_REG); 403} 404 405def anymem : X86MemOperand<"printMemReference">; 406def X86any_fcmp : PatFrags<(ops node:$lhs, node:$rhs), 407 [(X86strict_fcmp node:$lhs, node:$rhs), 408 (X86fcmp node:$lhs, node:$rhs)]>; 409 410// FIXME: Right now we allow any size during parsing, but we might want to 411// restrict to only unsized memory. 412def opaquemem : X86MemOperand<"printMemReference">; 413 414def sibmem: X86MemOperand<"printMemReference", X86SibMemOperand>; 415 416def i8mem : X86MemOperand<"printbytemem", X86Mem8AsmOperand>; 417def i16mem : X86MemOperand<"printwordmem", X86Mem16AsmOperand>; 418def i32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>; 419def i64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>; 420def i128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>; 421def i256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>; 422def i512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>; 423def f32mem : X86MemOperand<"printdwordmem", X86Mem32AsmOperand>; 424def f64mem : X86MemOperand<"printqwordmem", X86Mem64AsmOperand>; 425def f80mem : X86MemOperand<"printtbytemem", X86Mem80AsmOperand>; 426def f128mem : X86MemOperand<"printxmmwordmem", X86Mem128AsmOperand>; 427def f256mem : X86MemOperand<"printymmwordmem", X86Mem256AsmOperand>; 428def f512mem : X86MemOperand<"printzmmwordmem", X86Mem512AsmOperand>; 429 430// Gather mem operands 431def vx64mem : X86VMemOperand<VR128, "printqwordmem", X86Mem64_RC128Operand>; 432def vx128mem : X86VMemOperand<VR128, "printxmmwordmem", X86Mem128_RC128Operand>; 433def vx256mem : X86VMemOperand<VR128, "printymmwordmem", X86Mem256_RC128Operand>; 434def vy128mem : X86VMemOperand<VR256, "printxmmwordmem", X86Mem128_RC256Operand>; 435def vy256mem : X86VMemOperand<VR256, "printymmwordmem", X86Mem256_RC256Operand>; 436 437def vx64xmem : X86VMemOperand<VR128X, "printqwordmem", X86Mem64_RC128XOperand>; 438def vx128xmem : X86VMemOperand<VR128X, "printxmmwordmem", X86Mem128_RC128XOperand>; 439def vx256xmem : X86VMemOperand<VR128X, "printymmwordmem", X86Mem256_RC128XOperand>; 440def vy128xmem : X86VMemOperand<VR256X, "printxmmwordmem", X86Mem128_RC256XOperand>; 441def vy256xmem : X86VMemOperand<VR256X, "printymmwordmem", X86Mem256_RC256XOperand>; 442def vy512xmem : X86VMemOperand<VR256X, "printzmmwordmem", X86Mem512_RC256XOperand>; 443def vz256mem : X86VMemOperand<VR512, "printymmwordmem", X86Mem256_RC512Operand>; 444def vz512mem : X86VMemOperand<VR512, "printzmmwordmem", X86Mem512_RC512Operand>; 445 446// A version of i8mem for use on x86-64 and x32 that uses a NOREX GPR instead 447// of a plain GPR, so that it doesn't potentially require a REX prefix. 448def ptr_rc_norex : PointerLikeRegClass<2>; 449def ptr_rc_norex_nosp : PointerLikeRegClass<3>; 450 451def i8mem_NOREX : Operand<iPTR> { 452 let PrintMethod = "printbytemem"; 453 let MIOperandInfo = (ops ptr_rc_norex, i8imm, ptr_rc_norex_nosp, i32imm, 454 SEGMENT_REG); 455 let ParserMatchClass = X86Mem8AsmOperand; 456 let OperandType = "OPERAND_MEMORY"; 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, 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, 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, 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->hasCMov()">; 878def NoCMov : Predicate<"!Subtarget->hasCMov()">; 879 880def HasMMX : Predicate<"Subtarget->hasMMX()">; 881def Has3DNow : Predicate<"Subtarget->has3DNow()">; 882def Has3DNowA : Predicate<"Subtarget->has3DNowA()">; 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 HasAVXVNNI : Predicate <"Subtarget->hasAVXVNNI()">; 922def NoVLX_Or_NoVNNI : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVNNI()">; 923 924def HasBITALG : Predicate<"Subtarget->hasBITALG()">; 925def HasPOPCNT : Predicate<"Subtarget->hasPOPCNT()">; 926def HasAES : Predicate<"Subtarget->hasAES()">; 927def HasVAES : Predicate<"Subtarget->hasVAES()">; 928def NoVLX_Or_NoVAES : Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVAES()">; 929def HasFXSR : Predicate<"Subtarget->hasFXSR()">; 930def HasXSAVE : Predicate<"Subtarget->hasXSAVE()">; 931def HasXSAVEOPT : Predicate<"Subtarget->hasXSAVEOPT()">; 932def HasXSAVEC : Predicate<"Subtarget->hasXSAVEC()">; 933def HasXSAVES : Predicate<"Subtarget->hasXSAVES()">; 934def HasPCLMUL : Predicate<"Subtarget->hasPCLMUL()">; 935def NoVLX_Or_NoVPCLMULQDQ : 936 Predicate<"!Subtarget->hasVLX() || !Subtarget->hasVPCLMULQDQ()">; 937def HasVPCLMULQDQ : Predicate<"Subtarget->hasVPCLMULQDQ()">; 938def HasGFNI : Predicate<"Subtarget->hasGFNI()">; 939def HasFMA : Predicate<"Subtarget->hasFMA()">; 940def HasFMA4 : Predicate<"Subtarget->hasFMA4()">; 941def NoFMA4 : Predicate<"!Subtarget->hasFMA4()">; 942def HasXOP : Predicate<"Subtarget->hasXOP()">; 943def HasTBM : Predicate<"Subtarget->hasTBM()">; 944def NoTBM : Predicate<"!Subtarget->hasTBM()">; 945def HasLWP : Predicate<"Subtarget->hasLWP()">; 946def HasMOVBE : Predicate<"Subtarget->hasMOVBE()">; 947def HasRDRAND : Predicate<"Subtarget->hasRDRAND()">; 948def HasF16C : Predicate<"Subtarget->hasF16C()">; 949def HasFSGSBase : Predicate<"Subtarget->hasFSGSBase()">; 950def HasLZCNT : Predicate<"Subtarget->hasLZCNT()">; 951def HasBMI : Predicate<"Subtarget->hasBMI()">; 952def HasBMI2 : Predicate<"Subtarget->hasBMI2()">; 953def NoBMI2 : Predicate<"!Subtarget->hasBMI2()">; 954def HasVBMI : Predicate<"Subtarget->hasVBMI()">; 955def HasVBMI2 : Predicate<"Subtarget->hasVBMI2()">; 956def HasIFMA : Predicate<"Subtarget->hasIFMA()">; 957def HasRTM : Predicate<"Subtarget->hasRTM()">; 958def HasADX : Predicate<"Subtarget->hasADX()">; 959def HasSHA : Predicate<"Subtarget->hasSHA()">; 960def HasSGX : Predicate<"Subtarget->hasSGX()">; 961def HasRDSEED : Predicate<"Subtarget->hasRDSEED()">; 962def HasSSEPrefetch : Predicate<"Subtarget->hasSSEPrefetch()">; 963def NoSSEPrefetch : Predicate<"!Subtarget->hasSSEPrefetch()">; 964def HasPrefetchW : Predicate<"Subtarget->hasPrefetchW()">; 965def HasPREFETCHWT1 : Predicate<"Subtarget->hasPREFETCHWT1()">; 966def HasLAHFSAHF : Predicate<"Subtarget->hasLAHFSAHF()">; 967def HasMWAITX : Predicate<"Subtarget->hasMWAITX()">; 968def HasCLZERO : Predicate<"Subtarget->hasCLZERO()">; 969def HasCLDEMOTE : Predicate<"Subtarget->hasCLDEMOTE()">; 970def HasMOVDIRI : Predicate<"Subtarget->hasMOVDIRI()">; 971def HasMOVDIR64B : Predicate<"Subtarget->hasMOVDIR64B()">; 972def HasPTWRITE : Predicate<"Subtarget->hasPTWRITE()">; 973def FPStackf32 : Predicate<"!Subtarget->hasSSE1()">; 974def FPStackf64 : Predicate<"!Subtarget->hasSSE2()">; 975def HasSHSTK : Predicate<"Subtarget->hasSHSTK()">; 976def HasCLFLUSHOPT : Predicate<"Subtarget->hasCLFLUSHOPT()">; 977def HasCLWB : Predicate<"Subtarget->hasCLWB()">; 978def HasWBNOINVD : Predicate<"Subtarget->hasWBNOINVD()">; 979def HasRDPID : Predicate<"Subtarget->hasRDPID()">; 980def HasWAITPKG : Predicate<"Subtarget->hasWAITPKG()">; 981def HasINVPCID : Predicate<"Subtarget->hasINVPCID()">; 982def HasCmpxchg8b : Predicate<"Subtarget->hasCmpxchg8b()">; 983def HasCmpxchg16b: Predicate<"Subtarget->hasCmpxchg16b()">; 984def HasPCONFIG : Predicate<"Subtarget->hasPCONFIG()">; 985def HasENQCMD : Predicate<"Subtarget->hasENQCMD()">; 986def HasKL : Predicate<"Subtarget->hasKL()">; 987def HasWIDEKL : Predicate<"Subtarget->hasWIDEKL()">; 988def HasHRESET : Predicate<"Subtarget->hasHRESET()">; 989def HasSERIALIZE : Predicate<"Subtarget->hasSERIALIZE()">; 990def HasTSXLDTRK : Predicate<"Subtarget->hasTSXLDTRK()">; 991def HasAMXTILE : Predicate<"Subtarget->hasAMXTILE()">; 992def HasAMXBF16 : Predicate<"Subtarget->hasAMXBF16()">; 993def HasAMXINT8 : Predicate<"Subtarget->hasAMXINT8()">; 994def HasUINTR : Predicate<"Subtarget->hasUINTR()">; 995def Not64BitMode : Predicate<"!Subtarget->is64Bit()">, 996 AssemblerPredicate<(all_of (not Mode64Bit)), "Not 64-bit mode">; 997def In64BitMode : Predicate<"Subtarget->is64Bit()">, 998 AssemblerPredicate<(all_of Mode64Bit), "64-bit mode">; 999def IsLP64 : Predicate<"Subtarget->isTarget64BitLP64()">; 1000def NotLP64 : Predicate<"!Subtarget->isTarget64BitLP64()">; 1001def In16BitMode : Predicate<"Subtarget->is16Bit()">, 1002 AssemblerPredicate<(all_of Mode16Bit), "16-bit mode">; 1003def Not16BitMode : Predicate<"!Subtarget->is16Bit()">, 1004 AssemblerPredicate<(all_of (not Mode16Bit)), "Not 16-bit mode">; 1005def In32BitMode : Predicate<"Subtarget->is32Bit()">, 1006 AssemblerPredicate<(all_of Mode32Bit), "32-bit mode">; 1007def IsWin64 : Predicate<"Subtarget->isTargetWin64()">; 1008def NotWin64 : Predicate<"!Subtarget->isTargetWin64()">; 1009def NotWin64WithoutFP : Predicate<"!Subtarget->isTargetWin64() ||" 1010 "Subtarget->getFrameLowering()->hasFP(*MF)"> { 1011 let RecomputePerFunction = 1; 1012} 1013def IsPS4 : Predicate<"Subtarget->isTargetPS4()">; 1014def NotPS4 : Predicate<"!Subtarget->isTargetPS4()">; 1015def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">; 1016def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">; 1017def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">; 1018def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">; 1019def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||" 1020 "TM.getCodeModel() == CodeModel::Kernel">; 1021def IsNotPIC : Predicate<"!TM.isPositionIndependent()">; 1022 1023// We could compute these on a per-module basis but doing so requires accessing 1024// the Function object through the <Target>Subtarget and objections were raised 1025// to that (see post-commit review comments for r301750). 1026let RecomputePerFunction = 1 in { 1027 def OptForSize : Predicate<"shouldOptForSize(MF)">; 1028 def OptForMinSize : Predicate<"MF->getFunction().hasMinSize()">; 1029 def OptForSpeed : Predicate<"!shouldOptForSize(MF)">; 1030 def UseIncDec : Predicate<"!Subtarget->slowIncDec() || " 1031 "shouldOptForSize(MF)">; 1032 def NoSSE41_Or_OptForSize : Predicate<"shouldOptForSize(MF) || " 1033 "!Subtarget->hasSSE41()">; 1034} 1035 1036def CallImmAddr : Predicate<"Subtarget->isLegalToCallImmediateAddr()">; 1037def FavorMemIndirectCall : Predicate<"!Subtarget->slowTwoMemOps()">; 1038def HasFastMem32 : Predicate<"!Subtarget->isUnalignedMem32Slow()">; 1039def HasFastLZCNT : Predicate<"Subtarget->hasFastLZCNT()">; 1040def HasFastSHLDRotate : Predicate<"Subtarget->hasFastSHLDRotate()">; 1041def HasERMSB : Predicate<"Subtarget->hasERMSB()">; 1042def HasFSRM : Predicate<"Subtarget->hasFSRM()">; 1043def HasMFence : Predicate<"Subtarget->hasMFence()">; 1044def UseIndirectThunkCalls : Predicate<"Subtarget->useIndirectThunkCalls()">; 1045def NotUseIndirectThunkCalls : Predicate<"!Subtarget->useIndirectThunkCalls()">; 1046 1047//===----------------------------------------------------------------------===// 1048// X86 Instruction Format Definitions. 1049// 1050 1051include "X86InstrFormats.td" 1052 1053//===----------------------------------------------------------------------===// 1054// Pattern fragments. 1055// 1056 1057// X86 specific condition code. These correspond to CondCode in 1058// X86InstrInfo.h. They must be kept in synch. 1059def X86_COND_O : PatLeaf<(i8 0)>; 1060def X86_COND_NO : PatLeaf<(i8 1)>; 1061def X86_COND_B : PatLeaf<(i8 2)>; // alt. COND_C 1062def X86_COND_AE : PatLeaf<(i8 3)>; // alt. COND_NC 1063def X86_COND_E : PatLeaf<(i8 4)>; // alt. COND_Z 1064def X86_COND_NE : PatLeaf<(i8 5)>; // alt. COND_NZ 1065def X86_COND_BE : PatLeaf<(i8 6)>; // alt. COND_NA 1066def X86_COND_A : PatLeaf<(i8 7)>; // alt. COND_NBE 1067def X86_COND_S : PatLeaf<(i8 8)>; 1068def X86_COND_NS : PatLeaf<(i8 9)>; 1069def X86_COND_P : PatLeaf<(i8 10)>; // alt. COND_PE 1070def X86_COND_NP : PatLeaf<(i8 11)>; // alt. COND_PO 1071def X86_COND_L : PatLeaf<(i8 12)>; // alt. COND_NGE 1072def X86_COND_GE : PatLeaf<(i8 13)>; // alt. COND_NL 1073def X86_COND_LE : PatLeaf<(i8 14)>; // alt. COND_NG 1074def X86_COND_G : PatLeaf<(i8 15)>; // alt. COND_NLE 1075 1076def i16immSExt8 : ImmLeaf<i16, [{ return isInt<8>(Imm); }]>; 1077def i32immSExt8 : ImmLeaf<i32, [{ return isInt<8>(Imm); }]>; 1078def i64immSExt8 : ImmLeaf<i64, [{ return isInt<8>(Imm); }]>; 1079def i64immSExt32 : ImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 1080def i64timmSExt32 : TImmLeaf<i64, [{ return isInt<32>(Imm); }]>; 1081 1082def i16relocImmSExt8 : PatLeaf<(i16 relocImm), [{ 1083 return isSExtAbsoluteSymbolRef(8, N); 1084}]>; 1085def i32relocImmSExt8 : PatLeaf<(i32 relocImm), [{ 1086 return isSExtAbsoluteSymbolRef(8, N); 1087}]>; 1088def i64relocImmSExt8 : PatLeaf<(i64 relocImm), [{ 1089 return isSExtAbsoluteSymbolRef(8, N); 1090}]>; 1091def i64relocImmSExt32 : PatLeaf<(i64 relocImm), [{ 1092 return isSExtAbsoluteSymbolRef(32, N); 1093}]>; 1094 1095// If we have multiple users of an immediate, it's much smaller to reuse 1096// the register, rather than encode the immediate in every instruction. 1097// This has the risk of increasing register pressure from stretched live 1098// ranges, however, the immediates should be trivial to rematerialize by 1099// the RA in the event of high register pressure. 1100// TODO : This is currently enabled for stores and binary ops. There are more 1101// cases for which this can be enabled, though this catches the bulk of the 1102// issues. 1103// TODO2 : This should really also be enabled under O2, but there's currently 1104// an issue with RA where we don't pull the constants into their users 1105// when we rematerialize them. I'll follow-up on enabling O2 after we fix that 1106// issue. 1107// TODO3 : This is currently limited to single basic blocks (DAG creation 1108// pulls block immediates to the top and merges them if necessary). 1109// Eventually, it would be nice to allow ConstantHoisting to merge constants 1110// globally for potentially added savings. 1111// 1112def imm_su : PatLeaf<(imm), [{ 1113 return !shouldAvoidImmediateInstFormsForSize(N); 1114}]>; 1115def i64immSExt32_su : PatLeaf<(i64immSExt32), [{ 1116 return !shouldAvoidImmediateInstFormsForSize(N); 1117}]>; 1118 1119def relocImm8_su : PatLeaf<(i8 relocImm), [{ 1120 return !shouldAvoidImmediateInstFormsForSize(N); 1121}]>; 1122def relocImm16_su : PatLeaf<(i16 relocImm), [{ 1123 return !shouldAvoidImmediateInstFormsForSize(N); 1124}]>; 1125def relocImm32_su : PatLeaf<(i32 relocImm), [{ 1126 return !shouldAvoidImmediateInstFormsForSize(N); 1127}]>; 1128 1129def i16relocImmSExt8_su : PatLeaf<(i16relocImmSExt8), [{ 1130 return !shouldAvoidImmediateInstFormsForSize(N); 1131}]>; 1132def i32relocImmSExt8_su : PatLeaf<(i32relocImmSExt8), [{ 1133 return !shouldAvoidImmediateInstFormsForSize(N); 1134}]>; 1135def i64relocImmSExt8_su : PatLeaf<(i64relocImmSExt8), [{ 1136 return !shouldAvoidImmediateInstFormsForSize(N); 1137}]>; 1138def i64relocImmSExt32_su : PatLeaf<(i64relocImmSExt32), [{ 1139 return !shouldAvoidImmediateInstFormsForSize(N); 1140}]>; 1141 1142def i16immSExt8_su : PatLeaf<(i16immSExt8), [{ 1143 return !shouldAvoidImmediateInstFormsForSize(N); 1144}]>; 1145def i32immSExt8_su : PatLeaf<(i32immSExt8), [{ 1146 return !shouldAvoidImmediateInstFormsForSize(N); 1147}]>; 1148def i64immSExt8_su : PatLeaf<(i64immSExt8), [{ 1149 return !shouldAvoidImmediateInstFormsForSize(N); 1150}]>; 1151 1152// i64immZExt32 predicate - True if the 64-bit immediate fits in a 32-bit 1153// unsigned field. 1154def i64immZExt32 : ImmLeaf<i64, [{ return isUInt<32>(Imm); }]>; 1155 1156def i64immZExt32SExt8 : ImmLeaf<i64, [{ 1157 return isUInt<32>(Imm) && isInt<8>(static_cast<int32_t>(Imm)); 1158}]>; 1159 1160// Helper fragments for loads. 1161 1162// It's safe to fold a zextload/extload from i1 as a regular i8 load. The 1163// upper bits are guaranteed to be zero and we were going to emit a MOV8rm 1164// which might get folded during peephole anyway. 1165def loadi8 : PatFrag<(ops node:$ptr), (i8 (unindexedload node:$ptr)), [{ 1166 LoadSDNode *LD = cast<LoadSDNode>(N); 1167 ISD::LoadExtType ExtType = LD->getExtensionType(); 1168 return ExtType == ISD::NON_EXTLOAD || ExtType == ISD::EXTLOAD || 1169 ExtType == ISD::ZEXTLOAD; 1170}]>; 1171 1172// It's always safe to treat a anyext i16 load as a i32 load if the i16 is 1173// known to be 32-bit aligned or better. Ditto for i8 to i16. 1174def loadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{ 1175 LoadSDNode *LD = cast<LoadSDNode>(N); 1176 ISD::LoadExtType ExtType = LD->getExtensionType(); 1177 if (ExtType == ISD::NON_EXTLOAD) 1178 return true; 1179 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 1180 return LD->getAlignment() >= 2 && LD->isSimple(); 1181 return false; 1182}]>; 1183 1184def loadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{ 1185 LoadSDNode *LD = cast<LoadSDNode>(N); 1186 ISD::LoadExtType ExtType = LD->getExtensionType(); 1187 if (ExtType == ISD::NON_EXTLOAD) 1188 return true; 1189 if (ExtType == ISD::EXTLOAD && EnablePromoteAnyextLoad) 1190 return LD->getAlignment() >= 4 && LD->isSimple(); 1191 return false; 1192}]>; 1193 1194def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>; 1195def loadf32 : PatFrag<(ops node:$ptr), (f32 (load node:$ptr))>; 1196def loadf64 : PatFrag<(ops node:$ptr), (f64 (load node:$ptr))>; 1197def loadf80 : PatFrag<(ops node:$ptr), (f80 (load node:$ptr))>; 1198def loadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr))>; 1199def alignedloadf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 1200 LoadSDNode *Ld = cast<LoadSDNode>(N); 1201 return Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); 1202}]>; 1203def memopf128 : PatFrag<(ops node:$ptr), (f128 (load node:$ptr)), [{ 1204 LoadSDNode *Ld = cast<LoadSDNode>(N); 1205 return Subtarget->hasSSEUnalignedMem() || 1206 Ld->getAlignment() >= Ld->getMemoryVT().getStoreSize(); 1207}]>; 1208 1209def sextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>; 1210def sextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>; 1211def sextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>; 1212def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>; 1213def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>; 1214def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>; 1215 1216def zextloadi8i1 : PatFrag<(ops node:$ptr), (i8 (zextloadi1 node:$ptr))>; 1217def zextloadi16i1 : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>; 1218def zextloadi32i1 : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>; 1219def zextloadi16i8 : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>; 1220def zextloadi32i8 : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>; 1221def zextloadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>; 1222def zextloadi64i1 : PatFrag<(ops node:$ptr), (i64 (zextloadi1 node:$ptr))>; 1223def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>; 1224def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>; 1225def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>; 1226 1227def extloadi8i1 : PatFrag<(ops node:$ptr), (i8 (extloadi1 node:$ptr))>; 1228def extloadi16i1 : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>; 1229def extloadi32i1 : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>; 1230def extloadi16i8 : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>; 1231def extloadi32i8 : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>; 1232def extloadi32i16 : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>; 1233def extloadi64i1 : PatFrag<(ops node:$ptr), (i64 (extloadi1 node:$ptr))>; 1234def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>; 1235def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>; 1236 1237// We can treat an i8/i16 extending load to i64 as a 32 bit load if its known 1238// to be 4 byte aligned or better. 1239def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (unindexedload node:$ptr)), [{ 1240 LoadSDNode *LD = cast<LoadSDNode>(N); 1241 ISD::LoadExtType ExtType = LD->getExtensionType(); 1242 if (ExtType != ISD::EXTLOAD) 1243 return false; 1244 if (LD->getMemoryVT() == MVT::i32) 1245 return true; 1246 1247 return LD->getAlignment() >= 4 && LD->isSimple(); 1248}]>; 1249 1250 1251// An 'and' node with a single use. 1252def and_su : PatFrag<(ops node:$lhs, node:$rhs), (and node:$lhs, node:$rhs), [{ 1253 return N->hasOneUse(); 1254}]>; 1255// An 'srl' node with a single use. 1256def srl_su : PatFrag<(ops node:$lhs, node:$rhs), (srl node:$lhs, node:$rhs), [{ 1257 return N->hasOneUse(); 1258}]>; 1259// An 'trunc' node with a single use. 1260def trunc_su : PatFrag<(ops node:$src), (trunc node:$src), [{ 1261 return N->hasOneUse(); 1262}]>; 1263 1264//===----------------------------------------------------------------------===// 1265// Instruction list. 1266// 1267 1268// Nop 1269let hasSideEffects = 0, SchedRW = [WriteNop] in { 1270 def NOOP : I<0x90, RawFrm, (outs), (ins), "nop", []>; 1271 def NOOPW : I<0x1f, MRMXm, (outs), (ins i16mem:$zero), 1272 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable; 1273 def NOOPL : I<0x1f, MRMXm, (outs), (ins i32mem:$zero), 1274 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable; 1275 def NOOPQ : RI<0x1f, MRMXm, (outs), (ins i64mem:$zero), 1276 "nop{q}\t$zero", []>, TB, NotMemoryFoldable, 1277 Requires<[In64BitMode]>; 1278 // Also allow register so we can assemble/disassemble 1279 def NOOPWr : I<0x1f, MRMXr, (outs), (ins GR16:$zero), 1280 "nop{w}\t$zero", []>, TB, OpSize16, NotMemoryFoldable; 1281 def NOOPLr : I<0x1f, MRMXr, (outs), (ins GR32:$zero), 1282 "nop{l}\t$zero", []>, TB, OpSize32, NotMemoryFoldable; 1283 def NOOPQr : RI<0x1f, MRMXr, (outs), (ins GR64:$zero), 1284 "nop{q}\t$zero", []>, TB, NotMemoryFoldable, 1285 Requires<[In64BitMode]>; 1286} 1287 1288 1289// Constructing a stack frame. 1290def ENTER : Ii16<0xC8, RawFrmImm8, (outs), (ins i16imm:$len, i8imm:$lvl), 1291 "enter\t$len, $lvl", []>, Sched<[WriteMicrocoded]>; 1292 1293let SchedRW = [WriteALU] in { 1294let Defs = [EBP, ESP], Uses = [EBP, ESP], mayLoad = 1, hasSideEffects=0 in 1295def LEAVE : I<0xC9, RawFrm, (outs), (ins), "leave", []>, 1296 Requires<[Not64BitMode]>; 1297 1298let Defs = [RBP,RSP], Uses = [RBP,RSP], mayLoad = 1, hasSideEffects = 0 in 1299def LEAVE64 : I<0xC9, RawFrm, (outs), (ins), "leave", []>, 1300 Requires<[In64BitMode]>; 1301} // SchedRW 1302 1303//===----------------------------------------------------------------------===// 1304// Miscellaneous Instructions. 1305// 1306 1307let isBarrier = 1, hasSideEffects = 1, usesCustomInserter = 1, 1308 SchedRW = [WriteSystem] in 1309 def Int_eh_sjlj_setup_dispatch 1310 : PseudoI<(outs), (ins), [(X86eh_sjlj_setup_dispatch)]>; 1311 1312let Defs = [ESP], Uses = [ESP], hasSideEffects=0 in { 1313let mayLoad = 1, SchedRW = [WriteLoad] in { 1314def POP16r : I<0x58, AddRegFrm, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>, 1315 OpSize16; 1316def POP32r : I<0x58, AddRegFrm, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>, 1317 OpSize32, Requires<[Not64BitMode]>; 1318// Long form for the disassembler. 1319let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1320def POP16rmr: I<0x8F, MRM0r, (outs GR16:$reg), (ins), "pop{w}\t$reg", []>, 1321 OpSize16, NotMemoryFoldable; 1322def POP32rmr: I<0x8F, MRM0r, (outs GR32:$reg), (ins), "pop{l}\t$reg", []>, 1323 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable; 1324} // isCodeGenOnly = 1, ForceDisassemble = 1 1325} // mayLoad, SchedRW 1326let mayStore = 1, mayLoad = 1, SchedRW = [WriteCopy] in { 1327def POP16rmm: I<0x8F, MRM0m, (outs), (ins i16mem:$dst), "pop{w}\t$dst", []>, 1328 OpSize16; 1329def POP32rmm: I<0x8F, MRM0m, (outs), (ins i32mem:$dst), "pop{l}\t$dst", []>, 1330 OpSize32, Requires<[Not64BitMode]>; 1331} // mayStore, mayLoad, SchedRW 1332 1333let mayStore = 1, SchedRW = [WriteStore] in { 1334def PUSH16r : I<0x50, AddRegFrm, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>, 1335 OpSize16; 1336def PUSH32r : I<0x50, AddRegFrm, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>, 1337 OpSize32, Requires<[Not64BitMode]>; 1338// Long form for the disassembler. 1339let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1340def PUSH16rmr: I<0xFF, MRM6r, (outs), (ins GR16:$reg), "push{w}\t$reg",[]>, 1341 OpSize16, NotMemoryFoldable; 1342def PUSH32rmr: I<0xFF, MRM6r, (outs), (ins GR32:$reg), "push{l}\t$reg",[]>, 1343 OpSize32, Requires<[Not64BitMode]>, NotMemoryFoldable; 1344} // isCodeGenOnly = 1, ForceDisassemble = 1 1345 1346def PUSH16i8 : Ii8<0x6a, RawFrm, (outs), (ins i16i8imm:$imm), 1347 "push{w}\t$imm", []>, OpSize16; 1348def PUSHi16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), 1349 "push{w}\t$imm", []>, OpSize16; 1350 1351def PUSH32i8 : Ii8<0x6a, RawFrm, (outs), (ins i32i8imm:$imm), 1352 "push{l}\t$imm", []>, OpSize32, 1353 Requires<[Not64BitMode]>; 1354def PUSHi32 : Ii32<0x68, RawFrm, (outs), (ins i32imm:$imm), 1355 "push{l}\t$imm", []>, OpSize32, 1356 Requires<[Not64BitMode]>; 1357} // mayStore, SchedRW 1358 1359let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in { 1360def PUSH16rmm: I<0xFF, MRM6m, (outs), (ins i16mem:$src), "push{w}\t$src", []>, 1361 OpSize16; 1362def PUSH32rmm: I<0xFF, MRM6m, (outs), (ins i32mem:$src), "push{l}\t$src", []>, 1363 OpSize32, Requires<[Not64BitMode]>; 1364} // mayLoad, mayStore, SchedRW 1365 1366} 1367 1368let mayLoad = 1, mayStore = 1, usesCustomInserter = 1, 1369 SchedRW = [WriteRMW], Defs = [ESP] in { 1370 let Uses = [ESP] in 1371 def RDFLAGS32 : PseudoI<(outs GR32:$dst), (ins), 1372 [(set GR32:$dst, (int_x86_flags_read_u32))]>, 1373 Requires<[Not64BitMode]>; 1374 1375 let Uses = [RSP] in 1376 def RDFLAGS64 : PseudoI<(outs GR64:$dst), (ins), 1377 [(set GR64:$dst, (int_x86_flags_read_u64))]>, 1378 Requires<[In64BitMode]>; 1379} 1380 1381let mayLoad = 1, mayStore = 1, usesCustomInserter = 1, 1382 SchedRW = [WriteRMW] in { 1383 let Defs = [ESP, EFLAGS, DF], Uses = [ESP] in 1384 def WRFLAGS32 : PseudoI<(outs), (ins GR32:$src), 1385 [(int_x86_flags_write_u32 GR32:$src)]>, 1386 Requires<[Not64BitMode]>; 1387 1388 let Defs = [RSP, EFLAGS, DF], Uses = [RSP] in 1389 def WRFLAGS64 : PseudoI<(outs), (ins GR64:$src), 1390 [(int_x86_flags_write_u64 GR64:$src)]>, 1391 Requires<[In64BitMode]>; 1392} 1393 1394let Defs = [ESP, EFLAGS, DF], Uses = [ESP], mayLoad = 1, hasSideEffects=0, 1395 SchedRW = [WriteLoad] in { 1396def POPF16 : I<0x9D, RawFrm, (outs), (ins), "popf{w}", []>, OpSize16; 1397def POPF32 : I<0x9D, RawFrm, (outs), (ins), "popf{l|d}", []>, OpSize32, 1398 Requires<[Not64BitMode]>; 1399} 1400 1401let Defs = [ESP], Uses = [ESP, EFLAGS, DF], mayStore = 1, hasSideEffects=0, 1402 SchedRW = [WriteStore] in { 1403def PUSHF16 : I<0x9C, RawFrm, (outs), (ins), "pushf{w}", []>, OpSize16; 1404def PUSHF32 : I<0x9C, RawFrm, (outs), (ins), "pushf{l|d}", []>, OpSize32, 1405 Requires<[Not64BitMode]>; 1406} 1407 1408let Defs = [RSP], Uses = [RSP], hasSideEffects=0 in { 1409let mayLoad = 1, SchedRW = [WriteLoad] in { 1410def POP64r : I<0x58, AddRegFrm, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>, 1411 OpSize32, Requires<[In64BitMode]>; 1412// Long form for the disassembler. 1413let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1414def POP64rmr: I<0x8F, MRM0r, (outs GR64:$reg), (ins), "pop{q}\t$reg", []>, 1415 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable; 1416} // isCodeGenOnly = 1, ForceDisassemble = 1 1417} // mayLoad, SchedRW 1418let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in 1419def POP64rmm: I<0x8F, MRM0m, (outs), (ins i64mem:$dst), "pop{q}\t$dst", []>, 1420 OpSize32, Requires<[In64BitMode]>; 1421let mayStore = 1, SchedRW = [WriteStore] in { 1422def PUSH64r : I<0x50, AddRegFrm, (outs), (ins GR64:$reg), "push{q}\t$reg", []>, 1423 OpSize32, Requires<[In64BitMode]>; 1424// Long form for the disassembler. 1425let isCodeGenOnly = 1, ForceDisassemble = 1 in { 1426def PUSH64rmr: I<0xFF, MRM6r, (outs), (ins GR64:$reg), "push{q}\t$reg", []>, 1427 OpSize32, Requires<[In64BitMode]>, NotMemoryFoldable; 1428} // isCodeGenOnly = 1, ForceDisassemble = 1 1429} // mayStore, SchedRW 1430let mayLoad = 1, mayStore = 1, SchedRW = [WriteCopy] in { 1431def PUSH64rmm: I<0xFF, MRM6m, (outs), (ins i64mem:$src), "push{q}\t$src", []>, 1432 OpSize32, Requires<[In64BitMode]>; 1433} // mayLoad, mayStore, SchedRW 1434} 1435 1436let Defs = [RSP], Uses = [RSP], hasSideEffects = 0, mayStore = 1, 1437 SchedRW = [WriteStore] in { 1438def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm), 1439 "push{q}\t$imm", []>, OpSize32, 1440 Requires<[In64BitMode]>; 1441def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm), 1442 "push{q}\t$imm", []>, OpSize32, 1443 Requires<[In64BitMode]>; 1444} 1445 1446let Defs = [RSP, EFLAGS, DF], Uses = [RSP], mayLoad = 1, hasSideEffects=0 in 1447def POPF64 : I<0x9D, RawFrm, (outs), (ins), "popfq", []>, 1448 OpSize32, Requires<[In64BitMode]>, Sched<[WriteLoad]>; 1449let Defs = [RSP], Uses = [RSP, EFLAGS, DF], mayStore = 1, hasSideEffects=0 in 1450def PUSHF64 : I<0x9C, RawFrm, (outs), (ins), "pushfq", []>, 1451 OpSize32, Requires<[In64BitMode]>, Sched<[WriteStore]>; 1452 1453let Defs = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], Uses = [ESP], 1454 mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteLoad] in { 1455def POPA32 : I<0x61, RawFrm, (outs), (ins), "popal", []>, 1456 OpSize32, Requires<[Not64BitMode]>; 1457def POPA16 : I<0x61, RawFrm, (outs), (ins), "popaw", []>, 1458 OpSize16, Requires<[Not64BitMode]>; 1459} 1460let Defs = [ESP], Uses = [EDI, ESI, EBP, EBX, EDX, ECX, EAX, ESP], 1461 mayStore = 1, hasSideEffects = 0, SchedRW = [WriteStore] in { 1462def PUSHA32 : I<0x60, RawFrm, (outs), (ins), "pushal", []>, 1463 OpSize32, Requires<[Not64BitMode]>; 1464def PUSHA16 : I<0x60, RawFrm, (outs), (ins), "pushaw", []>, 1465 OpSize16, Requires<[Not64BitMode]>; 1466} 1467 1468let Constraints = "$src = $dst", SchedRW = [WriteBSWAP32] in { 1469// This instruction is a consequence of BSWAP32r observing operand size. The 1470// encoding is valid, but the behavior is undefined. 1471let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in 1472def BSWAP16r_BAD : I<0xC8, AddRegFrm, (outs GR16:$dst), (ins GR16:$src), 1473 "bswap{w}\t$dst", []>, OpSize16, TB; 1474// GR32 = bswap GR32 1475def BSWAP32r : I<0xC8, AddRegFrm, (outs GR32:$dst), (ins GR32:$src), 1476 "bswap{l}\t$dst", 1477 [(set GR32:$dst, (bswap GR32:$src))]>, OpSize32, TB; 1478 1479let SchedRW = [WriteBSWAP64] in 1480def BSWAP64r : RI<0xC8, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), 1481 "bswap{q}\t$dst", 1482 [(set GR64:$dst, (bswap GR64:$src))]>, TB; 1483} // Constraints = "$src = $dst", SchedRW 1484 1485// Bit scan instructions. 1486let Defs = [EFLAGS] in { 1487def BSF16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1488 "bsf{w}\t{$src, $dst|$dst, $src}", 1489 [(set GR16:$dst, EFLAGS, (X86bsf GR16:$src))]>, 1490 PS, OpSize16, Sched<[WriteBSF]>; 1491def BSF16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1492 "bsf{w}\t{$src, $dst|$dst, $src}", 1493 [(set GR16:$dst, EFLAGS, (X86bsf (loadi16 addr:$src)))]>, 1494 PS, OpSize16, Sched<[WriteBSFLd]>; 1495def BSF32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1496 "bsf{l}\t{$src, $dst|$dst, $src}", 1497 [(set GR32:$dst, EFLAGS, (X86bsf GR32:$src))]>, 1498 PS, OpSize32, Sched<[WriteBSF]>; 1499def BSF32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1500 "bsf{l}\t{$src, $dst|$dst, $src}", 1501 [(set GR32:$dst, EFLAGS, (X86bsf (loadi32 addr:$src)))]>, 1502 PS, OpSize32, Sched<[WriteBSFLd]>; 1503def BSF64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1504 "bsf{q}\t{$src, $dst|$dst, $src}", 1505 [(set GR64:$dst, EFLAGS, (X86bsf GR64:$src))]>, 1506 PS, Sched<[WriteBSF]>; 1507def BSF64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1508 "bsf{q}\t{$src, $dst|$dst, $src}", 1509 [(set GR64:$dst, EFLAGS, (X86bsf (loadi64 addr:$src)))]>, 1510 PS, Sched<[WriteBSFLd]>; 1511 1512def BSR16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1513 "bsr{w}\t{$src, $dst|$dst, $src}", 1514 [(set GR16:$dst, EFLAGS, (X86bsr GR16:$src))]>, 1515 PS, OpSize16, Sched<[WriteBSR]>; 1516def BSR16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1517 "bsr{w}\t{$src, $dst|$dst, $src}", 1518 [(set GR16:$dst, EFLAGS, (X86bsr (loadi16 addr:$src)))]>, 1519 PS, OpSize16, Sched<[WriteBSRLd]>; 1520def BSR32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1521 "bsr{l}\t{$src, $dst|$dst, $src}", 1522 [(set GR32:$dst, EFLAGS, (X86bsr GR32:$src))]>, 1523 PS, OpSize32, Sched<[WriteBSR]>; 1524def BSR32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1525 "bsr{l}\t{$src, $dst|$dst, $src}", 1526 [(set GR32:$dst, EFLAGS, (X86bsr (loadi32 addr:$src)))]>, 1527 PS, OpSize32, Sched<[WriteBSRLd]>; 1528def BSR64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1529 "bsr{q}\t{$src, $dst|$dst, $src}", 1530 [(set GR64:$dst, EFLAGS, (X86bsr GR64:$src))]>, 1531 PS, Sched<[WriteBSR]>; 1532def BSR64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1533 "bsr{q}\t{$src, $dst|$dst, $src}", 1534 [(set GR64:$dst, EFLAGS, (X86bsr (loadi64 addr:$src)))]>, 1535 PS, Sched<[WriteBSRLd]>; 1536} // Defs = [EFLAGS] 1537 1538let SchedRW = [WriteMicrocoded] in { 1539let Defs = [EDI,ESI], Uses = [EDI,ESI,DF] in { 1540def MOVSB : I<0xA4, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src), 1541 "movsb\t{$src, $dst|$dst, $src}", []>; 1542def MOVSW : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src), 1543 "movsw\t{$src, $dst|$dst, $src}", []>, OpSize16; 1544def MOVSL : I<0xA5, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src), 1545 "movs{l|d}\t{$src, $dst|$dst, $src}", []>, OpSize32; 1546def MOVSQ : RI<0xA5, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src), 1547 "movsq\t{$src, $dst|$dst, $src}", []>, 1548 Requires<[In64BitMode]>; 1549} 1550 1551let Defs = [EDI], Uses = [AL,EDI,DF] in 1552def STOSB : I<0xAA, RawFrmDst, (outs), (ins dstidx8:$dst), 1553 "stosb\t{%al, $dst|$dst, al}", []>; 1554let Defs = [EDI], Uses = [AX,EDI,DF] in 1555def STOSW : I<0xAB, RawFrmDst, (outs), (ins dstidx16:$dst), 1556 "stosw\t{%ax, $dst|$dst, ax}", []>, OpSize16; 1557let Defs = [EDI], Uses = [EAX,EDI,DF] in 1558def STOSL : I<0xAB, RawFrmDst, (outs), (ins dstidx32:$dst), 1559 "stos{l|d}\t{%eax, $dst|$dst, eax}", []>, OpSize32; 1560let Defs = [RDI], Uses = [RAX,RDI,DF] in 1561def STOSQ : RI<0xAB, RawFrmDst, (outs), (ins dstidx64:$dst), 1562 "stosq\t{%rax, $dst|$dst, rax}", []>, 1563 Requires<[In64BitMode]>; 1564 1565let Defs = [EDI,EFLAGS], Uses = [AL,EDI,DF] in 1566def SCASB : I<0xAE, RawFrmDst, (outs), (ins dstidx8:$dst), 1567 "scasb\t{$dst, %al|al, $dst}", []>; 1568let Defs = [EDI,EFLAGS], Uses = [AX,EDI,DF] in 1569def SCASW : I<0xAF, RawFrmDst, (outs), (ins dstidx16:$dst), 1570 "scasw\t{$dst, %ax|ax, $dst}", []>, OpSize16; 1571let Defs = [EDI,EFLAGS], Uses = [EAX,EDI,DF] in 1572def SCASL : I<0xAF, RawFrmDst, (outs), (ins dstidx32:$dst), 1573 "scas{l|d}\t{$dst, %eax|eax, $dst}", []>, OpSize32; 1574let Defs = [EDI,EFLAGS], Uses = [RAX,EDI,DF] in 1575def SCASQ : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst), 1576 "scasq\t{$dst, %rax|rax, $dst}", []>, 1577 Requires<[In64BitMode]>; 1578 1579let Defs = [EDI,ESI,EFLAGS], Uses = [EDI,ESI,DF] in { 1580def CMPSB : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src), 1581 "cmpsb\t{$dst, $src|$src, $dst}", []>; 1582def CMPSW : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src), 1583 "cmpsw\t{$dst, $src|$src, $dst}", []>, OpSize16; 1584def CMPSL : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src), 1585 "cmps{l|d}\t{$dst, $src|$src, $dst}", []>, OpSize32; 1586def CMPSQ : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src), 1587 "cmpsq\t{$dst, $src|$src, $dst}", []>, 1588 Requires<[In64BitMode]>; 1589} 1590} // SchedRW 1591 1592//===----------------------------------------------------------------------===// 1593// Move Instructions. 1594// 1595let SchedRW = [WriteMove] in { 1596let hasSideEffects = 0, isMoveReg = 1 in { 1597def MOV8rr : I<0x88, MRMDestReg, (outs GR8 :$dst), (ins GR8 :$src), 1598 "mov{b}\t{$src, $dst|$dst, $src}", []>; 1599def MOV16rr : I<0x89, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 1600 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16; 1601def MOV32rr : I<0x89, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), 1602 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32; 1603def MOV64rr : RI<0x89, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), 1604 "mov{q}\t{$src, $dst|$dst, $src}", []>; 1605} 1606 1607let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in { 1608def MOV8ri : Ii8 <0xB0, AddRegFrm, (outs GR8 :$dst), (ins i8imm :$src), 1609 "mov{b}\t{$src, $dst|$dst, $src}", 1610 [(set GR8:$dst, imm:$src)]>; 1611def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src), 1612 "mov{w}\t{$src, $dst|$dst, $src}", 1613 [(set GR16:$dst, imm:$src)]>, OpSize16; 1614def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src), 1615 "mov{l}\t{$src, $dst|$dst, $src}", 1616 [(set GR32:$dst, imm:$src)]>, OpSize32; 1617def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src), 1618 "mov{q}\t{$src, $dst|$dst, $src}", 1619 [(set GR64:$dst, i64immSExt32:$src)]>; 1620} 1621let isReMaterializable = 1, isMoveImm = 1 in { 1622def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src), 1623 "movabs{q}\t{$src, $dst|$dst, $src}", 1624 [(set GR64:$dst, imm:$src)]>; 1625} 1626 1627// Longer forms that use a ModR/M byte. Needed for disassembler 1628let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0 in { 1629def MOV8ri_alt : Ii8 <0xC6, MRM0r, (outs GR8 :$dst), (ins i8imm :$src), 1630 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1631 FoldGenData<"MOV8ri">; 1632def MOV16ri_alt : Ii16<0xC7, MRM0r, (outs GR16:$dst), (ins i16imm:$src), 1633 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16, 1634 FoldGenData<"MOV16ri">; 1635def MOV32ri_alt : Ii32<0xC7, MRM0r, (outs GR32:$dst), (ins i32imm:$src), 1636 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32, 1637 FoldGenData<"MOV32ri">; 1638} 1639} // SchedRW 1640 1641let SchedRW = [WriteStore] in { 1642def MOV8mi : Ii8 <0xC6, MRM0m, (outs), (ins i8mem :$dst, i8imm :$src), 1643 "mov{b}\t{$src, $dst|$dst, $src}", 1644 [(store (i8 imm_su:$src), addr:$dst)]>; 1645def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src), 1646 "mov{w}\t{$src, $dst|$dst, $src}", 1647 [(store (i16 imm_su:$src), addr:$dst)]>, OpSize16; 1648def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src), 1649 "mov{l}\t{$src, $dst|$dst, $src}", 1650 [(store (i32 imm_su:$src), addr:$dst)]>, OpSize32; 1651def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src), 1652 "mov{q}\t{$src, $dst|$dst, $src}", 1653 [(store i64immSExt32_su:$src, addr:$dst)]>, 1654 Requires<[In64BitMode]>; 1655} // SchedRW 1656 1657def : Pat<(i32 relocImm:$src), (MOV32ri relocImm:$src)>; 1658def : Pat<(i64 relocImm:$src), (MOV64ri relocImm:$src)>; 1659 1660def : Pat<(store (i8 relocImm8_su:$src), addr:$dst), 1661 (MOV8mi addr:$dst, relocImm8_su:$src)>; 1662def : Pat<(store (i16 relocImm16_su:$src), addr:$dst), 1663 (MOV16mi addr:$dst, relocImm16_su:$src)>; 1664def : Pat<(store (i32 relocImm32_su:$src), addr:$dst), 1665 (MOV32mi addr:$dst, relocImm32_su:$src)>; 1666def : Pat<(store (i64 i64relocImmSExt32_su:$src), addr:$dst), 1667 (MOV64mi32 addr:$dst, i64immSExt32_su:$src)>; 1668 1669let hasSideEffects = 0 in { 1670 1671/// Memory offset versions of moves. The immediate is an address mode sized 1672/// offset from the segment base. 1673let SchedRW = [WriteALU] in { 1674let mayLoad = 1 in { 1675let Defs = [AL] in 1676def MOV8ao32 : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset32_8:$src), 1677 "mov{b}\t{$src, %al|al, $src}", []>, 1678 AdSize32; 1679let Defs = [AX] in 1680def MOV16ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_16:$src), 1681 "mov{w}\t{$src, %ax|ax, $src}", []>, 1682 OpSize16, AdSize32; 1683let Defs = [EAX] in 1684def MOV32ao32 : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32_32:$src), 1685 "mov{l}\t{$src, %eax|eax, $src}", []>, 1686 OpSize32, AdSize32; 1687let Defs = [RAX] in 1688def MOV64ao32 : RIi32<0xA1, RawFrmMemOffs, (outs), (ins offset32_64:$src), 1689 "mov{q}\t{$src, %rax|rax, $src}", []>, 1690 AdSize32; 1691 1692let Defs = [AL] in 1693def MOV8ao16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset16_8:$src), 1694 "mov{b}\t{$src, %al|al, $src}", []>, AdSize16; 1695let Defs = [AX] in 1696def MOV16ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_16:$src), 1697 "mov{w}\t{$src, %ax|ax, $src}", []>, 1698 OpSize16, AdSize16; 1699let Defs = [EAX] in 1700def MOV32ao16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16_32:$src), 1701 "mov{l}\t{$src, %eax|eax, $src}", []>, 1702 AdSize16, OpSize32; 1703} // mayLoad 1704let mayStore = 1 in { 1705let Uses = [AL] in 1706def MOV8o32a : Ii32<0xA2, RawFrmMemOffs, (outs), (ins offset32_8:$dst), 1707 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize32; 1708let Uses = [AX] in 1709def MOV16o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_16:$dst), 1710 "mov{w}\t{%ax, $dst|$dst, ax}", []>, 1711 OpSize16, AdSize32; 1712let Uses = [EAX] in 1713def MOV32o32a : Ii32<0xA3, RawFrmMemOffs, (outs), (ins offset32_32:$dst), 1714 "mov{l}\t{%eax, $dst|$dst, eax}", []>, 1715 OpSize32, AdSize32; 1716let Uses = [RAX] in 1717def MOV64o32a : RIi32<0xA3, RawFrmMemOffs, (outs), (ins offset32_64:$dst), 1718 "mov{q}\t{%rax, $dst|$dst, rax}", []>, 1719 AdSize32; 1720 1721let Uses = [AL] in 1722def MOV8o16a : Ii16<0xA2, RawFrmMemOffs, (outs), (ins offset16_8:$dst), 1723 "mov{b}\t{%al, $dst|$dst, al}", []>, AdSize16; 1724let Uses = [AX] in 1725def MOV16o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_16:$dst), 1726 "mov{w}\t{%ax, $dst|$dst, ax}", []>, 1727 OpSize16, AdSize16; 1728let Uses = [EAX] in 1729def MOV32o16a : Ii16<0xA3, RawFrmMemOffs, (outs), (ins offset16_32:$dst), 1730 "mov{l}\t{%eax, $dst|$dst, eax}", []>, 1731 OpSize32, AdSize16; 1732} // mayStore 1733 1734// These forms all have full 64-bit absolute addresses in their instructions 1735// and use the movabs mnemonic to indicate this specific form. 1736let mayLoad = 1 in { 1737let Defs = [AL] in 1738def MOV8ao64 : Ii64<0xA0, RawFrmMemOffs, (outs), (ins offset64_8:$src), 1739 "movabs{b}\t{$src, %al|al, $src}", []>, 1740 AdSize64; 1741let Defs = [AX] in 1742def MOV16ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_16:$src), 1743 "movabs{w}\t{$src, %ax|ax, $src}", []>, 1744 OpSize16, AdSize64; 1745let Defs = [EAX] in 1746def MOV32ao64 : Ii64<0xA1, RawFrmMemOffs, (outs), (ins offset64_32:$src), 1747 "movabs{l}\t{$src, %eax|eax, $src}", []>, 1748 OpSize32, AdSize64; 1749let Defs = [RAX] in 1750def MOV64ao64 : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64_64:$src), 1751 "movabs{q}\t{$src, %rax|rax, $src}", []>, 1752 AdSize64; 1753} // mayLoad 1754 1755let mayStore = 1 in { 1756let Uses = [AL] in 1757def MOV8o64a : Ii64<0xA2, RawFrmMemOffs, (outs), (ins offset64_8:$dst), 1758 "movabs{b}\t{%al, $dst|$dst, al}", []>, 1759 AdSize64; 1760let Uses = [AX] in 1761def MOV16o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_16:$dst), 1762 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, 1763 OpSize16, AdSize64; 1764let Uses = [EAX] in 1765def MOV32o64a : Ii64<0xA3, RawFrmMemOffs, (outs), (ins offset64_32:$dst), 1766 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, 1767 OpSize32, AdSize64; 1768let Uses = [RAX] in 1769def MOV64o64a : RIi64<0xA3, RawFrmMemOffs, (outs), (ins offset64_64:$dst), 1770 "movabs{q}\t{%rax, $dst|$dst, rax}", []>, 1771 AdSize64; 1772} // mayStore 1773} // SchedRW 1774} // hasSideEffects = 0 1775 1776let isCodeGenOnly = 1, ForceDisassemble = 1, hasSideEffects = 0, 1777 SchedRW = [WriteMove], isMoveReg = 1 in { 1778def MOV8rr_REV : I<0x8A, MRMSrcReg, (outs GR8:$dst), (ins GR8:$src), 1779 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1780 FoldGenData<"MOV8rr">; 1781def MOV16rr_REV : I<0x8B, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 1782 "mov{w}\t{$src, $dst|$dst, $src}", []>, OpSize16, 1783 FoldGenData<"MOV16rr">; 1784def MOV32rr_REV : I<0x8B, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 1785 "mov{l}\t{$src, $dst|$dst, $src}", []>, OpSize32, 1786 FoldGenData<"MOV32rr">; 1787def MOV64rr_REV : RI<0x8B, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 1788 "mov{q}\t{$src, $dst|$dst, $src}", []>, 1789 FoldGenData<"MOV64rr">; 1790} 1791 1792// Reversed version with ".s" suffix for GAS compatibility. 1793def : InstAlias<"mov{b}.s\t{$src, $dst|$dst, $src}", 1794 (MOV8rr_REV GR8:$dst, GR8:$src), 0>; 1795def : InstAlias<"mov{w}.s\t{$src, $dst|$dst, $src}", 1796 (MOV16rr_REV GR16:$dst, GR16:$src), 0>; 1797def : InstAlias<"mov{l}.s\t{$src, $dst|$dst, $src}", 1798 (MOV32rr_REV GR32:$dst, GR32:$src), 0>; 1799def : InstAlias<"mov{q}.s\t{$src, $dst|$dst, $src}", 1800 (MOV64rr_REV GR64:$dst, GR64:$src), 0>; 1801def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1802 (MOV8rr_REV GR8:$dst, GR8:$src), 0, "att">; 1803def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1804 (MOV16rr_REV GR16:$dst, GR16:$src), 0, "att">; 1805def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1806 (MOV32rr_REV GR32:$dst, GR32:$src), 0, "att">; 1807def : InstAlias<"mov.s\t{$src, $dst|$dst, $src}", 1808 (MOV64rr_REV GR64:$dst, GR64:$src), 0, "att">; 1809 1810let canFoldAsLoad = 1, isReMaterializable = 1, SchedRW = [WriteLoad] in { 1811def MOV8rm : I<0x8A, MRMSrcMem, (outs GR8 :$dst), (ins i8mem :$src), 1812 "mov{b}\t{$src, $dst|$dst, $src}", 1813 [(set GR8:$dst, (loadi8 addr:$src))]>; 1814def MOV16rm : I<0x8B, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 1815 "mov{w}\t{$src, $dst|$dst, $src}", 1816 [(set GR16:$dst, (loadi16 addr:$src))]>, OpSize16; 1817def MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 1818 "mov{l}\t{$src, $dst|$dst, $src}", 1819 [(set GR32:$dst, (loadi32 addr:$src))]>, OpSize32; 1820def MOV64rm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 1821 "mov{q}\t{$src, $dst|$dst, $src}", 1822 [(set GR64:$dst, (load addr:$src))]>; 1823} 1824 1825let SchedRW = [WriteStore] in { 1826def MOV8mr : I<0x88, MRMDestMem, (outs), (ins i8mem :$dst, GR8 :$src), 1827 "mov{b}\t{$src, $dst|$dst, $src}", 1828 [(store GR8:$src, addr:$dst)]>; 1829def MOV16mr : I<0x89, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 1830 "mov{w}\t{$src, $dst|$dst, $src}", 1831 [(store GR16:$src, addr:$dst)]>, OpSize16; 1832def MOV32mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 1833 "mov{l}\t{$src, $dst|$dst, $src}", 1834 [(store GR32:$src, addr:$dst)]>, OpSize32; 1835def MOV64mr : RI<0x89, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 1836 "mov{q}\t{$src, $dst|$dst, $src}", 1837 [(store GR64:$src, addr:$dst)]>; 1838} // SchedRW 1839 1840// Versions of MOV8rr, MOV8mr, and MOV8rm that use i8mem_NOREX and GR8_NOREX so 1841// that they can be used for copying and storing h registers, which can't be 1842// encoded when a REX prefix is present. 1843let isCodeGenOnly = 1 in { 1844let hasSideEffects = 0, isMoveReg = 1 in 1845def MOV8rr_NOREX : I<0x88, MRMDestReg, 1846 (outs GR8_NOREX:$dst), (ins GR8_NOREX:$src), 1847 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1848 Sched<[WriteMove]>; 1849let mayStore = 1, hasSideEffects = 0 in 1850def MOV8mr_NOREX : I<0x88, MRMDestMem, 1851 (outs), (ins i8mem_NOREX:$dst, GR8_NOREX:$src), 1852 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1853 Sched<[WriteStore]>; 1854let mayLoad = 1, hasSideEffects = 0, 1855 canFoldAsLoad = 1, isReMaterializable = 1 in 1856def MOV8rm_NOREX : I<0x8A, MRMSrcMem, 1857 (outs GR8_NOREX:$dst), (ins i8mem_NOREX:$src), 1858 "mov{b}\t{$src, $dst|$dst, $src}", []>, 1859 Sched<[WriteLoad]>; 1860} 1861 1862 1863// Condition code ops, incl. set if equal/not equal/... 1864let SchedRW = [WriteLAHFSAHF] in { 1865let Defs = [EFLAGS], Uses = [AH], hasSideEffects = 0 in 1866def SAHF : I<0x9E, RawFrm, (outs), (ins), "sahf", []>, // flags = AH 1867 Requires<[HasLAHFSAHF]>; 1868let Defs = [AH], Uses = [EFLAGS], hasSideEffects = 0 in 1869def LAHF : I<0x9F, RawFrm, (outs), (ins), "lahf", []>, // AH = flags 1870 Requires<[HasLAHFSAHF]>; 1871} // SchedRW 1872 1873//===----------------------------------------------------------------------===// 1874// Bit tests instructions: BT, BTS, BTR, BTC. 1875 1876let Defs = [EFLAGS] in { 1877let SchedRW = [WriteBitTest] in { 1878def BT16rr : I<0xA3, MRMDestReg, (outs), (ins GR16:$src1, GR16:$src2), 1879 "bt{w}\t{$src2, $src1|$src1, $src2}", 1880 [(set EFLAGS, (X86bt GR16:$src1, GR16:$src2))]>, 1881 OpSize16, TB, NotMemoryFoldable; 1882def BT32rr : I<0xA3, MRMDestReg, (outs), (ins GR32:$src1, GR32:$src2), 1883 "bt{l}\t{$src2, $src1|$src1, $src2}", 1884 [(set EFLAGS, (X86bt GR32:$src1, GR32:$src2))]>, 1885 OpSize32, TB, NotMemoryFoldable; 1886def BT64rr : RI<0xA3, MRMDestReg, (outs), (ins GR64:$src1, GR64:$src2), 1887 "bt{q}\t{$src2, $src1|$src1, $src2}", 1888 [(set EFLAGS, (X86bt GR64:$src1, GR64:$src2))]>, TB, 1889 NotMemoryFoldable; 1890} // SchedRW 1891 1892// Unlike with the register+register form, the memory+register form of the 1893// bt instruction does not ignore the high bits of the index. From ISel's 1894// perspective, this is pretty bizarre. Make these instructions disassembly 1895// only for now. These instructions are also slow on modern CPUs so that's 1896// another reason to avoid generating them. 1897 1898let mayLoad = 1, hasSideEffects = 0, SchedRW = [WriteBitTestRegLd] in { 1899 def BT16mr : I<0xA3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 1900 "bt{w}\t{$src2, $src1|$src1, $src2}", 1901 []>, OpSize16, TB, NotMemoryFoldable; 1902 def BT32mr : I<0xA3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 1903 "bt{l}\t{$src2, $src1|$src1, $src2}", 1904 []>, OpSize32, TB, NotMemoryFoldable; 1905 def BT64mr : RI<0xA3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 1906 "bt{q}\t{$src2, $src1|$src1, $src2}", 1907 []>, TB, NotMemoryFoldable; 1908} 1909 1910let SchedRW = [WriteBitTest] in { 1911def BT16ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR16:$src1, i16u8imm:$src2), 1912 "bt{w}\t{$src2, $src1|$src1, $src2}", 1913 [(set EFLAGS, (X86bt GR16:$src1, imm:$src2))]>, 1914 OpSize16, TB; 1915def BT32ri8 : Ii8<0xBA, MRM4r, (outs), (ins GR32:$src1, i32u8imm:$src2), 1916 "bt{l}\t{$src2, $src1|$src1, $src2}", 1917 [(set EFLAGS, (X86bt GR32:$src1, imm:$src2))]>, 1918 OpSize32, TB; 1919def BT64ri8 : RIi8<0xBA, MRM4r, (outs), (ins GR64:$src1, i64u8imm:$src2), 1920 "bt{q}\t{$src2, $src1|$src1, $src2}", 1921 [(set EFLAGS, (X86bt GR64:$src1, imm:$src2))]>, TB; 1922} // SchedRW 1923 1924// Note that these instructions aren't slow because that only applies when the 1925// other operand is in a register. When it's an immediate, bt is still fast. 1926let SchedRW = [WriteBitTestImmLd] in { 1927def BT16mi8 : Ii8<0xBA, MRM4m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 1928 "bt{w}\t{$src2, $src1|$src1, $src2}", 1929 [(set EFLAGS, (X86bt (loadi16 addr:$src1), 1930 imm:$src2))]>, 1931 OpSize16, TB; 1932def BT32mi8 : Ii8<0xBA, MRM4m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 1933 "bt{l}\t{$src2, $src1|$src1, $src2}", 1934 [(set EFLAGS, (X86bt (loadi32 addr:$src1), 1935 imm:$src2))]>, 1936 OpSize32, TB; 1937def BT64mi8 : RIi8<0xBA, MRM4m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 1938 "bt{q}\t{$src2, $src1|$src1, $src2}", 1939 [(set EFLAGS, (X86bt (loadi64 addr:$src1), 1940 imm:$src2))]>, TB, 1941 Requires<[In64BitMode]>; 1942} // SchedRW 1943 1944let hasSideEffects = 0 in { 1945let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1946def BTC16rr : I<0xBB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 1947 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, 1948 OpSize16, TB, NotMemoryFoldable; 1949def BTC32rr : I<0xBB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 1950 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, 1951 OpSize32, TB, NotMemoryFoldable; 1952def BTC64rr : RI<0xBB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 1953 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1954 NotMemoryFoldable; 1955} // SchedRW 1956 1957let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 1958def BTC16mr : I<0xBB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 1959 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, 1960 OpSize16, TB, NotMemoryFoldable; 1961def BTC32mr : I<0xBB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 1962 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, 1963 OpSize32, TB, NotMemoryFoldable; 1964def BTC64mr : RI<0xBB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 1965 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1966 NotMemoryFoldable; 1967} 1968 1969let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1970def BTC16ri8 : Ii8<0xBA, MRM7r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 1971 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 1972def BTC32ri8 : Ii8<0xBA, MRM7r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 1973 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 1974def BTC64ri8 : RIi8<0xBA, MRM7r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 1975 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 1976} // SchedRW 1977 1978let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 1979def BTC16mi8 : Ii8<0xBA, MRM7m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 1980 "btc{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 1981def BTC32mi8 : Ii8<0xBA, MRM7m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 1982 "btc{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 1983def BTC64mi8 : RIi8<0xBA, MRM7m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 1984 "btc{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1985 Requires<[In64BitMode]>; 1986} 1987 1988let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 1989def BTR16rr : I<0xB3, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 1990 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 1991 OpSize16, TB, NotMemoryFoldable; 1992def BTR32rr : I<0xB3, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 1993 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 1994 OpSize32, TB, NotMemoryFoldable; 1995def BTR64rr : RI<0xB3, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 1996 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 1997 NotMemoryFoldable; 1998} // SchedRW 1999 2000let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 2001def BTR16mr : I<0xB3, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 2002 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2003 OpSize16, TB, NotMemoryFoldable; 2004def BTR32mr : I<0xB3, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 2005 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2006 OpSize32, TB, NotMemoryFoldable; 2007def BTR64mr : RI<0xB3, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 2008 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2009 NotMemoryFoldable; 2010} 2011 2012let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2013def BTR16ri8 : Ii8<0xBA, MRM6r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 2014 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2015 OpSize16, TB; 2016def BTR32ri8 : Ii8<0xBA, MRM6r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 2017 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2018 OpSize32, TB; 2019def BTR64ri8 : RIi8<0xBA, MRM6r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 2020 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2021} // SchedRW 2022 2023let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 2024def BTR16mi8 : Ii8<0xBA, MRM6m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 2025 "btr{w}\t{$src2, $src1|$src1, $src2}", []>, 2026 OpSize16, TB; 2027def BTR32mi8 : Ii8<0xBA, MRM6m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 2028 "btr{l}\t{$src2, $src1|$src1, $src2}", []>, 2029 OpSize32, TB; 2030def BTR64mi8 : RIi8<0xBA, MRM6m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 2031 "btr{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2032 Requires<[In64BitMode]>; 2033} 2034 2035let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2036def BTS16rr : I<0xAB, MRMDestReg, (outs GR16:$dst), (ins GR16:$src1, GR16:$src2), 2037 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, 2038 OpSize16, TB, NotMemoryFoldable; 2039def BTS32rr : I<0xAB, MRMDestReg, (outs GR32:$dst), (ins GR32:$src1, GR32:$src2), 2040 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, 2041 OpSize32, TB, NotMemoryFoldable; 2042def BTS64rr : RI<0xAB, MRMDestReg, (outs GR64:$dst), (ins GR64:$src1, GR64:$src2), 2043 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2044 NotMemoryFoldable; 2045} // SchedRW 2046 2047let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetRegRMW] in { 2048def BTS16mr : I<0xAB, MRMDestMem, (outs), (ins i16mem:$src1, GR16:$src2), 2049 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, 2050 OpSize16, TB, NotMemoryFoldable; 2051def BTS32mr : I<0xAB, MRMDestMem, (outs), (ins i32mem:$src1, GR32:$src2), 2052 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, 2053 OpSize32, TB, NotMemoryFoldable; 2054def BTS64mr : RI<0xAB, MRMDestMem, (outs), (ins i64mem:$src1, GR64:$src2), 2055 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2056 NotMemoryFoldable; 2057} 2058 2059let SchedRW = [WriteBitTestSet], Constraints = "$src1 = $dst" in { 2060def BTS16ri8 : Ii8<0xBA, MRM5r, (outs GR16:$dst), (ins GR16:$src1, i16u8imm:$src2), 2061 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 2062def BTS32ri8 : Ii8<0xBA, MRM5r, (outs GR32:$dst), (ins GR32:$src1, i32u8imm:$src2), 2063 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 2064def BTS64ri8 : RIi8<0xBA, MRM5r, (outs GR64:$dst), (ins GR64:$src1, i64u8imm:$src2), 2065 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2066} // SchedRW 2067 2068let mayLoad = 1, mayStore = 1, SchedRW = [WriteBitTestSetImmRMW] in { 2069def BTS16mi8 : Ii8<0xBA, MRM5m, (outs), (ins i16mem:$src1, i16u8imm:$src2), 2070 "bts{w}\t{$src2, $src1|$src1, $src2}", []>, OpSize16, TB; 2071def BTS32mi8 : Ii8<0xBA, MRM5m, (outs), (ins i32mem:$src1, i32u8imm:$src2), 2072 "bts{l}\t{$src2, $src1|$src1, $src2}", []>, OpSize32, TB; 2073def BTS64mi8 : RIi8<0xBA, MRM5m, (outs), (ins i64mem:$src1, i64u8imm:$src2), 2074 "bts{q}\t{$src2, $src1|$src1, $src2}", []>, TB, 2075 Requires<[In64BitMode]>; 2076} 2077} // hasSideEffects = 0 2078} // Defs = [EFLAGS] 2079 2080 2081//===----------------------------------------------------------------------===// 2082// Atomic support 2083// 2084 2085// Atomic swap. These are just normal xchg instructions. But since a memory 2086// operand is referenced, the atomicity is ensured. 2087multiclass ATOMIC_SWAP<bits<8> opc8, bits<8> opc, string mnemonic, string frag> { 2088 let Constraints = "$val = $dst", SchedRW = [WriteALULd, WriteRMW] in { 2089 def NAME#8rm : I<opc8, MRMSrcMem, (outs GR8:$dst), 2090 (ins GR8:$val, i8mem:$ptr), 2091 !strconcat(mnemonic, "{b}\t{$val, $ptr|$ptr, $val}"), 2092 [(set 2093 GR8:$dst, 2094 (!cast<PatFrag>(frag # "_8") addr:$ptr, GR8:$val))]>; 2095 def NAME#16rm : I<opc, MRMSrcMem, (outs GR16:$dst), 2096 (ins GR16:$val, i16mem:$ptr), 2097 !strconcat(mnemonic, "{w}\t{$val, $ptr|$ptr, $val}"), 2098 [(set 2099 GR16:$dst, 2100 (!cast<PatFrag>(frag # "_16") addr:$ptr, GR16:$val))]>, 2101 OpSize16; 2102 def NAME#32rm : I<opc, MRMSrcMem, (outs GR32:$dst), 2103 (ins GR32:$val, i32mem:$ptr), 2104 !strconcat(mnemonic, "{l}\t{$val, $ptr|$ptr, $val}"), 2105 [(set 2106 GR32:$dst, 2107 (!cast<PatFrag>(frag # "_32") addr:$ptr, GR32:$val))]>, 2108 OpSize32; 2109 def NAME#64rm : RI<opc, MRMSrcMem, (outs GR64:$dst), 2110 (ins GR64:$val, i64mem:$ptr), 2111 !strconcat(mnemonic, "{q}\t{$val, $ptr|$ptr, $val}"), 2112 [(set 2113 GR64:$dst, 2114 (!cast<PatFrag>(frag # "_64") addr:$ptr, GR64:$val))]>; 2115 } 2116} 2117 2118defm XCHG : ATOMIC_SWAP<0x86, 0x87, "xchg", "atomic_swap">, NotMemoryFoldable; 2119 2120// Swap between registers. 2121let SchedRW = [WriteXCHG] in { 2122let Constraints = "$src1 = $dst1, $src2 = $dst2", hasSideEffects = 0 in { 2123def XCHG8rr : I<0x86, MRMSrcReg, (outs GR8:$dst1, GR8:$dst2), 2124 (ins GR8:$src1, GR8:$src2), 2125 "xchg{b}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable; 2126def XCHG16rr : I<0x87, MRMSrcReg, (outs GR16:$dst1, GR16:$dst2), 2127 (ins GR16:$src1, GR16:$src2), 2128 "xchg{w}\t{$src2, $src1|$src1, $src2}", []>, 2129 OpSize16, NotMemoryFoldable; 2130def XCHG32rr : I<0x87, MRMSrcReg, (outs GR32:$dst1, GR32:$dst2), 2131 (ins GR32:$src1, GR32:$src2), 2132 "xchg{l}\t{$src2, $src1|$src1, $src2}", []>, 2133 OpSize32, NotMemoryFoldable; 2134def XCHG64rr : RI<0x87, MRMSrcReg, (outs GR64:$dst1, GR64:$dst2), 2135 (ins GR64:$src1 ,GR64:$src2), 2136 "xchg{q}\t{$src2, $src1|$src1, $src2}", []>, NotMemoryFoldable; 2137} 2138 2139// Swap between EAX and other registers. 2140let Constraints = "$src = $dst", hasSideEffects = 0 in { 2141let Uses = [AX], Defs = [AX] in 2142def XCHG16ar : I<0x90, AddRegFrm, (outs GR16:$dst), (ins GR16:$src), 2143 "xchg{w}\t{$src, %ax|ax, $src}", []>, OpSize16; 2144let Uses = [EAX], Defs = [EAX] in 2145def XCHG32ar : I<0x90, AddRegFrm, (outs GR32:$dst), (ins GR32:$src), 2146 "xchg{l}\t{$src, %eax|eax, $src}", []>, OpSize32; 2147let Uses = [RAX], Defs = [RAX] in 2148def XCHG64ar : RI<0x90, AddRegFrm, (outs GR64:$dst), (ins GR64:$src), 2149 "xchg{q}\t{$src, %rax|rax, $src}", []>; 2150} 2151} // SchedRW 2152 2153let hasSideEffects = 0, Constraints = "$src1 = $dst1, $src2 = $dst2", 2154 Defs = [EFLAGS], SchedRW = [WriteXCHG] in { 2155def XADD8rr : I<0xC0, MRMDestReg, (outs GR8:$dst1, GR8:$dst2), 2156 (ins GR8:$src1, GR8:$src2), 2157 "xadd{b}\t{$src2, $src1|$src1, $src2}", []>, TB; 2158def XADD16rr : I<0xC1, MRMDestReg, (outs GR16:$dst1, GR16:$dst2), 2159 (ins GR16:$src1, GR16:$src2), 2160 "xadd{w}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize16; 2161def XADD32rr : I<0xC1, MRMDestReg, (outs GR32:$dst1, GR32:$dst2), 2162 (ins GR32:$src1, GR32:$src2), 2163 "xadd{l}\t{$src2, $src1|$src1, $src2}", []>, TB, OpSize32; 2164def XADD64rr : RI<0xC1, MRMDestReg, (outs GR64:$dst1, GR64:$dst2), 2165 (ins GR64:$src1, GR64:$src2), 2166 "xadd{q}\t{$src2, $src1|$src1, $src2}", []>, TB; 2167} // SchedRW 2168 2169let mayLoad = 1, mayStore = 1, hasSideEffects = 0, Constraints = "$val = $dst", 2170 Defs = [EFLAGS], SchedRW = [WriteALULd, WriteRMW] in { 2171def XADD8rm : I<0xC0, MRMSrcMem, (outs GR8:$dst), 2172 (ins GR8:$val, i8mem:$ptr), 2173 "xadd{b}\t{$val, $ptr|$ptr, $val}", []>, TB; 2174def XADD16rm : I<0xC1, MRMSrcMem, (outs GR16:$dst), 2175 (ins GR16:$val, i16mem:$ptr), 2176 "xadd{w}\t{$val, $ptr|$ptr, $val}", []>, TB, 2177 OpSize16; 2178def XADD32rm : I<0xC1, MRMSrcMem, (outs GR32:$dst), 2179 (ins GR32:$val, i32mem:$ptr), 2180 "xadd{l}\t{$val, $ptr|$ptr, $val}", []>, TB, 2181 OpSize32; 2182def XADD64rm : RI<0xC1, MRMSrcMem, (outs GR64:$dst), 2183 (ins GR64:$val, i64mem:$ptr), 2184 "xadd{q}\t{$val, $ptr|$ptr, $val}", []>, TB; 2185 2186} 2187 2188let SchedRW = [WriteCMPXCHG], hasSideEffects = 0 in { 2189let Defs = [AL, EFLAGS], Uses = [AL] in 2190def CMPXCHG8rr : I<0xB0, MRMDestReg, (outs GR8:$dst), (ins GR8:$src), 2191 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB, 2192 NotMemoryFoldable; 2193let Defs = [AX, EFLAGS], Uses = [AX] in 2194def CMPXCHG16rr : I<0xB1, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 2195 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, 2196 NotMemoryFoldable; 2197let Defs = [EAX, EFLAGS], Uses = [EAX] in 2198def CMPXCHG32rr : I<0xB1, MRMDestReg, (outs GR32:$dst), (ins GR32:$src), 2199 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, 2200 NotMemoryFoldable; 2201let Defs = [RAX, EFLAGS], Uses = [RAX] in 2202def CMPXCHG64rr : RI<0xB1, MRMDestReg, (outs GR64:$dst), (ins GR64:$src), 2203 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB, 2204 NotMemoryFoldable; 2205} // SchedRW, hasSideEffects 2206 2207let SchedRW = [WriteCMPXCHGRMW], mayLoad = 1, mayStore = 1, 2208 hasSideEffects = 0 in { 2209let Defs = [AL, EFLAGS], Uses = [AL] in 2210def CMPXCHG8rm : I<0xB0, MRMDestMem, (outs), (ins i8mem:$dst, GR8:$src), 2211 "cmpxchg{b}\t{$src, $dst|$dst, $src}", []>, TB, 2212 NotMemoryFoldable; 2213let Defs = [AX, EFLAGS], Uses = [AX] in 2214def CMPXCHG16rm : I<0xB1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2215 "cmpxchg{w}\t{$src, $dst|$dst, $src}", []>, TB, OpSize16, 2216 NotMemoryFoldable; 2217let Defs = [EAX, EFLAGS], Uses = [EAX] in 2218def CMPXCHG32rm : I<0xB1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2219 "cmpxchg{l}\t{$src, $dst|$dst, $src}", []>, TB, OpSize32, 2220 NotMemoryFoldable; 2221let Defs = [RAX, EFLAGS], Uses = [RAX] in 2222def CMPXCHG64rm : RI<0xB1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2223 "cmpxchg{q}\t{$src, $dst|$dst, $src}", []>, TB, 2224 NotMemoryFoldable; 2225 2226let Defs = [EAX, EDX, EFLAGS], Uses = [EAX, EBX, ECX, EDX] in 2227def CMPXCHG8B : I<0xC7, MRM1m, (outs), (ins i64mem:$dst), 2228 "cmpxchg8b\t$dst", []>, TB, Requires<[HasCmpxchg8b]>; 2229 2230let Defs = [RAX, RDX, EFLAGS], Uses = [RAX, RBX, RCX, RDX] in 2231// NOTE: In64BitMode check needed for the AssemblerPredicate. 2232def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst), 2233 "cmpxchg16b\t$dst", []>, 2234 TB, Requires<[HasCmpxchg16b,In64BitMode]>; 2235} // SchedRW, mayLoad, mayStore, hasSideEffects 2236 2237 2238// Lock instruction prefix 2239let SchedRW = [WriteMicrocoded] in 2240def LOCK_PREFIX : I<0xF0, PrefixByte, (outs), (ins), "lock", []>; 2241 2242let SchedRW = [WriteNop] in { 2243 2244// Rex64 instruction prefix 2245def REX64_PREFIX : I<0x48, PrefixByte, (outs), (ins), "rex64", []>, 2246 Requires<[In64BitMode]>; 2247 2248// Data16 instruction prefix 2249def DATA16_PREFIX : I<0x66, PrefixByte, (outs), (ins), "data16", []>; 2250} // SchedRW 2251 2252// Repeat string operation instruction prefixes 2253let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in { 2254// Repeat (used with INS, OUTS, MOVS, LODS and STOS) 2255def REP_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "rep", []>; 2256// Repeat while not equal (used with CMPS and SCAS) 2257def REPNE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "repne", []>; 2258} 2259 2260// String manipulation instructions 2261let SchedRW = [WriteMicrocoded] in { 2262let Defs = [AL,ESI], Uses = [ESI,DF] in 2263def LODSB : I<0xAC, RawFrmSrc, (outs), (ins srcidx8:$src), 2264 "lodsb\t{$src, %al|al, $src}", []>; 2265let Defs = [AX,ESI], Uses = [ESI,DF] in 2266def LODSW : I<0xAD, RawFrmSrc, (outs), (ins srcidx16:$src), 2267 "lodsw\t{$src, %ax|ax, $src}", []>, OpSize16; 2268let Defs = [EAX,ESI], Uses = [ESI,DF] in 2269def LODSL : I<0xAD, RawFrmSrc, (outs), (ins srcidx32:$src), 2270 "lods{l|d}\t{$src, %eax|eax, $src}", []>, OpSize32; 2271let Defs = [RAX,ESI], Uses = [ESI,DF] in 2272def LODSQ : RI<0xAD, RawFrmSrc, (outs), (ins srcidx64:$src), 2273 "lodsq\t{$src, %rax|rax, $src}", []>, 2274 Requires<[In64BitMode]>; 2275} 2276 2277let SchedRW = [WriteSystem] in { 2278let Defs = [ESI], Uses = [DX,ESI,DF] in { 2279def OUTSB : I<0x6E, RawFrmSrc, (outs), (ins srcidx8:$src), 2280 "outsb\t{$src, %dx|dx, $src}", []>; 2281def OUTSW : I<0x6F, RawFrmSrc, (outs), (ins srcidx16:$src), 2282 "outsw\t{$src, %dx|dx, $src}", []>, OpSize16; 2283def OUTSL : I<0x6F, RawFrmSrc, (outs), (ins srcidx32:$src), 2284 "outs{l|d}\t{$src, %dx|dx, $src}", []>, OpSize32; 2285} 2286 2287let Defs = [EDI], Uses = [DX,EDI,DF] in { 2288def INSB : I<0x6C, RawFrmDst, (outs), (ins dstidx8:$dst), 2289 "insb\t{%dx, $dst|$dst, dx}", []>; 2290def INSW : I<0x6D, RawFrmDst, (outs), (ins dstidx16:$dst), 2291 "insw\t{%dx, $dst|$dst, dx}", []>, OpSize16; 2292def INSL : I<0x6D, RawFrmDst, (outs), (ins dstidx32:$dst), 2293 "ins{l|d}\t{%dx, $dst|$dst, dx}", []>, OpSize32; 2294} 2295} 2296 2297// EFLAGS management instructions. 2298let SchedRW = [WriteALU], Defs = [EFLAGS], Uses = [EFLAGS] in { 2299def CLC : I<0xF8, RawFrm, (outs), (ins), "clc", []>; 2300def STC : I<0xF9, RawFrm, (outs), (ins), "stc", []>; 2301def CMC : I<0xF5, RawFrm, (outs), (ins), "cmc", []>; 2302} 2303 2304// DF management instructions. 2305let SchedRW = [WriteALU], Defs = [DF] in { 2306def CLD : I<0xFC, RawFrm, (outs), (ins), "cld", []>; 2307def STD : I<0xFD, RawFrm, (outs), (ins), "std", []>; 2308} 2309 2310// Table lookup instructions 2311let Uses = [AL,EBX], Defs = [AL], hasSideEffects = 0, mayLoad = 1 in 2312def XLAT : I<0xD7, RawFrm, (outs), (ins), "xlatb", []>, Sched<[WriteLoad]>; 2313 2314let SchedRW = [WriteMicrocoded] in { 2315// ASCII Adjust After Addition 2316let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2317def AAA : I<0x37, RawFrm, (outs), (ins), "aaa", []>, 2318 Requires<[Not64BitMode]>; 2319 2320// ASCII Adjust AX Before Division 2321let Uses = [AX], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2322def AAD8i8 : Ii8<0xD5, RawFrm, (outs), (ins i8imm:$src), 2323 "aad\t$src", []>, Requires<[Not64BitMode]>; 2324 2325// ASCII Adjust AX After Multiply 2326let Uses = [AL], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2327def AAM8i8 : Ii8<0xD4, RawFrm, (outs), (ins i8imm:$src), 2328 "aam\t$src", []>, Requires<[Not64BitMode]>; 2329 2330// ASCII Adjust AL After Subtraction - sets 2331let Uses = [AL,EFLAGS], Defs = [AX,EFLAGS], hasSideEffects = 0 in 2332def AAS : I<0x3F, RawFrm, (outs), (ins), "aas", []>, 2333 Requires<[Not64BitMode]>; 2334 2335// Decimal Adjust AL after Addition 2336let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in 2337def DAA : I<0x27, RawFrm, (outs), (ins), "daa", []>, 2338 Requires<[Not64BitMode]>; 2339 2340// Decimal Adjust AL after Subtraction 2341let Uses = [AL,EFLAGS], Defs = [AL,EFLAGS], hasSideEffects = 0 in 2342def DAS : I<0x2F, RawFrm, (outs), (ins), "das", []>, 2343 Requires<[Not64BitMode]>; 2344} // SchedRW 2345 2346let SchedRW = [WriteSystem] in { 2347// Check Array Index Against Bounds 2348// Note: "bound" does not have reversed operands in at&t syntax. 2349def BOUNDS16rm : I<0x62, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2350 "bound\t$dst, $src", []>, OpSize16, 2351 Requires<[Not64BitMode]>; 2352def BOUNDS32rm : I<0x62, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2353 "bound\t$dst, $src", []>, OpSize32, 2354 Requires<[Not64BitMode]>; 2355 2356// Adjust RPL Field of Segment Selector 2357def ARPL16rr : I<0x63, MRMDestReg, (outs GR16:$dst), (ins GR16:$src), 2358 "arpl\t{$src, $dst|$dst, $src}", []>, 2359 Requires<[Not64BitMode]>, NotMemoryFoldable; 2360let mayStore = 1 in 2361def ARPL16mr : I<0x63, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2362 "arpl\t{$src, $dst|$dst, $src}", []>, 2363 Requires<[Not64BitMode]>, NotMemoryFoldable; 2364} // SchedRW 2365 2366//===----------------------------------------------------------------------===// 2367// MOVBE Instructions 2368// 2369let Predicates = [HasMOVBE] in { 2370 let SchedRW = [WriteALULd] in { 2371 def MOVBE16rm : I<0xF0, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2372 "movbe{w}\t{$src, $dst|$dst, $src}", 2373 [(set GR16:$dst, (bswap (loadi16 addr:$src)))]>, 2374 OpSize16, T8PS; 2375 def MOVBE32rm : I<0xF0, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2376 "movbe{l}\t{$src, $dst|$dst, $src}", 2377 [(set GR32:$dst, (bswap (loadi32 addr:$src)))]>, 2378 OpSize32, T8PS; 2379 def MOVBE64rm : RI<0xF0, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2380 "movbe{q}\t{$src, $dst|$dst, $src}", 2381 [(set GR64:$dst, (bswap (loadi64 addr:$src)))]>, 2382 T8PS; 2383 } 2384 let SchedRW = [WriteStore] in { 2385 def MOVBE16mr : I<0xF1, MRMDestMem, (outs), (ins i16mem:$dst, GR16:$src), 2386 "movbe{w}\t{$src, $dst|$dst, $src}", 2387 [(store (bswap GR16:$src), addr:$dst)]>, 2388 OpSize16, T8PS; 2389 def MOVBE32mr : I<0xF1, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2390 "movbe{l}\t{$src, $dst|$dst, $src}", 2391 [(store (bswap GR32:$src), addr:$dst)]>, 2392 OpSize32, T8PS; 2393 def MOVBE64mr : RI<0xF1, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2394 "movbe{q}\t{$src, $dst|$dst, $src}", 2395 [(store (bswap GR64:$src), addr:$dst)]>, 2396 T8PS; 2397 } 2398} 2399 2400//===----------------------------------------------------------------------===// 2401// RDRAND Instruction 2402// 2403let Predicates = [HasRDRAND], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 2404 def RDRAND16r : I<0xC7, MRM6r, (outs GR16:$dst), (ins), 2405 "rdrand{w}\t$dst", [(set GR16:$dst, EFLAGS, (X86rdrand))]>, 2406 OpSize16, PS; 2407 def RDRAND32r : I<0xC7, MRM6r, (outs GR32:$dst), (ins), 2408 "rdrand{l}\t$dst", [(set GR32:$dst, EFLAGS, (X86rdrand))]>, 2409 OpSize32, PS; 2410 def RDRAND64r : RI<0xC7, MRM6r, (outs GR64:$dst), (ins), 2411 "rdrand{q}\t$dst", [(set GR64:$dst, EFLAGS, (X86rdrand))]>, 2412 PS; 2413} 2414 2415//===----------------------------------------------------------------------===// 2416// RDSEED Instruction 2417// 2418let Predicates = [HasRDSEED], Defs = [EFLAGS], SchedRW = [WriteSystem] in { 2419 def RDSEED16r : I<0xC7, MRM7r, (outs GR16:$dst), (ins), "rdseed{w}\t$dst", 2420 [(set GR16:$dst, EFLAGS, (X86rdseed))]>, OpSize16, PS; 2421 def RDSEED32r : I<0xC7, MRM7r, (outs GR32:$dst), (ins), "rdseed{l}\t$dst", 2422 [(set GR32:$dst, EFLAGS, (X86rdseed))]>, OpSize32, PS; 2423 def RDSEED64r : RI<0xC7, MRM7r, (outs GR64:$dst), (ins), "rdseed{q}\t$dst", 2424 [(set GR64:$dst, EFLAGS, (X86rdseed))]>, PS; 2425} 2426 2427//===----------------------------------------------------------------------===// 2428// LZCNT Instruction 2429// 2430let Predicates = [HasLZCNT], Defs = [EFLAGS] in { 2431 def LZCNT16rr : I<0xBD, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 2432 "lzcnt{w}\t{$src, $dst|$dst, $src}", 2433 [(set GR16:$dst, (ctlz GR16:$src)), (implicit EFLAGS)]>, 2434 XS, OpSize16, Sched<[WriteLZCNT]>; 2435 def LZCNT16rm : I<0xBD, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2436 "lzcnt{w}\t{$src, $dst|$dst, $src}", 2437 [(set GR16:$dst, (ctlz (loadi16 addr:$src))), 2438 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteLZCNTLd]>; 2439 2440 def LZCNT32rr : I<0xBD, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 2441 "lzcnt{l}\t{$src, $dst|$dst, $src}", 2442 [(set GR32:$dst, (ctlz GR32:$src)), (implicit EFLAGS)]>, 2443 XS, OpSize32, Sched<[WriteLZCNT]>; 2444 def LZCNT32rm : I<0xBD, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2445 "lzcnt{l}\t{$src, $dst|$dst, $src}", 2446 [(set GR32:$dst, (ctlz (loadi32 addr:$src))), 2447 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteLZCNTLd]>; 2448 2449 def LZCNT64rr : RI<0xBD, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 2450 "lzcnt{q}\t{$src, $dst|$dst, $src}", 2451 [(set GR64:$dst, (ctlz GR64:$src)), (implicit EFLAGS)]>, 2452 XS, Sched<[WriteLZCNT]>; 2453 def LZCNT64rm : RI<0xBD, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2454 "lzcnt{q}\t{$src, $dst|$dst, $src}", 2455 [(set GR64:$dst, (ctlz (loadi64 addr:$src))), 2456 (implicit EFLAGS)]>, XS, Sched<[WriteLZCNTLd]>; 2457} 2458 2459//===----------------------------------------------------------------------===// 2460// BMI Instructions 2461// 2462let Predicates = [HasBMI], Defs = [EFLAGS] in { 2463 def TZCNT16rr : I<0xBC, MRMSrcReg, (outs GR16:$dst), (ins GR16:$src), 2464 "tzcnt{w}\t{$src, $dst|$dst, $src}", 2465 [(set GR16:$dst, (cttz GR16:$src)), (implicit EFLAGS)]>, 2466 XS, OpSize16, Sched<[WriteTZCNT]>; 2467 def TZCNT16rm : I<0xBC, MRMSrcMem, (outs GR16:$dst), (ins i16mem:$src), 2468 "tzcnt{w}\t{$src, $dst|$dst, $src}", 2469 [(set GR16:$dst, (cttz (loadi16 addr:$src))), 2470 (implicit EFLAGS)]>, XS, OpSize16, Sched<[WriteTZCNTLd]>; 2471 2472 def TZCNT32rr : I<0xBC, MRMSrcReg, (outs GR32:$dst), (ins GR32:$src), 2473 "tzcnt{l}\t{$src, $dst|$dst, $src}", 2474 [(set GR32:$dst, (cttz GR32:$src)), (implicit EFLAGS)]>, 2475 XS, OpSize32, Sched<[WriteTZCNT]>; 2476 def TZCNT32rm : I<0xBC, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), 2477 "tzcnt{l}\t{$src, $dst|$dst, $src}", 2478 [(set GR32:$dst, (cttz (loadi32 addr:$src))), 2479 (implicit EFLAGS)]>, XS, OpSize32, Sched<[WriteTZCNTLd]>; 2480 2481 def TZCNT64rr : RI<0xBC, MRMSrcReg, (outs GR64:$dst), (ins GR64:$src), 2482 "tzcnt{q}\t{$src, $dst|$dst, $src}", 2483 [(set GR64:$dst, (cttz GR64:$src)), (implicit EFLAGS)]>, 2484 XS, Sched<[WriteTZCNT]>; 2485 def TZCNT64rm : RI<0xBC, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), 2486 "tzcnt{q}\t{$src, $dst|$dst, $src}", 2487 [(set GR64:$dst, (cttz (loadi64 addr:$src))), 2488 (implicit EFLAGS)]>, XS, Sched<[WriteTZCNTLd]>; 2489} 2490 2491multiclass bmi_bls<string mnemonic, Format RegMRM, Format MemMRM, 2492 RegisterClass RC, X86MemOperand x86memop, 2493 X86FoldableSchedWrite sched> { 2494let hasSideEffects = 0 in { 2495 def rr : I<0xF3, RegMRM, (outs RC:$dst), (ins RC:$src), 2496 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, 2497 T8PS, VEX_4V, Sched<[sched]>; 2498 let mayLoad = 1 in 2499 def rm : I<0xF3, MemMRM, (outs RC:$dst), (ins x86memop:$src), 2500 !strconcat(mnemonic, "\t{$src, $dst|$dst, $src}"), []>, 2501 T8PS, VEX_4V, Sched<[sched.Folded]>; 2502} 2503} 2504 2505let Predicates = [HasBMI], Defs = [EFLAGS] in { 2506 defm BLSR32 : bmi_bls<"blsr{l}", MRM1r, MRM1m, GR32, i32mem, WriteBLS>; 2507 defm BLSR64 : bmi_bls<"blsr{q}", MRM1r, MRM1m, GR64, i64mem, WriteBLS>, VEX_W; 2508 defm BLSMSK32 : bmi_bls<"blsmsk{l}", MRM2r, MRM2m, GR32, i32mem, WriteBLS>; 2509 defm BLSMSK64 : bmi_bls<"blsmsk{q}", MRM2r, MRM2m, GR64, i64mem, WriteBLS>, VEX_W; 2510 defm BLSI32 : bmi_bls<"blsi{l}", MRM3r, MRM3m, GR32, i32mem, WriteBLS>; 2511 defm BLSI64 : bmi_bls<"blsi{q}", MRM3r, MRM3m, GR64, i64mem, WriteBLS>, VEX_W; 2512} 2513 2514//===----------------------------------------------------------------------===// 2515// Pattern fragments to auto generate BMI instructions. 2516//===----------------------------------------------------------------------===// 2517 2518def or_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2519 (X86or_flag node:$lhs, node:$rhs), [{ 2520 return hasNoCarryFlagUses(SDValue(N, 1)); 2521}]>; 2522 2523def xor_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2524 (X86xor_flag node:$lhs, node:$rhs), [{ 2525 return hasNoCarryFlagUses(SDValue(N, 1)); 2526}]>; 2527 2528def and_flag_nocf : PatFrag<(ops node:$lhs, node:$rhs), 2529 (X86and_flag node:$lhs, node:$rhs), [{ 2530 return hasNoCarryFlagUses(SDValue(N, 1)); 2531}]>; 2532 2533let Predicates = [HasBMI] in { 2534 // FIXME: patterns for the load versions are not implemented 2535 def : Pat<(and GR32:$src, (add GR32:$src, -1)), 2536 (BLSR32rr GR32:$src)>; 2537 def : Pat<(and GR64:$src, (add GR64:$src, -1)), 2538 (BLSR64rr GR64:$src)>; 2539 2540 def : Pat<(xor GR32:$src, (add GR32:$src, -1)), 2541 (BLSMSK32rr GR32:$src)>; 2542 def : Pat<(xor GR64:$src, (add GR64:$src, -1)), 2543 (BLSMSK64rr GR64:$src)>; 2544 2545 def : Pat<(and GR32:$src, (ineg GR32:$src)), 2546 (BLSI32rr GR32:$src)>; 2547 def : Pat<(and GR64:$src, (ineg GR64:$src)), 2548 (BLSI64rr GR64:$src)>; 2549 2550 // Versions to match flag producing ops. 2551 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, -1)), 2552 (BLSR32rr GR32:$src)>; 2553 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, -1)), 2554 (BLSR64rr GR64:$src)>; 2555 2556 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, -1)), 2557 (BLSMSK32rr GR32:$src)>; 2558 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, -1)), 2559 (BLSMSK64rr GR64:$src)>; 2560 2561 def : Pat<(and_flag_nocf GR32:$src, (ineg GR32:$src)), 2562 (BLSI32rr GR32:$src)>; 2563 def : Pat<(and_flag_nocf GR64:$src, (ineg GR64:$src)), 2564 (BLSI64rr GR64:$src)>; 2565} 2566 2567multiclass bmi_bextr<bits<8> opc, string mnemonic, RegisterClass RC, 2568 X86MemOperand x86memop, SDNode OpNode, 2569 PatFrag ld_frag, X86FoldableSchedWrite Sched> { 2570 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2571 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2572 [(set RC:$dst, (OpNode RC:$src1, RC:$src2)), (implicit EFLAGS)]>, 2573 T8PS, VEX, Sched<[Sched]>; 2574 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2), 2575 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2576 [(set RC:$dst, (OpNode (ld_frag addr:$src1), RC:$src2)), 2577 (implicit EFLAGS)]>, T8PS, VEX, 2578 Sched<[Sched.Folded, 2579 // x86memop:$src1 2580 ReadDefault, ReadDefault, ReadDefault, ReadDefault, 2581 ReadDefault, 2582 // RC:$src2 2583 Sched.ReadAfterFold]>; 2584} 2585 2586let Predicates = [HasBMI], Defs = [EFLAGS] in { 2587 defm BEXTR32 : bmi_bextr<0xF7, "bextr{l}", GR32, i32mem, 2588 X86bextr, loadi32, WriteBEXTR>; 2589 defm BEXTR64 : bmi_bextr<0xF7, "bextr{q}", GR64, i64mem, 2590 X86bextr, loadi64, WriteBEXTR>, VEX_W; 2591} 2592 2593multiclass bmi_bzhi<bits<8> opc, string mnemonic, RegisterClass RC, 2594 X86MemOperand x86memop, SDNode Int, 2595 PatFrag ld_frag, X86FoldableSchedWrite Sched> { 2596 def rr : I<opc, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2597 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2598 [(set RC:$dst, (Int RC:$src1, RC:$src2)), (implicit EFLAGS)]>, 2599 T8PS, VEX, Sched<[Sched]>; 2600 def rm : I<opc, MRMSrcMem4VOp3, (outs RC:$dst), (ins x86memop:$src1, RC:$src2), 2601 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2602 [(set RC:$dst, (Int (ld_frag addr:$src1), RC:$src2)), 2603 (implicit EFLAGS)]>, T8PS, VEX, 2604 Sched<[Sched.Folded, 2605 // x86memop:$src1 2606 ReadDefault, ReadDefault, ReadDefault, ReadDefault, 2607 ReadDefault, 2608 // RC:$src2 2609 Sched.ReadAfterFold]>; 2610} 2611 2612let Predicates = [HasBMI2], Defs = [EFLAGS] in { 2613 defm BZHI32 : bmi_bzhi<0xF5, "bzhi{l}", GR32, i32mem, 2614 X86bzhi, loadi32, WriteBZHI>; 2615 defm BZHI64 : bmi_bzhi<0xF5, "bzhi{q}", GR64, i64mem, 2616 X86bzhi, loadi64, WriteBZHI>, VEX_W; 2617} 2618 2619def CountTrailingOnes : SDNodeXForm<imm, [{ 2620 // Count the trailing ones in the immediate. 2621 return getI8Imm(countTrailingOnes(N->getZExtValue()), SDLoc(N)); 2622}]>; 2623 2624def BEXTRMaskXForm : SDNodeXForm<imm, [{ 2625 unsigned Length = countTrailingOnes(N->getZExtValue()); 2626 return getI32Imm(Length << 8, SDLoc(N)); 2627}]>; 2628 2629def AndMask64 : ImmLeaf<i64, [{ 2630 return isMask_64(Imm) && !isUInt<32>(Imm); 2631}]>; 2632 2633// Use BEXTR for 64-bit 'and' with large immediate 'mask'. 2634let Predicates = [HasBMI, NoBMI2, NoTBM] in { 2635 def : Pat<(and GR64:$src, AndMask64:$mask), 2636 (BEXTR64rr GR64:$src, 2637 (SUBREG_TO_REG (i64 0), 2638 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 2639 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2640 (BEXTR64rm addr:$src, 2641 (SUBREG_TO_REG (i64 0), 2642 (MOV32ri (BEXTRMaskXForm imm:$mask)), sub_32bit))>; 2643} 2644 2645// Use BZHI for 64-bit 'and' with large immediate 'mask'. 2646let Predicates = [HasBMI2, NoTBM] in { 2647 def : Pat<(and GR64:$src, AndMask64:$mask), 2648 (BZHI64rr GR64:$src, 2649 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2650 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 2651 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2652 (BZHI64rm addr:$src, 2653 (INSERT_SUBREG (i64 (IMPLICIT_DEF)), 2654 (MOV8ri (CountTrailingOnes imm:$mask)), sub_8bit))>; 2655} 2656 2657multiclass bmi_pdep_pext<string mnemonic, RegisterClass RC, 2658 X86MemOperand x86memop, SDNode OpNode, 2659 PatFrag ld_frag> { 2660 def rr : I<0xF5, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, RC:$src2), 2661 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2662 [(set RC:$dst, (OpNode RC:$src1, RC:$src2))]>, 2663 VEX_4V, Sched<[WriteALU]>; 2664 def rm : I<0xF5, MRMSrcMem, (outs RC:$dst), (ins RC:$src1, x86memop:$src2), 2665 !strconcat(mnemonic, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), 2666 [(set RC:$dst, (OpNode RC:$src1, (ld_frag addr:$src2)))]>, 2667 VEX_4V, Sched<[WriteALU.Folded, WriteALU.ReadAfterFold]>; 2668} 2669 2670let Predicates = [HasBMI2] in { 2671 defm PDEP32 : bmi_pdep_pext<"pdep{l}", GR32, i32mem, 2672 X86pdep, loadi32>, T8XD; 2673 defm PDEP64 : bmi_pdep_pext<"pdep{q}", GR64, i64mem, 2674 X86pdep, loadi64>, T8XD, VEX_W; 2675 defm PEXT32 : bmi_pdep_pext<"pext{l}", GR32, i32mem, 2676 X86pext, loadi32>, T8XS; 2677 defm PEXT64 : bmi_pdep_pext<"pext{q}", GR64, i64mem, 2678 X86pext, loadi64>, T8XS, VEX_W; 2679} 2680 2681//===----------------------------------------------------------------------===// 2682// TBM Instructions 2683// 2684let Predicates = [HasTBM], Defs = [EFLAGS] in { 2685 2686multiclass tbm_bextri<bits<8> opc, RegisterClass RC, string OpcodeStr, 2687 X86MemOperand x86memop, PatFrag ld_frag, 2688 SDNode OpNode, Operand immtype, 2689 SDPatternOperator immoperator, 2690 X86FoldableSchedWrite Sched> { 2691 def ri : Ii32<opc, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, immtype:$cntl), 2692 !strconcat(OpcodeStr, 2693 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 2694 [(set RC:$dst, (OpNode RC:$src1, immoperator:$cntl))]>, 2695 XOP, XOPA, Sched<[Sched]>; 2696 def mi : Ii32<opc, MRMSrcMem, (outs RC:$dst), 2697 (ins x86memop:$src1, immtype:$cntl), 2698 !strconcat(OpcodeStr, 2699 "\t{$cntl, $src1, $dst|$dst, $src1, $cntl}"), 2700 [(set RC:$dst, (OpNode (ld_frag addr:$src1), immoperator:$cntl))]>, 2701 XOP, XOPA, Sched<[Sched.Folded]>; 2702} 2703 2704defm BEXTRI32 : tbm_bextri<0x10, GR32, "bextr{l}", i32mem, loadi32, 2705 X86bextri, i32imm, timm, WriteBEXTR>; 2706let ImmT = Imm32S in 2707defm BEXTRI64 : tbm_bextri<0x10, GR64, "bextr{q}", i64mem, loadi64, 2708 X86bextri, i64i32imm, 2709 i64timmSExt32, WriteBEXTR>, VEX_W; 2710 2711multiclass tbm_binary_rm<bits<8> opc, Format FormReg, Format FormMem, 2712 RegisterClass RC, string OpcodeStr, 2713 X86MemOperand x86memop, X86FoldableSchedWrite Sched> { 2714let hasSideEffects = 0 in { 2715 def rr : I<opc, FormReg, (outs RC:$dst), (ins RC:$src), 2716 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 2717 XOP_4V, XOP9, Sched<[Sched]>; 2718 let mayLoad = 1 in 2719 def rm : I<opc, FormMem, (outs RC:$dst), (ins x86memop:$src), 2720 !strconcat(OpcodeStr,"\t{$src, $dst|$dst, $src}"), []>, 2721 XOP_4V, XOP9, Sched<[Sched.Folded]>; 2722} 2723} 2724 2725multiclass tbm_binary_intr<bits<8> opc, string OpcodeStr, 2726 X86FoldableSchedWrite Sched, 2727 Format FormReg, Format FormMem> { 2728 defm NAME#32 : tbm_binary_rm<opc, FormReg, FormMem, GR32, OpcodeStr#"{l}", 2729 i32mem, Sched>; 2730 defm NAME#64 : tbm_binary_rm<opc, FormReg, FormMem, GR64, OpcodeStr#"{q}", 2731 i64mem, Sched>, VEX_W; 2732} 2733 2734defm BLCFILL : tbm_binary_intr<0x01, "blcfill", WriteALU, MRM1r, MRM1m>; 2735defm BLCI : tbm_binary_intr<0x02, "blci", WriteALU, MRM6r, MRM6m>; 2736defm BLCIC : tbm_binary_intr<0x01, "blcic", WriteALU, MRM5r, MRM5m>; 2737defm BLCMSK : tbm_binary_intr<0x02, "blcmsk", WriteALU, MRM1r, MRM1m>; 2738defm BLCS : tbm_binary_intr<0x01, "blcs", WriteALU, MRM3r, MRM3m>; 2739defm BLSFILL : tbm_binary_intr<0x01, "blsfill", WriteALU, MRM2r, MRM2m>; 2740defm BLSIC : tbm_binary_intr<0x01, "blsic", WriteALU, MRM6r, MRM6m>; 2741defm T1MSKC : tbm_binary_intr<0x01, "t1mskc", WriteALU, MRM7r, MRM7m>; 2742defm TZMSK : tbm_binary_intr<0x01, "tzmsk", WriteALU, MRM4r, MRM4m>; 2743} // HasTBM, EFLAGS 2744 2745// Use BEXTRI for 64-bit 'and' with large immediate 'mask'. 2746let Predicates = [HasTBM] in { 2747 def : Pat<(and GR64:$src, AndMask64:$mask), 2748 (BEXTRI64ri GR64:$src, (BEXTRMaskXForm imm:$mask))>; 2749 2750 def : Pat<(and (loadi64 addr:$src), AndMask64:$mask), 2751 (BEXTRI64mi addr:$src, (BEXTRMaskXForm imm:$mask))>; 2752} 2753 2754//===----------------------------------------------------------------------===// 2755// Lightweight Profiling Instructions 2756 2757let Predicates = [HasLWP], SchedRW = [WriteSystem] in { 2758 2759def LLWPCB : I<0x12, MRM0r, (outs), (ins GR32:$src), "llwpcb\t$src", 2760 [(int_x86_llwpcb GR32:$src)]>, XOP, XOP9; 2761def SLWPCB : I<0x12, MRM1r, (outs GR32:$dst), (ins), "slwpcb\t$dst", 2762 [(set GR32:$dst, (int_x86_slwpcb))]>, XOP, XOP9; 2763 2764def LLWPCB64 : I<0x12, MRM0r, (outs), (ins GR64:$src), "llwpcb\t$src", 2765 [(int_x86_llwpcb GR64:$src)]>, XOP, XOP9, VEX_W; 2766def SLWPCB64 : I<0x12, MRM1r, (outs GR64:$dst), (ins), "slwpcb\t$dst", 2767 [(set GR64:$dst, (int_x86_slwpcb))]>, XOP, XOP9, VEX_W; 2768 2769multiclass lwpins_intr<RegisterClass RC> { 2770 def rri : Ii32<0x12, MRM0r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 2771 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2772 [(set EFLAGS, (X86lwpins RC:$src0, GR32:$src1, timm:$cntl))]>, 2773 XOP_4V, XOPA; 2774 let mayLoad = 1 in 2775 def rmi : Ii32<0x12, MRM0m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 2776 "lwpins\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2777 [(set EFLAGS, (X86lwpins RC:$src0, (loadi32 addr:$src1), timm:$cntl))]>, 2778 XOP_4V, XOPA; 2779} 2780 2781let Defs = [EFLAGS] in { 2782 defm LWPINS32 : lwpins_intr<GR32>; 2783 defm LWPINS64 : lwpins_intr<GR64>, VEX_W; 2784} // EFLAGS 2785 2786multiclass lwpval_intr<RegisterClass RC, Intrinsic Int> { 2787 def rri : Ii32<0x12, MRM1r, (outs), (ins RC:$src0, GR32:$src1, i32imm:$cntl), 2788 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2789 [(Int RC:$src0, GR32:$src1, timm:$cntl)]>, XOP_4V, XOPA; 2790 let mayLoad = 1 in 2791 def rmi : Ii32<0x12, MRM1m, (outs), (ins RC:$src0, i32mem:$src1, i32imm:$cntl), 2792 "lwpval\t{$cntl, $src1, $src0|$src0, $src1, $cntl}", 2793 [(Int RC:$src0, (loadi32 addr:$src1), timm:$cntl)]>, 2794 XOP_4V, XOPA; 2795} 2796 2797defm LWPVAL32 : lwpval_intr<GR32, int_x86_lwpval32>; 2798defm LWPVAL64 : lwpval_intr<GR64, int_x86_lwpval64>, VEX_W; 2799 2800} // HasLWP, SchedRW 2801 2802//===----------------------------------------------------------------------===// 2803// MONITORX/MWAITX Instructions 2804// 2805let SchedRW = [ WriteSystem ] in { 2806 let Uses = [ EAX, ECX, EDX ] in 2807 def MONITORX32rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 2808 TB, Requires<[ HasMWAITX, Not64BitMode ]>; 2809 let Uses = [ RAX, ECX, EDX ] in 2810 def MONITORX64rrr : I<0x01, MRM_FA, (outs), (ins), "monitorx", []>, 2811 TB, Requires<[ HasMWAITX, In64BitMode ]>; 2812 2813 let Uses = [ ECX, EAX, EBX ] in { 2814 def MWAITXrrr : I<0x01, MRM_FB, (outs), (ins), "mwaitx", 2815 []>, TB, Requires<[ HasMWAITX ]>; 2816 } 2817} // SchedRW 2818 2819def : InstAlias<"mwaitx\t{%eax, %ecx, %ebx|ebx, ecx, eax}", (MWAITXrrr)>, 2820 Requires<[ Not64BitMode ]>; 2821def : InstAlias<"mwaitx\t{%rax, %rcx, %rbx|rbx, rcx, rax}", (MWAITXrrr)>, 2822 Requires<[ In64BitMode ]>; 2823 2824def : InstAlias<"monitorx\t{%eax, %ecx, %edx|edx, ecx, eax}", (MONITORX32rrr)>, 2825 Requires<[ Not64BitMode ]>; 2826def : InstAlias<"monitorx\t{%rax, %rcx, %rdx|rdx, rcx, rax}", (MONITORX64rrr)>, 2827 Requires<[ In64BitMode ]>; 2828 2829//===----------------------------------------------------------------------===// 2830// WAITPKG Instructions 2831// 2832let SchedRW = [WriteSystem] in { 2833 def UMONITOR16 : I<0xAE, MRM6r, (outs), (ins GR16:$src), 2834 "umonitor\t$src", [(int_x86_umonitor GR16:$src)]>, 2835 XS, AdSize16, Requires<[HasWAITPKG, Not64BitMode]>; 2836 def UMONITOR32 : I<0xAE, MRM6r, (outs), (ins GR32:$src), 2837 "umonitor\t$src", [(int_x86_umonitor GR32:$src)]>, 2838 XS, AdSize32, Requires<[HasWAITPKG]>; 2839 def UMONITOR64 : I<0xAE, MRM6r, (outs), (ins GR64:$src), 2840 "umonitor\t$src", [(int_x86_umonitor GR64:$src)]>, 2841 XS, AdSize64, Requires<[HasWAITPKG, In64BitMode]>; 2842 let Uses = [EAX, EDX], Defs = [EFLAGS] in { 2843 def UMWAIT : I<0xAE, MRM6r, 2844 (outs), (ins GR32orGR64:$src), "umwait\t$src", 2845 [(set EFLAGS, (X86umwait GR32orGR64:$src, EDX, EAX))]>, 2846 XD, Requires<[HasWAITPKG]>; 2847 def TPAUSE : I<0xAE, MRM6r, 2848 (outs), (ins GR32orGR64:$src), "tpause\t$src", 2849 [(set EFLAGS, (X86tpause GR32orGR64:$src, EDX, EAX))]>, 2850 PD, Requires<[HasWAITPKG]>, NotMemoryFoldable; 2851 } 2852} // SchedRW 2853 2854//===----------------------------------------------------------------------===// 2855// MOVDIRI - Move doubleword/quadword as direct store 2856// 2857let SchedRW = [WriteStore] in { 2858def MOVDIRI32 : I<0xF9, MRMDestMem, (outs), (ins i32mem:$dst, GR32:$src), 2859 "movdiri\t{$src, $dst|$dst, $src}", 2860 [(int_x86_directstore32 addr:$dst, GR32:$src)]>, 2861 T8PS, Requires<[HasMOVDIRI]>; 2862def MOVDIRI64 : RI<0xF9, MRMDestMem, (outs), (ins i64mem:$dst, GR64:$src), 2863 "movdiri\t{$src, $dst|$dst, $src}", 2864 [(int_x86_directstore64 addr:$dst, GR64:$src)]>, 2865 T8PS, Requires<[In64BitMode, HasMOVDIRI]>; 2866} // SchedRW 2867 2868//===----------------------------------------------------------------------===// 2869// MOVDIR64B - Move 64 bytes as direct store 2870// 2871let SchedRW = [WriteStore] in { 2872def MOVDIR64B16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2873 "movdir64b\t{$src, $dst|$dst, $src}", []>, 2874 T8PD, AdSize16, Requires<[HasMOVDIR64B, Not64BitMode]>; 2875def MOVDIR64B32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2876 "movdir64b\t{$src, $dst|$dst, $src}", 2877 [(int_x86_movdir64b GR32:$dst, addr:$src)]>, 2878 T8PD, AdSize32, Requires<[HasMOVDIR64B]>; 2879def MOVDIR64B64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2880 "movdir64b\t{$src, $dst|$dst, $src}", 2881 [(int_x86_movdir64b GR64:$dst, addr:$src)]>, 2882 T8PD, AdSize64, Requires<[HasMOVDIR64B, In64BitMode]>; 2883} // SchedRW 2884 2885//===----------------------------------------------------------------------===// 2886// ENQCMD/S - Enqueue 64-byte command as user with 64-byte write atomicity 2887// 2888let SchedRW = [WriteStore], Defs = [EFLAGS] in { 2889 def ENQCMD16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2890 "enqcmd\t{$src, $dst|$dst, $src}", 2891 [(set EFLAGS, (X86enqcmd GR16:$dst, addr:$src))]>, 2892 T8XD, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 2893 def ENQCMD32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2894 "enqcmd\t{$src, $dst|$dst, $src}", 2895 [(set EFLAGS, (X86enqcmd GR32:$dst, addr:$src))]>, 2896 T8XD, AdSize32, Requires<[HasENQCMD]>; 2897 def ENQCMD64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2898 "enqcmd\t{$src, $dst|$dst, $src}", 2899 [(set EFLAGS, (X86enqcmd GR64:$dst, addr:$src))]>, 2900 T8XD, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 2901 2902 def ENQCMDS16 : I<0xF8, MRMSrcMem, (outs), (ins GR16:$dst, i512mem:$src), 2903 "enqcmds\t{$src, $dst|$dst, $src}", 2904 [(set EFLAGS, (X86enqcmds GR16:$dst, addr:$src))]>, 2905 T8XS, AdSize16, Requires<[HasENQCMD, Not64BitMode]>; 2906 def ENQCMDS32 : I<0xF8, MRMSrcMem, (outs), (ins GR32:$dst, i512mem:$src), 2907 "enqcmds\t{$src, $dst|$dst, $src}", 2908 [(set EFLAGS, (X86enqcmds GR32:$dst, addr:$src))]>, 2909 T8XS, AdSize32, Requires<[HasENQCMD]>; 2910 def ENQCMDS64 : I<0xF8, MRMSrcMem, (outs), (ins GR64:$dst, i512mem:$src), 2911 "enqcmds\t{$src, $dst|$dst, $src}", 2912 [(set EFLAGS, (X86enqcmds GR64:$dst, addr:$src))]>, 2913 T8XS, AdSize64, Requires<[HasENQCMD, In64BitMode]>; 2914} 2915 2916//===----------------------------------------------------------------------===// 2917// CLZERO Instruction 2918// 2919let SchedRW = [WriteLoad] in { 2920 let Uses = [EAX] in 2921 def CLZERO32r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 2922 TB, Requires<[HasCLZERO, Not64BitMode]>; 2923 let Uses = [RAX] in 2924 def CLZERO64r : I<0x01, MRM_FC, (outs), (ins), "clzero", []>, 2925 TB, Requires<[HasCLZERO, In64BitMode]>; 2926} // SchedRW 2927 2928def : InstAlias<"clzero\t{%eax|eax}", (CLZERO32r)>, Requires<[Not64BitMode]>; 2929def : InstAlias<"clzero\t{%rax|rax}", (CLZERO64r)>, Requires<[In64BitMode]>; 2930 2931//===----------------------------------------------------------------------===// 2932// INVLPGB Instruction 2933// OPCODE 0F 01 FE 2934// 2935let SchedRW = [WriteSystem] in { 2936 let Uses = [EAX, EDX] in 2937 def INVLPGB32 : I<0x01, MRM_FE, (outs), (ins), 2938 "invlpgb}", []>, 2939 PS, Requires<[Not64BitMode]>; 2940 let Uses = [RAX, EDX] in 2941 def INVLPGB64 : I<0x01, MRM_FE, (outs), (ins), 2942 "invlpgb", []>, 2943 PS, Requires<[In64BitMode]>; 2944} // SchedRW 2945 2946def : InstAlias<"invlpgb\t{%eax, %edx|eax, edx}", (INVLPGB32)>, Requires<[Not64BitMode]>; 2947def : InstAlias<"invlpgb\t{%rax, %edx|rax, edx}", (INVLPGB64)>, Requires<[In64BitMode]>; 2948 2949//===----------------------------------------------------------------------===// 2950// TLBSYNC Instruction 2951// OPCODE 0F 01 FF 2952// 2953let SchedRW = [WriteSystem] in { 2954 def TLBSYNC : I<0x01, MRM_FF, (outs), (ins), 2955 "tlbsync", []>, 2956 PS, Requires<[]>; 2957} // SchedRW 2958 2959//===----------------------------------------------------------------------===// 2960// HRESET Instruction 2961// 2962let Uses = [EAX], SchedRW = [WriteSystem] in 2963 def HRESET : Ii8<0xF0, MRM_C0, (outs), (ins i32u8imm:$imm), "hreset\t$imm", []>, 2964 Requires<[HasHRESET]>, TAXS; 2965 2966//===----------------------------------------------------------------------===// 2967// SERIALIZE Instruction 2968// 2969let SchedRW = [WriteSystem] in 2970 def SERIALIZE : I<0x01, MRM_E8, (outs), (ins), "serialize", 2971 [(int_x86_serialize)]>, PS, 2972 Requires<[HasSERIALIZE]>; 2973 2974//===----------------------------------------------------------------------===// 2975// TSXLDTRK - TSX Suspend Load Address Tracking 2976// 2977let Predicates = [HasTSXLDTRK], SchedRW = [WriteSystem] in { 2978 def XSUSLDTRK : I<0x01, MRM_E8, (outs), (ins), "xsusldtrk", 2979 [(int_x86_xsusldtrk)]>, XD; 2980 def XRESLDTRK : I<0x01, MRM_E9, (outs), (ins), "xresldtrk", 2981 [(int_x86_xresldtrk)]>, XD; 2982} 2983 2984//===----------------------------------------------------------------------===// 2985// UINTR Instructions 2986// 2987let Predicates = [HasUINTR, In64BitMode], SchedRW = [WriteSystem] in { 2988 def UIRET : I<0x01, MRM_EC, (outs), (ins), "uiret", 2989 []>, XS; 2990 def CLUI : I<0x01, MRM_EE, (outs), (ins), "clui", 2991 [(int_x86_clui)]>, XS; 2992 def STUI : I<0x01, MRM_EF, (outs), (ins), "stui", 2993 [(int_x86_stui)]>, XS; 2994 2995 def SENDUIPI : I<0xC7, MRM6r, (outs), (ins GR64:$arg), "senduipi\t$arg", 2996 [(int_x86_senduipi GR64:$arg)]>, XS; 2997 2998 let Defs = [EFLAGS] in 2999 def TESTUI : I<0x01, MRM_ED, (outs), (ins), "testui", 3000 [(set EFLAGS, (X86testui))]>, XS; 3001} 3002 3003//===----------------------------------------------------------------------===// 3004// Pattern fragments to auto generate TBM instructions. 3005//===----------------------------------------------------------------------===// 3006 3007let Predicates = [HasTBM] in { 3008 // FIXME: patterns for the load versions are not implemented 3009 def : Pat<(and GR32:$src, (add GR32:$src, 1)), 3010 (BLCFILL32rr GR32:$src)>; 3011 def : Pat<(and GR64:$src, (add GR64:$src, 1)), 3012 (BLCFILL64rr GR64:$src)>; 3013 3014 def : Pat<(or GR32:$src, (not (add GR32:$src, 1))), 3015 (BLCI32rr GR32:$src)>; 3016 def : Pat<(or GR64:$src, (not (add GR64:$src, 1))), 3017 (BLCI64rr GR64:$src)>; 3018 3019 // Extra patterns because opt can optimize the above patterns to this. 3020 def : Pat<(or GR32:$src, (sub -2, GR32:$src)), 3021 (BLCI32rr GR32:$src)>; 3022 def : Pat<(or GR64:$src, (sub -2, GR64:$src)), 3023 (BLCI64rr GR64:$src)>; 3024 3025 def : Pat<(and (not GR32:$src), (add GR32:$src, 1)), 3026 (BLCIC32rr GR32:$src)>; 3027 def : Pat<(and (not GR64:$src), (add GR64:$src, 1)), 3028 (BLCIC64rr GR64:$src)>; 3029 3030 def : Pat<(xor GR32:$src, (add GR32:$src, 1)), 3031 (BLCMSK32rr GR32:$src)>; 3032 def : Pat<(xor GR64:$src, (add GR64:$src, 1)), 3033 (BLCMSK64rr GR64:$src)>; 3034 3035 def : Pat<(or GR32:$src, (add GR32:$src, 1)), 3036 (BLCS32rr GR32:$src)>; 3037 def : Pat<(or GR64:$src, (add GR64:$src, 1)), 3038 (BLCS64rr GR64:$src)>; 3039 3040 def : Pat<(or GR32:$src, (add GR32:$src, -1)), 3041 (BLSFILL32rr GR32:$src)>; 3042 def : Pat<(or GR64:$src, (add GR64:$src, -1)), 3043 (BLSFILL64rr GR64:$src)>; 3044 3045 def : Pat<(or (not GR32:$src), (add GR32:$src, -1)), 3046 (BLSIC32rr GR32:$src)>; 3047 def : Pat<(or (not GR64:$src), (add GR64:$src, -1)), 3048 (BLSIC64rr GR64:$src)>; 3049 3050 def : Pat<(or (not GR32:$src), (add GR32:$src, 1)), 3051 (T1MSKC32rr GR32:$src)>; 3052 def : Pat<(or (not GR64:$src), (add GR64:$src, 1)), 3053 (T1MSKC64rr GR64:$src)>; 3054 3055 def : Pat<(and (not GR32:$src), (add GR32:$src, -1)), 3056 (TZMSK32rr GR32:$src)>; 3057 def : Pat<(and (not GR64:$src), (add GR64:$src, -1)), 3058 (TZMSK64rr GR64:$src)>; 3059 3060 // Patterns to match flag producing ops. 3061 def : Pat<(and_flag_nocf GR32:$src, (add GR32:$src, 1)), 3062 (BLCFILL32rr GR32:$src)>; 3063 def : Pat<(and_flag_nocf GR64:$src, (add GR64:$src, 1)), 3064 (BLCFILL64rr GR64:$src)>; 3065 3066 def : Pat<(or_flag_nocf GR32:$src, (not (add GR32:$src, 1))), 3067 (BLCI32rr GR32:$src)>; 3068 def : Pat<(or_flag_nocf GR64:$src, (not (add GR64:$src, 1))), 3069 (BLCI64rr GR64:$src)>; 3070 3071 // Extra patterns because opt can optimize the above patterns to this. 3072 def : Pat<(or_flag_nocf GR32:$src, (sub -2, GR32:$src)), 3073 (BLCI32rr GR32:$src)>; 3074 def : Pat<(or_flag_nocf GR64:$src, (sub -2, GR64:$src)), 3075 (BLCI64rr GR64:$src)>; 3076 3077 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 3078 (BLCIC32rr GR32:$src)>; 3079 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 3080 (BLCIC64rr GR64:$src)>; 3081 3082 def : Pat<(xor_flag_nocf GR32:$src, (add GR32:$src, 1)), 3083 (BLCMSK32rr GR32:$src)>; 3084 def : Pat<(xor_flag_nocf GR64:$src, (add GR64:$src, 1)), 3085 (BLCMSK64rr GR64:$src)>; 3086 3087 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, 1)), 3088 (BLCS32rr GR32:$src)>; 3089 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, 1)), 3090 (BLCS64rr GR64:$src)>; 3091 3092 def : Pat<(or_flag_nocf GR32:$src, (add GR32:$src, -1)), 3093 (BLSFILL32rr GR32:$src)>; 3094 def : Pat<(or_flag_nocf GR64:$src, (add GR64:$src, -1)), 3095 (BLSFILL64rr GR64:$src)>; 3096 3097 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 3098 (BLSIC32rr GR32:$src)>; 3099 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 3100 (BLSIC64rr GR64:$src)>; 3101 3102 def : Pat<(or_flag_nocf (not GR32:$src), (add GR32:$src, 1)), 3103 (T1MSKC32rr GR32:$src)>; 3104 def : Pat<(or_flag_nocf (not GR64:$src), (add GR64:$src, 1)), 3105 (T1MSKC64rr GR64:$src)>; 3106 3107 def : Pat<(and_flag_nocf (not GR32:$src), (add GR32:$src, -1)), 3108 (TZMSK32rr GR32:$src)>; 3109 def : Pat<(and_flag_nocf (not GR64:$src), (add GR64:$src, -1)), 3110 (TZMSK64rr GR64:$src)>; 3111} // HasTBM 3112 3113//===----------------------------------------------------------------------===// 3114// Memory Instructions 3115// 3116 3117let Predicates = [HasCLFLUSHOPT], SchedRW = [WriteLoad] in 3118def CLFLUSHOPT : I<0xAE, MRM7m, (outs), (ins i8mem:$src), 3119 "clflushopt\t$src", [(int_x86_clflushopt addr:$src)]>, PD; 3120 3121let Predicates = [HasCLWB], SchedRW = [WriteLoad] in 3122def CLWB : I<0xAE, MRM6m, (outs), (ins i8mem:$src), "clwb\t$src", 3123 [(int_x86_clwb addr:$src)]>, PD, NotMemoryFoldable; 3124 3125let Predicates = [HasCLDEMOTE], SchedRW = [WriteLoad] in 3126def CLDEMOTE : I<0x1C, MRM0m, (outs), (ins i8mem:$src), "cldemote\t$src", 3127 [(int_x86_cldemote addr:$src)]>, PS; 3128 3129//===----------------------------------------------------------------------===// 3130// Subsystems. 3131//===----------------------------------------------------------------------===// 3132 3133include "X86InstrArithmetic.td" 3134include "X86InstrCMovSetCC.td" 3135include "X86InstrExtension.td" 3136include "X86InstrControl.td" 3137include "X86InstrShiftRotate.td" 3138 3139// X87 Floating Point Stack. 3140include "X86InstrFPStack.td" 3141 3142// SIMD support (SSE, MMX and AVX) 3143include "X86InstrFragmentsSIMD.td" 3144 3145// FMA - Fused Multiply-Add support (requires FMA) 3146include "X86InstrFMA.td" 3147 3148// XOP 3149include "X86InstrXOP.td" 3150 3151// SSE, MMX and 3DNow! vector support. 3152include "X86InstrSSE.td" 3153include "X86InstrAVX512.td" 3154include "X86InstrMMX.td" 3155include "X86Instr3DNow.td" 3156 3157// MPX instructions 3158include "X86InstrMPX.td" 3159 3160include "X86InstrVMX.td" 3161include "X86InstrSVM.td" 3162include "X86InstrSNP.td" 3163 3164include "X86InstrTSX.td" 3165include "X86InstrSGX.td" 3166 3167include "X86InstrTDX.td" 3168 3169// Key Locker instructions 3170include "X86InstrKL.td" 3171 3172// AMX instructions 3173include "X86InstrAMX.td" 3174 3175// System instructions. 3176include "X86InstrSystem.td" 3177 3178// Compiler Pseudo Instructions and Pat Patterns 3179include "X86InstrCompiler.td" 3180include "X86InstrVecCompiler.td" 3181 3182//===----------------------------------------------------------------------===// 3183// Assembler Mnemonic Aliases 3184//===----------------------------------------------------------------------===// 3185 3186def : MnemonicAlias<"call", "callw", "att">, Requires<[In16BitMode]>; 3187def : MnemonicAlias<"call", "calll", "att">, Requires<[In32BitMode]>; 3188def : MnemonicAlias<"call", "callq", "att">, Requires<[In64BitMode]>; 3189 3190def : MnemonicAlias<"cbw", "cbtw", "att">; 3191def : MnemonicAlias<"cwde", "cwtl", "att">; 3192def : MnemonicAlias<"cwd", "cwtd", "att">; 3193def : MnemonicAlias<"cdq", "cltd", "att">; 3194def : MnemonicAlias<"cdqe", "cltq", "att">; 3195def : MnemonicAlias<"cqo", "cqto", "att">; 3196 3197// In 64-bit mode lret maps to lretl; it is not ambiguous with lretq. 3198def : MnemonicAlias<"lret", "lretw", "att">, Requires<[In16BitMode]>; 3199def : MnemonicAlias<"lret", "lretl", "att">, Requires<[Not16BitMode]>; 3200 3201def : MnemonicAlias<"leavel", "leave", "att">, Requires<[Not64BitMode]>; 3202def : MnemonicAlias<"leaveq", "leave", "att">, Requires<[In64BitMode]>; 3203 3204def : MnemonicAlias<"loopz", "loope">; 3205def : MnemonicAlias<"loopnz", "loopne">; 3206 3207def : MnemonicAlias<"pop", "popw", "att">, Requires<[In16BitMode]>; 3208def : MnemonicAlias<"pop", "popl", "att">, Requires<[In32BitMode]>; 3209def : MnemonicAlias<"pop", "popq", "att">, Requires<[In64BitMode]>; 3210def : MnemonicAlias<"popf", "popfw", "att">, Requires<[In16BitMode]>; 3211def : MnemonicAlias<"popf", "popfl", "att">, Requires<[In32BitMode]>; 3212def : MnemonicAlias<"popf", "popfq", "att">, Requires<[In64BitMode]>; 3213def : MnemonicAlias<"popf", "popfq", "intel">, Requires<[In64BitMode]>; 3214def : MnemonicAlias<"popfd", "popfl", "att">; 3215def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In32BitMode]>; 3216def : MnemonicAlias<"popfw", "popf", "intel">, Requires<[In64BitMode]>; 3217 3218// FIXME: This is wrong for "push reg". "push %bx" should turn into pushw in 3219// all modes. However: "push (addr)" and "push $42" should default to 3220// pushl/pushq depending on the current mode. Similar for "pop %bx" 3221def : MnemonicAlias<"push", "pushw", "att">, Requires<[In16BitMode]>; 3222def : MnemonicAlias<"push", "pushl", "att">, Requires<[In32BitMode]>; 3223def : MnemonicAlias<"push", "pushq", "att">, Requires<[In64BitMode]>; 3224def : MnemonicAlias<"pushf", "pushfw", "att">, Requires<[In16BitMode]>; 3225def : MnemonicAlias<"pushf", "pushfl", "att">, Requires<[In32BitMode]>; 3226def : MnemonicAlias<"pushf", "pushfq", "att">, Requires<[In64BitMode]>; 3227def : MnemonicAlias<"pushf", "pushfq", "intel">, Requires<[In64BitMode]>; 3228def : MnemonicAlias<"pushfd", "pushfl", "att">; 3229def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In32BitMode]>; 3230def : MnemonicAlias<"pushfw", "pushf", "intel">, Requires<[In64BitMode]>; 3231 3232def : MnemonicAlias<"popad", "popal", "intel">, Requires<[Not64BitMode]>; 3233def : MnemonicAlias<"pushad", "pushal", "intel">, Requires<[Not64BitMode]>; 3234def : MnemonicAlias<"popa", "popaw", "intel">, Requires<[In16BitMode]>; 3235def : MnemonicAlias<"pusha", "pushaw", "intel">, Requires<[In16BitMode]>; 3236def : MnemonicAlias<"popa", "popal", "intel">, Requires<[In32BitMode]>; 3237def : MnemonicAlias<"pusha", "pushal", "intel">, Requires<[In32BitMode]>; 3238 3239def : MnemonicAlias<"popa", "popaw", "att">, Requires<[In16BitMode]>; 3240def : MnemonicAlias<"pusha", "pushaw", "att">, Requires<[In16BitMode]>; 3241def : MnemonicAlias<"popa", "popal", "att">, Requires<[In32BitMode]>; 3242def : MnemonicAlias<"pusha", "pushal", "att">, Requires<[In32BitMode]>; 3243 3244def : MnemonicAlias<"repe", "rep">; 3245def : MnemonicAlias<"repz", "rep">; 3246def : MnemonicAlias<"repnz", "repne">; 3247 3248def : MnemonicAlias<"ret", "retw", "att">, Requires<[In16BitMode]>; 3249def : MnemonicAlias<"ret", "retl", "att">, Requires<[In32BitMode]>; 3250def : MnemonicAlias<"ret", "retq", "att">, Requires<[In64BitMode]>; 3251 3252// Apply 'ret' behavior to 'retn' 3253def : MnemonicAlias<"retn", "retw", "att">, Requires<[In16BitMode]>; 3254def : MnemonicAlias<"retn", "retl", "att">, Requires<[In32BitMode]>; 3255def : MnemonicAlias<"retn", "retq", "att">, Requires<[In64BitMode]>; 3256def : MnemonicAlias<"retn", "ret", "intel">; 3257 3258def : MnemonicAlias<"sal", "shl", "intel">; 3259def : MnemonicAlias<"salb", "shlb", "att">; 3260def : MnemonicAlias<"salw", "shlw", "att">; 3261def : MnemonicAlias<"sall", "shll", "att">; 3262def : MnemonicAlias<"salq", "shlq", "att">; 3263 3264def : MnemonicAlias<"smovb", "movsb", "att">; 3265def : MnemonicAlias<"smovw", "movsw", "att">; 3266def : MnemonicAlias<"smovl", "movsl", "att">; 3267def : MnemonicAlias<"smovq", "movsq", "att">; 3268 3269def : MnemonicAlias<"ud2a", "ud2", "att">; 3270def : MnemonicAlias<"ud2bw", "ud1w", "att">; 3271def : MnemonicAlias<"ud2bl", "ud1l", "att">; 3272def : MnemonicAlias<"ud2bq", "ud1q", "att">; 3273def : MnemonicAlias<"verrw", "verr", "att">; 3274 3275// MS recognizes 'xacquire'/'xrelease' as 'acquire'/'release' 3276def : MnemonicAlias<"acquire", "xacquire", "intel">; 3277def : MnemonicAlias<"release", "xrelease", "intel">; 3278 3279// System instruction aliases. 3280def : MnemonicAlias<"iret", "iretw", "att">, Requires<[In16BitMode]>; 3281def : MnemonicAlias<"iret", "iretl", "att">, Requires<[Not16BitMode]>; 3282def : MnemonicAlias<"sysret", "sysretl", "att">; 3283def : MnemonicAlias<"sysexit", "sysexitl", "att">; 3284 3285def : MnemonicAlias<"lgdt", "lgdtw", "att">, Requires<[In16BitMode]>; 3286def : MnemonicAlias<"lgdt", "lgdtl", "att">, Requires<[In32BitMode]>; 3287def : MnemonicAlias<"lgdt", "lgdtq", "att">, Requires<[In64BitMode]>; 3288def : MnemonicAlias<"lidt", "lidtw", "att">, Requires<[In16BitMode]>; 3289def : MnemonicAlias<"lidt", "lidtl", "att">, Requires<[In32BitMode]>; 3290def : MnemonicAlias<"lidt", "lidtq", "att">, Requires<[In64BitMode]>; 3291def : MnemonicAlias<"sgdt", "sgdtw", "att">, Requires<[In16BitMode]>; 3292def : MnemonicAlias<"sgdt", "sgdtl", "att">, Requires<[In32BitMode]>; 3293def : MnemonicAlias<"sgdt", "sgdtq", "att">, Requires<[In64BitMode]>; 3294def : MnemonicAlias<"sidt", "sidtw", "att">, Requires<[In16BitMode]>; 3295def : MnemonicAlias<"sidt", "sidtl", "att">, Requires<[In32BitMode]>; 3296def : MnemonicAlias<"sidt", "sidtq", "att">, Requires<[In64BitMode]>; 3297def : MnemonicAlias<"lgdt", "lgdtw", "intel">, Requires<[In16BitMode]>; 3298def : MnemonicAlias<"lgdt", "lgdtd", "intel">, Requires<[In32BitMode]>; 3299def : MnemonicAlias<"lidt", "lidtw", "intel">, Requires<[In16BitMode]>; 3300def : MnemonicAlias<"lidt", "lidtd", "intel">, Requires<[In32BitMode]>; 3301def : MnemonicAlias<"sgdt", "sgdtw", "intel">, Requires<[In16BitMode]>; 3302def : MnemonicAlias<"sgdt", "sgdtd", "intel">, Requires<[In32BitMode]>; 3303def : MnemonicAlias<"sidt", "sidtw", "intel">, Requires<[In16BitMode]>; 3304def : MnemonicAlias<"sidt", "sidtd", "intel">, Requires<[In32BitMode]>; 3305 3306 3307// Floating point stack aliases. 3308def : MnemonicAlias<"fcmovz", "fcmove", "att">; 3309def : MnemonicAlias<"fcmova", "fcmovnbe", "att">; 3310def : MnemonicAlias<"fcmovnae", "fcmovb", "att">; 3311def : MnemonicAlias<"fcmovna", "fcmovbe", "att">; 3312def : MnemonicAlias<"fcmovae", "fcmovnb", "att">; 3313def : MnemonicAlias<"fcomip", "fcompi">; 3314def : MnemonicAlias<"fildq", "fildll", "att">; 3315def : MnemonicAlias<"fistpq", "fistpll", "att">; 3316def : MnemonicAlias<"fisttpq", "fisttpll", "att">; 3317def : MnemonicAlias<"fldcww", "fldcw", "att">; 3318def : MnemonicAlias<"fnstcww", "fnstcw", "att">; 3319def : MnemonicAlias<"fnstsww", "fnstsw", "att">; 3320def : MnemonicAlias<"fucomip", "fucompi">; 3321def : MnemonicAlias<"fwait", "wait">; 3322 3323def : MnemonicAlias<"fxsaveq", "fxsave64", "att">; 3324def : MnemonicAlias<"fxrstorq", "fxrstor64", "att">; 3325def : MnemonicAlias<"xsaveq", "xsave64", "att">; 3326def : MnemonicAlias<"xrstorq", "xrstor64", "att">; 3327def : MnemonicAlias<"xsaveoptq", "xsaveopt64", "att">; 3328def : MnemonicAlias<"xrstorsq", "xrstors64", "att">; 3329def : MnemonicAlias<"xsavecq", "xsavec64", "att">; 3330def : MnemonicAlias<"xsavesq", "xsaves64", "att">; 3331 3332class CondCodeAlias<string Prefix,string Suffix, string OldCond, string NewCond, 3333 string VariantName> 3334 : MnemonicAlias<!strconcat(Prefix, OldCond, Suffix), 3335 !strconcat(Prefix, NewCond, Suffix), VariantName>; 3336 3337/// IntegerCondCodeMnemonicAlias - This multiclass defines a bunch of 3338/// MnemonicAlias's that canonicalize the condition code in a mnemonic, for 3339/// example "setz" -> "sete". 3340multiclass IntegerCondCodeMnemonicAlias<string Prefix, string Suffix, 3341 string V = ""> { 3342 def C : CondCodeAlias<Prefix, Suffix, "c", "b", V>; // setc -> setb 3343 def Z : CondCodeAlias<Prefix, Suffix, "z" , "e", V>; // setz -> sete 3344 def NA : CondCodeAlias<Prefix, Suffix, "na", "be", V>; // setna -> setbe 3345 def NB : CondCodeAlias<Prefix, Suffix, "nb", "ae", V>; // setnb -> setae 3346 def NC : CondCodeAlias<Prefix, Suffix, "nc", "ae", V>; // setnc -> setae 3347 def NG : CondCodeAlias<Prefix, Suffix, "ng", "le", V>; // setng -> setle 3348 def NL : CondCodeAlias<Prefix, Suffix, "nl", "ge", V>; // setnl -> setge 3349 def NZ : CondCodeAlias<Prefix, Suffix, "nz", "ne", V>; // setnz -> setne 3350 def PE : CondCodeAlias<Prefix, Suffix, "pe", "p", V>; // setpe -> setp 3351 def PO : CondCodeAlias<Prefix, Suffix, "po", "np", V>; // setpo -> setnp 3352 3353 def NAE : CondCodeAlias<Prefix, Suffix, "nae", "b", V>; // setnae -> setb 3354 def NBE : CondCodeAlias<Prefix, Suffix, "nbe", "a", V>; // setnbe -> seta 3355 def NGE : CondCodeAlias<Prefix, Suffix, "nge", "l", V>; // setnge -> setl 3356 def NLE : CondCodeAlias<Prefix, Suffix, "nle", "g", V>; // setnle -> setg 3357} 3358 3359// Aliases for set<CC> 3360defm : IntegerCondCodeMnemonicAlias<"set", "">; 3361// Aliases for j<CC> 3362defm : IntegerCondCodeMnemonicAlias<"j", "">; 3363// Aliases for cmov<CC>{w,l,q} 3364defm : IntegerCondCodeMnemonicAlias<"cmov", "w", "att">; 3365defm : IntegerCondCodeMnemonicAlias<"cmov", "l", "att">; 3366defm : IntegerCondCodeMnemonicAlias<"cmov", "q", "att">; 3367// No size suffix for intel-style asm. 3368defm : IntegerCondCodeMnemonicAlias<"cmov", "", "intel">; 3369 3370 3371//===----------------------------------------------------------------------===// 3372// Assembler Instruction Aliases 3373//===----------------------------------------------------------------------===// 3374 3375// aad/aam default to base 10 if no operand is specified. 3376def : InstAlias<"aad", (AAD8i8 10)>, Requires<[Not64BitMode]>; 3377def : InstAlias<"aam", (AAM8i8 10)>, Requires<[Not64BitMode]>; 3378 3379// Disambiguate the mem/imm form of bt-without-a-suffix as btl. 3380// Likewise for btc/btr/bts. 3381def : InstAlias<"bt\t{$imm, $mem|$mem, $imm}", 3382 (BT32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3383def : InstAlias<"btc\t{$imm, $mem|$mem, $imm}", 3384 (BTC32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3385def : InstAlias<"btr\t{$imm, $mem|$mem, $imm}", 3386 (BTR32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3387def : InstAlias<"bts\t{$imm, $mem|$mem, $imm}", 3388 (BTS32mi8 i32mem:$mem, i32u8imm:$imm), 0, "att">; 3389 3390// clr aliases. 3391def : InstAlias<"clr{b}\t$reg", (XOR8rr GR8 :$reg, GR8 :$reg), 0>; 3392def : InstAlias<"clr{w}\t$reg", (XOR16rr GR16:$reg, GR16:$reg), 0>; 3393def : InstAlias<"clr{l}\t$reg", (XOR32rr GR32:$reg, GR32:$reg), 0>; 3394def : InstAlias<"clr{q}\t$reg", (XOR64rr GR64:$reg, GR64:$reg), 0>; 3395 3396// lods aliases. Accept the destination being omitted because it's implicit 3397// in the mnemonic, or the mnemonic suffix being omitted because it's implicit 3398// in the destination. 3399def : InstAlias<"lodsb\t$src", (LODSB srcidx8:$src), 0>; 3400def : InstAlias<"lodsw\t$src", (LODSW srcidx16:$src), 0>; 3401def : InstAlias<"lods{l|d}\t$src", (LODSL srcidx32:$src), 0>; 3402def : InstAlias<"lodsq\t$src", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>; 3403def : InstAlias<"lods\t{$src, %al|al, $src}", (LODSB srcidx8:$src), 0>; 3404def : InstAlias<"lods\t{$src, %ax|ax, $src}", (LODSW srcidx16:$src), 0>; 3405def : InstAlias<"lods\t{$src, %eax|eax, $src}", (LODSL srcidx32:$src), 0>; 3406def : InstAlias<"lods\t{$src, %rax|rax, $src}", (LODSQ srcidx64:$src), 0>, Requires<[In64BitMode]>; 3407def : InstAlias<"lods\t$src", (LODSB srcidx8:$src), 0, "intel">; 3408def : InstAlias<"lods\t$src", (LODSW srcidx16:$src), 0, "intel">; 3409def : InstAlias<"lods\t$src", (LODSL srcidx32:$src), 0, "intel">; 3410def : InstAlias<"lods\t$src", (LODSQ srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3411 3412 3413// stos aliases. Accept the source being omitted because it's implicit in 3414// the mnemonic, or the mnemonic suffix being omitted because it's implicit 3415// in the source. 3416def : InstAlias<"stosb\t$dst", (STOSB dstidx8:$dst), 0>; 3417def : InstAlias<"stosw\t$dst", (STOSW dstidx16:$dst), 0>; 3418def : InstAlias<"stos{l|d}\t$dst", (STOSL dstidx32:$dst), 0>; 3419def : InstAlias<"stosq\t$dst", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3420def : InstAlias<"stos\t{%al, $dst|$dst, al}", (STOSB dstidx8:$dst), 0>; 3421def : InstAlias<"stos\t{%ax, $dst|$dst, ax}", (STOSW dstidx16:$dst), 0>; 3422def : InstAlias<"stos\t{%eax, $dst|$dst, eax}", (STOSL dstidx32:$dst), 0>; 3423def : InstAlias<"stos\t{%rax, $dst|$dst, rax}", (STOSQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3424def : InstAlias<"stos\t$dst", (STOSB dstidx8:$dst), 0, "intel">; 3425def : InstAlias<"stos\t$dst", (STOSW dstidx16:$dst), 0, "intel">; 3426def : InstAlias<"stos\t$dst", (STOSL dstidx32:$dst), 0, "intel">; 3427def : InstAlias<"stos\t$dst", (STOSQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>; 3428 3429 3430// scas aliases. Accept the destination being omitted because it's implicit 3431// in the mnemonic, or the mnemonic suffix being omitted because it's implicit 3432// in the destination. 3433def : InstAlias<"scasb\t$dst", (SCASB dstidx8:$dst), 0>; 3434def : InstAlias<"scasw\t$dst", (SCASW dstidx16:$dst), 0>; 3435def : InstAlias<"scas{l|d}\t$dst", (SCASL dstidx32:$dst), 0>; 3436def : InstAlias<"scasq\t$dst", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3437def : InstAlias<"scas\t{$dst, %al|al, $dst}", (SCASB dstidx8:$dst), 0>; 3438def : InstAlias<"scas\t{$dst, %ax|ax, $dst}", (SCASW dstidx16:$dst), 0>; 3439def : InstAlias<"scas\t{$dst, %eax|eax, $dst}", (SCASL dstidx32:$dst), 0>; 3440def : InstAlias<"scas\t{$dst, %rax|rax, $dst}", (SCASQ dstidx64:$dst), 0>, Requires<[In64BitMode]>; 3441def : InstAlias<"scas\t$dst", (SCASB dstidx8:$dst), 0, "intel">; 3442def : InstAlias<"scas\t$dst", (SCASW dstidx16:$dst), 0, "intel">; 3443def : InstAlias<"scas\t$dst", (SCASL dstidx32:$dst), 0, "intel">; 3444def : InstAlias<"scas\t$dst", (SCASQ dstidx64:$dst), 0, "intel">, Requires<[In64BitMode]>; 3445 3446// cmps aliases. Mnemonic suffix being omitted because it's implicit 3447// in the destination. 3448def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSB dstidx8:$dst, srcidx8:$src), 0, "intel">; 3449def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSW dstidx16:$dst, srcidx16:$src), 0, "intel">; 3450def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSL dstidx32:$dst, srcidx32:$src), 0, "intel">; 3451def : InstAlias<"cmps\t{$dst, $src|$src, $dst}", (CMPSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3452 3453// movs aliases. Mnemonic suffix being omitted because it's implicit 3454// in the destination. 3455def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSB dstidx8:$dst, srcidx8:$src), 0, "intel">; 3456def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSW dstidx16:$dst, srcidx16:$src), 0, "intel">; 3457def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSL dstidx32:$dst, srcidx32:$src), 0, "intel">; 3458def : InstAlias<"movs\t{$src, $dst|$dst, $src}", (MOVSQ dstidx64:$dst, srcidx64:$src), 0, "intel">, Requires<[In64BitMode]>; 3459 3460// div and idiv aliases for explicit A register. 3461def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8r GR8 :$src)>; 3462def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16r GR16:$src)>; 3463def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32r GR32:$src)>; 3464def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64r GR64:$src)>; 3465def : InstAlias<"div{b}\t{$src, %al|al, $src}", (DIV8m i8mem :$src)>; 3466def : InstAlias<"div{w}\t{$src, %ax|ax, $src}", (DIV16m i16mem:$src)>; 3467def : InstAlias<"div{l}\t{$src, %eax|eax, $src}", (DIV32m i32mem:$src)>; 3468def : InstAlias<"div{q}\t{$src, %rax|rax, $src}", (DIV64m i64mem:$src)>; 3469def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8r GR8 :$src)>; 3470def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16r GR16:$src)>; 3471def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32r GR32:$src)>; 3472def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64r GR64:$src)>; 3473def : InstAlias<"idiv{b}\t{$src, %al|al, $src}", (IDIV8m i8mem :$src)>; 3474def : InstAlias<"idiv{w}\t{$src, %ax|ax, $src}", (IDIV16m i16mem:$src)>; 3475def : InstAlias<"idiv{l}\t{$src, %eax|eax, $src}", (IDIV32m i32mem:$src)>; 3476def : InstAlias<"idiv{q}\t{$src, %rax|rax, $src}", (IDIV64m i64mem:$src)>; 3477 3478 3479 3480// Various unary fpstack operations default to operating on ST1. 3481// For example, "fxch" -> "fxch %st(1)" 3482def : InstAlias<"faddp", (ADD_FPrST0 ST1), 0>; 3483def: InstAlias<"fadd", (ADD_FPrST0 ST1), 0>; 3484def : InstAlias<"fsub{|r}p", (SUBR_FPrST0 ST1), 0>; 3485def : InstAlias<"fsub{r|}p", (SUB_FPrST0 ST1), 0>; 3486def : InstAlias<"fmul", (MUL_FPrST0 ST1), 0>; 3487def : InstAlias<"fmulp", (MUL_FPrST0 ST1), 0>; 3488def : InstAlias<"fdiv{|r}p", (DIVR_FPrST0 ST1), 0>; 3489def : InstAlias<"fdiv{r|}p", (DIV_FPrST0 ST1), 0>; 3490def : InstAlias<"fxch", (XCH_F ST1), 0>; 3491def : InstAlias<"fcom", (COM_FST0r ST1), 0>; 3492def : InstAlias<"fcomp", (COMP_FST0r ST1), 0>; 3493def : InstAlias<"fcomi", (COM_FIr ST1), 0>; 3494def : InstAlias<"fcompi", (COM_FIPr ST1), 0>; 3495def : InstAlias<"fucom", (UCOM_Fr ST1), 0>; 3496def : InstAlias<"fucomp", (UCOM_FPr ST1), 0>; 3497def : InstAlias<"fucomi", (UCOM_FIr ST1), 0>; 3498def : InstAlias<"fucompi", (UCOM_FIPr ST1), 0>; 3499 3500// Handle fmul/fadd/fsub/fdiv instructions with explicitly written st(0) op. 3501// For example, "fadd %st(4), %st(0)" -> "fadd %st(4)". We also disambiguate 3502// instructions like "fadd %st(0), %st(0)" as "fadd %st(0)" for consistency with 3503// gas. 3504multiclass FpUnaryAlias<string Mnemonic, Instruction Inst, bit EmitAlias = 1> { 3505 def : InstAlias<!strconcat(Mnemonic, "\t$op"), 3506 (Inst RSTi:$op), EmitAlias>; 3507 def : InstAlias<!strconcat(Mnemonic, "\t{%st, %st|st, st}"), 3508 (Inst ST0), EmitAlias>; 3509} 3510 3511defm : FpUnaryAlias<"fadd", ADD_FST0r, 0>; 3512defm : FpUnaryAlias<"faddp", ADD_FPrST0, 0>; 3513defm : FpUnaryAlias<"fsub", SUB_FST0r, 0>; 3514defm : FpUnaryAlias<"fsub{|r}p", SUBR_FPrST0, 0>; 3515defm : FpUnaryAlias<"fsubr", SUBR_FST0r, 0>; 3516defm : FpUnaryAlias<"fsub{r|}p", SUB_FPrST0, 0>; 3517defm : FpUnaryAlias<"fmul", MUL_FST0r, 0>; 3518defm : FpUnaryAlias<"fmulp", MUL_FPrST0, 0>; 3519defm : FpUnaryAlias<"fdiv", DIV_FST0r, 0>; 3520defm : FpUnaryAlias<"fdiv{|r}p", DIVR_FPrST0, 0>; 3521defm : FpUnaryAlias<"fdivr", DIVR_FST0r, 0>; 3522defm : FpUnaryAlias<"fdiv{r|}p", DIV_FPrST0, 0>; 3523defm : FpUnaryAlias<"fcomi", COM_FIr, 0>; 3524defm : FpUnaryAlias<"fucomi", UCOM_FIr, 0>; 3525defm : FpUnaryAlias<"fcompi", COM_FIPr, 0>; 3526defm : FpUnaryAlias<"fucompi", UCOM_FIPr, 0>; 3527 3528 3529// Handle "f{mulp,addp} $op, %st(0)" the same as "f{mulp,addp} $op", since they 3530// commute. We also allow fdiv[r]p/fsubrp even though they don't commute, 3531// solely because gas supports it. 3532def : InstAlias<"faddp\t{$op, %st|st, $op}", (ADD_FPrST0 RSTi:$op), 0>; 3533def : InstAlias<"fmulp\t{$op, %st|st, $op}", (MUL_FPrST0 RSTi:$op), 0>; 3534def : InstAlias<"fsub{|r}p\t{$op, %st|st, $op}", (SUBR_FPrST0 RSTi:$op), 0>; 3535def : InstAlias<"fsub{r|}p\t{$op, %st|st, $op}", (SUB_FPrST0 RSTi:$op), 0>; 3536def : InstAlias<"fdiv{|r}p\t{$op, %st|st, $op}", (DIVR_FPrST0 RSTi:$op), 0>; 3537def : InstAlias<"fdiv{r|}p\t{$op, %st|st, $op}", (DIV_FPrST0 RSTi:$op), 0>; 3538 3539def : InstAlias<"fnstsw" , (FNSTSW16r), 0>; 3540 3541// lcall and ljmp aliases. This seems to be an odd mapping in 64-bit mode, but 3542// this is compatible with what GAS does. 3543def : InstAlias<"lcall\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>; 3544def : InstAlias<"ljmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg), 0>, Requires<[In32BitMode]>; 3545def : InstAlias<"lcall\t{*}$dst", (FARCALL32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>; 3546def : InstAlias<"ljmp\t{*}$dst", (FARJMP32m opaquemem:$dst), 0>, Requires<[Not16BitMode]>; 3547def : InstAlias<"lcall\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>; 3548def : InstAlias<"ljmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg), 0>, Requires<[In16BitMode]>; 3549def : InstAlias<"lcall\t{*}$dst", (FARCALL16m opaquemem:$dst), 0>, Requires<[In16BitMode]>; 3550def : InstAlias<"ljmp\t{*}$dst", (FARJMP16m opaquemem:$dst), 0>, Requires<[In16BitMode]>; 3551 3552def : InstAlias<"jmp\t{*}$dst", (JMP64m i64mem:$dst), 0, "att">, Requires<[In64BitMode]>; 3553def : InstAlias<"jmp\t{*}$dst", (JMP32m i32mem:$dst), 0, "att">, Requires<[In32BitMode]>; 3554def : InstAlias<"jmp\t{*}$dst", (JMP16m i16mem:$dst), 0, "att">, Requires<[In16BitMode]>; 3555 3556 3557// "imul <imm>, B" is an alias for "imul <imm>, B, B". 3558def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri GR16:$r, GR16:$r, i16imm:$imm), 0>; 3559def : InstAlias<"imul{w}\t{$imm, $r|$r, $imm}", (IMUL16rri8 GR16:$r, GR16:$r, i16i8imm:$imm), 0>; 3560def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri GR32:$r, GR32:$r, i32imm:$imm), 0>; 3561def : InstAlias<"imul{l}\t{$imm, $r|$r, $imm}", (IMUL32rri8 GR32:$r, GR32:$r, i32i8imm:$imm), 0>; 3562def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri32 GR64:$r, GR64:$r, i64i32imm:$imm), 0>; 3563def : InstAlias<"imul{q}\t{$imm, $r|$r, $imm}", (IMUL64rri8 GR64:$r, GR64:$r, i64i8imm:$imm), 0>; 3564 3565// ins aliases. Accept the mnemonic suffix being omitted because it's implicit 3566// in the destination. 3567def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSB dstidx8:$dst), 0, "intel">; 3568def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSW dstidx16:$dst), 0, "intel">; 3569def : InstAlias<"ins\t{%dx, $dst|$dst, dx}", (INSL dstidx32:$dst), 0, "intel">; 3570 3571// outs aliases. Accept the mnemonic suffix being omitted because it's implicit 3572// in the source. 3573def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSB srcidx8:$src), 0, "intel">; 3574def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSW srcidx16:$src), 0, "intel">; 3575def : InstAlias<"outs\t{$src, %dx|dx, $src}", (OUTSL srcidx32:$src), 0, "intel">; 3576 3577// inb %dx -> inb %al, %dx 3578def : InstAlias<"inb\t{%dx|dx}", (IN8rr), 0>; 3579def : InstAlias<"inw\t{%dx|dx}", (IN16rr), 0>; 3580def : InstAlias<"inl\t{%dx|dx}", (IN32rr), 0>; 3581def : InstAlias<"inb\t$port", (IN8ri u8imm:$port), 0>; 3582def : InstAlias<"inw\t$port", (IN16ri u8imm:$port), 0>; 3583def : InstAlias<"inl\t$port", (IN32ri u8imm:$port), 0>; 3584 3585 3586// jmp and call aliases for lcall and ljmp. jmp $42,$5 -> ljmp 3587def : InstAlias<"call\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>; 3588def : InstAlias<"jmp\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[In16BitMode]>; 3589def : InstAlias<"call\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>; 3590def : InstAlias<"jmp\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[In32BitMode]>; 3591def : InstAlias<"callw\t$seg, $off", (FARCALL16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3592def : InstAlias<"jmpw\t$seg, $off", (FARJMP16i i16imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3593def : InstAlias<"calll\t$seg, $off", (FARCALL32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3594def : InstAlias<"jmpl\t$seg, $off", (FARJMP32i i32imm:$off, i16imm:$seg)>, Requires<[Not64BitMode]>; 3595 3596// Match 'movq <largeimm>, <reg>' as an alias for movabsq. 3597def : InstAlias<"mov{q}\t{$imm, $reg|$reg, $imm}", (MOV64ri GR64:$reg, i64imm:$imm), 0>; 3598 3599// Match 'movd GR64, MMX' as an alias for movq to be compatible with gas, 3600// which supports this due to an old AMD documentation bug when 64-bit mode was 3601// created. 3602def : InstAlias<"movd\t{$src, $dst|$dst, $src}", 3603 (MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>; 3604def : InstAlias<"movd\t{$src, $dst|$dst, $src}", 3605 (MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>; 3606 3607// movsx aliases 3608def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rr8 GR16:$dst, GR8:$src), 0, "att">; 3609def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX16rm8 GR16:$dst, i8mem:$src), 0, "att">; 3610def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr8 GR32:$dst, GR8:$src), 0, "att">; 3611def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX32rr16 GR32:$dst, GR16:$src), 0, "att">; 3612def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr8 GR64:$dst, GR8:$src), 0, "att">; 3613def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr16 GR64:$dst, GR16:$src), 0, "att">; 3614def : InstAlias<"movsx\t{$src, $dst|$dst, $src}", (MOVSX64rr32 GR64:$dst, GR32:$src), 0, "att">; 3615 3616// movzx aliases 3617def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rr8 GR16:$dst, GR8:$src), 0, "att">; 3618def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX16rm8 GR16:$dst, i8mem:$src), 0, "att">; 3619def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr8 GR32:$dst, GR8:$src), 0, "att">; 3620def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX32rr16 GR32:$dst, GR16:$src), 0, "att">; 3621def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr8 GR64:$dst, GR8:$src), 0, "att">; 3622def : InstAlias<"movzx\t{$src, $dst|$dst, $src}", (MOVZX64rr16 GR64:$dst, GR16:$src), 0, "att">; 3623// Note: No GR32->GR64 movzx form. 3624 3625// outb %dx -> outb %al, %dx 3626def : InstAlias<"outb\t{%dx|dx}", (OUT8rr), 0>; 3627def : InstAlias<"outw\t{%dx|dx}", (OUT16rr), 0>; 3628def : InstAlias<"outl\t{%dx|dx}", (OUT32rr), 0>; 3629def : InstAlias<"outb\t$port", (OUT8ir u8imm:$port), 0>; 3630def : InstAlias<"outw\t$port", (OUT16ir u8imm:$port), 0>; 3631def : InstAlias<"outl\t$port", (OUT32ir u8imm:$port), 0>; 3632 3633// 'sldt <mem>' can be encoded with either sldtw or sldtq with the same 3634// effect (both store to a 16-bit mem). Force to sldtw to avoid ambiguity 3635// errors, since its encoding is the most compact. 3636def : InstAlias<"sldt $mem", (SLDT16m i16mem:$mem), 0>; 3637 3638// shld/shrd op,op -> shld op, op, CL 3639def : InstAlias<"shld{w}\t{$r2, $r1|$r1, $r2}", (SHLD16rrCL GR16:$r1, GR16:$r2), 0>; 3640def : InstAlias<"shld{l}\t{$r2, $r1|$r1, $r2}", (SHLD32rrCL GR32:$r1, GR32:$r2), 0>; 3641def : InstAlias<"shld{q}\t{$r2, $r1|$r1, $r2}", (SHLD64rrCL GR64:$r1, GR64:$r2), 0>; 3642def : InstAlias<"shrd{w}\t{$r2, $r1|$r1, $r2}", (SHRD16rrCL GR16:$r1, GR16:$r2), 0>; 3643def : InstAlias<"shrd{l}\t{$r2, $r1|$r1, $r2}", (SHRD32rrCL GR32:$r1, GR32:$r2), 0>; 3644def : InstAlias<"shrd{q}\t{$r2, $r1|$r1, $r2}", (SHRD64rrCL GR64:$r1, GR64:$r2), 0>; 3645 3646def : InstAlias<"shld{w}\t{$reg, $mem|$mem, $reg}", (SHLD16mrCL i16mem:$mem, GR16:$reg), 0>; 3647def : InstAlias<"shld{l}\t{$reg, $mem|$mem, $reg}", (SHLD32mrCL i32mem:$mem, GR32:$reg), 0>; 3648def : InstAlias<"shld{q}\t{$reg, $mem|$mem, $reg}", (SHLD64mrCL i64mem:$mem, GR64:$reg), 0>; 3649def : InstAlias<"shrd{w}\t{$reg, $mem|$mem, $reg}", (SHRD16mrCL i16mem:$mem, GR16:$reg), 0>; 3650def : InstAlias<"shrd{l}\t{$reg, $mem|$mem, $reg}", (SHRD32mrCL i32mem:$mem, GR32:$reg), 0>; 3651def : InstAlias<"shrd{q}\t{$reg, $mem|$mem, $reg}", (SHRD64mrCL i64mem:$mem, GR64:$reg), 0>; 3652 3653/* FIXME: This is disabled because the asm matcher is currently incapable of 3654 * matching a fixed immediate like $1. 3655// "shl X, $1" is an alias for "shl X". 3656multiclass ShiftRotateByOneAlias<string Mnemonic, string Opc> { 3657 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"), 3658 (!cast<Instruction>(!strconcat(Opc, "8r1")) GR8:$op)>; 3659 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"), 3660 (!cast<Instruction>(!strconcat(Opc, "16r1")) GR16:$op)>; 3661 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"), 3662 (!cast<Instruction>(!strconcat(Opc, "32r1")) GR32:$op)>; 3663 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"), 3664 (!cast<Instruction>(!strconcat(Opc, "64r1")) GR64:$op)>; 3665 def : InstAlias<!strconcat(Mnemonic, "b $op, $$1"), 3666 (!cast<Instruction>(!strconcat(Opc, "8m1")) i8mem:$op)>; 3667 def : InstAlias<!strconcat(Mnemonic, "w $op, $$1"), 3668 (!cast<Instruction>(!strconcat(Opc, "16m1")) i16mem:$op)>; 3669 def : InstAlias<!strconcat(Mnemonic, "l $op, $$1"), 3670 (!cast<Instruction>(!strconcat(Opc, "32m1")) i32mem:$op)>; 3671 def : InstAlias<!strconcat(Mnemonic, "q $op, $$1"), 3672 (!cast<Instruction>(!strconcat(Opc, "64m1")) i64mem:$op)>; 3673} 3674 3675defm : ShiftRotateByOneAlias<"rcl", "RCL">; 3676defm : ShiftRotateByOneAlias<"rcr", "RCR">; 3677defm : ShiftRotateByOneAlias<"rol", "ROL">; 3678defm : ShiftRotateByOneAlias<"ror", "ROR">; 3679FIXME */ 3680 3681// test: We accept "testX <reg>, <mem>" and "testX <mem>, <reg>" as synonyms. 3682def : InstAlias<"test{b}\t{$mem, $val|$val, $mem}", 3683 (TEST8mr i8mem :$mem, GR8 :$val), 0>; 3684def : InstAlias<"test{w}\t{$mem, $val|$val, $mem}", 3685 (TEST16mr i16mem:$mem, GR16:$val), 0>; 3686def : InstAlias<"test{l}\t{$mem, $val|$val, $mem}", 3687 (TEST32mr i32mem:$mem, GR32:$val), 0>; 3688def : InstAlias<"test{q}\t{$mem, $val|$val, $mem}", 3689 (TEST64mr i64mem:$mem, GR64:$val), 0>; 3690 3691// xchg: We accept "xchgX <reg>, <mem>" and "xchgX <mem>, <reg>" as synonyms. 3692def : InstAlias<"xchg{b}\t{$mem, $val|$val, $mem}", 3693 (XCHG8rm GR8 :$val, i8mem :$mem), 0>; 3694def : InstAlias<"xchg{w}\t{$mem, $val|$val, $mem}", 3695 (XCHG16rm GR16:$val, i16mem:$mem), 0>; 3696def : InstAlias<"xchg{l}\t{$mem, $val|$val, $mem}", 3697 (XCHG32rm GR32:$val, i32mem:$mem), 0>; 3698def : InstAlias<"xchg{q}\t{$mem, $val|$val, $mem}", 3699 (XCHG64rm GR64:$val, i64mem:$mem), 0>; 3700 3701// xchg: We accept "xchgX <reg>, %eax" and "xchgX %eax, <reg>" as synonyms. 3702def : InstAlias<"xchg{w}\t{%ax, $src|$src, ax}", (XCHG16ar GR16:$src), 0>; 3703def : InstAlias<"xchg{l}\t{%eax, $src|$src, eax}", (XCHG32ar GR32:$src), 0>; 3704def : InstAlias<"xchg{q}\t{%rax, $src|$src, rax}", (XCHG64ar GR64:$src), 0>; 3705 3706// In 64-bit mode, xchg %eax, %eax can't be encoded with the 0x90 opcode we 3707// would get by default because it's defined as NOP. But xchg %eax, %eax implies 3708// implicit zeroing of the upper 32 bits. So alias to the longer encoding. 3709def : InstAlias<"xchg{l}\t{%eax, %eax|eax, eax}", 3710 (XCHG32rr EAX, EAX), 0>, Requires<[In64BitMode]>; 3711 3712// xchg %rax, %rax is a nop in x86-64 and can be encoded as such. Without this 3713// we emit an unneeded REX.w prefix. 3714def : InstAlias<"xchg{q}\t{%rax, %rax|rax, rax}", (NOOP), 0>; 3715 3716// These aliases exist to get the parser to prioritize matching 8-bit 3717// immediate encodings over matching the implicit ax/eax/rax encodings. By 3718// explicitly mentioning the A register here, these entries will be ordered 3719// first due to the more explicit immediate type. 3720def : InstAlias<"adc{w}\t{$imm, %ax|ax, $imm}", (ADC16ri8 AX, i16i8imm:$imm), 0>; 3721def : InstAlias<"add{w}\t{$imm, %ax|ax, $imm}", (ADD16ri8 AX, i16i8imm:$imm), 0>; 3722def : InstAlias<"and{w}\t{$imm, %ax|ax, $imm}", (AND16ri8 AX, i16i8imm:$imm), 0>; 3723def : InstAlias<"cmp{w}\t{$imm, %ax|ax, $imm}", (CMP16ri8 AX, i16i8imm:$imm), 0>; 3724def : InstAlias<"or{w}\t{$imm, %ax|ax, $imm}", (OR16ri8 AX, i16i8imm:$imm), 0>; 3725def : InstAlias<"sbb{w}\t{$imm, %ax|ax, $imm}", (SBB16ri8 AX, i16i8imm:$imm), 0>; 3726def : InstAlias<"sub{w}\t{$imm, %ax|ax, $imm}", (SUB16ri8 AX, i16i8imm:$imm), 0>; 3727def : InstAlias<"xor{w}\t{$imm, %ax|ax, $imm}", (XOR16ri8 AX, i16i8imm:$imm), 0>; 3728 3729def : InstAlias<"adc{l}\t{$imm, %eax|eax, $imm}", (ADC32ri8 EAX, i32i8imm:$imm), 0>; 3730def : InstAlias<"add{l}\t{$imm, %eax|eax, $imm}", (ADD32ri8 EAX, i32i8imm:$imm), 0>; 3731def : InstAlias<"and{l}\t{$imm, %eax|eax, $imm}", (AND32ri8 EAX, i32i8imm:$imm), 0>; 3732def : InstAlias<"cmp{l}\t{$imm, %eax|eax, $imm}", (CMP32ri8 EAX, i32i8imm:$imm), 0>; 3733def : InstAlias<"or{l}\t{$imm, %eax|eax, $imm}", (OR32ri8 EAX, i32i8imm:$imm), 0>; 3734def : InstAlias<"sbb{l}\t{$imm, %eax|eax, $imm}", (SBB32ri8 EAX, i32i8imm:$imm), 0>; 3735def : InstAlias<"sub{l}\t{$imm, %eax|eax, $imm}", (SUB32ri8 EAX, i32i8imm:$imm), 0>; 3736def : InstAlias<"xor{l}\t{$imm, %eax|eax, $imm}", (XOR32ri8 EAX, i32i8imm:$imm), 0>; 3737 3738def : InstAlias<"adc{q}\t{$imm, %rax|rax, $imm}", (ADC64ri8 RAX, i64i8imm:$imm), 0>; 3739def : InstAlias<"add{q}\t{$imm, %rax|rax, $imm}", (ADD64ri8 RAX, i64i8imm:$imm), 0>; 3740def : InstAlias<"and{q}\t{$imm, %rax|rax, $imm}", (AND64ri8 RAX, i64i8imm:$imm), 0>; 3741def : InstAlias<"cmp{q}\t{$imm, %rax|rax, $imm}", (CMP64ri8 RAX, i64i8imm:$imm), 0>; 3742def : InstAlias<"or{q}\t{$imm, %rax|rax, $imm}", (OR64ri8 RAX, i64i8imm:$imm), 0>; 3743def : InstAlias<"sbb{q}\t{$imm, %rax|rax, $imm}", (SBB64ri8 RAX, i64i8imm:$imm), 0>; 3744def : InstAlias<"sub{q}\t{$imm, %rax|rax, $imm}", (SUB64ri8 RAX, i64i8imm:$imm), 0>; 3745def : InstAlias<"xor{q}\t{$imm, %rax|rax, $imm}", (XOR64ri8 RAX, i64i8imm:$imm), 0>; 3746