+ // Get the instruction numbering.
+ Target.getInstructionsByEnumValue(NumberedInstructions);
+
+ // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not
+ // all machine instructions are necessarily being printed, so there may be
+ // target instructions not in this map.
+ for (unsigned i = 0, e = Instructions.size(); i != e; ++i)
+ CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i]));
+
+ // Build an aggregate string, and build a table of offsets into it.
+ std::map<std::string, unsigned> StringOffset;
+ std::string AggregateString;
+ AggregateString.push_back(0); // "\0"
+ AggregateString.push_back(0); // "\0"
+
+ /// OpcodeInfo - This encodes the index of the string to use for the first
+ /// chunk of the output as well as indices used for operand printing.
+ std::vector<unsigned> OpcodeInfo;
+
+ unsigned MaxStringIdx = 0;
+ for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ AsmWriterInst *AWI = CGIAWIMap[NumberedInstructions[i]];
+ unsigned Idx;
+ if (AWI == 0) {
+ // Something not handled by the asmwriter printer.
+ Idx = 0;
+ } else if (AWI->Operands[0].OperandType !=
+ AsmWriterOperand::isLiteralTextOperand ||
+ AWI->Operands[0].Str.empty()) {
+ // Something handled by the asmwriter printer, but with no leading string.
+ Idx = 1;
+ } else {
+ unsigned &Entry = StringOffset[AWI->Operands[0].Str];
+ if (Entry == 0) {
+ // Add the string to the aggregate if this is the first time found.
+ MaxStringIdx = Entry = AggregateString.size();
+ std::string Str = AWI->Operands[0].Str;
+ UnescapeString(Str);
+ AggregateString += Str;
+ AggregateString += '\0';
+ }
+ Idx = Entry;
+
+ // Nuke the string from the operand list. It is now handled!
+ AWI->Operands.erase(AWI->Operands.begin());
+ }
+ OpcodeInfo.push_back(Idx);
+ }
+
+ // Figure out how many bits we used for the string index.
+ unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+1);
+
+ // To reduce code size, we compactify common instructions into a few bits
+ // in the opcode-indexed table.
+ unsigned BitsLeft = 32-AsmStrBits;
+
+ std::vector<std::vector<std::string> > TableDrivenOperandPrinters;
+
+ bool isFirst = true;
+ while (1) {
+ std::vector<std::string> UniqueOperandCommands;
+
+ // For the first operand check, add a default value for instructions with
+ // just opcode strings to use.
+ if (isFirst) {
+ UniqueOperandCommands.push_back(" return true;\n");
+ isFirst = false;
+ }
+
+ std::vector<unsigned> InstIdxs;
+ std::vector<unsigned> NumInstOpsHandled;
+ FindUniqueOperandCommands(UniqueOperandCommands, InstIdxs,
+ NumInstOpsHandled);
+
+ // If we ran out of operands to print, we're done.
+ if (UniqueOperandCommands.empty()) break;
+
+ // Compute the number of bits we need to represent these cases, this is
+ // ceil(log2(numentries)).
+ unsigned NumBits = Log2_32_Ceil(UniqueOperandCommands.size());
+
+ // If we don't have enough bits for this operand, don't include it.
+ if (NumBits > BitsLeft) {
+ DOUT << "Not enough bits to densely encode " << NumBits
+ << " more bits\n";
+ break;
+ }
+
+ // Otherwise, we can include this in the initial lookup table. Add it in.
+ BitsLeft -= NumBits;
+ for (unsigned i = 0, e = InstIdxs.size(); i != e; ++i)
+ if (InstIdxs[i] != ~0U)
+ OpcodeInfo[i] |= InstIdxs[i] << (BitsLeft+AsmStrBits);
+
+ // Remove the info about this operand.
+ for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ if (AsmWriterInst *Inst = getAsmWriterInstByID(i))
+ if (!Inst->Operands.empty()) {
+ unsigned NumOps = NumInstOpsHandled[InstIdxs[i]];
+ assert(NumOps <= Inst->Operands.size() &&
+ "Can't remove this many ops!");
+ Inst->Operands.erase(Inst->Operands.begin(),
+ Inst->Operands.begin()+NumOps);
+ }
+ }
+
+ // Remember the handlers for this set of operands.
+ TableDrivenOperandPrinters.push_back(UniqueOperandCommands);
+ }
+
+
+
+ O<<" static const unsigned OpInfo[] = {\n";
+ for (unsigned i = 0, e = NumberedInstructions.size(); i != e; ++i) {
+ O << " " << OpcodeInfo[i] << "U,\t// "
+ << NumberedInstructions[i]->TheDef->getName() << "\n";
+ }
+ // Add a dummy entry so the array init doesn't end with a comma.
+ O << " 0U\n";
+ O << " };\n\n";
+
+ // Emit the string itself.
+ O << " const char *AsmStrs = \n \"";
+ unsigned CharsPrinted = 0;
+ EscapeString(AggregateString);
+ for (unsigned i = 0, e = AggregateString.size(); i != e; ++i) {
+ if (CharsPrinted > 70) {
+ O << "\"\n \"";
+ CharsPrinted = 0;
+ }
+ O << AggregateString[i];
+ ++CharsPrinted;
+
+ // Print escape sequences all together.
+ if (AggregateString[i] == '\\') {
+ assert(i+1 < AggregateString.size() && "Incomplete escape sequence!");
+ if (isdigit(AggregateString[i+1])) {
+ assert(isdigit(AggregateString[i+2]) && isdigit(AggregateString[i+3]) &&
+ "Expected 3 digit octal escape!");
+ O << AggregateString[++i];
+ O << AggregateString[++i];
+ O << AggregateString[++i];
+ CharsPrinted += 3;
+ } else {
+ O << AggregateString[++i];
+ ++CharsPrinted;
+ }
+ }
+ }
+ O << "\";\n\n";
+
+ O << " if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {\n"
+ << " O << \"\\t\";\n"
+ << " printInlineAsm(MI);\n"
+ << " return true;\n"
+ << " } else if (MI->isLabel()) {\n"
+ << " printLabel(MI);\n"
+ << " return true;\n"
+ << " } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) {\n"
+ << " printDeclare(MI);\n"
+ << " return true;\n"
+ << " } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {\n"
+ << " printImplicitDef(MI);\n"
+ << " return true;\n"
+ << " }\n\n";
+
+ O << " O << \"\\t\";\n\n";
+
+ O << " // Emit the opcode for the instruction.\n"
+ << " unsigned Bits = OpInfo[MI->getOpcode()];\n"
+ << " if (Bits == 0) return false;\n"
+ << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ");\n\n";
+
+ // Output the table driven operand information.
+ BitsLeft = 32-AsmStrBits;
+ for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) {
+ std::vector<std::string> &Commands = TableDrivenOperandPrinters[i];
+
+ // Compute the number of bits we need to represent these cases, this is
+ // ceil(log2(numentries)).
+ unsigned NumBits = Log2_32_Ceil(Commands.size());
+ assert(NumBits <= BitsLeft && "consistency error");
+
+ // Emit code to extract this field from Bits.
+ BitsLeft -= NumBits;
+
+ O << "\n // Fragment " << i << " encoded into " << NumBits
+ << " bits for " << Commands.size() << " unique commands.\n";
+
+ if (Commands.size() == 2) {
+ // Emit two possibilitys with if/else.
+ O << " if ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+ << ((1 << NumBits)-1) << ") {\n"
+ << Commands[1]
+ << " } else {\n"
+ << Commands[0]
+ << " }\n\n";
+ } else {
+ O << " switch ((Bits >> " << (BitsLeft+AsmStrBits) << ") & "
+ << ((1 << NumBits)-1) << ") {\n"
+ << " default: // unreachable.\n";
+
+ // Print out all the cases.
+ for (unsigned i = 0, e = Commands.size(); i != e; ++i) {
+ O << " case " << i << ":\n";
+ O << Commands[i];
+ O << " break;\n";
+ }
+ O << " }\n\n";
+ }
+ }
+
+ // Okay, delete instructions with no operand info left.
+ for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
+ // Entire instruction has been emitted?
+ AsmWriterInst &Inst = Instructions[i];
+ if (Inst.Operands.empty()) {
+ Instructions.erase(Instructions.begin()+i);
+ --i; --e;
+ }
+ }
+
+
+ // Because this is a vector, we want to emit from the end. Reverse all of the