1//===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
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 file contains the main function for LLVM's TableGen.
11//
12//===----------------------------------------------------------------------===//
13
14#include "TableGenBackends.h" // Declares all backends.
15
16#include "SetTheory.h"
17#include "llvm/Support/CommandLine.h"
18#include "llvm/Support/PrettyStackTrace.h"
19#include "llvm/Support/Signals.h"
20#include "llvm/TableGen/Error.h"
21#include "llvm/TableGen/Main.h"
22#include "llvm/TableGen/Record.h"
23#include "llvm/TableGen/TableGenAction.h"
24
25using namespace llvm;
26
27enum ActionType {
28  PrintRecords,
29  GenEmitter,
30  GenRegisterInfo,
31  GenInstrInfo,
32  GenAsmWriter,
33  GenAsmMatcher,
34  GenDisassembler,
35  GenPseudoLowering,
36  GenCallingConv,
37  GenDAGISel,
38  GenDFAPacketizer,
39  GenFastISel,
40  GenSubtarget,
41  GenIntrinsic,
42  GenTgtIntrinsic,
43  GenEDInfo,
44  PrintEnums,
45  PrintSets
46};
47
48namespace {
49  cl::opt<ActionType>
50  Action(cl::desc("Action to perform:"),
51         cl::values(clEnumValN(PrintRecords, "print-records",
52                               "Print all records to stdout (default)"),
53                    clEnumValN(GenEmitter, "gen-emitter",
54                               "Generate machine code emitter"),
55                    clEnumValN(GenRegisterInfo, "gen-register-info",
56                               "Generate registers and register classes info"),
57                    clEnumValN(GenInstrInfo, "gen-instr-info",
58                               "Generate instruction descriptions"),
59                    clEnumValN(GenCallingConv, "gen-callingconv",
60                               "Generate calling convention descriptions"),
61                    clEnumValN(GenAsmWriter, "gen-asm-writer",
62                               "Generate assembly writer"),
63                    clEnumValN(GenDisassembler, "gen-disassembler",
64                               "Generate disassembler"),
65                    clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
66                               "Generate pseudo instruction lowering"),
67                    clEnumValN(GenAsmMatcher, "gen-asm-matcher",
68                               "Generate assembly instruction matcher"),
69                    clEnumValN(GenDAGISel, "gen-dag-isel",
70                               "Generate a DAG instruction selector"),
71                    clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer",
72                               "Generate DFA Packetizer for VLIW targets"),
73                    clEnumValN(GenFastISel, "gen-fast-isel",
74                               "Generate a \"fast\" instruction selector"),
75                    clEnumValN(GenSubtarget, "gen-subtarget",
76                               "Generate subtarget enumerations"),
77                    clEnumValN(GenIntrinsic, "gen-intrinsic",
78                               "Generate intrinsic information"),
79                    clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
80                               "Generate target intrinsic information"),
81                    clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
82                               "Generate enhanced disassembly info"),
83                    clEnumValN(PrintEnums, "print-enums",
84                               "Print enum values for a class"),
85                    clEnumValN(PrintSets, "print-sets",
86                               "Print expanded sets for testing DAG exprs"),
87                    clEnumValEnd));
88
89  cl::opt<std::string>
90  Class("class", cl::desc("Print Enum list for this class"),
91          cl::value_desc("class name"));
92
93  class LLVMTableGenAction : public TableGenAction {
94  public:
95    bool operator()(raw_ostream &OS, RecordKeeper &Records) {
96      switch (Action) {
97      case PrintRecords:
98        OS << Records;           // No argument, dump all contents
99        break;
100      case GenEmitter:
101        EmitCodeEmitter(Records, OS);
102        break;
103      case GenRegisterInfo:
104        EmitRegisterInfo(Records, OS);
105        break;
106      case GenInstrInfo:
107        EmitInstrInfo(Records, OS);
108        break;
109      case GenCallingConv:
110        EmitCallingConv(Records, OS);
111        break;
112      case GenAsmWriter:
113        EmitAsmWriter(Records, OS);
114        break;
115      case GenAsmMatcher:
116        EmitAsmMatcher(Records, OS);
117        break;
118      case GenDisassembler:
119        EmitDisassembler(Records, OS);
120        break;
121      case GenPseudoLowering:
122        EmitPseudoLowering(Records, OS);
123        break;
124      case GenDAGISel:
125        EmitDAGISel(Records, OS);
126        break;
127      case GenDFAPacketizer:
128        EmitDFAPacketizer(Records, OS);
129        break;
130      case GenFastISel:
131        EmitFastISel(Records, OS);
132        break;
133      case GenSubtarget:
134        EmitSubtarget(Records, OS);
135        break;
136      case GenIntrinsic:
137        EmitIntrinsics(Records, OS);
138        break;
139      case GenTgtIntrinsic:
140        EmitIntrinsics(Records, OS, true);
141        break;
142      case GenEDInfo:
143        EmitEnhancedDisassemblerInfo(Records, OS);
144        break;
145      case PrintEnums:
146      {
147        std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
148        for (unsigned i = 0, e = Recs.size(); i != e; ++i)
149          OS << Recs[i]->getName() << ", ";
150        OS << "\n";
151        break;
152      }
153      case PrintSets:
154      {
155        SetTheory Sets;
156        Sets.addFieldExpander("Set", "Elements");
157        std::vector<Record*> Recs = Records.getAllDerivedDefinitions("Set");
158        for (unsigned i = 0, e = Recs.size(); i != e; ++i) {
159          OS << Recs[i]->getName() << " = [";
160          const std::vector<Record*> *Elts = Sets.expand(Recs[i]);
161          assert(Elts && "Couldn't expand Set instance");
162          for (unsigned ei = 0, ee = Elts->size(); ei != ee; ++ei)
163            OS << ' ' << (*Elts)[ei]->getName();
164          OS << " ]\n";
165        }
166        break;
167      }
168      }
169
170      return false;
171    }
172  };
173}
174
175int main(int argc, char **argv) {
176  sys::PrintStackTraceOnErrorSignal();
177  PrettyStackTraceProgram X(argc, argv);
178  cl::ParseCommandLineOptions(argc, argv);
179
180  LLVMTableGenAction Action;
181  return TableGenMain(argv[0], Action);
182}
183