Silencing a spurious -Wreturn-type warning; NFC.
[oota-llvm.git] / utils / TableGen / AsmWriterEmitter.cpp
index 7ef70d31b69356e9fe63d6c155d614c212e38d10..389889ab80f0a09ea0c7b28c85b8bd88916edf95 100644 (file)
@@ -208,9 +208,6 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
       // Otherwise, scan to see if all of the other instructions in this command
       // set share the operand.
       bool AllSame = true;
-      // Keep track of the maximum, number of operands or any
-      // instruction we see in the group.
-      size_t MaxSize = FirstInst->Operands.size();
 
       for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
            NIT != InstIdxs.end();
@@ -220,10 +217,6 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands,
         const AsmWriterInst *OtherInst =
           getAsmWriterInstByID(NIT-InstIdxs.begin());
 
-        if (OtherInst &&
-            OtherInst->Operands.size() > FirstInst->Operands.size())
-          MaxSize = std::max(MaxSize, OtherInst->Operands.size());
-
         if (!OtherInst || OtherInst->Operands.size() == Op ||
             OtherInst->Operands[Op] != FirstInst->Operands[Op]) {
           AllSame = false;
@@ -285,12 +278,15 @@ static void UnescapeString(std::string &Str) {
 void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   Record *AsmWriter = Target.getAsmWriter();
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
+  unsigned PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
 
   O <<
   "/// printInstruction - This method is automatically generated by tablegen\n"
   "/// from the instruction set description.\n"
     "void " << Target.getName() << ClassName
-            << "::printInstruction(const MCInst *MI, raw_ostream &O) {\n";
+            << "::printInstruction(const MCInst *MI, "
+            << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+            << "raw_ostream &O) {\n";
 
   // Build an aggregate string, and build a table of offsets into it.
   SequenceToOffsetTable<std::string> StringTable;
@@ -350,7 +346,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   // in the opcode-indexed table.
   unsigned BitsLeft = 64-AsmStrBits;
 
-  std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
+  std::vector<std::vector<std::string>> TableDrivenOperandPrinters;
 
   while (1) {
     std::vector<std::string> UniqueOperandCommands;
@@ -393,7 +389,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
     }
 
     // Remember the handlers for this set of operands.
-    TableDrivenOperandPrinters.push_back(UniqueOperandCommands);
+    TableDrivenOperandPrinters.push_back(std::move(UniqueOperandCommands));
   }
 
 
@@ -474,7 +470,7 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
       O << "  switch ((Bits >> "
         << (64-BitsLeft) << ") & "
         << ((1 << NumBits)-1) << ") {\n"
-        << "  default:   // unreachable.\n";
+        << "  default: llvm_unreachable(\"Invalid command number.\");\n";
 
       // Print out all the cases.
       for (unsigned i = 0, e = Commands.size(); i != e; ++i) {
@@ -520,14 +516,23 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) {
   O << "}\n";
 }
 
+static const char *getMinimalTypeForRange(uint64_t Range) {
+  assert(Range < 0xFFFFFFFFULL && "Enum too large");
+  if (Range > 0xFFFF)
+    return "uint32_t";
+  if (Range > 0xFF)
+    return "uint16_t";
+  return "uint8_t";
+}
+
 static void
 emitRegisterNameString(raw_ostream &O, StringRef AltName,
-                       const std::vector<CodeGenRegister*> &Registers) {
+                       const std::deque<CodeGenRegister> &Registers) {
   SequenceToOffsetTable<std::string> StringTable;
   SmallVector<std::string, 4> AsmNames(Registers.size());
-  for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
-    const CodeGenRegister &Reg = *Registers[i];
-    std::string &AsmName = AsmNames[i];
+  unsigned i = 0;
+  for (const auto &Reg : Registers) {
+    std::string &AsmName = AsmNames[i++];
 
     // "NoRegAltName" is special. We don't need to do a lookup for that,
     // as it's just a reference to the default register name.
@@ -564,7 +569,8 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
   StringTable.emit(O, printChar);
   O << "  };\n\n";
 
-  O << "  static const uint32_t RegAsmOffset" << AltName << "[] = {";
+  O << "  static const " << getMinimalTypeForRange(StringTable.size()-1)
+    << " RegAsmOffset" << AltName << "[] = {";
   for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
     if ((i % 14) == 0)
       O << "\n    ";
@@ -577,8 +583,7 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName,
 void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
   Record *AsmWriter = Target.getAsmWriter();
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
-  const std::vector<CodeGenRegister*> &Registers =
-    Target.getRegBank().getRegisters();
+  const auto &Registers = Target.getRegBank().getRegisters();
   std::vector<Record*> AltNameIndices = Target.getRegAltNameIndices();
   bool hasAltNames = AltNameIndices.size() > 1;
 
@@ -602,26 +607,25 @@ void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) {
     emitRegisterNameString(O, "", Registers);
 
   if (hasAltNames) {
-    O << "  const uint32_t *RegAsmOffset;\n"
-      << "  const char *AsmStrs;\n"
-      << "  switch(AltIdx) {\n"
+    O << "  switch(AltIdx) {\n"
       << "  default: llvm_unreachable(\"Invalid register alt name index!\");\n";
     for (unsigned i = 0, e = AltNameIndices.size(); i < e; ++i) {
       std::string Namespace = AltNameIndices[1]->getValueAsString("Namespace");
       std::string AltName(AltNameIndices[i]->getName());
-      O << "  case " << Namespace << "::" << AltName
-        << ":\n"
-        << "    AsmStrs = AsmStrs" << AltName  << ";\n"
-        << "    RegAsmOffset = RegAsmOffset" << AltName << ";\n"
-        << "    break;\n";
+      O << "  case " << Namespace << "::" << AltName << ":\n"
+        << "    assert(*(AsmStrs" << AltName << "+RegAsmOffset"
+        << AltName << "[RegNo-1]) &&\n"
+        << "           \"Invalid alt name index for register!\");\n"
+        << "    return AsmStrs" << AltName << "+RegAsmOffset"
+        << AltName << "[RegNo-1];\n";
     }
-    O << "}\n";
+    O << "  }\n";
+  } else {
+    O << "  assert (*(AsmStrs+RegAsmOffset[RegNo-1]) &&\n"
+      << "          \"Invalid alt name index for register!\");\n"
+      << "  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";
+  O << "}\n";
 }
 
 namespace {
@@ -654,20 +658,26 @@ public:
   std::pair<StringRef, StringRef::iterator> parseName(StringRef::iterator Start,
                                                       StringRef::iterator End) {
     StringRef::iterator I = Start;
+    StringRef::iterator Next;
     if (*I == '{') {
       // ${some_name}
       Start = ++I;
       while (I != End && *I != '}')
         ++I;
+      Next = I;
+      // eat the final '}'
+      if (Next != End)
+        ++Next;
     } else {
       // $name, just eat the usual suspects.
       while (I != End &&
              ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') ||
               (*I >= '0' && *I <= '9') || *I == '_'))
         ++I;
+      Next = I;
     }
 
-    return std::make_pair(StringRef(Start, I - Start), I);
+    return std::make_pair(StringRef(Start, I - Start), Next);
   }
 
   void print(raw_ostream &O) {
@@ -720,7 +730,7 @@ public:
     OS.flush();
 
     // Emit the string.
-    O.indent(6) << "AsmString = \"" << OutString.str() << "\";\n";
+    O.indent(6) << "AsmString = \"" << OutString << "\";\n";
 
     O.indent(6) << "break;\n";
     O.indent(4) << '}';
@@ -780,6 +790,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
   // Emit the method that prints the alias instruction.
   std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName");
   unsigned Variant = AsmWriter->getValueAsInt("Variant");
+  unsigned PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget");
 
   std::vector<Record*> AllInstAliases =
     Records.getAllDerivedDefinitions("InstAlias");
@@ -942,7 +953,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
 
   HeaderO << "bool " << Target.getName() << ClassName
           << "::printAliasInstr(const MCInst"
-          << " *MI, raw_ostream &OS) {\n";
+          << " *MI, " << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "")
+          << "raw_ostream &OS) {\n";
 
   std::string Cases;
   raw_string_ostream CasesO(Cases);
@@ -991,7 +1003,7 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
     return;
   }
 
-  if (MCOpPredicates.size())
+  if (!MCOpPredicates.empty())
     O << "static bool " << Target.getName() << ClassName
       << "ValidateMCOperand(\n"
       << "       const MCOperand &MCOp, unsigned PredicateIndex);\n";
@@ -1020,9 +1032,13 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
   O << "          ++I;\n";
   O << "          int OpIdx = AsmString[I++] - 1;\n";
   O << "          int PrintMethodIdx = AsmString[I++] - 1;\n";
-  O << "          printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);\n";
+  O << "          printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, ";
+  O << (PassSubtarget ? "STI, " : "");
+  O << "OS);\n";
   O << "        } else\n";
-  O << "          printOperand(MI, unsigned(AsmString[I++]) - 1, OS);\n";
+  O << "          printOperand(MI, unsigned(AsmString[I++]) - 1, ";
+  O << (PassSubtarget ? "STI, " : "");
+  O << "OS);\n";
   O << "      } else {\n";
   O << "        OS << AsmString[I++];\n";
   O << "      }\n";
@@ -1039,7 +1055,9 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
   O << "void " << Target.getName() << ClassName << "::"
     << "printCustomAliasOperand(\n"
     << "         const MCInst *MI, unsigned OpIdx,\n"
-    << "         unsigned PrintMethodIdx, raw_ostream &OS) {\n";
+    << "         unsigned PrintMethodIdx,\n"
+    << (PassSubtarget ? "         const MCSubtargetInfo &STI,\n" : "")
+    << "         raw_ostream &OS) {\n";
   if (PrintMethods.empty())
     O << "  llvm_unreachable(\"Unknown PrintMethod kind\");\n";
   else {
@@ -1050,14 +1068,15 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
 
     for (unsigned i = 0; i < PrintMethods.size(); ++i) {
       O << "  case " << i << ":\n"
-        << "    " << PrintMethods[i] << "(MI, OpIdx, OS);\n"
+        << "    " << PrintMethods[i] << "(MI, OpIdx, "
+        << (PassSubtarget ? "STI, " : "") << "OS);\n"
         << "    break;\n";
     }
     O << "  }\n";
   }    
   O << "}\n\n";
 
-  if (MCOpPredicates.size()) {
+  if (!MCOpPredicates.empty()) {
     O << "static bool " << Target.getName() << ClassName
       << "ValidateMCOperand(\n"
       << "       const MCOperand &MCOp, unsigned PredicateIndex) {\n"
@@ -1084,13 +1103,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) {
 
 AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) {
   Record *AsmWriter = Target.getAsmWriter();
-  for (CodeGenTarget::inst_iterator I = Target.inst_begin(),
-                                    E = Target.inst_end();
-       I != E; ++I)
-    if (!(*I)->AsmString.empty() && (*I)->TheDef->getName() != "PHI")
+  for (const CodeGenInstruction *I : Target.instructions())
+    if (!I->AsmString.empty() && I->TheDef->getName() != "PHI")
       Instructions.push_back(
-          AsmWriterInst(**I, AsmWriter->getValueAsInt("Variant"),
-                        AsmWriter->getValueAsInt("OperandSpacing")));
+          AsmWriterInst(*I, AsmWriter->getValueAsInt("Variant"),
+                        AsmWriter->getValueAsInt("PassSubtarget")));
 
   // Get the instruction numbering.
   NumberedInstructions = &Target.getInstructionsByEnumValue();