1f4a2713aSLionel Sambuc //===- CodeGenTarget.cpp - CodeGen Target Class Wrapper -------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This class wraps target description classes used by the various code
11f4a2713aSLionel Sambuc // generation TableGen backends. This makes it easier to access the data and
12f4a2713aSLionel Sambuc // provides a single place that needs to check it for validity. All of these
13f4a2713aSLionel Sambuc // classes abort on error conditions.
14f4a2713aSLionel Sambuc //
15f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16f4a2713aSLionel Sambuc
17f4a2713aSLionel Sambuc #include "CodeGenTarget.h"
18f4a2713aSLionel Sambuc #include "CodeGenIntrinsics.h"
19f4a2713aSLionel Sambuc #include "CodeGenSchedule.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/StringExtras.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/CommandLine.h"
23f4a2713aSLionel Sambuc #include "llvm/TableGen/Error.h"
24f4a2713aSLionel Sambuc #include "llvm/TableGen/Record.h"
25f4a2713aSLionel Sambuc #include <algorithm>
26f4a2713aSLionel Sambuc using namespace llvm;
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc static cl::opt<unsigned>
29f4a2713aSLionel Sambuc AsmParserNum("asmparsernum", cl::init(0),
30f4a2713aSLionel Sambuc cl::desc("Make -gen-asm-parser emit assembly parser #N"));
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc static cl::opt<unsigned>
33f4a2713aSLionel Sambuc AsmWriterNum("asmwriternum", cl::init(0),
34f4a2713aSLionel Sambuc cl::desc("Make -gen-asm-writer emit assembly writer #N"));
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc /// getValueType - Return the MVT::SimpleValueType that the specified TableGen
37f4a2713aSLionel Sambuc /// record corresponds to.
getValueType(Record * Rec)38f4a2713aSLionel Sambuc MVT::SimpleValueType llvm::getValueType(Record *Rec) {
39f4a2713aSLionel Sambuc return (MVT::SimpleValueType)Rec->getValueAsInt("Value");
40f4a2713aSLionel Sambuc }
41f4a2713aSLionel Sambuc
getName(MVT::SimpleValueType T)42f4a2713aSLionel Sambuc std::string llvm::getName(MVT::SimpleValueType T) {
43f4a2713aSLionel Sambuc switch (T) {
44f4a2713aSLionel Sambuc case MVT::Other: return "UNKNOWN";
45f4a2713aSLionel Sambuc case MVT::iPTR: return "TLI.getPointerTy()";
46f4a2713aSLionel Sambuc case MVT::iPTRAny: return "TLI.getPointerTy()";
47f4a2713aSLionel Sambuc default: return getEnumName(T);
48f4a2713aSLionel Sambuc }
49f4a2713aSLionel Sambuc }
50f4a2713aSLionel Sambuc
getEnumName(MVT::SimpleValueType T)51f4a2713aSLionel Sambuc std::string llvm::getEnumName(MVT::SimpleValueType T) {
52f4a2713aSLionel Sambuc switch (T) {
53f4a2713aSLionel Sambuc case MVT::Other: return "MVT::Other";
54f4a2713aSLionel Sambuc case MVT::i1: return "MVT::i1";
55f4a2713aSLionel Sambuc case MVT::i8: return "MVT::i8";
56f4a2713aSLionel Sambuc case MVT::i16: return "MVT::i16";
57f4a2713aSLionel Sambuc case MVT::i32: return "MVT::i32";
58f4a2713aSLionel Sambuc case MVT::i64: return "MVT::i64";
59f4a2713aSLionel Sambuc case MVT::i128: return "MVT::i128";
60f4a2713aSLionel Sambuc case MVT::iAny: return "MVT::iAny";
61f4a2713aSLionel Sambuc case MVT::fAny: return "MVT::fAny";
62f4a2713aSLionel Sambuc case MVT::vAny: return "MVT::vAny";
63f4a2713aSLionel Sambuc case MVT::f16: return "MVT::f16";
64f4a2713aSLionel Sambuc case MVT::f32: return "MVT::f32";
65f4a2713aSLionel Sambuc case MVT::f64: return "MVT::f64";
66f4a2713aSLionel Sambuc case MVT::f80: return "MVT::f80";
67f4a2713aSLionel Sambuc case MVT::f128: return "MVT::f128";
68f4a2713aSLionel Sambuc case MVT::ppcf128: return "MVT::ppcf128";
69f4a2713aSLionel Sambuc case MVT::x86mmx: return "MVT::x86mmx";
70f4a2713aSLionel Sambuc case MVT::Glue: return "MVT::Glue";
71f4a2713aSLionel Sambuc case MVT::isVoid: return "MVT::isVoid";
72f4a2713aSLionel Sambuc case MVT::v2i1: return "MVT::v2i1";
73f4a2713aSLionel Sambuc case MVT::v4i1: return "MVT::v4i1";
74f4a2713aSLionel Sambuc case MVT::v8i1: return "MVT::v8i1";
75f4a2713aSLionel Sambuc case MVT::v16i1: return "MVT::v16i1";
76f4a2713aSLionel Sambuc case MVT::v32i1: return "MVT::v32i1";
77f4a2713aSLionel Sambuc case MVT::v64i1: return "MVT::v64i1";
78f4a2713aSLionel Sambuc case MVT::v1i8: return "MVT::v1i8";
79f4a2713aSLionel Sambuc case MVT::v2i8: return "MVT::v2i8";
80f4a2713aSLionel Sambuc case MVT::v4i8: return "MVT::v4i8";
81f4a2713aSLionel Sambuc case MVT::v8i8: return "MVT::v8i8";
82f4a2713aSLionel Sambuc case MVT::v16i8: return "MVT::v16i8";
83f4a2713aSLionel Sambuc case MVT::v32i8: return "MVT::v32i8";
84f4a2713aSLionel Sambuc case MVT::v64i8: return "MVT::v64i8";
85f4a2713aSLionel Sambuc case MVT::v1i16: return "MVT::v1i16";
86f4a2713aSLionel Sambuc case MVT::v2i16: return "MVT::v2i16";
87f4a2713aSLionel Sambuc case MVT::v4i16: return "MVT::v4i16";
88f4a2713aSLionel Sambuc case MVT::v8i16: return "MVT::v8i16";
89f4a2713aSLionel Sambuc case MVT::v16i16: return "MVT::v16i16";
90f4a2713aSLionel Sambuc case MVT::v32i16: return "MVT::v32i16";
91f4a2713aSLionel Sambuc case MVT::v1i32: return "MVT::v1i32";
92f4a2713aSLionel Sambuc case MVT::v2i32: return "MVT::v2i32";
93f4a2713aSLionel Sambuc case MVT::v4i32: return "MVT::v4i32";
94f4a2713aSLionel Sambuc case MVT::v8i32: return "MVT::v8i32";
95f4a2713aSLionel Sambuc case MVT::v16i32: return "MVT::v16i32";
96f4a2713aSLionel Sambuc case MVT::v1i64: return "MVT::v1i64";
97f4a2713aSLionel Sambuc case MVT::v2i64: return "MVT::v2i64";
98f4a2713aSLionel Sambuc case MVT::v4i64: return "MVT::v4i64";
99f4a2713aSLionel Sambuc case MVT::v8i64: return "MVT::v8i64";
100f4a2713aSLionel Sambuc case MVT::v16i64: return "MVT::v16i64";
101f4a2713aSLionel Sambuc case MVT::v2f16: return "MVT::v2f16";
102f4a2713aSLionel Sambuc case MVT::v4f16: return "MVT::v4f16";
103f4a2713aSLionel Sambuc case MVT::v8f16: return "MVT::v8f16";
104f4a2713aSLionel Sambuc case MVT::v1f32: return "MVT::v1f32";
105f4a2713aSLionel Sambuc case MVT::v2f32: return "MVT::v2f32";
106f4a2713aSLionel Sambuc case MVT::v4f32: return "MVT::v4f32";
107f4a2713aSLionel Sambuc case MVT::v8f32: return "MVT::v8f32";
108f4a2713aSLionel Sambuc case MVT::v16f32: return "MVT::v16f32";
109f4a2713aSLionel Sambuc case MVT::v1f64: return "MVT::v1f64";
110f4a2713aSLionel Sambuc case MVT::v2f64: return "MVT::v2f64";
111f4a2713aSLionel Sambuc case MVT::v4f64: return "MVT::v4f64";
112f4a2713aSLionel Sambuc case MVT::v8f64: return "MVT::v8f64";
113f4a2713aSLionel Sambuc case MVT::Metadata: return "MVT::Metadata";
114f4a2713aSLionel Sambuc case MVT::iPTR: return "MVT::iPTR";
115f4a2713aSLionel Sambuc case MVT::iPTRAny: return "MVT::iPTRAny";
116f4a2713aSLionel Sambuc case MVT::Untyped: return "MVT::Untyped";
117f4a2713aSLionel Sambuc default: llvm_unreachable("ILLEGAL VALUE TYPE!");
118f4a2713aSLionel Sambuc }
119f4a2713aSLionel Sambuc }
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc /// getQualifiedName - Return the name of the specified record, with a
122f4a2713aSLionel Sambuc /// namespace qualifier if the record contains one.
123f4a2713aSLionel Sambuc ///
getQualifiedName(const Record * R)124f4a2713aSLionel Sambuc std::string llvm::getQualifiedName(const Record *R) {
125f4a2713aSLionel Sambuc std::string Namespace;
126f4a2713aSLionel Sambuc if (R->getValue("Namespace"))
127f4a2713aSLionel Sambuc Namespace = R->getValueAsString("Namespace");
128f4a2713aSLionel Sambuc if (Namespace.empty()) return R->getName();
129f4a2713aSLionel Sambuc return Namespace + "::" + R->getName();
130f4a2713aSLionel Sambuc }
131f4a2713aSLionel Sambuc
132f4a2713aSLionel Sambuc
133f4a2713aSLionel Sambuc /// getTarget - Return the current instance of the Target class.
134f4a2713aSLionel Sambuc ///
CodeGenTarget(RecordKeeper & records)135f4a2713aSLionel Sambuc CodeGenTarget::CodeGenTarget(RecordKeeper &records)
136*0a6a1f1dSLionel Sambuc : Records(records) {
137f4a2713aSLionel Sambuc std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
138f4a2713aSLionel Sambuc if (Targets.size() == 0)
139f4a2713aSLionel Sambuc PrintFatalError("ERROR: No 'Target' subclasses defined!");
140f4a2713aSLionel Sambuc if (Targets.size() != 1)
141f4a2713aSLionel Sambuc PrintFatalError("ERROR: Multiple subclasses of Target defined!");
142f4a2713aSLionel Sambuc TargetRec = Targets[0];
143f4a2713aSLionel Sambuc }
144f4a2713aSLionel Sambuc
~CodeGenTarget()145f4a2713aSLionel Sambuc CodeGenTarget::~CodeGenTarget() {
146f4a2713aSLionel Sambuc }
147f4a2713aSLionel Sambuc
getName() const148f4a2713aSLionel Sambuc const std::string &CodeGenTarget::getName() const {
149f4a2713aSLionel Sambuc return TargetRec->getName();
150f4a2713aSLionel Sambuc }
151f4a2713aSLionel Sambuc
getInstNamespace() const152f4a2713aSLionel Sambuc std::string CodeGenTarget::getInstNamespace() const {
153*0a6a1f1dSLionel Sambuc for (const CodeGenInstruction *Inst : instructions()) {
154f4a2713aSLionel Sambuc // Make sure not to pick up "TargetOpcode" by accidentally getting
155f4a2713aSLionel Sambuc // the namespace off the PHI instruction or something.
156*0a6a1f1dSLionel Sambuc if (Inst->Namespace != "TargetOpcode")
157*0a6a1f1dSLionel Sambuc return Inst->Namespace;
158f4a2713aSLionel Sambuc }
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc return "";
161f4a2713aSLionel Sambuc }
162f4a2713aSLionel Sambuc
getInstructionSet() const163f4a2713aSLionel Sambuc Record *CodeGenTarget::getInstructionSet() const {
164f4a2713aSLionel Sambuc return TargetRec->getValueAsDef("InstructionSet");
165f4a2713aSLionel Sambuc }
166f4a2713aSLionel Sambuc
167f4a2713aSLionel Sambuc
168f4a2713aSLionel Sambuc /// getAsmParser - Return the AssemblyParser definition for this target.
169f4a2713aSLionel Sambuc ///
getAsmParser() const170f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParser() const {
171f4a2713aSLionel Sambuc std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyParsers");
172f4a2713aSLionel Sambuc if (AsmParserNum >= LI.size())
173*0a6a1f1dSLionel Sambuc PrintFatalError("Target does not have an AsmParser #" +
174*0a6a1f1dSLionel Sambuc Twine(AsmParserNum) + "!");
175f4a2713aSLionel Sambuc return LI[AsmParserNum];
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc
178f4a2713aSLionel Sambuc /// getAsmParserVariant - Return the AssmblyParserVariant definition for
179f4a2713aSLionel Sambuc /// this target.
180f4a2713aSLionel Sambuc ///
getAsmParserVariant(unsigned i) const181f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmParserVariant(unsigned i) const {
182f4a2713aSLionel Sambuc std::vector<Record*> LI =
183f4a2713aSLionel Sambuc TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
184f4a2713aSLionel Sambuc if (i >= LI.size())
185*0a6a1f1dSLionel Sambuc PrintFatalError("Target does not have an AsmParserVariant #" + Twine(i) +
186*0a6a1f1dSLionel Sambuc "!");
187f4a2713aSLionel Sambuc return LI[i];
188f4a2713aSLionel Sambuc }
189f4a2713aSLionel Sambuc
190f4a2713aSLionel Sambuc /// getAsmParserVariantCount - Return the AssmblyParserVariant definition
191f4a2713aSLionel Sambuc /// available for this target.
192f4a2713aSLionel Sambuc ///
getAsmParserVariantCount() const193f4a2713aSLionel Sambuc unsigned CodeGenTarget::getAsmParserVariantCount() const {
194f4a2713aSLionel Sambuc std::vector<Record*> LI =
195f4a2713aSLionel Sambuc TargetRec->getValueAsListOfDefs("AssemblyParserVariants");
196f4a2713aSLionel Sambuc return LI.size();
197f4a2713aSLionel Sambuc }
198f4a2713aSLionel Sambuc
199f4a2713aSLionel Sambuc /// getAsmWriter - Return the AssemblyWriter definition for this target.
200f4a2713aSLionel Sambuc ///
getAsmWriter() const201f4a2713aSLionel Sambuc Record *CodeGenTarget::getAsmWriter() const {
202f4a2713aSLionel Sambuc std::vector<Record*> LI = TargetRec->getValueAsListOfDefs("AssemblyWriters");
203f4a2713aSLionel Sambuc if (AsmWriterNum >= LI.size())
204*0a6a1f1dSLionel Sambuc PrintFatalError("Target does not have an AsmWriter #" +
205*0a6a1f1dSLionel Sambuc Twine(AsmWriterNum) + "!");
206f4a2713aSLionel Sambuc return LI[AsmWriterNum];
207f4a2713aSLionel Sambuc }
208f4a2713aSLionel Sambuc
getRegBank() const209f4a2713aSLionel Sambuc CodeGenRegBank &CodeGenTarget::getRegBank() const {
210f4a2713aSLionel Sambuc if (!RegBank)
211*0a6a1f1dSLionel Sambuc RegBank = llvm::make_unique<CodeGenRegBank>(Records);
212f4a2713aSLionel Sambuc return *RegBank;
213f4a2713aSLionel Sambuc }
214f4a2713aSLionel Sambuc
ReadRegAltNameIndices() const215f4a2713aSLionel Sambuc void CodeGenTarget::ReadRegAltNameIndices() const {
216f4a2713aSLionel Sambuc RegAltNameIndices = Records.getAllDerivedDefinitions("RegAltNameIndex");
217f4a2713aSLionel Sambuc std::sort(RegAltNameIndices.begin(), RegAltNameIndices.end(), LessRecord());
218f4a2713aSLionel Sambuc }
219f4a2713aSLionel Sambuc
220f4a2713aSLionel Sambuc /// getRegisterByName - If there is a register with the specific AsmName,
221f4a2713aSLionel Sambuc /// return it.
getRegisterByName(StringRef Name) const222f4a2713aSLionel Sambuc const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
223f4a2713aSLionel Sambuc const StringMap<CodeGenRegister*> &Regs = getRegBank().getRegistersByName();
224f4a2713aSLionel Sambuc StringMap<CodeGenRegister*>::const_iterator I = Regs.find(Name);
225f4a2713aSLionel Sambuc if (I == Regs.end())
226*0a6a1f1dSLionel Sambuc return nullptr;
227f4a2713aSLionel Sambuc return I->second;
228f4a2713aSLionel Sambuc }
229f4a2713aSLionel Sambuc
230f4a2713aSLionel Sambuc std::vector<MVT::SimpleValueType> CodeGenTarget::
getRegisterVTs(Record * R) const231f4a2713aSLionel Sambuc getRegisterVTs(Record *R) const {
232f4a2713aSLionel Sambuc const CodeGenRegister *Reg = getRegBank().getReg(R);
233f4a2713aSLionel Sambuc std::vector<MVT::SimpleValueType> Result;
234*0a6a1f1dSLionel Sambuc for (const auto &RC : getRegBank().getRegClasses()) {
235f4a2713aSLionel Sambuc if (RC.contains(Reg)) {
236f4a2713aSLionel Sambuc ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
237f4a2713aSLionel Sambuc Result.insert(Result.end(), InVTs.begin(), InVTs.end());
238f4a2713aSLionel Sambuc }
239f4a2713aSLionel Sambuc }
240f4a2713aSLionel Sambuc
241f4a2713aSLionel Sambuc // Remove duplicates.
242f4a2713aSLionel Sambuc array_pod_sort(Result.begin(), Result.end());
243f4a2713aSLionel Sambuc Result.erase(std::unique(Result.begin(), Result.end()), Result.end());
244f4a2713aSLionel Sambuc return Result;
245f4a2713aSLionel Sambuc }
246f4a2713aSLionel Sambuc
247f4a2713aSLionel Sambuc
ReadLegalValueTypes() const248f4a2713aSLionel Sambuc void CodeGenTarget::ReadLegalValueTypes() const {
249*0a6a1f1dSLionel Sambuc for (const auto &RC : getRegBank().getRegClasses())
250*0a6a1f1dSLionel Sambuc LegalValueTypes.insert(LegalValueTypes.end(), RC.VTs.begin(), RC.VTs.end());
251f4a2713aSLionel Sambuc
252f4a2713aSLionel Sambuc // Remove duplicates.
253f4a2713aSLionel Sambuc std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
254f4a2713aSLionel Sambuc LegalValueTypes.erase(std::unique(LegalValueTypes.begin(),
255f4a2713aSLionel Sambuc LegalValueTypes.end()),
256f4a2713aSLionel Sambuc LegalValueTypes.end());
257f4a2713aSLionel Sambuc }
258f4a2713aSLionel Sambuc
getSchedModels() const259f4a2713aSLionel Sambuc CodeGenSchedModels &CodeGenTarget::getSchedModels() const {
260f4a2713aSLionel Sambuc if (!SchedModels)
261*0a6a1f1dSLionel Sambuc SchedModels = llvm::make_unique<CodeGenSchedModels>(Records, *this);
262f4a2713aSLionel Sambuc return *SchedModels;
263f4a2713aSLionel Sambuc }
264f4a2713aSLionel Sambuc
ReadInstructions() const265f4a2713aSLionel Sambuc void CodeGenTarget::ReadInstructions() const {
266f4a2713aSLionel Sambuc std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
267f4a2713aSLionel Sambuc if (Insts.size() <= 2)
268f4a2713aSLionel Sambuc PrintFatalError("No 'Instruction' subclasses defined!");
269f4a2713aSLionel Sambuc
270f4a2713aSLionel Sambuc // Parse the instructions defined in the .td file.
271f4a2713aSLionel Sambuc for (unsigned i = 0, e = Insts.size(); i != e; ++i)
272*0a6a1f1dSLionel Sambuc Instructions[Insts[i]] = llvm::make_unique<CodeGenInstruction>(Insts[i]);
273f4a2713aSLionel Sambuc }
274f4a2713aSLionel Sambuc
275f4a2713aSLionel Sambuc static const CodeGenInstruction *
GetInstByName(const char * Name,const DenseMap<const Record *,std::unique_ptr<CodeGenInstruction>> & Insts,RecordKeeper & Records)276f4a2713aSLionel Sambuc GetInstByName(const char *Name,
277*0a6a1f1dSLionel Sambuc const DenseMap<const Record*,
278*0a6a1f1dSLionel Sambuc std::unique_ptr<CodeGenInstruction>> &Insts,
279f4a2713aSLionel Sambuc RecordKeeper &Records) {
280f4a2713aSLionel Sambuc const Record *Rec = Records.getDef(Name);
281f4a2713aSLionel Sambuc
282*0a6a1f1dSLionel Sambuc const auto I = Insts.find(Rec);
283*0a6a1f1dSLionel Sambuc if (!Rec || I == Insts.end())
284*0a6a1f1dSLionel Sambuc PrintFatalError(Twine("Could not find '") + Name + "' instruction!");
285*0a6a1f1dSLionel Sambuc return I->second.get();
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc
288*0a6a1f1dSLionel Sambuc /// \brief Return all of the instructions defined by the target, ordered by
289*0a6a1f1dSLionel Sambuc /// their enum value.
ComputeInstrsByEnum() const290f4a2713aSLionel Sambuc void CodeGenTarget::ComputeInstrsByEnum() const {
291f4a2713aSLionel Sambuc // The ordering here must match the ordering in TargetOpcodes.h.
292f4a2713aSLionel Sambuc static const char *const FixedInstrs[] = {
293*0a6a1f1dSLionel Sambuc "PHI", "INLINEASM", "CFI_INSTRUCTION", "EH_LABEL",
294*0a6a1f1dSLionel Sambuc "GC_LABEL", "KILL", "EXTRACT_SUBREG", "INSERT_SUBREG",
295*0a6a1f1dSLionel Sambuc "IMPLICIT_DEF", "SUBREG_TO_REG", "COPY_TO_REGCLASS", "DBG_VALUE",
296*0a6a1f1dSLionel Sambuc "REG_SEQUENCE", "COPY", "BUNDLE", "LIFETIME_START",
297*0a6a1f1dSLionel Sambuc "LIFETIME_END", "STACKMAP", "PATCHPOINT", "LOAD_STACK_GUARD",
298*0a6a1f1dSLionel Sambuc "STATEPOINT", "FRAME_ALLOC",
299*0a6a1f1dSLionel Sambuc nullptr};
300*0a6a1f1dSLionel Sambuc const auto &Insts = getInstructions();
301f4a2713aSLionel Sambuc for (const char *const *p = FixedInstrs; *p; ++p) {
302f4a2713aSLionel Sambuc const CodeGenInstruction *Instr = GetInstByName(*p, Insts, Records);
303f4a2713aSLionel Sambuc assert(Instr && "Missing target independent instruction");
304f4a2713aSLionel Sambuc assert(Instr->Namespace == "TargetOpcode" && "Bad namespace");
305f4a2713aSLionel Sambuc InstrsByEnum.push_back(Instr);
306f4a2713aSLionel Sambuc }
307f4a2713aSLionel Sambuc unsigned EndOfPredefines = InstrsByEnum.size();
308f4a2713aSLionel Sambuc
309*0a6a1f1dSLionel Sambuc for (const auto &I : Insts) {
310*0a6a1f1dSLionel Sambuc const CodeGenInstruction *CGI = I.second.get();
311f4a2713aSLionel Sambuc if (CGI->Namespace != "TargetOpcode")
312f4a2713aSLionel Sambuc InstrsByEnum.push_back(CGI);
313f4a2713aSLionel Sambuc }
314f4a2713aSLionel Sambuc
315f4a2713aSLionel Sambuc assert(InstrsByEnum.size() == Insts.size() && "Missing predefined instr");
316f4a2713aSLionel Sambuc
317f4a2713aSLionel Sambuc // All of the instructions are now in random order based on the map iteration.
318f4a2713aSLionel Sambuc // Sort them by name.
319f4a2713aSLionel Sambuc std::sort(InstrsByEnum.begin() + EndOfPredefines, InstrsByEnum.end(),
320*0a6a1f1dSLionel Sambuc [](const CodeGenInstruction *Rec1, const CodeGenInstruction *Rec2) {
321*0a6a1f1dSLionel Sambuc return Rec1->TheDef->getName() < Rec2->TheDef->getName();
322*0a6a1f1dSLionel Sambuc });
323f4a2713aSLionel Sambuc }
324f4a2713aSLionel Sambuc
325f4a2713aSLionel Sambuc
326f4a2713aSLionel Sambuc /// isLittleEndianEncoding - Return whether this target encodes its instruction
327f4a2713aSLionel Sambuc /// in little-endian format, i.e. bits laid out in the order [0..n]
328f4a2713aSLionel Sambuc ///
isLittleEndianEncoding() const329f4a2713aSLionel Sambuc bool CodeGenTarget::isLittleEndianEncoding() const {
330f4a2713aSLionel Sambuc return getInstructionSet()->getValueAsBit("isLittleEndianEncoding");
331f4a2713aSLionel Sambuc }
332f4a2713aSLionel Sambuc
333*0a6a1f1dSLionel Sambuc /// reverseBitsForLittleEndianEncoding - For little-endian instruction bit
334*0a6a1f1dSLionel Sambuc /// encodings, reverse the bit order of all instructions.
reverseBitsForLittleEndianEncoding()335*0a6a1f1dSLionel Sambuc void CodeGenTarget::reverseBitsForLittleEndianEncoding() {
336*0a6a1f1dSLionel Sambuc if (!isLittleEndianEncoding())
337*0a6a1f1dSLionel Sambuc return;
338*0a6a1f1dSLionel Sambuc
339*0a6a1f1dSLionel Sambuc std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
340*0a6a1f1dSLionel Sambuc for (Record *R : Insts) {
341*0a6a1f1dSLionel Sambuc if (R->getValueAsString("Namespace") == "TargetOpcode" ||
342*0a6a1f1dSLionel Sambuc R->getValueAsBit("isPseudo"))
343*0a6a1f1dSLionel Sambuc continue;
344*0a6a1f1dSLionel Sambuc
345*0a6a1f1dSLionel Sambuc BitsInit *BI = R->getValueAsBitsInit("Inst");
346*0a6a1f1dSLionel Sambuc
347*0a6a1f1dSLionel Sambuc unsigned numBits = BI->getNumBits();
348*0a6a1f1dSLionel Sambuc
349*0a6a1f1dSLionel Sambuc SmallVector<Init *, 16> NewBits(numBits);
350*0a6a1f1dSLionel Sambuc
351*0a6a1f1dSLionel Sambuc for (unsigned bit = 0, end = numBits / 2; bit != end; ++bit) {
352*0a6a1f1dSLionel Sambuc unsigned bitSwapIdx = numBits - bit - 1;
353*0a6a1f1dSLionel Sambuc Init *OrigBit = BI->getBit(bit);
354*0a6a1f1dSLionel Sambuc Init *BitSwap = BI->getBit(bitSwapIdx);
355*0a6a1f1dSLionel Sambuc NewBits[bit] = BitSwap;
356*0a6a1f1dSLionel Sambuc NewBits[bitSwapIdx] = OrigBit;
357*0a6a1f1dSLionel Sambuc }
358*0a6a1f1dSLionel Sambuc if (numBits % 2) {
359*0a6a1f1dSLionel Sambuc unsigned middle = (numBits + 1) / 2;
360*0a6a1f1dSLionel Sambuc NewBits[middle] = BI->getBit(middle);
361*0a6a1f1dSLionel Sambuc }
362*0a6a1f1dSLionel Sambuc
363*0a6a1f1dSLionel Sambuc BitsInit *NewBI = BitsInit::get(NewBits);
364*0a6a1f1dSLionel Sambuc
365*0a6a1f1dSLionel Sambuc // Update the bits in reversed order so that emitInstrOpBits will get the
366*0a6a1f1dSLionel Sambuc // correct endianness.
367*0a6a1f1dSLionel Sambuc R->getValue("Inst")->setValue(NewBI);
368*0a6a1f1dSLionel Sambuc }
369*0a6a1f1dSLionel Sambuc }
370*0a6a1f1dSLionel Sambuc
371f4a2713aSLionel Sambuc /// guessInstructionProperties - Return true if it's OK to guess instruction
372f4a2713aSLionel Sambuc /// properties instead of raising an error.
373f4a2713aSLionel Sambuc ///
374f4a2713aSLionel Sambuc /// This is configurable as a temporary migration aid. It will eventually be
375f4a2713aSLionel Sambuc /// permanently false.
guessInstructionProperties() const376f4a2713aSLionel Sambuc bool CodeGenTarget::guessInstructionProperties() const {
377f4a2713aSLionel Sambuc return getInstructionSet()->getValueAsBit("guessInstructionProperties");
378f4a2713aSLionel Sambuc }
379f4a2713aSLionel Sambuc
380f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
381f4a2713aSLionel Sambuc // ComplexPattern implementation
382f4a2713aSLionel Sambuc //
ComplexPattern(Record * R)383f4a2713aSLionel Sambuc ComplexPattern::ComplexPattern(Record *R) {
384f4a2713aSLionel Sambuc Ty = ::getValueType(R->getValueAsDef("Ty"));
385f4a2713aSLionel Sambuc NumOperands = R->getValueAsInt("NumOperands");
386f4a2713aSLionel Sambuc SelectFunc = R->getValueAsString("SelectFunc");
387f4a2713aSLionel Sambuc RootNodes = R->getValueAsListOfDefs("RootNodes");
388f4a2713aSLionel Sambuc
389f4a2713aSLionel Sambuc // Parse the properties.
390f4a2713aSLionel Sambuc Properties = 0;
391f4a2713aSLionel Sambuc std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
392f4a2713aSLionel Sambuc for (unsigned i = 0, e = PropList.size(); i != e; ++i)
393f4a2713aSLionel Sambuc if (PropList[i]->getName() == "SDNPHasChain") {
394f4a2713aSLionel Sambuc Properties |= 1 << SDNPHasChain;
395f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPOptInGlue") {
396f4a2713aSLionel Sambuc Properties |= 1 << SDNPOptInGlue;
397f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPMayStore") {
398f4a2713aSLionel Sambuc Properties |= 1 << SDNPMayStore;
399f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPMayLoad") {
400f4a2713aSLionel Sambuc Properties |= 1 << SDNPMayLoad;
401f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPSideEffect") {
402f4a2713aSLionel Sambuc Properties |= 1 << SDNPSideEffect;
403f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPMemOperand") {
404f4a2713aSLionel Sambuc Properties |= 1 << SDNPMemOperand;
405f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPVariadic") {
406f4a2713aSLionel Sambuc Properties |= 1 << SDNPVariadic;
407f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPWantRoot") {
408f4a2713aSLionel Sambuc Properties |= 1 << SDNPWantRoot;
409f4a2713aSLionel Sambuc } else if (PropList[i]->getName() == "SDNPWantParent") {
410f4a2713aSLionel Sambuc Properties |= 1 << SDNPWantParent;
411f4a2713aSLionel Sambuc } else {
412f4a2713aSLionel Sambuc errs() << "Unsupported SD Node property '" << PropList[i]->getName()
413f4a2713aSLionel Sambuc << "' on ComplexPattern '" << R->getName() << "'!\n";
414f4a2713aSLionel Sambuc exit(1);
415f4a2713aSLionel Sambuc }
416f4a2713aSLionel Sambuc }
417f4a2713aSLionel Sambuc
418f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
419f4a2713aSLionel Sambuc // CodeGenIntrinsic Implementation
420f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
421f4a2713aSLionel Sambuc
LoadIntrinsics(const RecordKeeper & RC,bool TargetOnly)422f4a2713aSLionel Sambuc std::vector<CodeGenIntrinsic> llvm::LoadIntrinsics(const RecordKeeper &RC,
423f4a2713aSLionel Sambuc bool TargetOnly) {
424f4a2713aSLionel Sambuc std::vector<Record*> I = RC.getAllDerivedDefinitions("Intrinsic");
425f4a2713aSLionel Sambuc
426f4a2713aSLionel Sambuc std::vector<CodeGenIntrinsic> Result;
427f4a2713aSLionel Sambuc
428f4a2713aSLionel Sambuc for (unsigned i = 0, e = I.size(); i != e; ++i) {
429f4a2713aSLionel Sambuc bool isTarget = I[i]->getValueAsBit("isTarget");
430f4a2713aSLionel Sambuc if (isTarget == TargetOnly)
431f4a2713aSLionel Sambuc Result.push_back(CodeGenIntrinsic(I[i]));
432f4a2713aSLionel Sambuc }
433f4a2713aSLionel Sambuc return Result;
434f4a2713aSLionel Sambuc }
435f4a2713aSLionel Sambuc
CodeGenIntrinsic(Record * R)436f4a2713aSLionel Sambuc CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
437f4a2713aSLionel Sambuc TheDef = R;
438f4a2713aSLionel Sambuc std::string DefName = R->getName();
439f4a2713aSLionel Sambuc ModRef = ReadWriteMem;
440f4a2713aSLionel Sambuc isOverloaded = false;
441f4a2713aSLionel Sambuc isCommutative = false;
442f4a2713aSLionel Sambuc canThrow = false;
443f4a2713aSLionel Sambuc isNoReturn = false;
444*0a6a1f1dSLionel Sambuc isNoDuplicate = false;
445f4a2713aSLionel Sambuc
446f4a2713aSLionel Sambuc if (DefName.size() <= 4 ||
447f4a2713aSLionel Sambuc std::string(DefName.begin(), DefName.begin() + 4) != "int_")
448f4a2713aSLionel Sambuc PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");
449f4a2713aSLionel Sambuc
450f4a2713aSLionel Sambuc EnumName = std::string(DefName.begin()+4, DefName.end());
451f4a2713aSLionel Sambuc
452f4a2713aSLionel Sambuc if (R->getValue("GCCBuiltinName")) // Ignore a missing GCCBuiltinName field.
453f4a2713aSLionel Sambuc GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
454*0a6a1f1dSLionel Sambuc if (R->getValue("MSBuiltinName")) // Ignore a missing MSBuiltinName field.
455*0a6a1f1dSLionel Sambuc MSBuiltinName = R->getValueAsString("MSBuiltinName");
456f4a2713aSLionel Sambuc
457f4a2713aSLionel Sambuc TargetPrefix = R->getValueAsString("TargetPrefix");
458f4a2713aSLionel Sambuc Name = R->getValueAsString("LLVMName");
459f4a2713aSLionel Sambuc
460f4a2713aSLionel Sambuc if (Name == "") {
461f4a2713aSLionel Sambuc // If an explicit name isn't specified, derive one from the DefName.
462f4a2713aSLionel Sambuc Name = "llvm.";
463f4a2713aSLionel Sambuc
464f4a2713aSLionel Sambuc for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
465f4a2713aSLionel Sambuc Name += (EnumName[i] == '_') ? '.' : EnumName[i];
466f4a2713aSLionel Sambuc } else {
467f4a2713aSLionel Sambuc // Verify it starts with "llvm.".
468f4a2713aSLionel Sambuc if (Name.size() <= 5 ||
469f4a2713aSLionel Sambuc std::string(Name.begin(), Name.begin() + 5) != "llvm.")
470f4a2713aSLionel Sambuc PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
471f4a2713aSLionel Sambuc }
472f4a2713aSLionel Sambuc
473f4a2713aSLionel Sambuc // If TargetPrefix is specified, make sure that Name starts with
474f4a2713aSLionel Sambuc // "llvm.<targetprefix>.".
475f4a2713aSLionel Sambuc if (!TargetPrefix.empty()) {
476f4a2713aSLionel Sambuc if (Name.size() < 6+TargetPrefix.size() ||
477f4a2713aSLionel Sambuc std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
478f4a2713aSLionel Sambuc != (TargetPrefix + "."))
479f4a2713aSLionel Sambuc PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
480f4a2713aSLionel Sambuc TargetPrefix + ".'!");
481f4a2713aSLionel Sambuc }
482f4a2713aSLionel Sambuc
483f4a2713aSLionel Sambuc // Parse the list of return types.
484f4a2713aSLionel Sambuc std::vector<MVT::SimpleValueType> OverloadedVTs;
485f4a2713aSLionel Sambuc ListInit *TypeList = R->getValueAsListInit("RetTypes");
486f4a2713aSLionel Sambuc for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
487f4a2713aSLionel Sambuc Record *TyEl = TypeList->getElementAsRecord(i);
488f4a2713aSLionel Sambuc assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
489f4a2713aSLionel Sambuc MVT::SimpleValueType VT;
490f4a2713aSLionel Sambuc if (TyEl->isSubClassOf("LLVMMatchType")) {
491f4a2713aSLionel Sambuc unsigned MatchTy = TyEl->getValueAsInt("Number");
492f4a2713aSLionel Sambuc assert(MatchTy < OverloadedVTs.size() &&
493f4a2713aSLionel Sambuc "Invalid matching number!");
494f4a2713aSLionel Sambuc VT = OverloadedVTs[MatchTy];
495f4a2713aSLionel Sambuc // It only makes sense to use the extended and truncated vector element
496f4a2713aSLionel Sambuc // variants with iAny types; otherwise, if the intrinsic is not
497f4a2713aSLionel Sambuc // overloaded, all the types can be specified directly.
498*0a6a1f1dSLionel Sambuc assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
499*0a6a1f1dSLionel Sambuc !TyEl->isSubClassOf("LLVMTruncatedType")) ||
500f4a2713aSLionel Sambuc VT == MVT::iAny || VT == MVT::vAny) &&
501f4a2713aSLionel Sambuc "Expected iAny or vAny type");
502f4a2713aSLionel Sambuc } else {
503f4a2713aSLionel Sambuc VT = getValueType(TyEl->getValueAsDef("VT"));
504f4a2713aSLionel Sambuc }
505*0a6a1f1dSLionel Sambuc if (MVT(VT).isOverloaded()) {
506f4a2713aSLionel Sambuc OverloadedVTs.push_back(VT);
507f4a2713aSLionel Sambuc isOverloaded = true;
508f4a2713aSLionel Sambuc }
509f4a2713aSLionel Sambuc
510f4a2713aSLionel Sambuc // Reject invalid types.
511f4a2713aSLionel Sambuc if (VT == MVT::isVoid)
512f4a2713aSLionel Sambuc PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
513f4a2713aSLionel Sambuc
514f4a2713aSLionel Sambuc IS.RetVTs.push_back(VT);
515f4a2713aSLionel Sambuc IS.RetTypeDefs.push_back(TyEl);
516f4a2713aSLionel Sambuc }
517f4a2713aSLionel Sambuc
518f4a2713aSLionel Sambuc // Parse the list of parameter types.
519f4a2713aSLionel Sambuc TypeList = R->getValueAsListInit("ParamTypes");
520f4a2713aSLionel Sambuc for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
521f4a2713aSLionel Sambuc Record *TyEl = TypeList->getElementAsRecord(i);
522f4a2713aSLionel Sambuc assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
523f4a2713aSLionel Sambuc MVT::SimpleValueType VT;
524f4a2713aSLionel Sambuc if (TyEl->isSubClassOf("LLVMMatchType")) {
525f4a2713aSLionel Sambuc unsigned MatchTy = TyEl->getValueAsInt("Number");
526f4a2713aSLionel Sambuc assert(MatchTy < OverloadedVTs.size() &&
527f4a2713aSLionel Sambuc "Invalid matching number!");
528f4a2713aSLionel Sambuc VT = OverloadedVTs[MatchTy];
529f4a2713aSLionel Sambuc // It only makes sense to use the extended and truncated vector element
530f4a2713aSLionel Sambuc // variants with iAny types; otherwise, if the intrinsic is not
531f4a2713aSLionel Sambuc // overloaded, all the types can be specified directly.
532*0a6a1f1dSLionel Sambuc assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
533*0a6a1f1dSLionel Sambuc !TyEl->isSubClassOf("LLVMTruncatedType") &&
534*0a6a1f1dSLionel Sambuc !TyEl->isSubClassOf("LLVMVectorSameWidth") &&
535*0a6a1f1dSLionel Sambuc !TyEl->isSubClassOf("LLVMPointerToElt")) ||
536f4a2713aSLionel Sambuc VT == MVT::iAny || VT == MVT::vAny) &&
537f4a2713aSLionel Sambuc "Expected iAny or vAny type");
538f4a2713aSLionel Sambuc } else
539f4a2713aSLionel Sambuc VT = getValueType(TyEl->getValueAsDef("VT"));
540f4a2713aSLionel Sambuc
541*0a6a1f1dSLionel Sambuc if (MVT(VT).isOverloaded()) {
542f4a2713aSLionel Sambuc OverloadedVTs.push_back(VT);
543f4a2713aSLionel Sambuc isOverloaded = true;
544f4a2713aSLionel Sambuc }
545f4a2713aSLionel Sambuc
546f4a2713aSLionel Sambuc // Reject invalid types.
547f4a2713aSLionel Sambuc if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
548f4a2713aSLionel Sambuc PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");
549f4a2713aSLionel Sambuc
550f4a2713aSLionel Sambuc IS.ParamVTs.push_back(VT);
551f4a2713aSLionel Sambuc IS.ParamTypeDefs.push_back(TyEl);
552f4a2713aSLionel Sambuc }
553f4a2713aSLionel Sambuc
554f4a2713aSLionel Sambuc // Parse the intrinsic properties.
555f4a2713aSLionel Sambuc ListInit *PropList = R->getValueAsListInit("Properties");
556f4a2713aSLionel Sambuc for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
557f4a2713aSLionel Sambuc Record *Property = PropList->getElementAsRecord(i);
558f4a2713aSLionel Sambuc assert(Property->isSubClassOf("IntrinsicProperty") &&
559f4a2713aSLionel Sambuc "Expected a property!");
560f4a2713aSLionel Sambuc
561f4a2713aSLionel Sambuc if (Property->getName() == "IntrNoMem")
562f4a2713aSLionel Sambuc ModRef = NoMem;
563f4a2713aSLionel Sambuc else if (Property->getName() == "IntrReadArgMem")
564f4a2713aSLionel Sambuc ModRef = ReadArgMem;
565f4a2713aSLionel Sambuc else if (Property->getName() == "IntrReadMem")
566f4a2713aSLionel Sambuc ModRef = ReadMem;
567f4a2713aSLionel Sambuc else if (Property->getName() == "IntrReadWriteArgMem")
568f4a2713aSLionel Sambuc ModRef = ReadWriteArgMem;
569f4a2713aSLionel Sambuc else if (Property->getName() == "Commutative")
570f4a2713aSLionel Sambuc isCommutative = true;
571f4a2713aSLionel Sambuc else if (Property->getName() == "Throws")
572f4a2713aSLionel Sambuc canThrow = true;
573*0a6a1f1dSLionel Sambuc else if (Property->getName() == "IntrNoDuplicate")
574*0a6a1f1dSLionel Sambuc isNoDuplicate = true;
575f4a2713aSLionel Sambuc else if (Property->getName() == "IntrNoReturn")
576f4a2713aSLionel Sambuc isNoReturn = true;
577f4a2713aSLionel Sambuc else if (Property->isSubClassOf("NoCapture")) {
578f4a2713aSLionel Sambuc unsigned ArgNo = Property->getValueAsInt("ArgNo");
579f4a2713aSLionel Sambuc ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
580f4a2713aSLionel Sambuc } else if (Property->isSubClassOf("ReadOnly")) {
581f4a2713aSLionel Sambuc unsigned ArgNo = Property->getValueAsInt("ArgNo");
582f4a2713aSLionel Sambuc ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
583f4a2713aSLionel Sambuc } else if (Property->isSubClassOf("ReadNone")) {
584f4a2713aSLionel Sambuc unsigned ArgNo = Property->getValueAsInt("ArgNo");
585f4a2713aSLionel Sambuc ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
586f4a2713aSLionel Sambuc } else
587f4a2713aSLionel Sambuc llvm_unreachable("Unknown property!");
588f4a2713aSLionel Sambuc }
589f4a2713aSLionel Sambuc
590f4a2713aSLionel Sambuc // Sort the argument attributes for later benefit.
591f4a2713aSLionel Sambuc std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
592f4a2713aSLionel Sambuc }
593