blob: 96c2223fb3b30f97887f0a3aa5d590a0e8af2a35 [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
Lei Zhang16981f82017-09-21 17:24:57 -040023#include "operand.kinds-1.0.inc"
24#include "operand.kinds-1.1.inc"
25#include "operand.kinds-1.2.inc"
26
Lei Zhang063dbea2017-10-25 12:15:51 -040027static const spv_operand_table_t kTable_1_0 = {
28 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_0),
29 pygen_variable_OperandInfoTable_1_0};
30static const spv_operand_table_t kTable_1_1 = {
31 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_1),
32 pygen_variable_OperandInfoTable_1_1};
33static const spv_operand_table_t kTable_1_2 = {
34 ARRAY_SIZE(pygen_variable_OperandInfoTable_1_2),
35 pygen_variable_OperandInfoTable_1_2};
36
37spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
38 spv_target_env env) {
39 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010040
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040041 switch (env) {
42 case SPV_ENV_UNIVERSAL_1_0:
43 case SPV_ENV_VULKAN_1_0:
Pierre Moreau12447d82017-11-30 00:49:23 +010044 case SPV_ENV_OPENCL_1_2:
45 case SPV_ENV_OPENCL_EMBEDDED_1_2:
46 case SPV_ENV_OPENCL_2_0:
47 case SPV_ENV_OPENCL_EMBEDDED_2_0:
David Netoc2967012016-08-05 18:19:30 -040048 case SPV_ENV_OPENCL_2_1:
Pierre Moreau12447d82017-11-30 00:49:23 +010049 case SPV_ENV_OPENCL_EMBEDDED_2_1:
David Netoc2967012016-08-05 18:19:30 -040050 case SPV_ENV_OPENGL_4_0:
51 case SPV_ENV_OPENGL_4_1:
52 case SPV_ENV_OPENGL_4_2:
53 case SPV_ENV_OPENGL_4_3:
54 case SPV_ENV_OPENGL_4_5:
Lei Zhang063dbea2017-10-25 12:15:51 -040055 *pOperandTable = &kTable_1_0;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040056 return SPV_SUCCESS;
57 case SPV_ENV_UNIVERSAL_1_1:
Lei Zhang063dbea2017-10-25 12:15:51 -040058 *pOperandTable = &kTable_1_1;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040059 return SPV_SUCCESS;
David Netodbc20492017-03-14 12:43:41 -040060 case SPV_ENV_UNIVERSAL_1_2:
61 case SPV_ENV_OPENCL_2_2:
Pierre Moreau12447d82017-11-30 00:49:23 +010062 case SPV_ENV_OPENCL_EMBEDDED_2_2:
Lei Zhang063dbea2017-10-25 12:15:51 -040063 *pOperandTable = &kTable_1_2;
David Netodbc20492017-03-14 12:43:41 -040064 return SPV_SUCCESS;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040065 }
66 assert(0 && "Unknown spv_target_env in spvOperandTableGet()");
67 return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010068}
69
Dejan Mircevski3e6b2df2016-01-07 11:00:38 -050070#undef ARRAY_SIZE
71
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010072spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
73 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040074 const char* name,
75 const size_t nameLength,
76 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040077 if (!table) return SPV_ERROR_INVALID_TABLE;
78 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010079
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010080 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040081 const auto& group = table->types[typeIndex];
82 if (type != group.type) continue;
83 for (uint64_t index = 0; index < group.count; ++index) {
84 const auto& entry = group.entries[index];
85 if (nameLength == strlen(entry.name) &&
86 !strncmp(entry.name, name, nameLength)) {
87 *pEntry = &entry;
88 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010089 }
90 }
91 }
92
93 return SPV_ERROR_INVALID_LOOKUP;
94}
95
96spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
97 const spv_operand_type_t type,
98 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040099 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400100 if (!table) return SPV_ERROR_INVALID_TABLE;
101 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100102
103 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400104 const auto& group = table->types[typeIndex];
105 if (type != group.type) continue;
106 for (uint64_t index = 0; index < group.count; ++index) {
107 const auto& entry = group.entries[index];
108 if (value == entry.value) {
109 *pEntry = &entry;
110 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100111 }
112 }
113 }
114
115 return SPV_ERROR_INVALID_LOOKUP;
116}
117
Dejan Mircevski50babb22015-09-29 10:56:32 -0400118const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100119 switch (type) {
120 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400121 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400122 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500123 case SPV_OPERAND_TYPE_TYPE_ID:
124 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100125 case SPV_OPERAND_TYPE_RESULT_ID:
126 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400127 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500128 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
129 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100130 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500131 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
132 return "possibly multi-word literal integer";
133 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
134 return "possibly multi-word literal number";
135 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
136 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500137 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
138 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100139 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500140 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100141 return "literal string";
142 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400143 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100144 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
145 return "execution model";
146 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
147 return "addressing model";
148 case SPV_OPERAND_TYPE_MEMORY_MODEL:
149 return "memory model";
150 case SPV_OPERAND_TYPE_EXECUTION_MODE:
151 return "execution mode";
152 case SPV_OPERAND_TYPE_STORAGE_CLASS:
153 return "storage class";
154 case SPV_OPERAND_TYPE_DIMENSIONALITY:
155 return "dimensionality";
156 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500157 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100158 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
159 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400160 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400161 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100162 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400163 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100164 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400165 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100166 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
167 return "linkage type";
168 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500169 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100170 return "access qualifier";
171 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
172 return "function parameter attribute";
173 case SPV_OPERAND_TYPE_DECORATION:
174 return "decoration";
175 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400176 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100177 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
178 return "selection control";
179 case SPV_OPERAND_TYPE_LOOP_CONTROL:
180 return "loop control";
181 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
182 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500183 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500184 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500185 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400186 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100187 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500188 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500189 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100190 case SPV_OPERAND_TYPE_GROUP_OPERATION:
191 return "group operation";
192 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
193 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400194 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100195 return "kernel profiling info";
196 case SPV_OPERAND_TYPE_CAPABILITY:
197 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500198 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400199 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500200 return "image";
David Neto201caf72015-11-04 17:38:17 -0500201 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
202 return "context-insensitive value";
203
204 // The next values are for values returned from an instruction, not actually
205 // an operand. So the specific strings don't matter. But let's add them
206 // for completeness and ease of testing.
207 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
208 return "image channel order";
209 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
210 return "image channel data type";
211
David Neto78c3b432015-08-27 13:03:52 -0400212 case SPV_OPERAND_TYPE_NONE:
213 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100214 default:
215 assert(0 && "Unhandled operand type!");
216 break;
217 }
218 return "unknown";
219}
David Neto78c3b432015-08-27 13:03:52 -0400220
Chris Forbes78338d52017-06-27 16:28:22 -0700221void spvPushOperandTypes(const spv_operand_type_t* types,
222 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400223 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400224 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400225 ;
Chris Forbes78338d52017-06-27 16:28:22 -0700226 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400227 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700228 }
David Neto78c3b432015-08-27 13:03:52 -0400229}
230
Chris Forbes78338d52017-06-27 16:28:22 -0700231void spvPushOperandTypesForMask(const spv_operand_table operandTable,
232 const spv_operand_type_t type,
233 const uint32_t mask,
234 spv_operand_pattern_t* pattern) {
235 // Scan from highest bits to lowest bits because we will append in LIFO
236 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400237 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
238 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400239 if (candidate_bit & mask) {
240 spv_operand_desc entry = nullptr;
241 if (SPV_SUCCESS == spvOperandTableValueLookup(operandTable, type,
242 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700243 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400244 }
245 }
246 }
247}
248
David Neto0dbe1842017-12-03 14:26:16 -0500249bool spvOperandIsConcrete(spv_operand_type_t type) {
250 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
251 return true;
252 }
253 switch (type) {
254 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
255 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
256 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
257 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
258 case SPV_OPERAND_TYPE_LITERAL_STRING:
259 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
260 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
261 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
262 case SPV_OPERAND_TYPE_MEMORY_MODEL:
263 case SPV_OPERAND_TYPE_EXECUTION_MODE:
264 case SPV_OPERAND_TYPE_STORAGE_CLASS:
265 case SPV_OPERAND_TYPE_DIMENSIONALITY:
266 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
267 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
268 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
269 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
270 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
271 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
272 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
273 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
274 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
275 case SPV_OPERAND_TYPE_DECORATION:
276 case SPV_OPERAND_TYPE_BUILT_IN:
277 case SPV_OPERAND_TYPE_GROUP_OPERATION:
278 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
279 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
280 case SPV_OPERAND_TYPE_CAPABILITY:
281 return true;
282 default:
283 break;
284 }
285 return false;
286}
287
David Netob5267562016-02-02 12:05:34 -0500288bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500289 switch (type) {
290 case SPV_OPERAND_TYPE_IMAGE:
291 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
292 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
293 case SPV_OPERAND_TYPE_LOOP_CONTROL:
294 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
295 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
296 return true;
297 default:
298 break;
299 }
300 return false;
David Netob5267562016-02-02 12:05:34 -0500301}
302
David Neto78c3b432015-08-27 13:03:52 -0400303bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500304 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
305 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400306}
307
308bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500309 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
310 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400311}
312
David Neto78c3b432015-08-27 13:03:52 -0400313bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
314 spv_operand_pattern_t* pattern) {
315 switch (type) {
316 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700317 pattern->push_back(type);
318 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400319 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400320 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700321 pattern->push_back(type);
322 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400323 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400324 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500325 // Represents Zero or more (Literal number, Id) pairs,
326 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700327 pattern->push_back(type);
328 pattern->push_back(SPV_OPERAND_TYPE_ID);
329 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400330 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400331 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400332 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700333 pattern->push_back(type);
334 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
335 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400336 return true;
David Neto78c3b432015-08-27 13:03:52 -0400337 default:
338 break;
339 }
340 return false;
341}
342
Dejan Mircevski50babb22015-09-29 10:56:32 -0400343spv_operand_type_t spvTakeFirstMatchableOperand(
344 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400345 assert(!pattern->empty());
346 spv_operand_type_t result;
347 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700348 result = pattern->back();
349 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400350 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400351 return result;
352}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400353
Dejan Mircevski897bff92015-09-29 10:38:18 -0400354spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
355 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400356 auto it =
357 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700358 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400359 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
360 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700361 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
362 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400363 }
Chris Forbes78338d52017-06-27 16:28:22 -0700364
Dejan Mircevski897bff92015-09-29 10:38:18 -0400365 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400366 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400367}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500368
369bool spvIsIdType(spv_operand_type_t type) {
370 switch (type) {
371 case SPV_OPERAND_TYPE_ID:
372 case SPV_OPERAND_TYPE_TYPE_ID:
373 case SPV_OPERAND_TYPE_RESULT_ID:
374 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
375 case SPV_OPERAND_TYPE_SCOPE_ID:
376 return true;
377 default:
378 return false;
379 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500380}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400381
382std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
383 SpvOp opcode) {
384 std::function<bool(unsigned index)> out;
385 switch (opcode) {
386 case SpvOpExecutionMode:
387 case SpvOpEntryPoint:
388 case SpvOpName:
389 case SpvOpMemberName:
390 case SpvOpSelectionMerge:
391 case SpvOpDecorate:
392 case SpvOpMemberDecorate:
393 case SpvOpTypeStruct:
394 case SpvOpBranch:
395 case SpvOpLoopMerge:
396 out = [](unsigned) { return true; };
397 break;
398 case SpvOpGroupDecorate:
399 case SpvOpGroupMemberDecorate:
400 case SpvOpBranchConditional:
401 case SpvOpSwitch:
402 out = [](unsigned index) { return index != 0; };
403 break;
404
405 case SpvOpFunctionCall:
406 // The Function parameter.
407 out = [](unsigned index) { return index == 2; };
408 break;
409
410 case SpvOpPhi:
411 out = [](unsigned index) { return index > 1; };
412 break;
413
414 case SpvOpEnqueueKernel:
415 // The Invoke parameter.
416 out = [](unsigned index) { return index == 8; };
417 break;
418
419 case SpvOpGetKernelNDrangeSubGroupCount:
420 case SpvOpGetKernelNDrangeMaxSubGroupSize:
421 // The Invoke parameter.
422 out = [](unsigned index) { return index == 3; };
423 break;
424
425 case SpvOpGetKernelWorkGroupSize:
426 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
427 // The Invoke parameter.
428 out = [](unsigned index) { return index == 2; };
429 break;
430 case SpvOpTypeForwardPointer:
431 out = [](unsigned index) { return index == 0; };
432 break;
433 default:
434 out = [](unsigned) { return false; };
435 break;
436 }
437 return out;
438}