/src/spirv-tools/source/table2.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2025 The Khronos Group Inc. |
2 | | // Copyright (c) 2025 Google LLC |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | // you may not use this file except in compliance with the License. |
6 | | // You may obtain a copy of the License at |
7 | | // |
8 | | // http://www.apache.org/licenses/LICENSE-2.0 |
9 | | // |
10 | | // Unless required by applicable law or agreed to in writing, software |
11 | | // distributed under the License is distributed on an "AS IS" BASIS, |
12 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | // See the License for the specific language governing permissions and |
14 | | // limitations under the License. |
15 | | |
16 | | #ifndef SOURCE_TABLE2_H_ |
17 | | #define SOURCE_TABLE2_H_ |
18 | | |
19 | | #include "source/latest_version_spirv_header.h" |
20 | | #include "source/util/index_range.h" |
21 | | #include "spirv-tools/libspirv.hpp" |
22 | | |
23 | | // Define the objects that describe the grammatical structure of SPIR-V |
24 | | // instructions and their operands. The objects are owned by static |
25 | | // tables populated at C++ build time from the grammar files from SPIRV-Headers. |
26 | | // |
27 | | // Clients use freestanding methods to lookup an opcode or an operand, either |
28 | | // by numeric value (in the binary), or by name. |
29 | | // |
30 | | // For historical reasons, the opcode lookup can also use a target enviroment |
31 | | // enum to filter for opcodes supported in that environment. |
32 | | // |
33 | | // It should be very fast for the system loader to load (and possibly relocate) |
34 | | // the static tables. In particular, there should be very few global symbols |
35 | | // with independent addresses. Prefer a very few large tables of items rather |
36 | | // than dozens or hundreds of global symbols. |
37 | | // |
38 | | // The overall structure among containers (i.e. skipping scalar data members) |
39 | | // is as follows: |
40 | | // |
41 | | // An OperandDesc describes an operand. |
42 | | // An InstructionDesc desribes an instruction. |
43 | | // An ExtInstDesc describes an extended intruction. |
44 | | // |
45 | | // Both OperandDesc and InstructionDesc have members: |
46 | | // - a name string |
47 | | // - array of alias strings |
48 | | // - array of spv::Capability (as an enum) |
49 | | // - array of spv_operand_type_t (as an enum) |
50 | | // - array of spvtools::Extension (as an enum) |
51 | | // - a minVersion |
52 | | // - a lastVersion |
53 | | // |
54 | | // An OperandDesc also has: |
55 | | // - a uint32_t value. |
56 | | // |
57 | | // An InstructionDesc also has: |
58 | | // - a spv::Op opcode |
59 | | // - a bool hasResult |
60 | | // - a bool hasType |
61 | | // - a printing class |
62 | | // |
63 | | // An ExtInstDesc has: |
64 | | // - a name |
65 | | // - array of spv::Capability (as an enum) |
66 | | // - array of spv_operand_type_t (as an enum) |
67 | | // |
68 | | // The arrays are represented by spans into a global static array, with one |
69 | | // array for each of: |
70 | | // - null-terminated strings, for names |
71 | | // - arrays of null-terminated strings, for alias lists |
72 | | // - spv_operand_type_t |
73 | | // - spv::Capability |
74 | | // - spvtools::Extension |
75 | | // |
76 | | // Note: Currently alias lists never have more than one element. |
77 | | // The data structures and code do not assume this. |
78 | | |
79 | | // TODO(dneto): convert the tables for extended instructions |
80 | | // Currently (as defined in table.h): |
81 | | // An spv_ext_inst_group_t has: |
82 | | // - array of spv_ext_inst_desc_t |
83 | | // |
84 | | // An spv_ext_inst_desc_t has: |
85 | | // - a name string |
86 | | // - array of spv::Capability |
87 | | // - array of spv_operand_type_t |
88 | | |
89 | | namespace spvtools { |
90 | | |
91 | | #include "core_tables_header.inc" |
92 | | |
93 | | using IndexRange = utils::IndexRange<uint32_t, uint32_t>; |
94 | | |
95 | | // Describes a SPIR-V operand. |
96 | | struct OperandDesc { |
97 | | const uint32_t value; |
98 | | |
99 | | const IndexRange operands_range; // Indexes kOperandSpans |
100 | | const IndexRange name_range; // Indexes kStrings |
101 | | const IndexRange aliases_range; // Indexes kAliasSpans |
102 | | const IndexRange capabilities_range; // Indexes kCapabilitySpans |
103 | | // A set of extensions that enable this feature. If empty then this operand |
104 | | // value is in core and its availability is subject to minVersion. The |
105 | | // assembler, binary parser, and disassembler ignore this rule, so you can |
106 | | // freely process invalid modules. |
107 | | const IndexRange extensions_range; // Indexes kExtensionSpans |
108 | | // Minimal core SPIR-V version required for this feature, if without |
109 | | // extensions. ~0u means reserved for future use. ~0u and non-empty |
110 | | // extension lists means only available in extensions. |
111 | | const uint32_t minVersion = 0xFFFFFFFFu; |
112 | | const uint32_t lastVersion = 0xFFFFFFFFu; |
113 | | utils::Span<const spv_operand_type_t> operands() const; |
114 | | utils::Span<const char> name() const; |
115 | | utils::Span<const IndexRange> aliases() const; |
116 | | utils::Span<const spv::Capability> capabilities() const; |
117 | | utils::Span<const spvtools::Extension> extensions() const; |
118 | | |
119 | | constexpr OperandDesc(uint32_t v, IndexRange o, IndexRange n, IndexRange a, |
120 | | IndexRange c, IndexRange e, uint32_t mv, uint32_t lv) |
121 | | : value(v), |
122 | | operands_range(o), |
123 | | name_range(n), |
124 | | aliases_range(a), |
125 | | capabilities_range(c), |
126 | | extensions_range(e), |
127 | | minVersion(mv), |
128 | 0 | lastVersion(lv) {} |
129 | | |
130 | 24.3k | constexpr OperandDesc(uint32_t v) : value(v) {} |
131 | | |
132 | | OperandDesc(const OperandDesc&) = delete; |
133 | | OperandDesc(OperandDesc&&) = delete; |
134 | | }; |
135 | | |
136 | | // Describes an Instruction |
137 | | struct InstructionDesc { |
138 | | const spv::Op opcode; |
139 | | const bool hasResult = false; |
140 | | const bool hasType = false; |
141 | | |
142 | | const IndexRange operands_range; // Indexes kOperandSpans |
143 | | const IndexRange name_range; // Indexes kStrings |
144 | | const IndexRange aliases_range; // Indexes kAliasSpans |
145 | | const IndexRange capabilities_range; // Indexes kCapbilitySpans |
146 | | // A set of extensions that enable this feature. If empty then this operand |
147 | | // value is in core and its availability is subject to minVersion. The |
148 | | // assembler, binary parser, and disassembler ignore this rule, so you can |
149 | | // freely process invalid modules. |
150 | | const IndexRange extensions_range; // Indexes kExtensionSpans |
151 | | // Minimal core SPIR-V version required for this feature, if without |
152 | | // extensions. ~0u means reserved for future use. ~0u and non-empty |
153 | | // extension lists means only available in extensions. |
154 | | const uint32_t minVersion = 0xFFFFFFFFu; |
155 | | const uint32_t lastVersion = 0xFFFFFFFFu; |
156 | | // The printing class specifies what kind of instruction it is, e.g. what |
157 | | // section of the SPIR-V spec. E.g. kImage, kComposite |
158 | | const PrintingClass printingClass = PrintingClass::kReserved; |
159 | | // Returns the span of elements in the global grammar tables corresponding |
160 | | // to the privately-stored index ranges |
161 | | utils::Span<const spv_operand_type_t> operands() const; |
162 | | utils::Span<const char> name() const; |
163 | | utils::Span<const IndexRange> aliases() const; |
164 | | utils::Span<const spv::Capability> capabilities() const; |
165 | | utils::Span<const spvtools::Extension> extensions() const; |
166 | | |
167 | | constexpr InstructionDesc(spv::Op oc, bool hr, bool ht, IndexRange o, |
168 | | IndexRange n, IndexRange a, IndexRange c, |
169 | | IndexRange e, uint32_t mv, uint32_t lv, |
170 | | PrintingClass pc) |
171 | | : opcode(oc), |
172 | | hasResult(hr), |
173 | | hasType(ht), |
174 | | operands_range(o), |
175 | | name_range(n), |
176 | | aliases_range(a), |
177 | | capabilities_range(c), |
178 | | extensions_range(e), |
179 | | minVersion(mv), |
180 | | lastVersion(lv), |
181 | 0 | printingClass(pc) {} |
182 | | |
183 | 2.64k | constexpr InstructionDesc(spv::Op oc) : opcode(oc) {} |
184 | | |
185 | | InstructionDesc(const InstructionDesc&) = delete; |
186 | | InstructionDesc(InstructionDesc&&) = delete; |
187 | | }; |
188 | | |
189 | | // Describes an extended instruction |
190 | | struct ExtInstDesc { |
191 | | const uint32_t value; |
192 | | const IndexRange operands_range; // Indexes kOperandSpans |
193 | | const IndexRange name_range; // Indexes kStrings |
194 | | const IndexRange capabilities_range; // Indexes kCapbilitySpans |
195 | | // Returns the span of elements in the global grammar tables corresponding |
196 | | // to the privately-stored index ranges |
197 | | utils::Span<const spv_operand_type_t> operands() const; |
198 | | utils::Span<const char> name() const; |
199 | | utils::Span<const spv::Capability> capabilities() const; |
200 | | |
201 | | constexpr ExtInstDesc(uint32_t v, IndexRange o, IndexRange n, IndexRange c) |
202 | 0 | : value(v), operands_range(o), name_range(n), capabilities_range(c) {} |
203 | | |
204 | 0 | constexpr ExtInstDesc(uint32_t v) : value(v) {} |
205 | | |
206 | | ExtInstDesc(const ExtInstDesc&) = delete; |
207 | | ExtInstDesc(ExtInstDesc&&) = delete; |
208 | | }; |
209 | | |
210 | | // Finds the instruction description by opcode name. The name should not |
211 | | // have the "Op" prefix. On success, returns SPV_SUCCESS and updates *desc. |
212 | | spv_result_t LookupOpcode(const char* name, const InstructionDesc** desc); |
213 | | // Finds the instruction description by opcode value. |
214 | | // On success, returns SPV_SUCCESS and updates *desc. |
215 | | spv_result_t LookupOpcode(spv::Op opcode, const InstructionDesc** desc); |
216 | | |
217 | | // Finds the instruction description by opcode name, without the "Op" prefix. |
218 | | // A lookup will succeed if: |
219 | | // - The instruction exists, and |
220 | | // - Either the target environment supports the SPIR-V version of the |
221 | | // instruction, |
222 | | // or the instruction is enabled by at least one extension, |
223 | | // or the instruction is enabled by at least one capability., |
224 | | // On success, returns SPV_SUCCESS and updates *desc. |
225 | | spv_result_t LookupOpcodeForEnv(spv_target_env env, const char* name, |
226 | | const InstructionDesc** desc); |
227 | | |
228 | | // Finds the instruction description by opcode value. |
229 | | // A lookup will succeed if: |
230 | | // - The instruction exists, and |
231 | | // - Either the target environment supports the SPIR-V version of the |
232 | | // instruction, |
233 | | // or the instruction is enabled by at least one extension, |
234 | | // or the instruction is enabled by at least one capability., |
235 | | // On success, returns SPV_SUCCESS and updates *desc. |
236 | | spv_result_t LookupOpcodeForEnv(spv_target_env env, spv::Op, |
237 | | const InstructionDesc** desc); |
238 | | |
239 | | spv_result_t LookupOperand(spv_operand_type_t type, const char* name, |
240 | | size_t name_len, const OperandDesc** desc); |
241 | | spv_result_t LookupOperand(spv_operand_type_t type, uint32_t operand, |
242 | | const OperandDesc** desc); |
243 | | |
244 | | // Finds the extended instruction description by opcode name. |
245 | | // On success, returns SPV_SUCCESS and updates *desc. |
246 | | spv_result_t LookupExtInst(spv_ext_inst_type_t type, const char* name, |
247 | | const ExtInstDesc** desc); |
248 | | // Finds the extended instruction description by opcode value. |
249 | | // On success, returns SPV_SUCCESS and updates *desc. |
250 | | spv_result_t LookupExtInst(spv_ext_inst_type_t type, uint32_t value, |
251 | | const ExtInstDesc** desc); |
252 | | |
253 | | // Finds Extension enum corresponding to |str|. Returns false if not found. |
254 | | bool GetExtensionFromString(const char* str, Extension* extension); |
255 | | |
256 | | // Returns text string corresponding to |extension|. |
257 | | const char* ExtensionToString(Extension extension); |
258 | | |
259 | | } // namespace spvtools |
260 | | #endif // SOURCE_TABLE2_H_ |