TableGen.cpp revision 50d456539dea5e61d7a1592a78f1861fb35b0063
11d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//===- TableGen.cpp - Top-Level TableGen implementation -------------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
301d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//                     The LLVM Compiler Infrastructure
401d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//
501d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// This file was developed by the LLVM research group and is distributed under
601d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
801d45827a1e512f3b19ba857772bf02baa3c0c4eJohn Criswell//===----------------------------------------------------------------------===//
91d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//
101d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// TableGen is a tool which can be used to build up a description of something,
111d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// then invoke one or more "tablegen backends" to emit information about the
121d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// description in some predefined format.  In practice, this is used by the LLVM
131d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// code generators to automate generation of a code generator through a
141d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner// high-level description of the target.
151d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//
161d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner//===----------------------------------------------------------------------===//
171d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner
18e62c1185bee05facc25d1d725434f517261d308bChris Lattner#include "Record.h"
19551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
20f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling#include "llvm/Support/Streams.h"
21bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h"
22551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h"
2350d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner#include "CallingConvEmitter.h"
24f00ce8bc29c3194485b7251dd3e234cead10008eMisha Brukman#include "CodeEmitterGen.h"
251d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner#include "RegisterInfoEmitter.h"
26169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner#include "InstrInfoEmitter.h"
272e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner#include "AsmWriterEmitter.h"
284a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner#include "DAGISelEmitter.h"
29f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey#include "SubtargetEmitter.h"
309e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner#include "IntrinsicEmitter.h"
31e62c1185bee05facc25d1d725434f517261d308bChris Lattner#include <algorithm>
32c3fe45b2f577eaf4d12cb7890773af3a8dea73c7Misha Brukman#include <cstdio>
339a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner#include <fstream>
346fb9a84e79212f550981b6545aa435e7ca0cd794Duraid Madina#include <ios>
352082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnerusing namespace llvm;
36d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
37bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattnerenum ActionType {
38bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner  PrintRecords,
39bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner  GenEmitter,
4054d156d33324b7715453993f21684915a28e310aChris Lattner  GenRegisterEnums, GenRegister, GenRegisterHeader,
412dc74dd831c611895bf5ac66521b4d944b15cc0bChris Lattner  GenInstrEnums, GenInstrs, GenAsmWriter,
4250d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner  GenCallingConv,
434a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner  GenDAGISel,
44f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey  GenSubtarget,
459e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner  GenIntrinsic,
463b2397211b806e723369f99b0ec674c6f616901bChris Lattner  PrintEnums
47bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner};
48bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner
49bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattnernamespace {
50bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner  cl::opt<ActionType>
51bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner  Action(cl::desc("Action to perform:"),
52bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner         cl::values(clEnumValN(PrintRecords, "print-records",
5385df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner                               "Print all records to stdout (default)"),
54bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner                    clEnumValN(GenEmitter, "gen-emitter",
55bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner                               "Generate machine code emitter"),
5654d156d33324b7715453993f21684915a28e310aChris Lattner                    clEnumValN(GenRegisterEnums, "gen-register-enums",
5754d156d33324b7715453993f21684915a28e310aChris Lattner                               "Generate enum values for registers"),
581d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner                    clEnumValN(GenRegister, "gen-register-desc",
591d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner                               "Generate a register info description"),
601d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner                    clEnumValN(GenRegisterHeader, "gen-register-desc-header",
611d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner                               "Generate a register info description header"),
62169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner                    clEnumValN(GenInstrEnums, "gen-instr-enums",
63169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner                               "Generate enum values for instructions"),
6415de32d706287e1457ab26b74d731f5367083b99Chris Lattner                    clEnumValN(GenInstrs, "gen-instr-desc",
6515de32d706287e1457ab26b74d731f5367083b99Chris Lattner                               "Generate instruction descriptions"),
6650d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner                    clEnumValN(GenCallingConv, "gen-callingconv",
6750d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner                               "Generate calling convention descriptions"),
682e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner                    clEnumValN(GenAsmWriter, "gen-asm-writer",
692e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner                               "Generate assembly writer"),
704a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner                    clEnumValN(GenDAGISel, "gen-dag-isel",
714a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner                               "Generate a DAG instruction selector"),
72f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey                    clEnumValN(GenSubtarget, "gen-subtarget",
73f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey                               "Generate subtarget enumerations"),
749e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner                    clEnumValN(GenIntrinsic, "gen-intrinsic",
759e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner                               "Generate intrinsic information"),
76bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner                    clEnumValN(PrintEnums, "print-enums",
77bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner                               "Print enum values for a class"),
78bd935336d4dd9d9a55feed9d9ef0bd6941060f37Chris Lattner                    clEnumValEnd));
79bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner
80bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner  cl::opt<std::string>
8185df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner  Class("class", cl::desc("Print Enum list for this class"),
8285df22568d3eebfde900dd30038c29ae01caf5bdChris Lattner        cl::value_desc("class name"));
839a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner
8490523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner  cl::opt<std::string>
8590523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner  OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"),
8690523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner                 cl::init("-"));
8790523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner
8890523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner  cl::opt<std::string>
8990523906fa31c8f4e156dc7ef4a433a50d4b706dChris Lattner  InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
9096b4beda5c180f4091d55752bc22129f15d4030cJohn Criswell
91d9f5d90af198eff5fa78e313d019bd1770db7f03Chris Lattner  cl::list<std::string>
92d9f5d90af198eff5fa78e313d019bd1770db7f03Chris Lattner  IncludeDirs("I", cl::desc("Directory of include files"),
93ed5424196d79746542e14bf959842fb94bc8fb9cChris Lattner              cl::value_desc("directory"), cl::Prefix);
94bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner}
95bc52013e30f69655f941313c3fa1a2c18de5b7abChris Lattner
962082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattnernamespace llvm {
972082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattner  void ParseFile(const std::string &Filename,
98d9f5d90af198eff5fa78e313d019bd1770db7f03Chris Lattner                 const std::vector<std::string> &IncludeDirs);
992082ebe8b3a5db302748828ab4f79a36d239c1d9Chris Lattner}
100e62c1185bee05facc25d1d725434f517261d308bChris Lattner
1012082ebe8b3a5db302748828ab4f79a36d239c1d9Chris LattnerRecordKeeper llvm::Records;
102e62c1185bee05facc25d1d725434f517261d308bChris Lattner
103e62c1185bee05facc25d1d725434f517261d308bChris Lattnerint main(int argc, char **argv) {
104e62c1185bee05facc25d1d725434f517261d308bChris Lattner  cl::ParseCommandLineOptions(argc, argv);
105d9f5d90af198eff5fa78e313d019bd1770db7f03Chris Lattner  ParseFile(InputFilename, IncludeDirs);
106e62c1185bee05facc25d1d725434f517261d308bChris Lattner
107f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling  std::ostream *Out = cout.stream();
1089a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner  if (OutputFilename != "-") {
10942df6d1396d0335621f648b0e4a6e59f13e868f2Chris Lattner    Out = new std::ofstream(OutputFilename.c_str());
1109a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner
1119a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner    if (!Out->good()) {
112f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling      cerr << argv[0] << ": error opening " << OutputFilename << "!\n";
1139a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner      return 1;
1149a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner    }
1159a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner
1169a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner    // Make sure the file gets removed if *gasp* tablegen crashes...
117227b6d00dd1faee07c921c7e2256e0fca737d2e5Reid Spencer    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
1189a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner  }
1199a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner
1201d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner  try {
1211d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    switch (Action) {
122accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner    case PrintRecords:
123accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner      *Out << Records;           // No argument, dump all contents
124accd8abeebfa73e0a4cb2d4372ecf42513561460Chris Lattner      break;
1251d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    case GenEmitter:
1261d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      CodeEmitterGen(Records).run(*Out);
1271d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      break;
128169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner
12954d156d33324b7715453993f21684915a28e310aChris Lattner    case GenRegisterEnums:
13054d156d33324b7715453993f21684915a28e310aChris Lattner      RegisterInfoEmitter(Records).runEnums(*Out);
13154d156d33324b7715453993f21684915a28e310aChris Lattner      break;
1321d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    case GenRegister:
1331d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      RegisterInfoEmitter(Records).run(*Out);
1341d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      break;
1351d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    case GenRegisterHeader:
1361d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      RegisterInfoEmitter(Records).runHeader(*Out);
1371d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      break;
138169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner
139169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner    case GenInstrEnums:
140169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner      InstrInfoEmitter(Records).runEnums(*Out);
141169e66bfc23c20a3df7d0364f5f1abb43f33694bChris Lattner      break;
14215de32d706287e1457ab26b74d731f5367083b99Chris Lattner    case GenInstrs:
14315de32d706287e1457ab26b74d731f5367083b99Chris Lattner      InstrInfoEmitter(Records).run(*Out);
14415de32d706287e1457ab26b74d731f5367083b99Chris Lattner      break;
14550d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner    case GenCallingConv:
14650d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner      CallingConvEmitter(Records).run(*Out);
14750d456539dea5e61d7a1592a78f1861fb35b0063Chris Lattner      break;
1482e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner    case GenAsmWriter:
1492e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner      AsmWriterEmitter(Records).run(*Out);
1502e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner      break;
1512e1f51b8a583649d74cb666ca5e4cf680cc1ced9Chris Lattner
1524a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner    case GenDAGISel:
1534a24c645c8402dff59dbf20d5a422227a611e908Chris Lattner      DAGISelEmitter(Records).run(*Out);
154f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey      break;
155f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey    case GenSubtarget:
156f5fc2cbd6bcf80cc34c8114007f31d8ffd1d138dJim Laskey      SubtargetEmitter(Records).run(*Out);
1579e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      break;
1589e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner    case GenIntrinsic:
1599e493cfcc32aee58e6750ce1efa52d5c3bc3f893Chris Lattner      IntrinsicEmitter(Records).run(*Out);
1603f781341f97da31bfee55bc221ff58b76e7a60dfChris Lattner      break;
1611d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    case PrintEnums:
162d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke    {
1631d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      std::vector<Record*> Recs = Records.getAllDerivedDefinitions(Class);
1641d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      for (unsigned i = 0, e = Recs.size(); i != e; ++i)
1657b9ee51a55f7f16b54e9839d99841bc2fab71ebeChris Lattner        *Out << Recs[i]->getName() << ", ";
1661d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      *Out << "\n";
1671d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner      break;
168e62c1185bee05facc25d1d725434f517261d308bChris Lattner    }
169d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke    default:
170d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke      assert(1 && "Invalid Action");
171d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke      return 1;
172d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke    }
1731d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner  } catch (const std::string &Error) {
174f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    cerr << argv[0] << ": " << Error << "\n";
175f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    if (Out != cout.stream()) {
176f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner      delete Out;                             // Close the file
177f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner      std::remove(OutputFilename.c_str());    // Remove the file, it's broken
178f1e366acffbe4bdbb1d4a573c178f5531efdf7f8Chris Lattner    }
1791d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner    return 1;
18023f7d5131cf9519b90ac4fc2d200671d128b5464Reid Spencer  } catch (...) {
181f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    cerr << argv[0] << ": Unknown unexpected exception occurred.\n";
182f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling    if (Out != cout.stream()) {
18323f7d5131cf9519b90ac4fc2d200671d128b5464Reid Spencer      delete Out;                             // Close the file
18423f7d5131cf9519b90ac4fc2d200671d128b5464Reid Spencer      std::remove(OutputFilename.c_str());    // Remove the file, it's broken
18523f7d5131cf9519b90ac4fc2d200671d128b5464Reid Spencer    }
18623f7d5131cf9519b90ac4fc2d200671d128b5464Reid Spencer    return 2;
187e62c1185bee05facc25d1d725434f517261d308bChris Lattner  }
1889a886386a4067a2407a284c947bd1044b43e2b1bChris Lattner
189f5da13367f88f06e3b585dc2263ab6e9ca6c4bf8Bill Wendling  if (Out != cout.stream()) {
190e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner    delete Out;                               // Close the file
191e79c72d4cd68fce6ccb30b2cc222069619f7d503Chris Lattner  }
1921d1adea4937aa5c7b4bd0aa0463fe38fcdd22c7eChris Lattner  return 0;
193e62c1185bee05facc25d1d725434f517261d308bChris Lattner}
194