forked from OSchip/llvm-project
Updated the TableGen emitter for the Enhanced
Disassembler to take advantage of the refactored AsmWriterInst.h. Note removed parser code. llvm-svn: 95760
This commit is contained in:
parent
515937d2ea
commit
e9959a5f1a
|
@ -199,223 +199,40 @@ namespace {
|
||||||
EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
|
EDEmitter::EDEmitter(RecordKeeper &R) : Records(R) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////
|
/// populateOperandOrder - Accepts a CodeGenInstruction and generates its
|
||||||
// Support functions for parsing AsmStrings //
|
/// AsmWriterInst for the desired assembly syntax, giving an ordered list of
|
||||||
//////////////////////////////////////////////
|
/// operands in the order they appear in the printed instruction. Then, for
|
||||||
|
/// each entry in that list, determines the index of the same operand in the
|
||||||
/// parseError - A better error reporter for use in AsmString parsers
|
/// CodeGenInstruction, and emits the resulting mapping into an array, filling
|
||||||
///
|
/// in unused slots with -1.
|
||||||
/// @arg asmString - The original assembly string, for use in the error report
|
|
||||||
/// @arg index - The character where the error occurred
|
|
||||||
/// @arg err - The text of the error itself
|
|
||||||
static void parseError(const std::string& asmString,
|
|
||||||
unsigned int index,
|
|
||||||
const char* err) {
|
|
||||||
errs() << "In: " << asmString.c_str() << "\n";
|
|
||||||
errs() << "Error at " << format("%d", index) << ": " << err << "\n";
|
|
||||||
llvm_unreachable("Parse error");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// resolveBraces - Interprets the brace syntax in an AsmString in favor of just
|
|
||||||
/// one syntax, and returns the result. "{A}" is resolved to "A" for syntax 0
|
|
||||||
/// and "" for all others; "{A|B}" is resolved to "A" for syntax 0, "B" for
|
|
||||||
/// syntax 1, and "" for all others; and so on.
|
|
||||||
///
|
|
||||||
/// @arg asmString - The original string, as loaded from the .td file
|
|
||||||
/// @arg syntaxIndex - The index to use
|
|
||||||
static std::string resolveBraces(const std::string &asmString,
|
|
||||||
unsigned int syntaxIndex) {
|
|
||||||
std::string ret;
|
|
||||||
|
|
||||||
unsigned int index;
|
|
||||||
unsigned int numChars = asmString.length();
|
|
||||||
|
|
||||||
// Brace parsing countable-state transducer
|
|
||||||
//
|
|
||||||
// STATES - -1, 0, 1, ..., error
|
|
||||||
// SYMBOLS - '{', '|', '}', ?, EOF
|
|
||||||
// START STATE - -1
|
|
||||||
//
|
|
||||||
// state input -> state output
|
|
||||||
// -1 '{' -> 0
|
|
||||||
// -1 '|' -> error
|
|
||||||
// -1 '}' -> error
|
|
||||||
// -1 ? -> -1 ?
|
|
||||||
// -1 EOF -> -1
|
|
||||||
// n '{' -> error
|
|
||||||
// n '|' -> n+1
|
|
||||||
// n '}' -> -1
|
|
||||||
// n ? -> n ? if n == syntaxIndex
|
|
||||||
// if not
|
|
||||||
// n EOF -> error
|
|
||||||
|
|
||||||
int state = -1;
|
|
||||||
|
|
||||||
for (index = 0; index < numChars; ++index) {
|
|
||||||
char input = asmString[index];
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
default:
|
|
||||||
switch (input) {
|
|
||||||
default:
|
|
||||||
if (state == (int)syntaxIndex)
|
|
||||||
ret.push_back(input);
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
parseError(asmString, index, "Nested { in AsmString");
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
state++;
|
|
||||||
break;
|
|
||||||
case '}':
|
|
||||||
state = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
switch (input) {
|
|
||||||
default:
|
|
||||||
ret.push_back(input);
|
|
||||||
break;
|
|
||||||
case '{':
|
|
||||||
state = 0;
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
parseError(asmString, index, "| outside braces in AsmString");
|
|
||||||
break;
|
|
||||||
case '}':
|
|
||||||
parseError(asmString, index, "Unmatched } in AsmString");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state != -1)
|
|
||||||
parseError(asmString, index, "Unmatched { in AsmString");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getOperandIndex - looks up a named operand in an instruction and determines
|
|
||||||
/// its index in the operand descriptor array, returning the index or -1 if it
|
|
||||||
/// is not present.
|
|
||||||
///
|
|
||||||
/// @arg asmString - The assembly string for the instruction, for errors only
|
|
||||||
/// @arg operand - The operand's name
|
|
||||||
/// @arg inst - The instruction to use when looking up the operand
|
|
||||||
static int8_t getOperandIndex(const std::string &asmString,
|
|
||||||
const std::string &operand,
|
|
||||||
const CodeGenInstruction &inst) {
|
|
||||||
int8_t operandIndex;
|
|
||||||
|
|
||||||
if(operand.length() == 0) {
|
|
||||||
errs() << "In: " << asmString << "\n";
|
|
||||||
errs() << "Operand: " << operand << "\n";
|
|
||||||
llvm_unreachable("Empty operand");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
operandIndex = inst.getOperandNamed(operand);
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return operandIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isAlphanumeric - returns true if a character is a valid alphanumeric
|
|
||||||
/// character, and false otherwise
|
|
||||||
///
|
|
||||||
/// input - The character to query
|
|
||||||
static inline bool isAlphanumeric(char input) {
|
|
||||||
if((input >= 'a' && input <= 'z') ||
|
|
||||||
(input >= 'A' && input <= 'Z') ||
|
|
||||||
(input >= '0' && input <= '9') ||
|
|
||||||
(input == '_'))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// populateOperandOrder - reads a resolved AsmString (see resolveBraces) and
|
|
||||||
/// records the index into the operand descriptor array for each operand in
|
|
||||||
/// that string, in the order of appearance.
|
|
||||||
///
|
///
|
||||||
/// @arg operandOrder - The array that will be populated with the operand
|
/// @arg operandOrder - The array that will be populated with the operand
|
||||||
/// mapping. Each entry will contain -1 (invalid index
|
/// mapping. Each entry will contain -1 (invalid index
|
||||||
/// into the operands present in the AsmString) or a number
|
/// into the operands present in the AsmString) or a number
|
||||||
/// representing an index in the operand descriptor array.
|
/// representing an index in the operand descriptor array.
|
||||||
/// @arg asmString - The operand's name
|
/// @arg inst - The instruction to use when looking up the operands
|
||||||
/// @arg inst - The instruction to use when looking up the operand
|
/// @arg syntax - The syntax to use, according to LLVM's enumeration
|
||||||
void populateOperandOrder(CompoundConstantEmitter *operandOrder,
|
void populateOperandOrder(CompoundConstantEmitter *operandOrder,
|
||||||
const std::string &asmString,
|
const CodeGenInstruction &inst,
|
||||||
const CodeGenInstruction &inst) {
|
unsigned syntax) {
|
||||||
std::string aux;
|
|
||||||
|
|
||||||
unsigned int index;
|
|
||||||
unsigned int numChars = asmString.length();
|
|
||||||
unsigned int numArgs = 0;
|
unsigned int numArgs = 0;
|
||||||
|
|
||||||
// Argument processing finite-state transducer
|
AsmWriterInst awInst(inst, syntax, -1, -1);
|
||||||
//
|
|
||||||
// STATES - 0, 1, error
|
|
||||||
// SYMBOLS - A(lphanumeric), '$', ?, EOF
|
|
||||||
// START STATE - 0
|
|
||||||
//
|
|
||||||
// state input -> state aux
|
|
||||||
// 0 A -> 0
|
|
||||||
// 0 '$' -> 1
|
|
||||||
// 0 ? -> 0
|
|
||||||
// 0 EOF -> 0
|
|
||||||
// 1 A -> 1 A
|
|
||||||
// 1 '$' -> error
|
|
||||||
// 1 ? -> 0 clear
|
|
||||||
// 1 EOF -> 0 clear
|
|
||||||
|
|
||||||
unsigned int state = 0;
|
std::vector<AsmWriterOperand>::iterator operandIterator;
|
||||||
|
|
||||||
for (index = 0; index < numChars; ++index) {
|
for (operandIterator = awInst.Operands.begin();
|
||||||
char input = asmString[index];
|
operandIterator != awInst.Operands.end();
|
||||||
|
++operandIterator) {
|
||||||
switch (state) {
|
if (operandIterator->OperandType ==
|
||||||
default:
|
AsmWriterOperand::isMachineInstrOperand) {
|
||||||
parseError(asmString, index, "Parser in unreachable state");
|
char buf[2];
|
||||||
case 0:
|
snprintf(buf, sizeof(buf), "%u", operandIterator->CGIOpNo);
|
||||||
if (input == '$') {
|
operandOrder->addEntry(new LiteralConstantEmitter(buf));
|
||||||
state = 1;
|
numArgs++;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (isAlphanumeric(input)) {
|
|
||||||
aux.push_back(input);
|
|
||||||
}
|
|
||||||
else if (input == '$') {
|
|
||||||
parseError(asmString, index, "$ found in argument name");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int8_t operandIndex = getOperandIndex(asmString, aux, inst);
|
|
||||||
char buf[3];
|
|
||||||
snprintf(buf, sizeof(buf), "%d", operandIndex);
|
|
||||||
operandOrder->addEntry(new LiteralConstantEmitter(buf));
|
|
||||||
aux.clear();
|
|
||||||
state = 0;
|
|
||||||
numArgs++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == 1) {
|
|
||||||
int8_t operandIndex = getOperandIndex(asmString, aux, inst);
|
|
||||||
char buf[2];
|
|
||||||
snprintf(buf, 2, "%d", operandIndex);
|
|
||||||
operandOrder->addEntry(new LiteralConstantEmitter(buf));
|
|
||||||
aux.clear();
|
|
||||||
numArgs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(; numArgs < MAX_OPERANDS; numArgs++) {
|
for(; numArgs < MAX_OPERANDS; numArgs++) {
|
||||||
operandOrder->addEntry(new LiteralConstantEmitter("-1"));
|
operandOrder->addEntry(new LiteralConstantEmitter("-1"));
|
||||||
}
|
}
|
||||||
|
@ -780,9 +597,7 @@ static void populateInstInfo(CompoundConstantEmitter &infoArray,
|
||||||
operandOrderArray->addEntry(operandOrder);
|
operandOrderArray->addEntry(operandOrder);
|
||||||
|
|
||||||
if (syntaxIndex < numSyntaxes) {
|
if (syntaxIndex < numSyntaxes) {
|
||||||
std::string asmString = inst.AsmString;
|
populateOperandOrder(operandOrder, inst, syntaxIndex);
|
||||||
asmString = resolveBraces(asmString, syntaxIndex);
|
|
||||||
populateOperandOrder(operandOrder, asmString, inst);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (unsigned operandIndex = 0;
|
for (unsigned operandIndex = 0;
|
||||||
|
|
Loading…
Reference in New Issue