1//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class represents the inline asm strings, which are Value*'s that are
11// used as the callee operand of call instructions.  InlineAsm's are uniqued
12// like constants, and created via InlineAsm::get(...).
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_IR_INLINEASM_H
17#define LLVM_IR_INLINEASM_H
18
19#include "llvm/ADT/StringRef.h"
20#include "llvm/IR/Value.h"
21#include <vector>
22
23namespace llvm {
24
25class PointerType;
26class FunctionType;
27class Module;
28
29struct InlineAsmKeyType;
30template <class ConstantClass> class ConstantUniqueMap;
31
32class InlineAsm : public Value {
33public:
34  enum AsmDialect {
35    AD_ATT,
36    AD_Intel
37  };
38
39private:
40  friend struct InlineAsmKeyType;
41  friend class ConstantUniqueMap<InlineAsm>;
42
43  InlineAsm(const InlineAsm &) = delete;
44  void operator=(const InlineAsm&) = delete;
45
46  std::string AsmString, Constraints;
47  bool HasSideEffects;
48  bool IsAlignStack;
49  AsmDialect Dialect;
50
51  InlineAsm(PointerType *Ty, const std::string &AsmString,
52            const std::string &Constraints, bool hasSideEffects,
53            bool isAlignStack, AsmDialect asmDialect);
54  ~InlineAsm() override;
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();
59public:
60
61  /// InlineAsm::get - Return the specified uniqued inline asm string.
62  ///
63  static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
64                        StringRef Constraints, bool hasSideEffects,
65                        bool isAlignStack = false,
66                        AsmDialect asmDialect = AD_ATT);
67
68  bool hasSideEffects() const { return HasSideEffects; }
69  bool isAlignStack() const { return IsAlignStack; }
70  AsmDialect getDialect() const { return Dialect; }
71
72  /// getType - InlineAsm's are always pointers.
73  ///
74  PointerType *getType() const {
75    return reinterpret_cast<PointerType*>(Value::getType());
76  }
77
78  /// getFunctionType - InlineAsm's are always pointers to functions.
79  ///
80  FunctionType *getFunctionType() const;
81
82  const std::string &getAsmString() const { return AsmString; }
83  const std::string &getConstraintString() const { return Constraints; }
84
85  /// Verify - This static method can be used by the parser to check to see if
86  /// the specified constraint string is legal for the type.  This returns true
87  /// if legal, false if not.
88  ///
89  static bool Verify(FunctionType *Ty, StringRef Constraints);
90
91  // Constraint String Parsing
92  enum ConstraintPrefix {
93    isInput,            // 'x'
94    isOutput,           // '=x'
95    isClobber           // '~x'
96  };
97
98  typedef std::vector<std::string> ConstraintCodeVector;
99
100  struct SubConstraintInfo {
101    /// MatchingInput - If this is not -1, this is an output constraint where an
102    /// input constraint is required to match it (e.g. "0").  The value is the
103    /// constraint number that matches this one (for example, if this is
104    /// constraint #0 and constraint #4 has the value "0", this will be 4).
105    signed char MatchingInput;
106    /// Code - The constraint code, either the register name (in braces) or the
107    /// constraint letter/number.
108    ConstraintCodeVector Codes;
109    /// Default constructor.
110    SubConstraintInfo() : MatchingInput(-1) {}
111  };
112
113  typedef std::vector<SubConstraintInfo> SubConstraintInfoVector;
114  struct ConstraintInfo;
115  typedef std::vector<ConstraintInfo> ConstraintInfoVector;
116
117  struct ConstraintInfo {
118    /// Type - The basic type of the constraint: input/output/clobber
119    ///
120    ConstraintPrefix Type;
121
122    /// isEarlyClobber - "&": output operand writes result before inputs are all
123    /// read.  This is only ever set for an output operand.
124    bool isEarlyClobber;
125
126    /// MatchingInput - If this is not -1, this is an output constraint where an
127    /// input constraint is required to match it (e.g. "0").  The value is the
128    /// constraint number that matches this one (for example, if this is
129    /// constraint #0 and constraint #4 has the value "0", this will be 4).
130    signed char MatchingInput;
131
132    /// hasMatchingInput - Return true if this is an output constraint that has
133    /// a matching input constraint.
134    bool hasMatchingInput() const { return MatchingInput != -1; }
135
136    /// isCommutative - This is set to true for a constraint that is commutative
137    /// with the next operand.
138    bool isCommutative;
139
140    /// isIndirect - True if this operand is an indirect operand.  This means
141    /// that the address of the source or destination is present in the call
142    /// instruction, instead of it being returned or passed in explicitly.  This
143    /// is represented with a '*' in the asm string.
144    bool isIndirect;
145
146    /// Code - The constraint code, either the register name (in braces) or the
147    /// constraint letter/number.
148    ConstraintCodeVector Codes;
149
150    /// isMultipleAlternative - '|': has multiple-alternative constraints.
151    bool isMultipleAlternative;
152
153    /// multipleAlternatives - If there are multiple alternative constraints,
154    /// this array will contain them.  Otherwise it will be empty.
155    SubConstraintInfoVector multipleAlternatives;
156
157    /// The currently selected alternative constraint index.
158    unsigned currentAlternativeIndex;
159
160    ///Default constructor.
161    ConstraintInfo();
162
163    /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
164    /// fields in this structure.  If the constraint string is not understood,
165    /// return true, otherwise return false.
166    bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
167
168    /// selectAlternative - Point this constraint to the alternative constraint
169    /// indicated by the index.
170    void selectAlternative(unsigned index);
171  };
172
173  /// ParseConstraints - Split up the constraint string into the specific
174  /// constraints and their prefixes.  If this returns an empty vector, and if
175  /// the constraint string itself isn't empty, there was an error parsing.
176  static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
177
178  /// ParseConstraints - Parse the constraints of this inlineasm object,
179  /// returning them the same way that ParseConstraints(str) does.
180  ConstraintInfoVector ParseConstraints() const {
181    return ParseConstraints(Constraints);
182  }
183
184  // Methods for support type inquiry through isa, cast, and dyn_cast:
185  static inline bool classof(const Value *V) {
186    return V->getValueID() == Value::InlineAsmVal;
187  }
188
189
190  // These are helper methods for dealing with flags in the INLINEASM SDNode
191  // in the backend.
192  //
193  // The encoding of the flag word is currently:
194  //   Bits 2-0 - A Kind_* value indicating the kind of the operand.
195  //   Bits 15-3 - The number of SDNode operands associated with this inline
196  //               assembly operand.
197  //   If bit 31 is set:
198  //     Bit 30-16 - The operand number that this operand must match.
199  //                 When bits 2-0 are Kind_Mem, the Constraint_* value must be
200  //                 obtained from the flags for this operand number.
201  //   Else if bits 2-0 are Kind_Mem:
202  //     Bit 30-16 - A Constraint_* value indicating the original constraint
203  //                 code.
204  //   Else:
205  //     Bit 30-16 - The register class ID to use for the operand.
206
207  enum : uint32_t {
208    // Fixed operands on an INLINEASM SDNode.
209    Op_InputChain = 0,
210    Op_AsmString = 1,
211    Op_MDNode = 2,
212    Op_ExtraInfo = 3,    // HasSideEffects, IsAlignStack, AsmDialect.
213    Op_FirstOperand = 4,
214
215    // Fixed operands on an INLINEASM MachineInstr.
216    MIOp_AsmString = 0,
217    MIOp_ExtraInfo = 1,    // HasSideEffects, IsAlignStack, AsmDialect.
218    MIOp_FirstOperand = 2,
219
220    // Interpretation of the MIOp_ExtraInfo bit field.
221    Extra_HasSideEffects = 1,
222    Extra_IsAlignStack = 2,
223    Extra_AsmDialect = 4,
224    Extra_MayLoad = 8,
225    Extra_MayStore = 16,
226
227    // Inline asm operands map to multiple SDNode / MachineInstr operands.
228    // The first operand is an immediate describing the asm operand, the low
229    // bits is the kind:
230    Kind_RegUse = 1,             // Input register, "r".
231    Kind_RegDef = 2,             // Output register, "=r".
232    Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
233    Kind_Clobber = 4,            // Clobbered register, "~r".
234    Kind_Imm = 5,                // Immediate.
235    Kind_Mem = 6,                // Memory operand, "m".
236
237    // Memory constraint codes.
238    // These could be tablegenerated but there's little need to do that since
239    // there's plenty of space in the encoding to support the union of all
240    // constraint codes for all targets.
241    Constraint_Unknown = 0,
242    Constraint_es,
243    Constraint_i,
244    Constraint_m,
245    Constraint_o,
246    Constraint_v,
247    Constraint_Q,
248    Constraint_R,
249    Constraint_S,
250    Constraint_T,
251    Constraint_Z,
252    Constraint_ZC,
253    Constraint_Zy,
254    Constraints_Max = Constraint_Zy,
255    Constraints_ShiftAmount = 16,
256
257    Flag_MatchingOperand = 0x80000000
258  };
259
260  static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
261    assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
262    assert(Kind >= Kind_RegUse && Kind <= Kind_Mem && "Invalid Kind");
263    return Kind | (NumOps << 3);
264  }
265
266  /// getFlagWordForMatchingOp - Augment an existing flag word returned by
267  /// getFlagWord with information indicating that this input operand is tied
268  /// to a previous output operand.
269  static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
270                                           unsigned MatchedOperandNo) {
271    assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
272    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
273    return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
274  }
275
276  /// getFlagWordForRegClass - Augment an existing flag word returned by
277  /// getFlagWord with the required register class for the following register
278  /// operands.
279  /// A tied use operand cannot have a register class, use the register class
280  /// from the def operand instead.
281  static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
282    // Store RC + 1, reserve the value 0 to mean 'no register class'.
283    ++RC;
284    assert(RC <= 0x7fff && "Too large register class ID");
285    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
286    return InputFlag | (RC << 16);
287  }
288
289  /// Augment an existing flag word returned by getFlagWord with the constraint
290  /// code for a memory constraint.
291  static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
292    assert(Constraint <= 0x7fff && "Too large a memory constraint ID");
293    assert(Constraint <= Constraints_Max && "Unknown constraint ID");
294    assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
295    return InputFlag | (Constraint << Constraints_ShiftAmount);
296  }
297
298  static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
299    assert(isMemKind(InputFlag));
300    return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
301  }
302
303  static unsigned getKind(unsigned Flags) {
304    return Flags & 7;
305  }
306
307  static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
308  static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
309  static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
310  static bool isRegDefEarlyClobberKind(unsigned Flag) {
311    return getKind(Flag) == Kind_RegDefEarlyClobber;
312  }
313  static bool isClobberKind(unsigned Flag) {
314    return getKind(Flag) == Kind_Clobber;
315  }
316
317  static unsigned getMemoryConstraintID(unsigned Flag) {
318    assert(isMemKind(Flag));
319    return (Flag >> Constraints_ShiftAmount) & 0x7fff;
320  }
321
322  /// getNumOperandRegisters - Extract the number of registers field from the
323  /// inline asm operand flag.
324  static unsigned getNumOperandRegisters(unsigned Flag) {
325    return (Flag & 0xffff) >> 3;
326  }
327
328  /// isUseOperandTiedToDef - Return true if the flag of the inline asm
329  /// operand indicates it is an use operand that's matched to a def operand.
330  static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
331    if ((Flag & Flag_MatchingOperand) == 0)
332      return false;
333    Idx = (Flag & ~Flag_MatchingOperand) >> 16;
334    return true;
335  }
336
337  /// hasRegClassConstraint - Returns true if the flag contains a register
338  /// class constraint.  Sets RC to the register class ID.
339  static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
340    if (Flag & Flag_MatchingOperand)
341      return false;
342    unsigned High = Flag >> 16;
343    // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
344    // stores RC + 1.
345    if (!High)
346      return false;
347    RC = High - 1;
348    return true;
349  }
350
351};
352
353} // End llvm namespace
354
355#endif
356