xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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