//
//===----------------------------------------------------------------------===//
-#include "InstrInfoEmitter.h"
+
+#include "CodeGenDAGPatterns.h"
+#include "CodeGenSchedule.h"
#include "CodeGenTarget.h"
#include "SequenceToOffsetTable.h"
-#include "llvm/TableGen/Record.h"
+#include "TableGenBackends.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
#include <algorithm>
#include <cstdio>
+#include <map>
+#include <vector>
using namespace llvm;
+namespace {
+class InstrInfoEmitter {
+ RecordKeeper &Records;
+ CodeGenDAGPatterns CDP;
+ const CodeGenSchedModels &SchedModels;
+
+public:
+ InstrInfoEmitter(RecordKeeper &R):
+ Records(R), CDP(R), SchedModels(CDP.getTargetInfo().getSchedModels()) {}
+
+ // run - Output the instruction set description.
+ void run(raw_ostream &OS);
+
+private:
+ void emitEnums(raw_ostream &OS);
+
+ typedef std::map<std::vector<std::string>, unsigned> OperandInfoMapTy;
+ void emitRecord(const CodeGenInstruction &Inst, unsigned Num,
+ Record *InstrInfo,
+ std::map<std::vector<Record*>, unsigned> &EL,
+ const OperandInfoMapTy &OpInfo,
+ raw_ostream &OS);
+
+ // Operand information.
+ void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
+ std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
+};
+} // End anonymous namespace
+
static void PrintDefList(const std::vector<Record*> &Uses,
unsigned Num, raw_ostream &OS) {
OS << "static const uint16_t ImplicitList" << Num << "[] = { ";
OS << "0 };\n";
}
-//===----------------------------------------------------------------------===//
-// Instruction Itinerary Information.
-//===----------------------------------------------------------------------===//
-
-void InstrInfoEmitter::GatherItinClasses() {
- std::vector<Record*> DefList =
- Records.getAllDerivedDefinitions("InstrItinClass");
- std::sort(DefList.begin(), DefList.end(), LessRecord());
-
- for (unsigned i = 0, N = DefList.size(); i < N; i++)
- ItinClassMap[DefList[i]->getName()] = i;
-}
-
-unsigned InstrInfoEmitter::getItinClassNumber(const Record *InstRec) {
- return ItinClassMap[InstRec->getValueAsDef("Itinerary")->getName()];
-}
-
//===----------------------------------------------------------------------===//
// Operand Info Emission.
//===----------------------------------------------------------------------===//
for (unsigned j = 0, e = Inst.Operands[i].MINumOperands; j != e; ++j) {
OperandList.push_back(Inst.Operands[i]);
- Record *OpR = dynamic_cast<DefInit*>(MIOI->getArg(j))->getDef();
+ Record *OpR = cast<DefInit>(MIOI->getArg(j))->getDef();
OperandList.back().Rec = OpR;
}
}
// run - Emit the main instruction description records for the target...
void InstrInfoEmitter::run(raw_ostream &OS) {
+ emitSourceFileHeader("Target Instruction Enum Values", OS);
emitEnums(OS);
- GatherItinClasses();
-
- EmitSourceFileHeader("Target Instruction Descriptors", OS);
+ emitSourceFileHeader("Target Instruction Descriptors", OS);
OS << "\n#ifdef GET_INSTRINFO_MC_DESC\n";
OS << "#undef GET_INSTRINFO_MC_DESC\n";
std::string ClassName = TargetName + "GenInstrInfo";
OS << "namespace llvm {\n";
- OS << "struct " << ClassName << " : public TargetInstrInfoImpl {\n"
+ OS << "struct " << ClassName << " : public TargetInstrInfo {\n"
<< " explicit " << ClassName << "(int SO = -1, int DO = -1);\n"
<< "};\n";
OS << "} // End llvm namespace \n";
OS << "extern const unsigned " << TargetName << "InstrNameIndices[];\n";
OS << "extern const char " << TargetName << "InstrNameData[];\n";
OS << ClassName << "::" << ClassName << "(int SO, int DO)\n"
- << " : TargetInstrInfoImpl(SO, DO) {\n"
+ << " : TargetInstrInfo(SO, DO) {\n"
<< " InitMCInstrInfo(" << TargetName << "Insts, "
<< TargetName << "InstrNameIndices, " << TargetName << "InstrNameData, "
<< NumberedInstructions.size() << ");\n}\n";
const OperandInfoMapTy &OpInfo,
raw_ostream &OS) {
int MinOperands = 0;
- if (!Inst.Operands.size() == 0)
+ if (!Inst.Operands.empty())
// Each logical operand can be multiple MI operands.
MinOperands = Inst.Operands.back().MIOperandNo +
Inst.Operands.back().MINumOperands;
OS << " { ";
OS << Num << ",\t" << MinOperands << ",\t"
<< Inst.Operands.NumDefs << ",\t"
- << getItinClassNumber(Inst.TheDef) << ",\t"
+ << SchedModels.getSchedClassIdx(Inst) << ",\t"
<< Inst.TheDef->getValueAsInt("Size") << ",\t0";
// Emit all of the target indepedent flags...
if (Inst.isCompare) OS << "|(1<<MCID::Compare)";
if (Inst.isMoveImm) OS << "|(1<<MCID::MoveImm)";
if (Inst.isBitcast) OS << "|(1<<MCID::Bitcast)";
+ if (Inst.isSelect) OS << "|(1<<MCID::Select)";
if (Inst.isBarrier) OS << "|(1<<MCID::Barrier)";
if (Inst.hasDelaySlot) OS << "|(1<<MCID::DelaySlot)";
if (Inst.isCall) OS << "|(1<<MCID::Call)";
// Emit all of the target-specific flags...
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
- if (!TSF) throw "no TSFlags?";
+ if (!TSF)
+ PrintFatalError("no TSFlags?");
uint64_t Value = 0;
for (unsigned i = 0, e = TSF->getNumBits(); i != e; ++i) {
- if (BitInit *Bit = dynamic_cast<BitInit*>(TSF->getBit(i)))
+ if (BitInit *Bit = dyn_cast<BitInit>(TSF->getBit(i)))
Value |= uint64_t(Bit->getValue()) << i;
else
- throw "Invalid TSFlags bit in " + Inst.TheDef->getName();
+ PrintFatalError("Invalid TSFlags bit in " + Inst.TheDef->getName());
}
OS << ", 0x";
OS.write_hex(Value);
// emitEnums - Print out enum values for all of the instructions.
void InstrInfoEmitter::emitEnums(raw_ostream &OS) {
- EmitSourceFileHeader("Target Instruction Enum Values", OS);
OS << "\n#ifdef GET_INSTRINFO_ENUM\n";
OS << "#undef GET_INSTRINFO_ENUM\n";
OS << "#endif // GET_INSTRINFO_ENUM\n\n";
}
+
+namespace llvm {
+
+void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS) {
+ InstrInfoEmitter(RK).run(OS);
+ EmitMapTable(RK, OS);
+}
+
+} // End llvm namespace