+ switch (*I) {
+ default:
+ PrintFatalError("invalid decode table opcode");
+ case MCD::OPC_ExtractField: {
+ ++I;
+ unsigned Start = *I++;
+ unsigned Len = *I++;
+ OS.indent(Indentation) << "MCD::OPC_ExtractField, " << Start << ", "
+ << Len << ", // Inst{";
+ if (Len > 1)
+ OS << (Start + Len - 1) << "-";
+ OS << Start << "} ...\n";
+ break;
+ }
+ case MCD::OPC_FilterValue: {
+ ++I;
+ OS.indent(Indentation) << "MCD::OPC_FilterValue, ";
+ // The filter value is ULEB128 encoded.
+ while (*I >= 128)
+ OS << utostr(*I++) << ", ";
+ OS << utostr(*I++) << ", ";
+
+ // 16-bit numtoskip value.
+ uint8_t Byte = *I++;
+ uint32_t NumToSkip = Byte;
+ OS << utostr(Byte) << ", ";
+ Byte = *I++;
+ OS << utostr(Byte) << ", ";
+ NumToSkip |= Byte << 8;
+ OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
+ break;
+ }
+ case MCD::OPC_CheckField: {
+ ++I;
+ unsigned Start = *I++;
+ unsigned Len = *I++;
+ OS.indent(Indentation) << "MCD::OPC_CheckField, " << Start << ", "
+ << Len << ", ";// << Val << ", " << NumToSkip << ",\n";
+ // ULEB128 encoded field value.
+ for (; *I >= 128; ++I)
+ OS << utostr(*I) << ", ";
+ OS << utostr(*I++) << ", ";
+ // 16-bit numtoskip value.
+ uint8_t Byte = *I++;
+ uint32_t NumToSkip = Byte;
+ OS << utostr(Byte) << ", ";
+ Byte = *I++;
+ OS << utostr(Byte) << ", ";
+ NumToSkip |= Byte << 8;
+ OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
+ break;
+ }
+ case MCD::OPC_CheckPredicate: {
+ ++I;
+ OS.indent(Indentation) << "MCD::OPC_CheckPredicate, ";
+ for (; *I >= 128; ++I)
+ OS << utostr(*I) << ", ";
+ OS << utostr(*I++) << ", ";
+
+ // 16-bit numtoskip value.
+ uint8_t Byte = *I++;
+ uint32_t NumToSkip = Byte;
+ OS << utostr(Byte) << ", ";
+ Byte = *I++;
+ OS << utostr(Byte) << ", ";
+ NumToSkip |= Byte << 8;
+ OS << "// Skip to: " << ((I - Table.begin()) + NumToSkip) << "\n";
+ break;
+ }
+ case MCD::OPC_Decode: {
+ ++I;
+ // Extract the ULEB128 encoded Opcode to a buffer.
+ uint8_t Buffer[8], *p = Buffer;
+ while ((*p++ = *I++) >= 128)
+ assert((p - Buffer) <= (ptrdiff_t)sizeof(Buffer)
+ && "ULEB128 value too large!");
+ // Decode the Opcode value.
+ unsigned Opc = decodeULEB128(Buffer);
+ OS.indent(Indentation) << "MCD::OPC_Decode, ";
+ for (p = Buffer; *p >= 128; ++p)
+ OS << utostr(*p) << ", ";
+ OS << utostr(*p) << ", ";
+
+ // Decoder index.
+ for (; *I >= 128; ++I)
+ OS << utostr(*I) << ", ";
+ OS << utostr(*I++) << ", ";
+
+ OS << "// Opcode: "
+ << NumberedInstructions->at(Opc)->TheDef->getName() << "\n";
+ break;
+ }
+ case MCD::OPC_SoftFail: {
+ ++I;
+ OS.indent(Indentation) << "MCD::OPC_SoftFail";
+ // Positive mask
+ uint64_t Value = 0;
+ unsigned Shift = 0;
+ do {
+ OS << ", " << utostr(*I);
+ Value += (*I & 0x7f) << Shift;
+ Shift += 7;
+ } while (*I++ >= 128);
+ if (Value > 127)
+ OS << " /* 0x" << utohexstr(Value) << " */";
+ // Negative mask
+ Value = 0;
+ Shift = 0;
+ do {
+ OS << ", " << utostr(*I);
+ Value += (*I & 0x7f) << Shift;
+ Shift += 7;
+ } while (*I++ >= 128);
+ if (Value > 127)
+ OS << " /* 0x" << utohexstr(Value) << " */";
+ OS << ",\n";
+ break;
+ }
+ case MCD::OPC_Fail: {
+ ++I;
+ OS.indent(Indentation) << "MCD::OPC_Fail,\n";
+ break;
+ }
+ }
+ }
+ OS.indent(Indentation) << "0\n";
+
+ Indentation -= 2;
+
+ OS.indent(Indentation) << "};\n\n";
+}
+
+void FixedLenDecoderEmitter::
+emitPredicateFunction(formatted_raw_ostream &OS, PredicateSet &Predicates,
+ unsigned Indentation) const {
+ // The predicate function is just a big switch statement based on the
+ // input predicate index.
+ OS.indent(Indentation) << "static bool checkDecoderPredicate(unsigned Idx, "
+ << "uint64_t Bits) {\n";
+ Indentation += 2;
+ if (!Predicates.empty()) {
+ OS.indent(Indentation) << "switch (Idx) {\n";
+ OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
+ unsigned Index = 0;
+ for (const auto &Predicate : Predicates) {
+ OS.indent(Indentation) << "case " << Index++ << ":\n";
+ OS.indent(Indentation+2) << "return (" << Predicate << ");\n";
+ }
+ OS.indent(Indentation) << "}\n";
+ } else {
+ // No case statement to emit
+ OS.indent(Indentation) << "llvm_unreachable(\"Invalid index!\");\n";
+ }
+ Indentation -= 2;
+ OS.indent(Indentation) << "}\n\n";
+}
+
+void FixedLenDecoderEmitter::
+emitDecoderFunction(formatted_raw_ostream &OS, DecoderSet &Decoders,
+ unsigned Indentation) const {
+ // The decoder function is just a big switch statement based on the
+ // input decoder index.
+ OS.indent(Indentation) << "template<typename InsnType>\n";
+ OS.indent(Indentation) << "static DecodeStatus decodeToMCInst(DecodeStatus S,"
+ << " unsigned Idx, InsnType insn, MCInst &MI,\n";
+ OS.indent(Indentation) << " uint64_t "
+ << "Address, const void *Decoder) {\n";
+ Indentation += 2;
+ OS.indent(Indentation) << "InsnType tmp;\n";
+ OS.indent(Indentation) << "switch (Idx) {\n";
+ OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
+ unsigned Index = 0;
+ for (const auto &Decoder : Decoders) {
+ OS.indent(Indentation) << "case " << Index++ << ":\n";
+ OS << Decoder;
+ OS.indent(Indentation+2) << "return S;\n";
+ }
+ OS.indent(Indentation) << "}\n";
+ Indentation -= 2;
+ OS.indent(Indentation) << "}\n\n";