//===- EDEmitter.cpp - Generate instruction descriptions for ED -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This tablegen backend is responsible for emitting a description of each
// instruction in a format that the enhanced disassembler can use to tokenize
// and parse instructions.
//
//===----------------------------------------------------------------------===//
#include "EDEmitter.h"
#include "AsmWriterInst.h"
#include "CodeGenTarget.h"
#include "Record.h"
#include "llvm/MC/EDInstInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <map>
#include <string>
#include <vector>
using namespace llvm;
///////////////////////////////////////////////////////////
// Support classes for emitting nested C data structures //
///////////////////////////////////////////////////////////
namespace {
class EnumEmitter {
private:
std::string Name;
std::vector<std::string> Entries;
public:
EnumEmitter(const char *N) : Name(N) {
}
int addEntry(const char *e) {
Entries.push_back(std::string(e));
return Entries.size() - 1;
}
void emit(raw_ostream &o, unsigned int &i) {
o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
i += 2;
unsigned int index = 0;
unsigned int numEntries = Entries.size();
for (index = 0; index < numEntries; ++index) {
o.indent(i) << Entries[index];
if (index < (numEntries - 1))
o << ",";
o << "\n";
}
i -= 2;
o.indent(i) << "};" << "\n";
}
void emitAsFlags(raw_ostream &o, unsigned int &i) {
o.indent(i) << "enum " << Name.c_str() << " {" << "\n";
i += 2;
unsigned int index = 0;
unsigned int numEntries = Entries.size();
unsigned int flag = 1;
for (index = 0; index < numEntries; ++index) {
o.indent(i) << Entries[index] << " = " << format("0x%x", flag);
if (index < (numEntries - 1))
o << ",";
o << "\n";
flag <<= 1;
}
i -= 2;
o.indent(i) << "};" << "\n";
}
};
class StructEmitter {
private:
std::string Name;
typedef std::pair<const char*, const char*> member;
std::vector< member > Members;
public:
StructEmitter(const char *N) : Name(N) {
}
void addMember(const char *t, const char *n) {
member m(t, n);
Members.push_back(m);
}
void emit(raw_ostream &o, unsigned int &i) {
o.indent(i) << "struct " << Name.c_str() << " {" << "\n";
i += 2;
unsigned int index = 0;
unsigned int numMembers = Members.size();
for (index = 0; index < numMembers; ++index) {
o.indent(i) << Members[index].first << " ";
o.indent(i) << Members[index].second << ";" << "\n";
}
i -= 2;
o.indent(i) << "};" << "\n";
}
};
class ConstantEmitter {
public:
virtual ~ConstantEmitter() { }
virtual void emit(raw_ostream &o, unsigned int &i) = 0;
};
class LiteralConstantEmitter :