aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/PredicateExpander.h
blob: a0dc63023978838aa511abaed4c92fadf2604f46 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//===--------------------- PredicateExpander.h ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// Functionalities used by the Tablegen backends to expand machine predicates.
///
/// See file llvm/Target/TargetInstrPredicate.td for a full list and description
/// of all the supported MCInstPredicate classes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_UTILS_TABLEGEN_PREDICATEEXPANDER_H
#define LLVM_UTILS_TABLEGEN_PREDICATEEXPANDER_H

#include "llvm/ADT/StringRef.h"
#include <vector>

namespace llvm {

class raw_ostream;
class Record;

class PredicateExpander {
  bool EmitCallsByRef;
  bool NegatePredicate;
  bool ExpandForMC;
  unsigned IndentLevel;
  StringRef TargetName;

  PredicateExpander(const PredicateExpander &) = delete;
  PredicateExpander &operator=(const PredicateExpander &) = delete;

public:
  PredicateExpander(StringRef Target)
      : EmitCallsByRef(true), NegatePredicate(false), ExpandForMC(false),
        IndentLevel(1U), TargetName(Target) {}
  bool isByRef() const { return EmitCallsByRef; }
  bool shouldNegate() const { return NegatePredicate; }
  bool shouldExpandForMC() const { return ExpandForMC; }
  unsigned getIndentLevel() const { return IndentLevel; }
  StringRef getTargetName() const { return TargetName; }

  void setByRef(bool Value) { EmitCallsByRef = Value; }
  void flipNegatePredicate() { NegatePredicate = !NegatePredicate; }
  void setNegatePredicate(bool Value) { NegatePredicate = Value; }
  void setExpandForMC(bool Value) { ExpandForMC = Value; }
  void setIndentLevel(unsigned Level) { IndentLevel = Level; }
  void increaseIndentLevel() { ++IndentLevel; }
  void decreaseIndentLevel() { --IndentLevel; }

  using RecVec = std::vector<Record *>;
  void expandTrue(raw_ostream &OS);
  void expandFalse(raw_ostream &OS);
  void expandCheckImmOperand(raw_ostream &OS, int OpIndex, int ImmVal,
                             StringRef FunctionMapper);
  void expandCheckImmOperand(raw_ostream &OS, int OpIndex, StringRef ImmVal,
                             StringRef FunctionMapperer);
  void expandCheckImmOperandSimple(raw_ostream &OS, int OpIndex,
                                   StringRef FunctionMapper);
  void expandCheckImmOperandLT(raw_ostream &OS, int OpIndex, int ImmVal,
                               StringRef FunctionMapper);
  void expandCheckImmOperandGT(raw_ostream &OS, int OpIndex, int ImmVal,
                               StringRef FunctionMapper);
  void expandCheckRegOperand(raw_ostream &OS, int OpIndex, const Record *Reg,
                             StringRef FunctionMapper);
  void expandCheckRegOperandSimple(raw_ostream &OS, int OpIndex,
                                   StringRef FunctionMapper);
  void expandCheckSameRegOperand(raw_ostream &OS, int First, int Second);
  void expandCheckNumOperands(raw_ostream &OS, int NumOps);
  void expandCheckOpcode(raw_ostream &OS, const Record *Inst);

  void expandCheckPseudo(raw_ostream &OS, const RecVec &Opcodes);
  void expandCheckOpcode(raw_ostream &OS, const RecVec &Opcodes);
  void expandPredicateSequence(raw_ostream &OS, const RecVec &Sequence,
                               bool IsCheckAll);
  void expandTIIFunctionCall(raw_ostream &OS, StringRef MethodName);
  void expandCheckIsRegOperand(raw_ostream &OS, int OpIndex);
  void expandCheckIsVRegOperand(raw_ostream &OS, int OpIndex);
  void expandCheckIsImmOperand(raw_ostream &OS, int OpIndex);
  void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex);
  void expandCheckFunctionPredicate(raw_ostream &OS, StringRef MCInstFn,
                                    StringRef MachineInstrFn);
  void expandCheckFunctionPredicateWithTII(raw_ostream &OS, StringRef MCInstFn,
                                           StringRef MachineInstrFn,
                                           StringRef TIIPtr);
  void expandCheckNonPortable(raw_ostream &OS, StringRef CodeBlock);
  void expandPredicate(raw_ostream &OS, const Record *Rec);
  void expandReturnStatement(raw_ostream &OS, const Record *Rec);
  void expandOpcodeSwitchCase(raw_ostream &OS, const Record *Rec);
  void expandOpcodeSwitchStatement(raw_ostream &OS, const RecVec &Cases,
                                   const Record *Default);
  void expandStatement(raw_ostream &OS, const Record *Rec);
};

// Forward declarations.
class STIPredicateFunction;
class OpcodeGroup;

class STIPredicateExpander : public PredicateExpander {
  StringRef ClassPrefix;
  bool ExpandDefinition;

  STIPredicateExpander(const PredicateExpander &) = delete;
  STIPredicateExpander &operator=(const PredicateExpander &) = delete;

  void expandHeader(raw_ostream &OS, const STIPredicateFunction &Fn);
  void expandPrologue(raw_ostream &OS, const STIPredicateFunction &Fn);
  void expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group,
                         bool ShouldUpdateOpcodeMask);
  void expandBody(raw_ostream &OS, const STIPredicateFunction &Fn);
  void expandEpilogue(raw_ostream &OS, const STIPredicateFunction &Fn);

public:
  STIPredicateExpander(StringRef Target)
      : PredicateExpander(Target), ExpandDefinition(false) {}

  bool shouldExpandDefinition() const { return ExpandDefinition; }
  StringRef getClassPrefix() const { return ClassPrefix; }
  void setClassPrefix(StringRef S) { ClassPrefix = S; }
  void setExpandDefinition(bool Value) { ExpandDefinition = Value; }

  void expandSTIPredicate(raw_ostream &OS, const STIPredicateFunction &Fn);
};

} // namespace llvm

#endif