Exemple #1
0
//
// runMCDesc - Print out MC register descriptions.
//
void
RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
                               CodeGenRegBank &RegBank) {
    EmitSourceFileHeader("MC Register Information", OS);

    OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
    OS << "#undef GET_REGINFO_MC_DESC\n";

    std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
    RegBank.computeOverlaps(Overlaps);

    OS << "namespace llvm {\n\n";

    const std::string &TargetName = Target.getName();

    const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();

    OS << "extern const uint16_t " << TargetName << "RegOverlaps[] = {\n";

    // Emit an overlap list for all registers.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister *Reg = Regs[i];
        const CodeGenRegister::Set &O = Overlaps[Reg];
        // Move Reg to the front so TRI::getAliasSet can share the list.
        OS << "  /* " << Reg->getName() << "_Overlaps */ "
           << getQualifiedName(Reg->TheDef) << ", ";
        for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
                I != E; ++I)
            if (*I != Reg)
                OS << getQualifiedName((*I)->TheDef) << ", ";
        OS << "0,\n";
    }
    OS << "};\n\n";

    OS << "extern const uint16_t " << TargetName << "SubRegsSet[] = {\n";
    // Emit the empty sub-registers list
    OS << "  /* Empty_SubRegsSet */ 0,\n";
    // Loop over all of the registers which have sub-registers, emitting the
    // sub-registers list to memory.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister &Reg = *Regs[i];
        if (Reg.getSubRegs().empty())
            continue;
        // getSubRegs() orders by SubRegIndex. We want a topological order.
        SetVector<CodeGenRegister*> SR;
        Reg.addSubRegsPreOrder(SR, RegBank);
        OS << "  /* " << Reg.getName() << "_SubRegsSet */ ";
        for (unsigned j = 0, je = SR.size(); j != je; ++j)
            OS << getQualifiedName(SR[j]->TheDef) << ", ";
        OS << "0,\n";
    }
    OS << "};\n\n";

    OS << "extern const uint16_t " << TargetName << "SuperRegsSet[] = {\n";
    // Emit the empty super-registers list
    OS << "  /* Empty_SuperRegsSet */ 0,\n";
    // Loop over all of the registers which have super-registers, emitting the
    // super-registers list to memory.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister &Reg = *Regs[i];
        const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs();
        if (SR.empty())
            continue;
        OS << "  /* " << Reg.getName() << "_SuperRegsSet */ ";
        for (unsigned j = 0, je = SR.size(); j != je; ++j)
            OS << getQualifiedName(SR[j]->TheDef) << ", ";
        OS << "0,\n";
    }
    OS << "};\n\n";

    OS << "extern const MCRegisterDesc " << TargetName
       << "RegDesc[] = { // Descriptors\n";
    OS << "  { \"NOREG\", 0, 0, 0 },\n";

    // Now that register alias and sub-registers sets have been emitted, emit the
    // register descriptors now.
    unsigned OverlapsIndex = 0;
    unsigned SubRegIndex = 1; // skip 1 for empty set
    unsigned SuperRegIndex = 1; // skip 1 for empty set
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister *Reg = Regs[i];
        OS << "  { \"";
        OS << Reg->getName() << "\", /* " << Reg->getName() << "_Overlaps */ "
           << OverlapsIndex << ", ";
        OverlapsIndex += Overlaps[Reg].size() + 1;
        if (!Reg->getSubRegs().empty()) {
            OS << "/* " << Reg->getName() << "_SubRegsSet */ " << SubRegIndex
               << ", ";
            // FIXME not very nice to recalculate this
            SetVector<CodeGenRegister*> SR;
            Reg->addSubRegsPreOrder(SR, RegBank);
            SubRegIndex += SR.size() + 1;
        } else
            OS << "/* Empty_SubRegsSet */ 0, ";
        if (!Reg->getSuperRegs().empty()) {
            OS << "/* " << Reg->getName() << "_SuperRegsSet */ " << SuperRegIndex;
            SuperRegIndex += Reg->getSuperRegs().size() + 1;
        } else
            OS << "/* Empty_SuperRegsSet */ 0";
        OS << " },\n";
    }
    OS << "};\n\n";      // End of register descriptors...

    ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();

    // Loop over all of the register classes... emitting each one.
    OS << "namespace {     // Register classes...\n";

    // Emit the register enum value arrays for each RegisterClass
    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];
        ArrayRef<Record*> Order = RC.getOrder();

        // Give the register class a legal C name if it's anonymous.
        std::string Name = RC.getName();

        // Emit the register list now.
        OS << "  // " << Name << " Register Class...\n"
           << "  const uint16_t " << Name
           << "[] = {\n    ";
        for (unsigned i = 0, e = Order.size(); i != e; ++i) {
            Record *Reg = Order[i];
            OS << getQualifiedName(Reg) << ", ";
        }
        OS << "\n  };\n\n";

        OS << "  // " << Name << " Bit set.\n"
           << "  const uint8_t " << Name
           << "Bits[] = {\n    ";
        BitVectorEmitter BVE;
        for (unsigned i = 0, e = Order.size(); i != e; ++i) {
            Record *Reg = Order[i];
            BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);
        }
        BVE.print(OS);
        OS << "\n  };\n\n";

    }
    OS << "}\n\n";

    OS << "extern const MCRegisterClass " << TargetName
       << "MCRegisterClasses[] = {\n";

    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];

        // Asserts to make sure values will fit in table assuming types from
        // MCRegisterInfo.h
        assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
        assert((RC.SpillAlignment/8) <= 0xffff && "SpillAlignment too large.");
        assert(RC.CopyCost >= -128 && RC.CopyCost <= 127 && "Copy cost too large.");

        OS << "  { " << '\"' << RC.getName() << "\", "
           << RC.getName() << ", " << RC.getName() << "Bits, "
           << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
           << RC.getQualifiedName() + "RegClassID" << ", "
           << RC.SpillSize/8 << ", "
           << RC.SpillAlignment/8 << ", "
           << RC.CopyCost << ", "
           << RC.Allocatable << " },\n";
    }

    OS << "};\n\n";

    // Emit the data table for getSubReg().
    ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
    if (SubRegIndices.size()) {
        OS << "const uint16_t " << TargetName << "SubRegTable[]["
           << SubRegIndices.size() << "] = {\n";
        for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
            const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs();
            OS << "  /* " << Regs[i]->TheDef->getName() << " */\n";
            if (SRM.empty()) {
                OS << "  {0},\n";
                continue;
            }
            OS << "  {";
            for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) {
                // FIXME: We really should keep this to 80 columns...
                CodeGenRegister::SubRegMap::const_iterator SubReg =
                    SRM.find(SubRegIndices[j]);
                if (SubReg != SRM.end())
                    OS << getQualifiedName(SubReg->second->TheDef);
                else
                    OS << "0";
                if (j != je - 1)
                    OS << ", ";
            }
            OS << "}" << (i != e ? "," : "") << "\n";
        }
        OS << "};\n\n";
        OS << "const uint16_t *get" << TargetName
           << "SubRegTable() {\n  return (const uint16_t *)" << TargetName
           << "SubRegTable;\n}\n\n";
    }

    // MCRegisterInfo initialization routine.
    OS << "static inline void Init" << TargetName
       << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
       << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n";
    OS << "  RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
       << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
       << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, "
       << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet, ";
    if (SubRegIndices.size() != 0)
        OS << "(uint16_t*)" << TargetName << "SubRegTable, "
           << SubRegIndices.size() << ");\n\n";
    else
        OS << "NULL, 0);\n\n";

    EmitRegMapping(OS, Regs, false);

    OS << "}\n\n";

    OS << "} // End llvm namespace \n";
    OS << "#endif // GET_REGINFO_MC_DESC\n\n";
}
//
// runMCDesc - Print out MC register descriptions.
//
void
RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
                               CodeGenRegBank &RegBank) {
  EmitSourceFileHeader("MC Register Information", OS);

  OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
  OS << "#undef GET_REGINFO_MC_DESC\n";

  std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
  RegBank.computeOverlaps(Overlaps);

  OS << "namespace llvm {\n\n";

  const std::string &TargetName = Target.getName();

  OS << "\nnamespace {\n";

  const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();

  // Emit an overlap list for all registers.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    const CodeGenRegister *Reg = Regs[i];
    const CodeGenRegister::Set &O = Overlaps[Reg];
    // Move Reg to the front so TRI::getAliasSet can share the list.
    OS << "  const unsigned " << Reg->getName() << "_Overlaps[] = { "
       << getQualifiedName(Reg->TheDef) << ", ";
    for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
         I != E; ++I)
      if (*I != Reg)
        OS << getQualifiedName((*I)->TheDef) << ", ";
    OS << "0 };\n";
  }

  // Emit the empty sub-registers list
  OS << "  const unsigned Empty_SubRegsSet[] = { 0 };\n";
  // Loop over all of the registers which have sub-registers, emitting the
  // sub-registers list to memory.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    const CodeGenRegister &Reg = *Regs[i];
    if (Reg.getSubRegs().empty())
     continue;
    // getSubRegs() orders by SubRegIndex. We want a topological order.
    SetVector<CodeGenRegister*> SR;
    Reg.addSubRegsPreOrder(SR);
    OS << "  const unsigned " << Reg.getName() << "_SubRegsSet[] = { ";
    for (unsigned j = 0, je = SR.size(); j != je; ++j)
      OS << getQualifiedName(SR[j]->TheDef) << ", ";
    OS << "0 };\n";
  }

  // Emit the empty super-registers list
  OS << "  const unsigned Empty_SuperRegsSet[] = { 0 };\n";
  // Loop over all of the registers which have super-registers, emitting the
  // super-registers list to memory.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    const CodeGenRegister &Reg = *Regs[i];
    const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs();
    if (SR.empty())
      continue;
    OS << "  const unsigned " << Reg.getName() << "_SuperRegsSet[] = { ";
    for (unsigned j = 0, je = SR.size(); j != je; ++j)
      OS << getQualifiedName(SR[j]->TheDef) << ", ";
    OS << "0 };\n";
  }
  OS << "}\n";       // End of anonymous namespace...

  OS << "\nextern const MCRegisterDesc " << TargetName
     << "RegDesc[] = { // Descriptors\n";
  OS << "  { \"NOREG\",\t0,\t0,\t0 },\n";

  // Now that register alias and sub-registers sets have been emitted, emit the
  // register descriptors now.
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    const CodeGenRegister &Reg = *Regs[i];
    OS << "  { \"";
    OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t";
    if (!Reg.getSubRegs().empty())
      OS << Reg.getName() << "_SubRegsSet,\t";
    else
      OS << "Empty_SubRegsSet,\t";
    if (!Reg.getSuperRegs().empty())
      OS << Reg.getName() << "_SuperRegsSet";
    else
      OS << "Empty_SuperRegsSet";
    OS << " },\n";
  }
  OS << "};\n\n";      // End of register descriptors...

  ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();

  // Loop over all of the register classes... emitting each one.
  OS << "namespace {     // Register classes...\n";

  // Emit the register enum value arrays for each RegisterClass
  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
    const CodeGenRegisterClass &RC = *RegisterClasses[rc];
    ArrayRef<Record*> Order = RC.getOrder();

    // Give the register class a legal C name if it's anonymous.
    std::string Name = RC.getName();

    // Emit the register list now.
    OS << "  // " << Name << " Register Class...\n"
       << "  static const unsigned " << Name
       << "[] = {\n    ";
    for (unsigned i = 0, e = Order.size(); i != e; ++i) {
      Record *Reg = Order[i];
      OS << getQualifiedName(Reg) << ", ";
    }
    OS << "\n  };\n\n";

    OS << "  // " << Name << " Bit set.\n"
       << "  static const unsigned char " << Name
       << "Bits[] = {\n    ";
    BitVectorEmitter BVE;
    for (unsigned i = 0, e = Order.size(); i != e; ++i) {
      Record *Reg = Order[i];
      BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);
    }
    BVE.print(OS);
    OS << "\n  };\n\n";

  }
  OS << "}\n\n";

  OS << "extern const MCRegisterClass " << TargetName
     << "MCRegisterClasses[] = {\n";

  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
    const CodeGenRegisterClass &RC = *RegisterClasses[rc];
    OS << "  MCRegisterClass(" << RC.getQualifiedName() + "RegClassID" << ", "
       << '\"' << RC.getName() << "\", "
       << RC.SpillSize/8 << ", "
       << RC.SpillAlignment/8 << ", "
       << RC.CopyCost << ", "
       << RC.Allocatable << ", "
       << RC.getName() << ", " << RC.getName() << " + "
       << RC.getOrder().size() << ", "
       << RC.getName() << "Bits, sizeof(" << RC.getName() << "Bits)"
       << "),\n";
  }

  OS << "};\n\n";

  // MCRegisterInfo initialization routine.
  OS << "static inline void Init" << TargetName
     << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
     << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n";
  OS << "  RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
     << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
     << RegisterClasses.size() << ");\n\n";

  EmitRegMapping(OS, Regs, false);

  OS << "}\n\n";


  OS << "} // End llvm namespace \n";
  OS << "#endif // GET_REGINFO_MC_DESC\n\n";
}
//
// runMCDesc - Print out MC register descriptions.
//
void
RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
                               CodeGenRegBank &RegBank) {
    EmitSourceFileHeader("MC Register Information", OS);

    OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
    OS << "#undef GET_REGINFO_MC_DESC\n";

    const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
    std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
    RegBank.computeOverlaps(Overlaps);

    // The lists of sub-registers, super-registers, and overlaps all go in the
    // same array. That allows us to share suffixes.
    typedef std::vector<const CodeGenRegister*> RegVec;
    SmallVector<RegVec, 4> SubRegLists(Regs.size());
    SmallVector<RegVec, 4> OverlapLists(Regs.size());
    SequenceToOffsetTable<RegVec, CodeGenRegister::Less> RegSeqs;

    // Precompute register lists for the SequenceToOffsetTable.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister *Reg = Regs[i];

        // Compute the ordered sub-register list.
        SetVector<const CodeGenRegister*> SR;
        Reg->addSubRegsPreOrder(SR, RegBank);
        RegVec &SubRegList = SubRegLists[i];
        SubRegList.assign(SR.begin(), SR.end());
        RegSeqs.add(SubRegList);

        // Super-registers are already computed.
        const RegVec &SuperRegList = Reg->getSuperRegs();
        RegSeqs.add(SuperRegList);

        // The list of overlaps doesn't need to have any particular order, except
        // Reg itself must be the first element. Pick an ordering that has one of
        // the other lists as a suffix.
        RegVec &OverlapList = OverlapLists[i];
        const RegVec &Suffix = SubRegList.size() > SuperRegList.size() ?
                               SubRegList : SuperRegList;
        CodeGenRegister::Set Omit(Suffix.begin(), Suffix.end());

        // First element is Reg itself.
        OverlapList.push_back(Reg);
        Omit.insert(Reg);

        // Any elements not in Suffix.
        const CodeGenRegister::Set &OSet = Overlaps[Reg];
        std::set_difference(OSet.begin(), OSet.end(),
                            Omit.begin(), Omit.end(),
                            std::back_inserter(OverlapList),
                            CodeGenRegister::Less());

        // Finally, Suffix itself.
        OverlapList.insert(OverlapList.end(), Suffix.begin(), Suffix.end());
        RegSeqs.add(OverlapList);
    }

    // Compute the final layout of the sequence table.
    RegSeqs.layout();

    OS << "namespace llvm {\n\n";

    const std::string &TargetName = Target.getName();

    // Emit the shared table of register lists.
    OS << "extern const uint16_t " << TargetName << "RegLists[] = {\n";
    RegSeqs.emit(OS, printRegister);
    OS << "};\n\n";

    OS << "extern const MCRegisterDesc " << TargetName
       << "RegDesc[] = { // Descriptors\n";
    OS << "  { \"NOREG\", 0, 0, 0 },\n";

    // Emit the register descriptors now.
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister *Reg = Regs[i];
        OS << "  { \"" << Reg->getName() << "\", "
           << RegSeqs.get(OverlapLists[i]) << ", "
           << RegSeqs.get(SubRegLists[i]) << ", "
           << RegSeqs.get(Reg->getSuperRegs()) << " },\n";
    }
    OS << "};\n\n";      // End of register descriptors...

    ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();

    // Loop over all of the register classes... emitting each one.
    OS << "namespace {     // Register classes...\n";

    // Emit the register enum value arrays for each RegisterClass
    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];
        ArrayRef<Record*> Order = RC.getOrder();

        // Give the register class a legal C name if it's anonymous.
        std::string Name = RC.getName();

        // Emit the register list now.
        OS << "  // " << Name << " Register Class...\n"
           << "  const uint16_t " << Name
           << "[] = {\n    ";
        for (unsigned i = 0, e = Order.size(); i != e; ++i) {
            Record *Reg = Order[i];
            OS << getQualifiedName(Reg) << ", ";
        }
        OS << "\n  };\n\n";

        OS << "  // " << Name << " Bit set.\n"
           << "  const uint8_t " << Name
           << "Bits[] = {\n    ";
        BitVectorEmitter BVE;
        for (unsigned i = 0, e = Order.size(); i != e; ++i) {
            Record *Reg = Order[i];
            BVE.add(Target.getRegBank().getReg(Reg)->EnumValue);
        }
        BVE.print(OS);
        OS << "\n  };\n\n";

    }
    OS << "}\n\n";

    OS << "extern const MCRegisterClass " << TargetName
       << "MCRegisterClasses[] = {\n";

    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];

        // Asserts to make sure values will fit in table assuming types from
        // MCRegisterInfo.h
        assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
        assert((RC.SpillAlignment/8) <= 0xffff && "SpillAlignment too large.");
        assert(RC.CopyCost >= -128 && RC.CopyCost <= 127 && "Copy cost too large.");

        OS << "  { " << '\"' << RC.getName() << "\", "
           << RC.getName() << ", " << RC.getName() << "Bits, "
           << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
           << RC.getQualifiedName() + "RegClassID" << ", "
           << RC.SpillSize/8 << ", "
           << RC.SpillAlignment/8 << ", "
           << RC.CopyCost << ", "
           << RC.Allocatable << " },\n";
    }

    OS << "};\n\n";

    // Emit the data table for getSubReg().
    ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
    if (SubRegIndices.size()) {
        OS << "const uint16_t " << TargetName << "SubRegTable[]["
           << SubRegIndices.size() << "] = {\n";
        for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
            const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs();
            OS << "  /* " << Regs[i]->TheDef->getName() << " */\n";
            if (SRM.empty()) {
                OS << "  {0},\n";
                continue;
            }
            OS << "  {";
            for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) {
                // FIXME: We really should keep this to 80 columns...
                CodeGenRegister::SubRegMap::const_iterator SubReg =
                    SRM.find(SubRegIndices[j]);
                if (SubReg != SRM.end())
                    OS << getQualifiedName(SubReg->second->TheDef);
                else
                    OS << "0";
                if (j != je - 1)
                    OS << ", ";
            }
            OS << "}" << (i != e ? "," : "") << "\n";
        }
        OS << "};\n\n";
        OS << "const uint16_t *get" << TargetName
           << "SubRegTable() {\n  return (const uint16_t *)" << TargetName
           << "SubRegTable;\n}\n\n";
    }

    EmitRegMappingTables(OS, Regs, false);

    // MCRegisterInfo initialization routine.
    OS << "static inline void Init" << TargetName
       << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
       << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n";
    OS << "  RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
       << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
       << RegisterClasses.size() << ", " << TargetName << "RegLists, ";
    if (SubRegIndices.size() != 0)
        OS << "(uint16_t*)" << TargetName << "SubRegTable, "
           << SubRegIndices.size() << ");\n\n";
    else
        OS << "NULL, 0);\n\n";

    EmitRegMapping(OS, Regs, false);

    OS << "}\n\n";

    OS << "} // End llvm namespace \n";
    OS << "#endif // GET_REGINFO_MC_DESC\n\n";
}