aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/AsmWriterEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/AsmWriterEmitter.cpp')
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp116
1 files changed, 90 insertions, 26 deletions
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index 066e03d..b77d2e4 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -18,6 +18,7 @@
#include "CodeGenTarget.h"
#include "Record.h"
#include "StringToOffsetTable.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
@@ -458,6 +459,58 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
O << "}\n";
}
+static void
+emitRegisterNameString(raw_ostream &O, StringRef AltName,
+ const std::vector<CodeGenRegister*> &Registers) {
+ StringToOffsetTable StringTable;
+ O << " static const unsigned RegAsmOffset" << AltName << "[] = {\n ";
+ for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
+ const CodeGenRegister &Reg = *Registers[i];
+
+ std::string AsmName;
+ // "NoRegAltName" is special. We don't need to do a lookup for that,
+ // as it's just a reference to the default register name.
+ if (AltName == "" || AltName == "NoRegAltName") {
+ AsmName = Reg.TheDef->getValueAsString("AsmName");
+ if (AsmName.empty())
+ AsmName = Reg.getName();
+ } else {
+ // Make sure the register has an alternate name for this index.
+ std::vector<Record*> AltNameList =
+ Reg.TheDef->getValueAsListOfDefs("RegAltNameIndices");
+ unsigned Idx = 0, e;
+ for (e = AltNameList.size();
+ Idx < e && (AltNameList[Idx]->getName() != AltName);
+ ++Idx)
+ ;
+ // If the register has an alternate name for this index, use it.
+ // Otherwise, leave it empty as an error flag.
+ if (Idx < e) {
+ std::vector<std::string> AltNames =
+ Reg.TheDef->getValueAsListOfStrings("AltNames");
+ if (AltNames.size() <= Idx)
+ throw TGError(Reg.TheDef->getLoc(),
+ (Twine("Register definition missing alt name for '") +
+ AltName + "'.").str());
+ AsmName = AltNames[Idx];
+ }
+ }
+
+ O << StringTable.GetOrAddStringOffset(AsmName);
+ if (((i + 1) % 14) == 0)
+ O << ",\n ";
+ else
+ O << ", ";
+
+ }
+ O << "0\n"
+ << " };\n"
+ << "\n";
+
+ O << " const char *AsmStrs" << AltName << " =\n";
+ StringTable.EmitString(O);
+ O << ";\n";
+}
void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
CodeGenTarget Target(Records);
@@ -465,40 +518,48 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
const std::vector<CodeGenRegister*> &Registers =
Target.getRegBank().getRegisters();
+ std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices();
+ bool hasAltNames = AltNameIndices.size() > 1;
- StringToOffsetTable StringTable;
O <<
"\n\n/// getRegisterName - This method is automatically generated by tblgen\n"
"/// from the register set description. This returns the assembler name\n"
"/// for the specified register.\n"
- "const char *" << Target.getName() << ClassName
- << "::getRegisterName(unsigned RegNo) {\n"
- << " assert(RegNo && RegNo < " << (Registers.size()+1)
- << " && \"Invalid register number!\");\n"
- << "\n"
- << " static const unsigned RegAsmOffset[] = {";
- for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
- const CodeGenRegister &Reg = *Registers[i];
-
- std::string AsmName = Reg.TheDef->getValueAsString("AsmName");
- if (AsmName.empty())
- AsmName = Reg.getName();
-
-
- if ((i % 14) == 0)
- O << "\n ";
-
- O << StringTable.GetOrAddStringOffset(AsmName) << ", ";
- }
- O << "0\n"
- << " };\n"
+ "const char *" << Target.getName() << ClassName << "::";
+ if (hasAltNames)
+ O << "\ngetRegisterName(unsigned RegNo, unsigned AltIdx) {\n";
+ else
+ O << "getRegisterName(unsigned RegNo) {\n";
+ O << " assert(RegNo && RegNo < " << (Registers.size()+1)
+ << " && \"Invalid register number!\");\n"
<< "\n";
- O << " const char *AsmStrs =\n";
- StringTable.EmitString(O);
- O << ";\n";
+ if (hasAltNames) {
+ for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i)
+ emitRegisterNameString(O, AltNameIndices[i]->getName(), Registers);
+ } else
+ emitRegisterNameString(O, "", Registers);
+
+ if (hasAltNames) {
+ O << " const unsigned *RegAsmOffset;\n"
+ << " const char *AsmStrs;\n"
+ << " switch(AltIdx) {\n"
+ << " default: assert(0 && \"Invalid register alt name index!\");\n";
+ for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
+ StringRef Namespace = AltNameIndices[1]->getValueAsString("Namespace");
+ StringRef AltName(AltNameIndices[i]->getName());
+ O << " case " << Namespace << "::" << AltName
+ << ":\n"
+ << " AsmStrs = AsmStrs" << AltName << ";\n"
+ << " RegAsmOffset = RegAsmOffset" << AltName << ";\n"
+ << " break;\n";
+ }
+ O << "}\n";
+ }
- O << " return AsmStrs+RegAsmOffset[RegNo-1];\n"
+ O << " assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
+ << " \"Invalid alt name index for register!\");\n"
+ << " return AsmStrs+RegAsmOffset[RegNo-1];\n"
<< "}\n";
}
@@ -936,6 +997,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
const Record *Rec = RO.getRecord();
StringRef ROName = RO.getName();
+
+ if (Rec->isSubClassOf("RegisterOperand"))
+ Rec = Rec->getValueAsDef("RegClass");
if (Rec->isSubClassOf("RegisterClass")) {
Cond = std::string("MI->getOperand(")+llvm::utostr(i)+").isReg()";
IAP->addCond(Cond);