+
+ // This command matches one operand so far.
+ InstOpsUsed.push_back(1);
+ }
+ }
+
+ // For each entry of UniqueOperandCommands, there is a set of instructions
+ // that uses it. If the next command of all instructions in the set are
+ // identical, fold it into the command.
+ for (unsigned CommandIdx = 0, e = UniqueOperandCommands.size();
+ CommandIdx != e; ++CommandIdx) {
+
+ for (unsigned Op = 1; ; ++Op) {
+ // Scan for the first instruction in the set.
+ std::vector<unsigned>::iterator NIT =
+ std::find(InstIdxs.begin(), InstIdxs.end(), CommandIdx);
+ if (NIT == InstIdxs.end()) break; // No commonality.
+
+ // If this instruction has no more operands, we isn't anything to merge
+ // into this command.
+ const AsmWriterInst *FirstInst =
+ getAsmWriterInstByID(NIT-InstIdxs.begin());
+ if (!FirstInst || FirstInst->Operands.size() == Op)
+ break;
+
+ // Otherwise, scan to see if all of the other instructions in this command
+ // set share the operand.
+ bool AllSame = true;
+
+ for (NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx);
+ NIT != InstIdxs.end();
+ NIT = std::find(NIT+1, InstIdxs.end(), CommandIdx)) {
+ // Okay, found another instruction in this command set. If the operand
+ // matches, we're ok, otherwise bail out.
+ const AsmWriterInst *OtherInst =
+ getAsmWriterInstByID(NIT-InstIdxs.begin());
+ if (!OtherInst || OtherInst->Operands.size() == Op ||
+ OtherInst->Operands[Op] != FirstInst->Operands[Op]) {
+ AllSame = false;
+ break;
+ }
+ }
+ if (!AllSame) break;
+
+ // Okay, everything in this command set has the same next operand. Add it
+ // to UniqueOperandCommands and remember that it was consumed.
+ std::string Command = " " + FirstInst->Operands[Op].getCode() + "\n";
+
+ // If this is the last operand, emit a return after the code.
+ if (FirstInst->Operands.size() == Op+1)
+ Command += " return true;\n";
+
+ UniqueOperandCommands[CommandIdx] += Command;
+ InstOpsUsed[CommandIdx]++;