16122f3e6SDimitry Andric //===- TableGen.cpp - Top-Level TableGen implementation for LLVM ----------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
106122f3e6SDimitry Andric // This file contains the main function for LLVM's TableGen.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
147ae0e2c9SDimitry Andric #include "TableGenBackends.h" // Declares all backends.
15f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h"
164d0b32cdSDimitry Andric #include "llvm/Support/ManagedStatic.h"
17f22ef01cSRoman Divacky #include "llvm/Support/PrettyStackTrace.h"
182754fe60SDimitry Andric #include "llvm/Support/Signals.h"
196122f3e6SDimitry Andric #include "llvm/TableGen/Main.h"
206122f3e6SDimitry Andric #include "llvm/TableGen/Record.h"
2191bc56edSDimitry Andric #include "llvm/TableGen/SetTheory.h"
226122f3e6SDimitry Andric 
23f22ef01cSRoman Divacky using namespace llvm;
24f22ef01cSRoman Divacky 
25f22ef01cSRoman Divacky enum ActionType {
26f22ef01cSRoman Divacky   PrintRecords,
274ba319b5SDimitry Andric   DumpJSON,
28f22ef01cSRoman Divacky   GenEmitter,
2917a519f9SDimitry Andric   GenRegisterInfo,
3017a519f9SDimitry Andric   GenInstrInfo,
312cab237bSDimitry Andric   GenInstrDocs,
3217a519f9SDimitry Andric   GenAsmWriter,
3317a519f9SDimitry Andric   GenAsmMatcher,
34f22ef01cSRoman Divacky   GenDisassembler,
3517a519f9SDimitry Andric   GenPseudoLowering,
364ba319b5SDimitry Andric   GenCompressInst,
37f22ef01cSRoman Divacky   GenCallingConv,
38f22ef01cSRoman Divacky   GenDAGISel,
39dff0c46cSDimitry Andric   GenDFAPacketizer,
40f22ef01cSRoman Divacky   GenFastISel,
41f22ef01cSRoman Divacky   GenSubtarget,
424ba319b5SDimitry Andric   GenIntrinsicEnums,
434ba319b5SDimitry Andric   GenIntrinsicImpl,
444ba319b5SDimitry Andric   GenTgtIntrinsicEnums,
454ba319b5SDimitry Andric   GenTgtIntrinsicImpl,
46bd5abe19SDimitry Andric   PrintEnums,
47139f7f9bSDimitry Andric   PrintSets,
48139f7f9bSDimitry Andric   GenOptParserDefs,
497d523365SDimitry Andric   GenCTags,
503ca95b02SDimitry Andric   GenAttributes,
513ca95b02SDimitry Andric   GenSearchableTables,
52d88c1a5aSDimitry Andric   GenGlobalISel,
537a7e6055SDimitry Andric   GenX86EVEX2VEXTables,
542cab237bSDimitry Andric   GenX86FoldTables,
557a7e6055SDimitry Andric   GenRegisterBank,
56*b5893f02SDimitry Andric   GenExegesis,
57f22ef01cSRoman Divacky };
58f22ef01cSRoman Divacky 
59f22ef01cSRoman Divacky namespace {
60f22ef01cSRoman Divacky   cl::opt<ActionType>
61f22ef01cSRoman Divacky   Action(cl::desc("Action to perform:"),
62f22ef01cSRoman Divacky          cl::values(clEnumValN(PrintRecords, "print-records",
63f22ef01cSRoman Divacky                                "Print all records to stdout (default)"),
644ba319b5SDimitry Andric                     clEnumValN(DumpJSON, "dump-json",
654ba319b5SDimitry Andric                                "Dump all records as machine-readable JSON"),
66f22ef01cSRoman Divacky                     clEnumValN(GenEmitter, "gen-emitter",
67f22ef01cSRoman Divacky                                "Generate machine code emitter"),
6817a519f9SDimitry Andric                     clEnumValN(GenRegisterInfo, "gen-register-info",
6917a519f9SDimitry Andric                                "Generate registers and register classes info"),
7017a519f9SDimitry Andric                     clEnumValN(GenInstrInfo, "gen-instr-info",
71f22ef01cSRoman Divacky                                "Generate instruction descriptions"),
722cab237bSDimitry Andric                     clEnumValN(GenInstrDocs, "gen-instr-docs",
732cab237bSDimitry Andric                                "Generate instruction documentation"),
74f22ef01cSRoman Divacky                     clEnumValN(GenCallingConv, "gen-callingconv",
75f22ef01cSRoman Divacky                                "Generate calling convention descriptions"),
76f22ef01cSRoman Divacky                     clEnumValN(GenAsmWriter, "gen-asm-writer",
77f22ef01cSRoman Divacky                                "Generate assembly writer"),
78f22ef01cSRoman Divacky                     clEnumValN(GenDisassembler, "gen-disassembler",
79f22ef01cSRoman Divacky                                "Generate disassembler"),
8017a519f9SDimitry Andric                     clEnumValN(GenPseudoLowering, "gen-pseudo-lowering",
8117a519f9SDimitry Andric                                "Generate pseudo instruction lowering"),
824ba319b5SDimitry Andric                     clEnumValN(GenCompressInst, "gen-compress-inst-emitter",
834ba319b5SDimitry Andric                                "Generate RISCV compressed instructions."),
84f22ef01cSRoman Divacky                     clEnumValN(GenAsmMatcher, "gen-asm-matcher",
85f22ef01cSRoman Divacky                                "Generate assembly instruction matcher"),
86f22ef01cSRoman Divacky                     clEnumValN(GenDAGISel, "gen-dag-isel",
87f22ef01cSRoman Divacky                                "Generate a DAG instruction selector"),
88dff0c46cSDimitry Andric                     clEnumValN(GenDFAPacketizer, "gen-dfa-packetizer",
89dff0c46cSDimitry Andric                                "Generate DFA Packetizer for VLIW targets"),
90f22ef01cSRoman Divacky                     clEnumValN(GenFastISel, "gen-fast-isel",
91f22ef01cSRoman Divacky                                "Generate a \"fast\" instruction selector"),
92f22ef01cSRoman Divacky                     clEnumValN(GenSubtarget, "gen-subtarget",
93f22ef01cSRoman Divacky                                "Generate subtarget enumerations"),
944ba319b5SDimitry Andric                     clEnumValN(GenIntrinsicEnums, "gen-intrinsic-enums",
954ba319b5SDimitry Andric                                "Generate intrinsic enums"),
964ba319b5SDimitry Andric                     clEnumValN(GenIntrinsicImpl, "gen-intrinsic-impl",
97f22ef01cSRoman Divacky                                "Generate intrinsic information"),
984ba319b5SDimitry Andric                     clEnumValN(GenTgtIntrinsicEnums, "gen-tgt-intrinsic-enums",
994ba319b5SDimitry Andric                                "Generate target intrinsic enums"),
1004ba319b5SDimitry Andric                     clEnumValN(GenTgtIntrinsicImpl, "gen-tgt-intrinsic-impl",
101f22ef01cSRoman Divacky                                "Generate target intrinsic information"),
102f22ef01cSRoman Divacky                     clEnumValN(PrintEnums, "print-enums",
103f22ef01cSRoman Divacky                                "Print enum values for a class"),
104bd5abe19SDimitry Andric                     clEnumValN(PrintSets, "print-sets",
105bd5abe19SDimitry Andric                                "Print expanded sets for testing DAG exprs"),
106139f7f9bSDimitry Andric                     clEnumValN(GenOptParserDefs, "gen-opt-parser-defs",
107139f7f9bSDimitry Andric                                "Generate option definitions"),
108139f7f9bSDimitry Andric                     clEnumValN(GenCTags, "gen-ctags",
109139f7f9bSDimitry Andric                                "Generate ctags-compatible index"),
1107d523365SDimitry Andric                     clEnumValN(GenAttributes, "gen-attrs",
1117d523365SDimitry Andric                                "Generate attributes"),
1123ca95b02SDimitry Andric                     clEnumValN(GenSearchableTables, "gen-searchable-tables",
1133ca95b02SDimitry Andric                                "Generate generic binary-searchable table"),
114d88c1a5aSDimitry Andric                     clEnumValN(GenGlobalISel, "gen-global-isel",
1157a7e6055SDimitry Andric                                "Generate GlobalISel selector"),
1167a7e6055SDimitry Andric                     clEnumValN(GenX86EVEX2VEXTables, "gen-x86-EVEX2VEX-tables",
1177a7e6055SDimitry Andric                                "Generate X86 EVEX to VEX compress tables"),
1182cab237bSDimitry Andric                     clEnumValN(GenX86FoldTables, "gen-x86-fold-tables",
1192cab237bSDimitry Andric                                "Generate X86 fold tables"),
1207a7e6055SDimitry Andric                     clEnumValN(GenRegisterBank, "gen-register-bank",
121*b5893f02SDimitry Andric                                "Generate registers bank descriptions"),
122*b5893f02SDimitry Andric                     clEnumValN(GenExegesis, "gen-exegesis",
123*b5893f02SDimitry Andric                                "Generate llvm-exegesis tables")));
124f22ef01cSRoman Divacky 
1257a7e6055SDimitry Andric   cl::OptionCategory PrintEnumsCat("Options for -print-enums");
126f22ef01cSRoman Divacky   cl::opt<std::string>
127f22ef01cSRoman Divacky   Class("class", cl::desc("Print Enum list for this class"),
1287a7e6055SDimitry Andric         cl::value_desc("class name"), cl::cat(PrintEnumsCat));
129f22ef01cSRoman Divacky 
LLVMTableGenMain(raw_ostream & OS,RecordKeeper & Records)1303861d79fSDimitry Andric bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
131f22ef01cSRoman Divacky   switch (Action) {
132f22ef01cSRoman Divacky   case PrintRecords:
1336122f3e6SDimitry Andric     OS << Records;           // No argument, dump all contents
134f22ef01cSRoman Divacky     break;
1354ba319b5SDimitry Andric   case DumpJSON:
1364ba319b5SDimitry Andric     EmitJSON(Records, OS);
1374ba319b5SDimitry Andric     break;
138f22ef01cSRoman Divacky   case GenEmitter:
1397ae0e2c9SDimitry Andric     EmitCodeEmitter(Records, OS);
140f22ef01cSRoman Divacky     break;
14117a519f9SDimitry Andric   case GenRegisterInfo:
1427ae0e2c9SDimitry Andric     EmitRegisterInfo(Records, OS);
143f22ef01cSRoman Divacky     break;
14417a519f9SDimitry Andric   case GenInstrInfo:
1457ae0e2c9SDimitry Andric     EmitInstrInfo(Records, OS);
146f22ef01cSRoman Divacky     break;
1472cab237bSDimitry Andric   case GenInstrDocs:
1482cab237bSDimitry Andric     EmitInstrDocs(Records, OS);
1492cab237bSDimitry Andric     break;
150f22ef01cSRoman Divacky   case GenCallingConv:
1517ae0e2c9SDimitry Andric     EmitCallingConv(Records, OS);
152f22ef01cSRoman Divacky     break;
153f22ef01cSRoman Divacky   case GenAsmWriter:
1547ae0e2c9SDimitry Andric     EmitAsmWriter(Records, OS);
155f22ef01cSRoman Divacky     break;
156f22ef01cSRoman Divacky   case GenAsmMatcher:
1577ae0e2c9SDimitry Andric     EmitAsmMatcher(Records, OS);
1582754fe60SDimitry Andric     break;
159f22ef01cSRoman Divacky   case GenDisassembler:
1607ae0e2c9SDimitry Andric     EmitDisassembler(Records, OS);
161f22ef01cSRoman Divacky     break;
16217a519f9SDimitry Andric   case GenPseudoLowering:
1637ae0e2c9SDimitry Andric     EmitPseudoLowering(Records, OS);
164f22ef01cSRoman Divacky     break;
1654ba319b5SDimitry Andric   case GenCompressInst:
1664ba319b5SDimitry Andric     EmitCompressInst(Records, OS);
1674ba319b5SDimitry Andric     break;
168f22ef01cSRoman Divacky   case GenDAGISel:
1697ae0e2c9SDimitry Andric     EmitDAGISel(Records, OS);
170f22ef01cSRoman Divacky     break;
171dff0c46cSDimitry Andric   case GenDFAPacketizer:
1727ae0e2c9SDimitry Andric     EmitDFAPacketizer(Records, OS);
173dff0c46cSDimitry Andric     break;
174f22ef01cSRoman Divacky   case GenFastISel:
1757ae0e2c9SDimitry Andric     EmitFastISel(Records, OS);
176f22ef01cSRoman Divacky     break;
177f22ef01cSRoman Divacky   case GenSubtarget:
1787ae0e2c9SDimitry Andric     EmitSubtarget(Records, OS);
179f22ef01cSRoman Divacky     break;
1804ba319b5SDimitry Andric   case GenIntrinsicEnums:
1814ba319b5SDimitry Andric     EmitIntrinsicEnums(Records, OS);
182f22ef01cSRoman Divacky     break;
1834ba319b5SDimitry Andric   case GenIntrinsicImpl:
1844ba319b5SDimitry Andric     EmitIntrinsicImpl(Records, OS);
1854ba319b5SDimitry Andric     break;
1864ba319b5SDimitry Andric   case GenTgtIntrinsicEnums:
1874ba319b5SDimitry Andric     EmitIntrinsicEnums(Records, OS, true);
1884ba319b5SDimitry Andric     break;
1894ba319b5SDimitry Andric   case GenTgtIntrinsicImpl:
1904ba319b5SDimitry Andric     EmitIntrinsicImpl(Records, OS, true);
191f22ef01cSRoman Divacky     break;
192139f7f9bSDimitry Andric   case GenOptParserDefs:
193139f7f9bSDimitry Andric     EmitOptParser(Records, OS);
1942754fe60SDimitry Andric     break;
195f22ef01cSRoman Divacky   case PrintEnums:
196f22ef01cSRoman Divacky   {
19739d628a0SDimitry Andric     for (Record *Rec : Records.getAllDerivedDefinitions(Class))
19839d628a0SDimitry Andric       OS << Rec->getName() << ", ";
1996122f3e6SDimitry Andric     OS << "\n";
200f22ef01cSRoman Divacky     break;
201f22ef01cSRoman Divacky   }
202bd5abe19SDimitry Andric   case PrintSets:
203bd5abe19SDimitry Andric   {
204bd5abe19SDimitry Andric     SetTheory Sets;
205bd5abe19SDimitry Andric     Sets.addFieldExpander("Set", "Elements");
20639d628a0SDimitry Andric     for (Record *Rec : Records.getAllDerivedDefinitions("Set")) {
20739d628a0SDimitry Andric       OS << Rec->getName() << " = [";
20839d628a0SDimitry Andric       const std::vector<Record*> *Elts = Sets.expand(Rec);
209bd5abe19SDimitry Andric       assert(Elts && "Couldn't expand Set instance");
21039d628a0SDimitry Andric       for (Record *Elt : *Elts)
21139d628a0SDimitry Andric         OS << ' ' << Elt->getName();
2126122f3e6SDimitry Andric       OS << " ]\n";
213bd5abe19SDimitry Andric     }
214bd5abe19SDimitry Andric     break;
215bd5abe19SDimitry Andric   }
216139f7f9bSDimitry Andric   case GenCTags:
217139f7f9bSDimitry Andric     EmitCTags(Records, OS);
218139f7f9bSDimitry Andric     break;
2197d523365SDimitry Andric   case GenAttributes:
2207d523365SDimitry Andric     EmitAttributes(Records, OS);
2217d523365SDimitry Andric     break;
2223ca95b02SDimitry Andric   case GenSearchableTables:
2233ca95b02SDimitry Andric     EmitSearchableTables(Records, OS);
2243ca95b02SDimitry Andric     break;
225d88c1a5aSDimitry Andric   case GenGlobalISel:
226d88c1a5aSDimitry Andric     EmitGlobalISel(Records, OS);
227d88c1a5aSDimitry Andric     break;
2287a7e6055SDimitry Andric   case GenRegisterBank:
2297a7e6055SDimitry Andric     EmitRegisterBank(Records, OS);
2307a7e6055SDimitry Andric     break;
2317a7e6055SDimitry Andric   case GenX86EVEX2VEXTables:
2327a7e6055SDimitry Andric     EmitX86EVEX2VEXTables(Records, OS);
2337a7e6055SDimitry Andric     break;
2342cab237bSDimitry Andric   case GenX86FoldTables:
2352cab237bSDimitry Andric     EmitX86FoldTables(Records, OS);
2362cab237bSDimitry Andric     break;
237*b5893f02SDimitry Andric   case GenExegesis:
238*b5893f02SDimitry Andric     EmitExegesis(Records, OS);
239*b5893f02SDimitry Andric     break;
240f22ef01cSRoman Divacky   }
241f22ef01cSRoman Divacky 
2426122f3e6SDimitry Andric   return false;
243f22ef01cSRoman Divacky }
244dff0c46cSDimitry Andric }
245f22ef01cSRoman Divacky 
main(int argc,char ** argv)2466122f3e6SDimitry Andric int main(int argc, char **argv) {
2473ca95b02SDimitry Andric   sys::PrintStackTraceOnErrorSignal(argv[0]);
2486122f3e6SDimitry Andric   PrettyStackTraceProgram X(argc, argv);
2496122f3e6SDimitry Andric   cl::ParseCommandLineOptions(argc, argv);
2506122f3e6SDimitry Andric 
2514d0b32cdSDimitry Andric   llvm_shutdown_obj Y;
2524d0b32cdSDimitry Andric 
2533861d79fSDimitry Andric   return TableGenMain(argv[0], &LLVMTableGenMain);
254f22ef01cSRoman Divacky }
25591bc56edSDimitry Andric 
25691bc56edSDimitry Andric #ifdef __has_feature
25791bc56edSDimitry Andric #if __has_feature(address_sanitizer)
25891bc56edSDimitry Andric #include <sanitizer/lsan_interface.h>
25991bc56edSDimitry Andric // Disable LeakSanitizer for this binary as it has too many leaks that are not
26091bc56edSDimitry Andric // very interesting to fix. See compiler-rt/include/sanitizer/lsan_interface.h .
__lsan_is_turned_off()2612cab237bSDimitry Andric LLVM_ATTRIBUTE_USED int __lsan_is_turned_off() { return 1; }
26291bc56edSDimitry Andric #endif  // __has_feature(address_sanitizer)
26391bc56edSDimitry Andric #endif  // defined(__has_feature)
264