1
- // ===- WebAssemblyDisassemblerEmitter.cpp - Disassembler tables -*- C++ -* -===//
1
+ // ===--------------------------------------------------------------------- -===//
2
2
//
3
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
4
// See https://llvm.org/LICENSE.txt for license information.
16
16
#include " WebAssemblyDisassemblerEmitter.h"
17
17
#include " Common/CodeGenInstruction.h"
18
18
#include " llvm/ADT/STLExtras.h"
19
+ #include " llvm/ADT/iterator.h"
19
20
#include " llvm/Support/raw_ostream.h"
20
21
#include " llvm/TableGen/Record.h"
21
22
22
- static constexpr int WebAssemblyInstructionTableSize = 256 ;
23
+ constexpr int WebAssemblyInstructionTableSize = 256 ;
23
24
24
25
void llvm::emitWebAssemblyDisassemblerTables (
25
26
raw_ostream &OS,
@@ -29,8 +30,8 @@ void llvm::emitWebAssemblyDisassemblerTables(
29
30
std::map<unsigned ,
30
31
std::map<unsigned , std::pair<unsigned , const CodeGenInstruction *>>>
31
32
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))) {
34
35
const Record &Def = *CGI.TheDef ;
35
36
if (!Def.getValue (" Inst" ))
36
37
continue ;
@@ -75,27 +76,31 @@ void llvm::emitWebAssemblyDisassemblerTables(
75
76
}
76
77
}
77
78
// Set this instruction as the one to use.
78
- CGIP = {I , &CGI};
79
+ CGIP = {Idx , &CGI};
79
80
}
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
+
93
98
std::vector<std::string> OperandTable, CurOperandList;
94
99
// Output one table per prefix.
95
100
for (const auto &[Prefix, Table] : OpcodeTable) {
96
101
if (Table.empty ())
97
102
continue ;
98
- OS << " WebAssemblyInstruction InstructionTable" << Prefix;
103
+ OS << " constexpr WebAssemblyInstruction InstructionTable" << Prefix;
99
104
OS << " [] = {\n " ;
100
105
for (unsigned I = 0 ; I < WebAssemblyInstructionTableSize; I++) {
101
106
auto InstIt = Table.find (I);
@@ -116,53 +121,43 @@ void llvm::emitWebAssemblyDisassemblerTables(
116
121
}
117
122
// See if we already have stored this sequence before. This is not
118
123
// 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);
134
128
// Store operands if no prior occurrence.
135
- if (OperandStart == OperandTable.size ()) {
129
+ if (SearchI == OperandTable.end ())
136
130
llvm::append_range (OperandTable, CurOperandList);
137
- }
138
- OS << OperandStart;
139
131
} else {
140
132
auto PrefixIt = OpcodeTable.find (I);
141
133
// 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)
143
135
OS << " { 0, ET_Prefix, 0, 0" ;
144
- } else {
136
+ else
145
137
OS << " { 0, ET_Unused, 0, 0" ;
146
- }
147
138
}
148
139
OS << " },\n " ;
149
140
}
150
141
OS << " };\n\n " ;
151
142
}
152
143
// 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)
155
146
OS << " " << Op << " ,\n " ;
156
- }
157
147
OS << " };\n\n " ;
148
+
158
149
// 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
+
161
157
for (const auto &[Prefix, Table] : OpcodeTable) {
162
158
if (Table.empty () || !Prefix)
163
159
continue ;
164
160
OS << " { " << Prefix << " , InstructionTable" << Prefix << " },\n " ;
165
161
}
166
- OS << " { 0, nullptr }\n };\n\n " ;
167
- OS << " } // end namespace llvm\n " ;
162
+ OS << " };\n " ;
168
163
}
0 commit comments