1- // ===- WebAssemblyDisassemblerEmitter.cpp - Disassembler tables -*- C++ -* -===//
1+ // ===--------------------------------------------------------------------- -===//
22//
33// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44// See https://llvm.org/LICENSE.txt for license information.
1616#include " WebAssemblyDisassemblerEmitter.h"
1717#include " Common/CodeGenInstruction.h"
1818#include " llvm/ADT/STLExtras.h"
19+ #include " llvm/ADT/iterator.h"
1920#include " llvm/Support/raw_ostream.h"
2021#include " llvm/TableGen/Record.h"
2122
22- static constexpr int WebAssemblyInstructionTableSize = 256 ;
23+ constexpr int WebAssemblyInstructionTableSize = 256 ;
2324
2425void llvm::emitWebAssemblyDisassemblerTables (
2526 raw_ostream &OS,
@@ -29,8 +30,8 @@ void llvm::emitWebAssemblyDisassemblerTables(
2930 std::map<unsigned ,
3031 std::map<unsigned , std::pair<unsigned , const CodeGenInstruction *>>>
3132 OpcodeTable;
32- for (unsigned I = 0 ; I != NumberedInstructions. size (); ++I) {
33- const CodeGenInstruction &CGI = * NumberedInstructions[I];
33+ for (const auto &[Idx, CGI] :
34+ enumerate( make_pointee_range ( NumberedInstructions))) {
3435 const Record &Def = *CGI.TheDef ;
3536 if (!Def.getValue (" Inst" ))
3637 continue ;
@@ -75,27 +76,31 @@ void llvm::emitWebAssemblyDisassemblerTables(
7576 }
7677 }
7778 // Set this instruction as the one to use.
78- CGIP = {I , &CGI};
79+ CGIP = {Idx , &CGI};
7980 }
80- OS << " #include \" MCTargetDesc/WebAssemblyMCTargetDesc.h\"\n " ;
81- OS << " \n " ;
82- OS << " namespace llvm {\n\n " ;
83- OS << " static constexpr int WebAssemblyInstructionTableSize = " ;
84- OS << WebAssemblyInstructionTableSize << " ;\n\n " ;
85- OS << " enum EntryType : uint8_t { " ;
86- OS << " ET_Unused, ET_Prefix, ET_Instruction };\n\n " ;
87- OS << " struct WebAssemblyInstruction {\n " ;
88- OS << " uint16_t Opcode;\n " ;
89- OS << " EntryType ET;\n " ;
90- OS << " uint8_t NumOperands;\n " ;
91- OS << " uint16_t OperandStart;\n " ;
92- OS << " };\n\n " ;
81+
82+ OS << R"(
83+ #include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
84+
85+ namespace {
86+ enum EntryType : uint8_t { ET_Unused, ET_Prefix, ET_Instruction };
87+
88+ struct WebAssemblyInstruction {
89+ uint16_t Opcode;
90+ EntryType ET;
91+ uint8_t NumOperands;
92+ uint16_t OperandStart;
93+ };
94+ } // end anonymous namespace
95+
96+ )" ;
97+
9398 std::vector<std::string> OperandTable, CurOperandList;
9499 // Output one table per prefix.
95100 for (const auto &[Prefix, Table] : OpcodeTable) {
96101 if (Table.empty ())
97102 continue ;
98- OS << " WebAssemblyInstruction InstructionTable" << Prefix;
103+ OS << " constexpr WebAssemblyInstruction InstructionTable" << Prefix;
99104 OS << " [] = {\n " ;
100105 for (unsigned I = 0 ; I < WebAssemblyInstructionTableSize; I++) {
101106 auto InstIt = Table.find (I);
@@ -116,53 +121,43 @@ void llvm::emitWebAssemblyDisassemblerTables(
116121 }
117122 // See if we already have stored this sequence before. This is not
118123 // strictly necessary but makes the table really small.
119- size_t OperandStart = OperandTable.size ();
120- if (CurOperandList.size () <= OperandTable.size ()) {
121- for (size_t J = 0 ; J <= OperandTable.size () - CurOperandList.size ();
122- ++J) {
123- size_t K = 0 ;
124- for (; K < CurOperandList.size (); ++K) {
125- if (OperandTable[J + K] != CurOperandList[K])
126- break ;
127- }
128- if (K == CurOperandList.size ()) {
129- OperandStart = J;
130- break ;
131- }
132- }
133- }
124+ auto SearchI =
125+ std::search (OperandTable.begin (), OperandTable.end (),
126+ CurOperandList.begin (), CurOperandList.end ());
127+ OS << std::distance (OperandTable.begin (), SearchI);
134128 // Store operands if no prior occurrence.
135- if (OperandStart == OperandTable.size ()) {
129+ if (SearchI == OperandTable.end ())
136130 llvm::append_range (OperandTable, CurOperandList);
137- }
138- OS << OperandStart;
139131 } else {
140132 auto PrefixIt = OpcodeTable.find (I);
141133 // If we have a non-empty table for it that's not 0, this is a prefix.
142- if (PrefixIt != OpcodeTable.end () && I && !Prefix) {
134+ if (PrefixIt != OpcodeTable.end () && I && !Prefix)
143135 OS << " { 0, ET_Prefix, 0, 0" ;
144- } else {
136+ else
145137 OS << " { 0, ET_Unused, 0, 0" ;
146- }
147138 }
148139 OS << " },\n " ;
149140 }
150141 OS << " };\n\n " ;
151142 }
152143 // Create a table of all operands:
153- OS << " const uint8_t OperandTable[] = {\n " ;
154- for (auto &Op : OperandTable) {
144+ OS << " constexpr uint8_t OperandTable[] = {\n " ;
145+ for (const auto &Op : OperandTable)
155146 OS << " " << Op << " ,\n " ;
156- }
157147 OS << " };\n\n " ;
148+
158149 // Create a table of all extension tables:
159- OS << " struct { uint8_t Prefix; const WebAssemblyInstruction *Table; }\n " ;
160- OS << " PrefixTable[] = {\n " ;
150+ OS << R"(
151+ constexpr struct {
152+ uint8_t Prefix;
153+ const WebAssemblyInstruction *Table;
154+ } PrefixTable[] = {
155+ )" ;
156+
161157 for (const auto &[Prefix, Table] : OpcodeTable) {
162158 if (Table.empty () || !Prefix)
163159 continue ;
164160 OS << " { " << Prefix << " , InstructionTable" << Prefix << " },\n " ;
165161 }
166- OS << " { 0, nullptr }\n };\n\n " ;
167- OS << " } // end namespace llvm\n " ;
162+ OS << " };\n " ;
168163}
0 commit comments