Coverage Report

Created: 2025-06-13 06:37

/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_