blob: cdb99a7a53c7285836b819b21e1fbbfe87d567f4 [file] [log] [blame]
Dejan Mircevskib6fe02f2016-01-07 13:44:22 -05001// Copyright (c) 2015-2016 The Khronos Group Inc.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01002//
David Neto9fc86582016-09-01 15:33:59 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01006//
David Neto9fc86582016-09-01 15:33:59 -04007// http://www.apache.org/licenses/LICENSE-2.0
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +01008//
David Neto9fc86582016-09-01 15:33:59 -04009// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010014
15#include "operand.h"
16
17#include <assert.h>
18#include <string.h>
Chris Forbes78338d52017-06-27 16:28:22 -070019#include <algorithm>
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010020
Lei Zhangca1bf942016-04-27 16:47:13 -040021#include "macro.h"
David Netoba73a7c2016-01-06 13:08:39 -050022
David Neto00fa3932018-02-09 14:29:02 -050023// For now, assume unified1 contains up to SPIR-V 1.3 and no later
24// SPIR-V version.
25// TODO(dneto): Make one set of tables, but with version tags on a
26// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
27
Lei Zhang16981f82017-09-21 17:24:57 -040028#include "operand.kinds-1.0.inc"
29#include "operand.kinds-1.1.inc"
30#include "operand.kinds-1.2.inc"
David Neto00fa3932018-02-09 14:29:02 -050031#include "operand.kinds-unified1.inc"
Lei Zhang16981f82017-09-21 17:24:57 -040032
Lei Zhang063dbea2017-10-25 12:15:51 -040033static const spv_operand_table_t kTable_1_0 = {
34 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_0),
35 pygen_variable_OperandInfoTable_1_0};
36static const spv_operand_table_t kTable_1_1 = {
37 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_1),
38 pygen_variable_OperandInfoTable_1_1};
39static const spv_operand_table_t kTable_1_2 = {
40 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_2),
41 pygen_variable_OperandInfoTable_1_2};
David Neto00fa3932018-02-09 14:29:02 -050042static const spv_operand_table_t kTable_1_3 = {
43 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_3),
44 pygen_variable_OperandInfoTable_1_3};
Lei Zhang063dbea2017-10-25 12:15:51 -040045
46spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
47 spv_target_env env) {
48 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010049
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040050 switch (env) {
51 case SPV_ENV_UNIVERSAL_1_0:
52 case SPV_ENV_VULKAN_1_0:
Pierre Moreau12447d82017-11-30 00:49:23 +010053 case SPV_ENV_OPENCL_1_2:
54 case SPV_ENV_OPENCL_EMBEDDED_1_2:
55 case SPV_ENV_OPENCL_2_0:
56 case SPV_ENV_OPENCL_EMBEDDED_2_0:
David Netoc2967012016-08-05 18:19:30 -040057 case SPV_ENV_OPENCL_2_1:
Pierre Moreau12447d82017-11-30 00:49:23 +010058 case SPV_ENV_OPENCL_EMBEDDED_2_1:
David Netoc2967012016-08-05 18:19:30 -040059 case SPV_ENV_OPENGL_4_0:
60 case SPV_ENV_OPENGL_4_1:
61 case SPV_ENV_OPENGL_4_2:
62 case SPV_ENV_OPENGL_4_3:
63 case SPV_ENV_OPENGL_4_5:
Lei Zhang063dbea2017-10-25 12:15:51 -040064 *pOperandTable = &kTable_1_0;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040065 return SPV_SUCCESS;
66 case SPV_ENV_UNIVERSAL_1_1:
Lei Zhang063dbea2017-10-25 12:15:51 -040067 *pOperandTable = &kTable_1_1;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040068 return SPV_SUCCESS;
David Netodbc20492017-03-14 12:43:41 -040069 case SPV_ENV_UNIVERSAL_1_2:
70 case SPV_ENV_OPENCL_2_2:
Pierre Moreau12447d82017-11-30 00:49:23 +010071 case SPV_ENV_OPENCL_EMBEDDED_2_2:
Lei Zhang063dbea2017-10-25 12:15:51 -040072 *pOperandTable = &kTable_1_2;
David Netodbc20492017-03-14 12:43:41 -040073 return SPV_SUCCESS;
David Neto00fa3932018-02-09 14:29:02 -050074 case SPV_ENV_UNIVERSAL_1_3:
75 case SPV_ENV_VULKAN_1_1:
76 *pOperandTable = &kTable_1_3;
77 return SPV_SUCCESS;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040078 }
79 assert(0 && "Unknown spv_target_env in spvOperandTableGet()");
80 return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010081}
82
Dejan Mircevski3e6b2df2016-01-07 11:00:38 -050083#undef ARRAY_SIZE
84
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010085spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
86 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040087 const char* name,
88 const size_t nameLength,
89 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040090 if (!table) return SPV_ERROR_INVALID_TABLE;
91 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010092
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010093 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040094 const auto& group = table->types[typeIndex];
95 if (type != group.type) continue;
96 for (uint64_t index = 0; index < group.count; ++index) {
97 const auto& entry = group.entries[index];
98 if (nameLength == strlen(entry.name) &&
99 !strncmp(entry.name, name, nameLength)) {
100 *pEntry = &entry;
101 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100102 }
103 }
104 }
105
106 return SPV_ERROR_INVALID_LOOKUP;
107}
108
109spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
110 const spv_operand_type_t type,
111 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -0400112 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400113 if (!table) return SPV_ERROR_INVALID_TABLE;
114 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100115
116 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400117 const auto& group = table->types[typeIndex];
118 if (type != group.type) continue;
119 for (uint64_t index = 0; index < group.count; ++index) {
120 const auto& entry = group.entries[index];
121 if (value == entry.value) {
122 *pEntry = &entry;
123 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100124 }
125 }
126 }
127
128 return SPV_ERROR_INVALID_LOOKUP;
129}
130
Dejan Mircevski50babb22015-09-29 10:56:32 -0400131const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100132 switch (type) {
133 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400134 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400135 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500136 case SPV_OPERAND_TYPE_TYPE_ID:
137 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100138 case SPV_OPERAND_TYPE_RESULT_ID:
139 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400140 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500141 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
142 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100143 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500144 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
145 return "possibly multi-word literal integer";
146 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
147 return "possibly multi-word literal number";
148 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
149 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500150 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
151 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100152 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500153 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100154 return "literal string";
155 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400156 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100157 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
158 return "execution model";
159 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
160 return "addressing model";
161 case SPV_OPERAND_TYPE_MEMORY_MODEL:
162 return "memory model";
163 case SPV_OPERAND_TYPE_EXECUTION_MODE:
164 return "execution mode";
165 case SPV_OPERAND_TYPE_STORAGE_CLASS:
166 return "storage class";
167 case SPV_OPERAND_TYPE_DIMENSIONALITY:
168 return "dimensionality";
169 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500170 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100171 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
172 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400173 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400174 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100175 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400176 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100177 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400178 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100179 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
180 return "linkage type";
181 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500182 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100183 return "access qualifier";
184 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
185 return "function parameter attribute";
186 case SPV_OPERAND_TYPE_DECORATION:
187 return "decoration";
188 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400189 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100190 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
191 return "selection control";
192 case SPV_OPERAND_TYPE_LOOP_CONTROL:
193 return "loop control";
194 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
195 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500196 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500197 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500198 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400199 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100200 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500201 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500202 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100203 case SPV_OPERAND_TYPE_GROUP_OPERATION:
204 return "group operation";
205 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
206 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400207 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100208 return "kernel profiling info";
209 case SPV_OPERAND_TYPE_CAPABILITY:
210 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500211 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400212 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500213 return "image";
David Neto201caf72015-11-04 17:38:17 -0500214 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
215 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500216 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
217 return "debug info flags";
218 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
219 return "debug base type encoding";
220 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
221 return "debug composite type";
222 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
223 return "debug type qualifier";
224 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
225 return "debug operation";
David Neto201caf72015-11-04 17:38:17 -0500226
227 // The next values are for values returned from an instruction, not actually
228 // an operand. So the specific strings don't matter. But let's add them
229 // for completeness and ease of testing.
230 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
231 return "image channel order";
232 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
233 return "image channel data type";
234
David Neto78c3b432015-08-27 13:03:52 -0400235 case SPV_OPERAND_TYPE_NONE:
236 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100237 default:
238 assert(0 && "Unhandled operand type!");
239 break;
240 }
241 return "unknown";
242}
David Neto78c3b432015-08-27 13:03:52 -0400243
Chris Forbes78338d52017-06-27 16:28:22 -0700244void spvPushOperandTypes(const spv_operand_type_t* types,
245 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400246 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400247 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400248 ;
Chris Forbes78338d52017-06-27 16:28:22 -0700249 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400250 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700251 }
David Neto78c3b432015-08-27 13:03:52 -0400252}
253
Chris Forbes78338d52017-06-27 16:28:22 -0700254void spvPushOperandTypesForMask(const spv_operand_table operandTable,
255 const spv_operand_type_t type,
256 const uint32_t mask,
257 spv_operand_pattern_t* pattern) {
258 // Scan from highest bits to lowest bits because we will append in LIFO
259 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400260 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
261 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400262 if (candidate_bit & mask) {
263 spv_operand_desc entry = nullptr;
264 if (SPV_SUCCESS == spvOperandTableValueLookup(operandTable, type,
265 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700266 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400267 }
268 }
269 }
270}
271
David Neto0dbe1842017-12-03 14:26:16 -0500272bool spvOperandIsConcrete(spv_operand_type_t type) {
273 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
274 return true;
275 }
276 switch (type) {
277 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
278 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
279 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
280 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
281 case SPV_OPERAND_TYPE_LITERAL_STRING:
282 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
283 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
284 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
285 case SPV_OPERAND_TYPE_MEMORY_MODEL:
286 case SPV_OPERAND_TYPE_EXECUTION_MODE:
287 case SPV_OPERAND_TYPE_STORAGE_CLASS:
288 case SPV_OPERAND_TYPE_DIMENSIONALITY:
289 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
290 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
291 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
292 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
293 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
294 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
295 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
296 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
297 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
298 case SPV_OPERAND_TYPE_DECORATION:
299 case SPV_OPERAND_TYPE_BUILT_IN:
300 case SPV_OPERAND_TYPE_GROUP_OPERATION:
301 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
302 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
303 case SPV_OPERAND_TYPE_CAPABILITY:
David Neto59de6102017-12-03 12:30:08 -0500304 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
305 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
306 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
307 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto0dbe1842017-12-03 14:26:16 -0500308 return true;
309 default:
310 break;
311 }
312 return false;
313}
314
David Netob5267562016-02-02 12:05:34 -0500315bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500316 switch (type) {
317 case SPV_OPERAND_TYPE_IMAGE:
318 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
319 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
320 case SPV_OPERAND_TYPE_LOOP_CONTROL:
321 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
322 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto59de6102017-12-03 12:30:08 -0500323 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500324 return true;
325 default:
326 break;
327 }
328 return false;
David Netob5267562016-02-02 12:05:34 -0500329}
330
David Neto78c3b432015-08-27 13:03:52 -0400331bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500332 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
333 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400334}
335
336bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500337 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
338 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400339}
340
David Neto78c3b432015-08-27 13:03:52 -0400341bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
342 spv_operand_pattern_t* pattern) {
343 switch (type) {
344 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700345 pattern->push_back(type);
346 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400347 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400348 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700349 pattern->push_back(type);
350 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400351 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400352 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500353 // Represents Zero or more (Literal number, Id) pairs,
354 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700355 pattern->push_back(type);
356 pattern->push_back(SPV_OPERAND_TYPE_ID);
357 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400358 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400359 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400360 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700361 pattern->push_back(type);
362 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
363 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400364 return true;
David Neto78c3b432015-08-27 13:03:52 -0400365 default:
366 break;
367 }
368 return false;
369}
370
Dejan Mircevski50babb22015-09-29 10:56:32 -0400371spv_operand_type_t spvTakeFirstMatchableOperand(
372 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400373 assert(!pattern->empty());
374 spv_operand_type_t result;
375 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700376 result = pattern->back();
377 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400378 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400379 return result;
380}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400381
Dejan Mircevski897bff92015-09-29 10:38:18 -0400382spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
383 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400384 auto it =
385 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700386 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400387 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
388 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700389 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
390 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400391 }
Chris Forbes78338d52017-06-27 16:28:22 -0700392
Dejan Mircevski897bff92015-09-29 10:38:18 -0400393 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400394 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400395}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500396
397bool spvIsIdType(spv_operand_type_t type) {
398 switch (type) {
399 case SPV_OPERAND_TYPE_ID:
400 case SPV_OPERAND_TYPE_TYPE_ID:
401 case SPV_OPERAND_TYPE_RESULT_ID:
402 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
403 case SPV_OPERAND_TYPE_SCOPE_ID:
404 return true;
405 default:
406 return false;
407 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500408}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400409
410std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
411 SpvOp opcode) {
412 std::function<bool(unsigned index)> out;
413 switch (opcode) {
414 case SpvOpExecutionMode:
415 case SpvOpEntryPoint:
416 case SpvOpName:
417 case SpvOpMemberName:
418 case SpvOpSelectionMerge:
419 case SpvOpDecorate:
420 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500421 case SpvOpDecorateId:
422 case SpvOpDecorateStringGOOGLE:
423 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400424 case SpvOpTypeStruct:
425 case SpvOpBranch:
426 case SpvOpLoopMerge:
427 out = [](unsigned) { return true; };
428 break;
429 case SpvOpGroupDecorate:
430 case SpvOpGroupMemberDecorate:
431 case SpvOpBranchConditional:
432 case SpvOpSwitch:
433 out = [](unsigned index) { return index != 0; };
434 break;
435
436 case SpvOpFunctionCall:
437 // The Function parameter.
438 out = [](unsigned index) { return index == 2; };
439 break;
440
441 case SpvOpPhi:
442 out = [](unsigned index) { return index > 1; };
443 break;
444
445 case SpvOpEnqueueKernel:
446 // The Invoke parameter.
447 out = [](unsigned index) { return index == 8; };
448 break;
449
450 case SpvOpGetKernelNDrangeSubGroupCount:
451 case SpvOpGetKernelNDrangeMaxSubGroupSize:
452 // The Invoke parameter.
453 out = [](unsigned index) { return index == 3; };
454 break;
455
456 case SpvOpGetKernelWorkGroupSize:
457 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
458 // The Invoke parameter.
459 out = [](unsigned index) { return index == 2; };
460 break;
461 case SpvOpTypeForwardPointer:
462 out = [](unsigned index) { return index == 0; };
463 break;
464 default:
465 out = [](unsigned) { return false; };
466 break;
467 }
468 return out;
469}