1 //===- llvm/InlineAsm.h - Class to represent inline asm strings -*- C++ -*-===// 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 class represents the inline asm strings, which are Value*'s that are 10 // used as the callee operand of call instructions. InlineAsm's are uniqued 11 // like constants, and created via InlineAsm::get(...). 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_INLINEASM_H 16 #define LLVM_IR_INLINEASM_H 17 18 #include "llvm/ADT/Bitfields.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/IR/Value.h" 22 #include "llvm/Support/Compiler.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include <cassert> 25 #include <string> 26 #include <vector> 27 28 namespace llvm { 29 30 class Error; 31 class FunctionType; 32 class PointerType; 33 template <class ConstantClass> class ConstantUniqueMap; 34 35 class InlineAsm final : public Value { 36 public: 37 enum AsmDialect { 38 AD_ATT, 39 AD_Intel 40 }; 41 42 private: 43 friend struct InlineAsmKeyType; 44 friend class ConstantUniqueMap<InlineAsm>; 45 46 std::string AsmString, Constraints; 47 FunctionType *FTy; 48 bool HasSideEffects; 49 bool IsAlignStack; 50 AsmDialect Dialect; 51 bool CanThrow; 52 53 InlineAsm(FunctionType *Ty, const std::string &AsmString, 54 const std::string &Constraints, bool hasSideEffects, 55 bool isAlignStack, AsmDialect asmDialect, bool canThrow); 56 57 /// When the ConstantUniqueMap merges two types and makes two InlineAsms 58 /// identical, it destroys one of them with this method. 59 void destroyConstant(); 60 61 public: 62 InlineAsm(const InlineAsm &) = delete; 63 InlineAsm &operator=(const InlineAsm &) = delete; 64 65 /// InlineAsm::get - Return the specified uniqued inline asm string. 66 /// 67 LLVM_ABI static InlineAsm *get(FunctionType *Ty, StringRef AsmString, 68 StringRef Constraints, bool hasSideEffects, 69 bool isAlignStack = false, 70 AsmDialect asmDialect = AD_ATT, 71 bool canThrow = false); 72 hasSideEffects()73 bool hasSideEffects() const { return HasSideEffects; } isAlignStack()74 bool isAlignStack() const { return IsAlignStack; } getDialect()75 AsmDialect getDialect() const { return Dialect; } canThrow()76 bool canThrow() const { return CanThrow; } 77 78 /// getType - InlineAsm's are always pointers. 79 /// getType()80 PointerType *getType() const { 81 return reinterpret_cast<PointerType*>(Value::getType()); 82 } 83 84 /// getFunctionType - InlineAsm's are always pointers to functions. 85 /// 86 LLVM_ABI FunctionType *getFunctionType() const; 87 getAsmString()88 StringRef getAsmString() const { return AsmString; } getConstraintString()89 StringRef getConstraintString() const { return Constraints; } 90 LLVM_ABI void collectAsmStrs(SmallVectorImpl<StringRef> &AsmStrs) const; 91 92 /// This static method can be used by the parser to check to see if the 93 /// specified constraint string is legal for the type. 94 LLVM_ABI static Error verify(FunctionType *Ty, StringRef Constraints); 95 96 // Constraint String Parsing 97 enum ConstraintPrefix { 98 isInput, // 'x' 99 isOutput, // '=x' 100 isClobber, // '~x' 101 isLabel, // '!x' 102 }; 103 104 using ConstraintCodeVector = std::vector<std::string>; 105 106 struct SubConstraintInfo { 107 /// MatchingInput - If this is not -1, this is an output constraint where an 108 /// input constraint is required to match it (e.g. "0"). The value is the 109 /// constraint number that matches this one (for example, if this is 110 /// constraint #0 and constraint #4 has the value "0", this will be 4). 111 int MatchingInput = -1; 112 113 /// Code - The constraint code, either the register name (in braces) or the 114 /// constraint letter/number. 115 ConstraintCodeVector Codes; 116 117 /// Default constructor. 118 SubConstraintInfo() = default; 119 }; 120 121 using SubConstraintInfoVector = std::vector<SubConstraintInfo>; 122 struct ConstraintInfo; 123 using ConstraintInfoVector = std::vector<ConstraintInfo>; 124 125 struct ConstraintInfo { 126 /// Type - The basic type of the constraint: input/output/clobber/label 127 /// 128 ConstraintPrefix Type = isInput; 129 130 /// isEarlyClobber - "&": output operand writes result before inputs are all 131 /// read. This is only ever set for an output operand. 132 bool isEarlyClobber = false; 133 134 /// MatchingInput - If this is not -1, this is an output constraint where an 135 /// input constraint is required to match it (e.g. "0"). The value is the 136 /// constraint number that matches this one (for example, if this is 137 /// constraint #0 and constraint #4 has the value "0", this will be 4). 138 int MatchingInput = -1; 139 140 /// hasMatchingInput - Return true if this is an output constraint that has 141 /// a matching input constraint. hasMatchingInputConstraintInfo142 bool hasMatchingInput() const { return MatchingInput != -1; } 143 144 /// isCommutative - This is set to true for a constraint that is commutative 145 /// with the next operand. 146 bool isCommutative = false; 147 148 /// isIndirect - True if this operand is an indirect operand. This means 149 /// that the address of the source or destination is present in the call 150 /// instruction, instead of it being returned or passed in explicitly. This 151 /// is represented with a '*' in the asm string. 152 bool isIndirect = false; 153 154 /// Code - The constraint code, either the register name (in braces) or the 155 /// constraint letter/number. 156 ConstraintCodeVector Codes; 157 158 /// isMultipleAlternative - '|': has multiple-alternative constraints. 159 bool isMultipleAlternative = false; 160 161 /// multipleAlternatives - If there are multiple alternative constraints, 162 /// this array will contain them. Otherwise it will be empty. 163 SubConstraintInfoVector multipleAlternatives; 164 165 /// The currently selected alternative constraint index. 166 unsigned currentAlternativeIndex = 0; 167 168 /// Default constructor. 169 ConstraintInfo() = default; 170 171 /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the 172 /// fields in this structure. If the constraint string is not understood, 173 /// return true, otherwise return false. 174 LLVM_ABI bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar); 175 176 /// selectAlternative - Point this constraint to the alternative constraint 177 /// indicated by the index. 178 LLVM_ABI void selectAlternative(unsigned index); 179 180 /// Whether this constraint corresponds to an argument. hasArgConstraintInfo181 bool hasArg() const { 182 return Type == isInput || (Type == isOutput && isIndirect); 183 } 184 }; 185 186 /// ParseConstraints - Split up the constraint string into the specific 187 /// constraints and their prefixes. If this returns an empty vector, and if 188 /// the constraint string itself isn't empty, there was an error parsing. 189 LLVM_ABI static ConstraintInfoVector 190 ParseConstraints(StringRef ConstraintString); 191 192 /// ParseConstraints - Parse the constraints of this inlineasm object, 193 /// returning them the same way that ParseConstraints(str) does. ParseConstraints()194 ConstraintInfoVector ParseConstraints() const { 195 return ParseConstraints(Constraints); 196 } 197 198 // Methods for support type inquiry through isa, cast, and dyn_cast: classof(const Value * V)199 static bool classof(const Value *V) { 200 return V->getValueID() == Value::InlineAsmVal; 201 } 202 203 enum : uint32_t { 204 // Fixed operands on an INLINEASM SDNode. 205 Op_InputChain = 0, 206 Op_AsmString = 1, 207 Op_MDNode = 2, 208 Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect. 209 Op_FirstOperand = 4, 210 211 // Fixed operands on an INLINEASM MachineInstr. 212 MIOp_AsmString = 0, 213 MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect. 214 MIOp_FirstOperand = 2, 215 216 // Interpretation of the MIOp_ExtraInfo bit field. 217 Extra_HasSideEffects = 1, 218 Extra_IsAlignStack = 2, 219 Extra_AsmDialect = 4, 220 Extra_MayLoad = 8, 221 Extra_MayStore = 16, 222 Extra_IsConvergent = 32, 223 }; 224 225 // Inline asm operands map to multiple SDNode / MachineInstr operands. 226 // The first operand is an immediate describing the asm operand, the low 227 // bits is the kind: 228 enum class Kind : uint8_t { 229 RegUse = 1, // Input register, "r". 230 RegDef = 2, // Output register, "=r". 231 RegDefEarlyClobber = 3, // Early-clobber output register, "=&r". 232 Clobber = 4, // Clobbered register, "~r". 233 Imm = 5, // Immediate. 234 Mem = 6, // Memory operand, "m", or an address, "p". 235 Func = 7, // Address operand of function call 236 }; 237 238 // Memory constraint codes. 239 // Addresses are included here as they need to be treated the same by the 240 // backend, the only difference is that they are not used to actaully 241 // access memory by the instruction. 242 enum class ConstraintCode : uint32_t { 243 Unknown = 0, 244 es, 245 i, 246 k, 247 m, 248 o, 249 v, 250 A, 251 Q, 252 R, 253 S, 254 T, 255 Um, 256 Un, 257 Uq, 258 Us, 259 Ut, 260 Uv, 261 Uy, 262 X, 263 Z, 264 ZB, 265 ZC, 266 Zy, 267 268 // Address constraints 269 p, 270 ZQ, 271 ZR, 272 ZS, 273 ZT, 274 275 Max = ZT, 276 }; 277 278 // This class is intentionally packed into a 32b value as it is used as a 279 // MVT::i32 ConstantSDNode SDValue for SelectionDAG and as immediate operands 280 // on INLINEASM and INLINEASM_BR MachineInstr's. 281 // 282 // The encoding of Flag is currently: 283 // Bits 2-0 - A Kind::* value indicating the kind of the operand. 284 // (KindField) 285 // Bits 15-3 - The number of SDNode operands associated with this inline 286 // assembly operand. Once lowered to MIR, this represents the 287 // number of MachineOperands necessary to refer to a 288 // MachineOperandType::MO_FrameIndex. (NumOperands) 289 // Bit 31 - Determines if this is a matched operand. (IsMatched) 290 // If bit 31 is set: 291 // Bits 30-16 - The operand number that this operand must match. 292 // (MatchedOperandNo) 293 // Else if bits 2-0 are Kind::Mem: 294 // Bits 30-16 - A ConstraintCode:: value indicating the original 295 // constraint code. (MemConstraintCode) 296 // Else: 297 // Bits 29-16 - The register class ID to use for the operand. (RegClass) 298 // Bit 30 - If the register is permitted to be spilled. 299 // (RegMayBeFolded) 300 // Defaults to false "r", may be set for constraints like 301 // "rm" (or "g"). 302 // 303 // As such, MatchedOperandNo, MemConstraintCode, and 304 // (RegClass+RegMayBeFolded) are views of the same slice of bits, but are 305 // mutually exclusive depending on the fields IsMatched then KindField. 306 class Flag { 307 uint32_t Storage; 308 using KindField = Bitfield::Element<Kind, 0, 3, Kind::Func>; 309 using NumOperands = Bitfield::Element<unsigned, 3, 13>; 310 using MatchedOperandNo = Bitfield::Element<unsigned, 16, 15>; 311 using MemConstraintCode = Bitfield::Element<ConstraintCode, 16, 15, ConstraintCode::Max>; 312 using RegClass = Bitfield::Element<unsigned, 16, 14>; 313 using RegMayBeFolded = Bitfield::Element<bool, 30, 1>; 314 using IsMatched = Bitfield::Element<bool, 31, 1>; 315 316 getMatchedOperandNo()317 unsigned getMatchedOperandNo() const { return Bitfield::get<MatchedOperandNo>(Storage); } getRegClass()318 unsigned getRegClass() const { return Bitfield::get<RegClass>(Storage); } isMatched()319 bool isMatched() const { return Bitfield::get<IsMatched>(Storage); } 320 321 public: Flag()322 Flag() : Storage(0) {} Flag(uint32_t F)323 explicit Flag(uint32_t F) : Storage(F) {} Flag(enum Kind K,unsigned NumOps)324 Flag(enum Kind K, unsigned NumOps) : Storage(0) { 325 Bitfield::set<KindField>(Storage, K); 326 Bitfield::set<NumOperands>(Storage, NumOps); 327 } uint32_t()328 operator uint32_t() { return Storage; } getKind()329 Kind getKind() const { return Bitfield::get<KindField>(Storage); } isRegUseKind()330 bool isRegUseKind() const { return getKind() == Kind::RegUse; } isRegDefKind()331 bool isRegDefKind() const { return getKind() == Kind::RegDef; } isRegDefEarlyClobberKind()332 bool isRegDefEarlyClobberKind() const { 333 return getKind() == Kind::RegDefEarlyClobber; 334 } isClobberKind()335 bool isClobberKind() const { return getKind() == Kind::Clobber; } isImmKind()336 bool isImmKind() const { return getKind() == Kind::Imm; } isMemKind()337 bool isMemKind() const { return getKind() == Kind::Mem; } isFuncKind()338 bool isFuncKind() const { return getKind() == Kind::Func; } getKindName()339 StringRef getKindName() const { 340 switch (getKind()) { 341 case Kind::RegUse: 342 return "reguse"; 343 case Kind::RegDef: 344 return "regdef"; 345 case Kind::RegDefEarlyClobber: 346 return "regdef-ec"; 347 case Kind::Clobber: 348 return "clobber"; 349 case Kind::Imm: 350 return "imm"; 351 case Kind::Mem: 352 case Kind::Func: 353 return "mem"; 354 } 355 llvm_unreachable("impossible kind"); 356 } 357 358 /// getNumOperandRegisters - Extract the number of registers field from the 359 /// inline asm operand flag. getNumOperandRegisters()360 unsigned getNumOperandRegisters() const { 361 return Bitfield::get<NumOperands>(Storage); 362 } 363 364 /// isUseOperandTiedToDef - Return true if the flag of the inline asm 365 /// operand indicates it is an use operand that's matched to a def operand. isUseOperandTiedToDef(unsigned & Idx)366 bool isUseOperandTiedToDef(unsigned &Idx) const { 367 if (!isMatched()) 368 return false; 369 Idx = getMatchedOperandNo(); 370 return true; 371 } 372 373 /// hasRegClassConstraint - Returns true if the flag contains a register 374 /// class constraint. Sets RC to the register class ID. hasRegClassConstraint(unsigned & RC)375 bool hasRegClassConstraint(unsigned &RC) const { 376 if (isMatched()) 377 return false; 378 // setRegClass() uses 0 to mean no register class, and otherwise stores 379 // RC + 1. 380 if (!getRegClass()) 381 return false; 382 RC = getRegClass() - 1; 383 return true; 384 } 385 getMemoryConstraintID()386 ConstraintCode getMemoryConstraintID() const { 387 assert((isMemKind() || isFuncKind()) && 388 "Not expected mem or function flag!"); 389 return Bitfield::get<MemConstraintCode>(Storage); 390 } 391 392 /// setMatchingOp - Augment an existing flag with information indicating 393 /// that this input operand is tied to a previous output operand. setMatchingOp(unsigned OperandNo)394 void setMatchingOp(unsigned OperandNo) { 395 assert(getMatchedOperandNo() == 0 && "Matching operand already set"); 396 Bitfield::set<MatchedOperandNo>(Storage, OperandNo); 397 Bitfield::set<IsMatched>(Storage, true); 398 } 399 400 /// setRegClass - Augment an existing flag with the required register class 401 /// for the following register operands. A tied use operand cannot have a 402 /// register class, use the register class from the def operand instead. setRegClass(unsigned RC)403 void setRegClass(unsigned RC) { 404 assert(!isImmKind() && "Immediates cannot have a register class"); 405 assert(!isMemKind() && "Memory operand cannot have a register class"); 406 assert(getRegClass() == 0 && "Register class already set"); 407 // Store RC + 1, reserve the value 0 to mean 'no register class'. 408 Bitfield::set<RegClass>(Storage, RC + 1); 409 } 410 411 /// setMemConstraint - Augment an existing flag with the constraint code for 412 /// a memory constraint. setMemConstraint(ConstraintCode C)413 void setMemConstraint(ConstraintCode C) { 414 assert(getMemoryConstraintID() == ConstraintCode::Unknown && "Mem constraint already set"); 415 Bitfield::set<MemConstraintCode>(Storage, C); 416 } 417 /// clearMemConstraint - Similar to setMemConstraint(0), but without the 418 /// assertion checking that the constraint has not been set previously. clearMemConstraint()419 void clearMemConstraint() { 420 assert((isMemKind() || isFuncKind()) && 421 "Flag is not a memory or function constraint!"); 422 Bitfield::set<MemConstraintCode>(Storage, ConstraintCode::Unknown); 423 } 424 425 /// Set a bit to denote that while this operand is some kind of register 426 /// (use, def, ...), a memory flag did appear in the original constraint 427 /// list. This is set by the instruction selection framework, and consumed 428 /// by the register allocator. While the register allocator is generally 429 /// responsible for spilling registers, we need to be able to distinguish 430 /// between registers that the register allocator has permission to fold 431 /// ("rm") vs ones it does not ("r"). This is because the inline asm may use 432 /// instructions which don't support memory addressing modes for that 433 /// operand. setRegMayBeFolded(bool B)434 void setRegMayBeFolded(bool B) { 435 assert((isRegDefKind() || isRegDefEarlyClobberKind() || isRegUseKind()) && 436 "Must be reg"); 437 Bitfield::set<RegMayBeFolded>(Storage, B); 438 } getRegMayBeFolded()439 bool getRegMayBeFolded() const { 440 assert((isRegDefKind() || isRegDefEarlyClobberKind() || isRegUseKind()) && 441 "Must be reg"); 442 return Bitfield::get<RegMayBeFolded>(Storage); 443 } 444 }; 445 getExtraInfoNames(unsigned ExtraInfo)446 static std::vector<StringRef> getExtraInfoNames(unsigned ExtraInfo) { 447 std::vector<StringRef> Result; 448 if (ExtraInfo & InlineAsm::Extra_HasSideEffects) 449 Result.push_back("sideeffect"); 450 if (ExtraInfo & InlineAsm::Extra_MayLoad) 451 Result.push_back("mayload"); 452 if (ExtraInfo & InlineAsm::Extra_MayStore) 453 Result.push_back("maystore"); 454 if (ExtraInfo & InlineAsm::Extra_IsConvergent) 455 Result.push_back("isconvergent"); 456 if (ExtraInfo & InlineAsm::Extra_IsAlignStack) 457 Result.push_back("alignstack"); 458 459 AsmDialect Dialect = 460 InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect)); 461 462 if (Dialect == InlineAsm::AD_ATT) 463 Result.push_back("attdialect"); 464 if (Dialect == InlineAsm::AD_Intel) 465 Result.push_back("inteldialect"); 466 467 return Result; 468 } 469 getMemConstraintName(ConstraintCode C)470 static StringRef getMemConstraintName(ConstraintCode C) { 471 switch (C) { 472 case ConstraintCode::es: 473 return "es"; 474 case ConstraintCode::i: 475 return "i"; 476 case ConstraintCode::k: 477 return "k"; 478 case ConstraintCode::m: 479 return "m"; 480 case ConstraintCode::o: 481 return "o"; 482 case ConstraintCode::v: 483 return "v"; 484 case ConstraintCode::A: 485 return "A"; 486 case ConstraintCode::Q: 487 return "Q"; 488 case ConstraintCode::R: 489 return "R"; 490 case ConstraintCode::S: 491 return "S"; 492 case ConstraintCode::T: 493 return "T"; 494 case ConstraintCode::Um: 495 return "Um"; 496 case ConstraintCode::Un: 497 return "Un"; 498 case ConstraintCode::Uq: 499 return "Uq"; 500 case ConstraintCode::Us: 501 return "Us"; 502 case ConstraintCode::Ut: 503 return "Ut"; 504 case ConstraintCode::Uv: 505 return "Uv"; 506 case ConstraintCode::Uy: 507 return "Uy"; 508 case ConstraintCode::X: 509 return "X"; 510 case ConstraintCode::Z: 511 return "Z"; 512 case ConstraintCode::ZB: 513 return "ZB"; 514 case ConstraintCode::ZC: 515 return "ZC"; 516 case ConstraintCode::Zy: 517 return "Zy"; 518 case ConstraintCode::p: 519 return "p"; 520 case ConstraintCode::ZQ: 521 return "ZQ"; 522 case ConstraintCode::ZR: 523 return "ZR"; 524 case ConstraintCode::ZS: 525 return "ZS"; 526 case ConstraintCode::ZT: 527 return "ZT"; 528 default: 529 llvm_unreachable("Unknown memory constraint"); 530 } 531 } 532 }; 533 534 } // end namespace llvm 535 536 #endif // LLVM_IR_INLINEASM_H 537