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