blob: 62ac3f4713ab8c8c56e7427ab6f0f191261bf32e [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"
Lei Zhangddbaf322018-03-28 16:42:44 -040022#include "spirv_constant.h"
Alan Baker42840d12018-04-06 14:15:27 -040023#include "spirv_target_env.h"
David Netoba73a7c2016-01-06 13:08:39 -050024
David Neto00fa3932018-02-09 14:29:02 -050025// For now, assume unified1 contains up to SPIR-V 1.3 and no later
26// SPIR-V version.
27// TODO(dneto): Make one set of tables, but with version tags on a
28// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
29
David Neto00fa3932018-02-09 14:29:02 -050030#include "operand.kinds-unified1.inc"
Lei Zhang16981f82017-09-21 17:24:57 -040031
Lei Zhang1ef6b192018-03-14 13:06:18 -040032static const spv_operand_table_t kOperandTable = {
33 ARRAY_SIZE(pygen_variable_OperandInfoTable),
34 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040035
36spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040037 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040038 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010039
Lei Zhang1ef6b192018-03-14 13:06:18 -040040 *pOperandTable = &kOperandTable;
41 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010042}
43
Lei Zhang1ef6b192018-03-14 13:06:18 -040044spv_result_t spvOperandTableNameLookup(spv_target_env env,
45 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010046 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040047 const char* name,
48 const size_t nameLength,
49 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040050 if (!table) return SPV_ERROR_INVALID_TABLE;
51 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010052
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010053 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040054 const auto& group = table->types[typeIndex];
55 if (type != group.type) continue;
56 for (uint64_t index = 0; index < group.count; ++index) {
57 const auto& entry = group.entries[index];
David Neto363bfca2018-06-05 23:07:51 -070058 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -040059 // 1. The target environment satisfies the minimal requirement of the
60 // operand; or
David Neto363bfca2018-06-05 23:07:51 -070061 // 2. There is at least one extension enabling this operand; or
62 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -040063 //
64 // Note that the second rule assumes the extension enabling this operand
65 // is indeed requested in the SPIR-V code; checking that should be
66 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -040067 if ((spvVersionForTargetEnv(env) >= entry.minVersion ||
David Neto363bfca2018-06-05 23:07:51 -070068 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -040069 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040070 !strncmp(entry.name, name, nameLength)) {
71 *pEntry = &entry;
72 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010073 }
74 }
75 }
76
77 return SPV_ERROR_INVALID_LOOKUP;
78}
79
Lei Zhang1ef6b192018-03-14 13:06:18 -040080spv_result_t spvOperandTableValueLookup(spv_target_env env,
81 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010082 const spv_operand_type_t type,
83 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040084 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040085 if (!table) return SPV_ERROR_INVALID_TABLE;
86 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010087
Lei Zhang1ef6b192018-03-14 13:06:18 -040088 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u};
89
90 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
91 return lhs.value < rhs.value;
92 };
93
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010094 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040095 const auto& group = table->types[typeIndex];
96 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -040097
98 const auto beg = group.entries;
99 const auto end = group.entries + group.count;
100
101 // We need to loop here because there can exist multiple symbols for the
102 // same operand value, and they can be introduced in different target
103 // environments, which means they can have different minimal version
104 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
105 // version as long as the SPV_KHR_shader_ballot extension is there; but
106 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
107 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
108 // requirements.
109 // Assumes the underlying table is already sorted ascendingly according to
110 // opcode value.
111 for (auto it = std::lower_bound(beg, end, needle, comp);
112 it != end && it->value == value; ++it) {
David Neto363bfca2018-06-05 23:07:51 -0700113 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -0400114 // 1. The target environment satisfies the minimal requirement of the
115 // operand; or
David Neto363bfca2018-06-05 23:07:51 -0700116 // 2. There is at least one extension enabling this operand; or
117 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -0400118 //
119 // Note that the second rule assumes the extension enabling this operand
120 // is indeed requested in the SPIR-V code; checking that should be
121 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -0400122 if (spvVersionForTargetEnv(env) >= it->minVersion ||
David Neto363bfca2018-06-05 23:07:51 -0700123 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400124 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400125 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100126 }
127 }
128 }
129
130 return SPV_ERROR_INVALID_LOOKUP;
131}
132
Dejan Mircevski50babb22015-09-29 10:56:32 -0400133const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100134 switch (type) {
135 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400136 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400137 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500138 case SPV_OPERAND_TYPE_TYPE_ID:
139 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100140 case SPV_OPERAND_TYPE_RESULT_ID:
141 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400142 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500143 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
144 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100145 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500146 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
147 return "possibly multi-word literal integer";
148 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
149 return "possibly multi-word literal number";
150 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
151 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500152 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
153 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100154 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500155 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100156 return "literal string";
157 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400158 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100159 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
160 return "execution model";
161 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
162 return "addressing model";
163 case SPV_OPERAND_TYPE_MEMORY_MODEL:
164 return "memory model";
165 case SPV_OPERAND_TYPE_EXECUTION_MODE:
166 return "execution mode";
167 case SPV_OPERAND_TYPE_STORAGE_CLASS:
168 return "storage class";
169 case SPV_OPERAND_TYPE_DIMENSIONALITY:
170 return "dimensionality";
171 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500172 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100173 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
174 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400175 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400176 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100177 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400178 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100179 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400180 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100181 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
182 return "linkage type";
183 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500184 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100185 return "access qualifier";
186 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
187 return "function parameter attribute";
188 case SPV_OPERAND_TYPE_DECORATION:
189 return "decoration";
190 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400191 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100192 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
193 return "selection control";
194 case SPV_OPERAND_TYPE_LOOP_CONTROL:
195 return "loop control";
196 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
197 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500198 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500199 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500200 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400201 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100202 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500203 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500204 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100205 case SPV_OPERAND_TYPE_GROUP_OPERATION:
206 return "group operation";
207 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
208 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400209 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100210 return "kernel profiling info";
211 case SPV_OPERAND_TYPE_CAPABILITY:
212 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500213 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400214 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500215 return "image";
David Neto201caf72015-11-04 17:38:17 -0500216 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
217 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500218 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
219 return "debug info flags";
220 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
221 return "debug base type encoding";
222 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
223 return "debug composite type";
224 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
225 return "debug type qualifier";
226 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
227 return "debug operation";
David Neto201caf72015-11-04 17:38:17 -0500228
229 // The next values are for values returned from an instruction, not actually
230 // an operand. So the specific strings don't matter. But let's add them
231 // for completeness and ease of testing.
232 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
233 return "image channel order";
234 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
235 return "image channel data type";
236
David Neto78c3b432015-08-27 13:03:52 -0400237 case SPV_OPERAND_TYPE_NONE:
238 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100239 default:
240 assert(0 && "Unhandled operand type!");
241 break;
242 }
243 return "unknown";
244}
David Neto78c3b432015-08-27 13:03:52 -0400245
Chris Forbes78338d52017-06-27 16:28:22 -0700246void spvPushOperandTypes(const spv_operand_type_t* types,
247 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400248 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400249 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400250 ;
Chris Forbes78338d52017-06-27 16:28:22 -0700251 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400252 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700253 }
David Neto78c3b432015-08-27 13:03:52 -0400254}
255
Lei Zhang1ef6b192018-03-14 13:06:18 -0400256void spvPushOperandTypesForMask(spv_target_env env,
257 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700258 const spv_operand_type_t type,
259 const uint32_t mask,
260 spv_operand_pattern_t* pattern) {
261 // Scan from highest bits to lowest bits because we will append in LIFO
262 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400263 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
264 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400265 if (candidate_bit & mask) {
266 spv_operand_desc entry = nullptr;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400267 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400268 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700269 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400270 }
271 }
272 }
273}
274
David Neto0dbe1842017-12-03 14:26:16 -0500275bool spvOperandIsConcrete(spv_operand_type_t type) {
276 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
277 return true;
278 }
279 switch (type) {
280 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
281 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
282 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
283 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
284 case SPV_OPERAND_TYPE_LITERAL_STRING:
285 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
286 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
287 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
288 case SPV_OPERAND_TYPE_MEMORY_MODEL:
289 case SPV_OPERAND_TYPE_EXECUTION_MODE:
290 case SPV_OPERAND_TYPE_STORAGE_CLASS:
291 case SPV_OPERAND_TYPE_DIMENSIONALITY:
292 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
293 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
294 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
295 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
296 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
297 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
298 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
299 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
300 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
301 case SPV_OPERAND_TYPE_DECORATION:
302 case SPV_OPERAND_TYPE_BUILT_IN:
303 case SPV_OPERAND_TYPE_GROUP_OPERATION:
304 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
305 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
306 case SPV_OPERAND_TYPE_CAPABILITY:
David Neto59de6102017-12-03 12:30:08 -0500307 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
308 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
309 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
310 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto0dbe1842017-12-03 14:26:16 -0500311 return true;
312 default:
313 break;
314 }
315 return false;
316}
317
David Netob5267562016-02-02 12:05:34 -0500318bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500319 switch (type) {
320 case SPV_OPERAND_TYPE_IMAGE:
321 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
322 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
323 case SPV_OPERAND_TYPE_LOOP_CONTROL:
324 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
325 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto59de6102017-12-03 12:30:08 -0500326 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500327 return true;
328 default:
329 break;
330 }
331 return false;
David Netob5267562016-02-02 12:05:34 -0500332}
333
David Neto78c3b432015-08-27 13:03:52 -0400334bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500335 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
336 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400337}
338
339bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500340 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
341 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400342}
343
David Neto78c3b432015-08-27 13:03:52 -0400344bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
345 spv_operand_pattern_t* pattern) {
346 switch (type) {
347 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700348 pattern->push_back(type);
349 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400350 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400351 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
Chris Forbes78338d52017-06-27 16:28:22 -0700352 pattern->push_back(type);
353 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400354 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400355 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500356 // Represents Zero or more (Literal number, Id) pairs,
357 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700358 pattern->push_back(type);
359 pattern->push_back(SPV_OPERAND_TYPE_ID);
360 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400361 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400362 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400363 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700364 pattern->push_back(type);
365 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
366 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400367 return true;
David Neto78c3b432015-08-27 13:03:52 -0400368 default:
369 break;
370 }
371 return false;
372}
373
Dejan Mircevski50babb22015-09-29 10:56:32 -0400374spv_operand_type_t spvTakeFirstMatchableOperand(
375 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400376 assert(!pattern->empty());
377 spv_operand_type_t result;
378 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700379 result = pattern->back();
380 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400381 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400382 return result;
383}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400384
Dejan Mircevski897bff92015-09-29 10:38:18 -0400385spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
386 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400387 auto it =
388 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700389 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400390 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
391 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700392 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
393 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400394 }
Chris Forbes78338d52017-06-27 16:28:22 -0700395
Dejan Mircevski897bff92015-09-29 10:38:18 -0400396 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400397 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400398}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500399
400bool spvIsIdType(spv_operand_type_t type) {
401 switch (type) {
402 case SPV_OPERAND_TYPE_ID:
403 case SPV_OPERAND_TYPE_TYPE_ID:
404 case SPV_OPERAND_TYPE_RESULT_ID:
405 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
406 case SPV_OPERAND_TYPE_SCOPE_ID:
407 return true;
408 default:
409 return false;
410 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500411}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400412
413std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
414 SpvOp opcode) {
415 std::function<bool(unsigned index)> out;
416 switch (opcode) {
417 case SpvOpExecutionMode:
Lei Zhangefcc33e2018-05-16 08:43:50 -0400418 case SpvOpExecutionModeId:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400419 case SpvOpEntryPoint:
420 case SpvOpName:
421 case SpvOpMemberName:
422 case SpvOpSelectionMerge:
423 case SpvOpDecorate:
424 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500425 case SpvOpDecorateId:
426 case SpvOpDecorateStringGOOGLE:
427 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400428 case SpvOpTypeStruct:
429 case SpvOpBranch:
430 case SpvOpLoopMerge:
431 out = [](unsigned) { return true; };
432 break;
433 case SpvOpGroupDecorate:
434 case SpvOpGroupMemberDecorate:
435 case SpvOpBranchConditional:
436 case SpvOpSwitch:
437 out = [](unsigned index) { return index != 0; };
438 break;
439
440 case SpvOpFunctionCall:
441 // The Function parameter.
442 out = [](unsigned index) { return index == 2; };
443 break;
444
445 case SpvOpPhi:
446 out = [](unsigned index) { return index > 1; };
447 break;
448
449 case SpvOpEnqueueKernel:
450 // The Invoke parameter.
451 out = [](unsigned index) { return index == 8; };
452 break;
453
454 case SpvOpGetKernelNDrangeSubGroupCount:
455 case SpvOpGetKernelNDrangeMaxSubGroupSize:
456 // The Invoke parameter.
457 out = [](unsigned index) { return index == 3; };
458 break;
459
460 case SpvOpGetKernelWorkGroupSize:
461 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
462 // The Invoke parameter.
463 out = [](unsigned index) { return index == 2; };
464 break;
465 case SpvOpTypeForwardPointer:
466 out = [](unsigned index) { return index == 0; };
467 break;
468 default:
469 out = [](unsigned) { return false; };
470 break;
471 }
472 return out;
473}