diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp new file mode 100644 index 00000000000..b2cf1072b9a --- /dev/null +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -0,0 +1,48 @@ +//===- AsmWriterEmitter.cpp - Generate an assembly writer -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is emits an assembly printer for the current target. +// Note that this is currently fairly skeletal, but will grow over time. +// +//===----------------------------------------------------------------------===// + +#include "AsmWriterEmitter.h" +#include "CodeGenTarget.h" +#include +using namespace llvm; + +void AsmWriterEmitter::run(std::ostream &O) { + EmitSourceFileHeader("Assembly Writer Source Fragment", O); + + CodeGenTarget Target; + O << + "/// printInstruction - This method is automatically generated by tablegen\n" + "/// from the instruction set description. This method returns true if the\n" + "/// machine instruction was sufficiently described to print it, otherwise\n" + "/// it returns false.\n" + "bool " << Target.getName() + << "AsmPrinter::printInstruction(const MachineInstr *MI) {\n"; + O << " switch (MI->getOpcode()) {\n" + " default: return false;\n"; + + std::string Namespace = Target.inst_begin()->second.Namespace; + + for (CodeGenTarget::inst_iterator I = Target.inst_begin(), + E = Target.inst_end(); I != E; ++I) + if (!I->second.AsmString.empty()) { + const std::string &AsmString = I->second.AsmString; + O << " case " << Namespace << "::" << I->first << ": O << \"" + << AsmString << "\" << '\\n'; break;\n"; + } + + O << " }\n" + " return true;\n" + "}\n"; + EmitSourceFileTail(O); +} diff --git a/utils/TableGen/AsmWriterEmitter.h b/utils/TableGen/AsmWriterEmitter.h new file mode 100644 index 00000000000..42d070ec752 --- /dev/null +++ b/utils/TableGen/AsmWriterEmitter.h @@ -0,0 +1,31 @@ +//===- AsmWriterEmitter.h - Generate an assembly writer ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend is responsible for emitting an assembly printer for the +// code generator. +// +//===----------------------------------------------------------------------===// + +#ifndef ASMWRITER_EMITTER_H +#define ASMWRITER_EMITTER_H + +#include "TableGenBackend.h" + +namespace llvm { + + class AsmWriterEmitter : public TableGenBackend { + RecordKeeper &Records; + public: + AsmWriterEmitter(RecordKeeper &R) : Records(R) {} + + // run - Output the asmwriter, returning true on failure. + void run(std::ostream &o); + }; +} +#endif diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 026119d8d0a..422e8d0b4f2 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -122,14 +122,23 @@ CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) { Namespace = R->getValueAsString("Namespace"); AsmString = R->getValueAsString("AsmString"); - //TODO: Parse OperandList - isReturn = R->getValueAsBit("isReturn"); isBranch = R->getValueAsBit("isBranch"); isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); isTwoAddress = R->getValueAsBit("isTwoAddress"); isTerminator = R->getValueAsBit("isTerminator"); + + + //TODO: Parse OperandList + try { + DagInit *DI = R->getValueAsDag("OperandList"); + + // Cannot handle instructions with operands yet. + if (DI->getNumArgs()) + AsmString.clear(); + } catch (...) { + } } diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index 7bd52b37cf0..dc980a60a85 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -22,6 +22,7 @@ #include "CodeEmitterGen.h" #include "RegisterInfoEmitter.h" #include "InstrInfoEmitter.h" +#include "AsmWriterEmitter.h" #include "InstrSelectorEmitter.h" #include #include @@ -32,7 +33,7 @@ enum ActionType { PrintRecords, GenEmitter, GenRegisterEnums, GenRegister, GenRegisterHeader, - GenInstrEnums, GenInstrs, GenInstrSelector, + GenInstrEnums, GenInstrs, GenAsmWriter, GenInstrSelector, PrintEnums, Parse }; @@ -54,6 +55,8 @@ namespace { "Generate enum values for instructions"), clEnumValN(GenInstrs, "gen-instr-desc", "Generate instruction descriptions"), + clEnumValN(GenAsmWriter, "gen-asm-writer", + "Generate assembly writer"), clEnumValN(GenInstrSelector, "gen-instr-selector", "Generate an instruction selector"), clEnumValN(PrintEnums, "print-enums", @@ -454,6 +457,11 @@ int main(int argc, char **argv) { case GenInstrs: InstrInfoEmitter(Records).run(*Out); break; + + case GenAsmWriter: + AsmWriterEmitter(Records).run(*Out); + break; + case GenInstrSelector: InstrSelectorEmitter(Records).run(*Out); break;