Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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