blob: cd26a3d1a582d7c009e8116f1ad987ea99952131 [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
dan sinclaireda2cfb2018-08-03 15:06:09 -040015#include "source/operand.h"
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010016
17#include <assert.h>
18#include <string.h>
alan-baker45fb6962019-05-10 11:02:01 -040019
Chris Forbes78338d52017-06-27 16:28:22 -070020#include <algorithm>
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010021
dan sinclaireda2cfb2018-08-03 15:06:09 -040022#include "source/macro.h"
23#include "source/spirv_constant.h"
24#include "source/spirv_target_env.h"
David Netoba73a7c2016-01-06 13:08:39 -050025
David Neto00fa3932018-02-09 14:29:02 -050026// For now, assume unified1 contains up to SPIR-V 1.3 and no later
27// SPIR-V version.
28// TODO(dneto): Make one set of tables, but with version tags on a
29// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
30
David Neto00fa3932018-02-09 14:29:02 -050031#include "operand.kinds-unified1.inc"
Lei Zhang16981f82017-09-21 17:24:57 -040032
Lei Zhang1ef6b192018-03-14 13:06:18 -040033static const spv_operand_table_t kOperandTable = {
34 ARRAY_SIZE(pygen_variable_OperandInfoTable),
35 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040036
37spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040038 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040039 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010040
Lei Zhang1ef6b192018-03-14 13:06:18 -040041 *pOperandTable = &kOperandTable;
42 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010043}
44
Lei Zhang1ef6b192018-03-14 13:06:18 -040045spv_result_t spvOperandTableNameLookup(spv_target_env env,
46 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010047 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040048 const char* name,
49 const size_t nameLength,
50 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040051 if (!table) return SPV_ERROR_INVALID_TABLE;
52 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010053
alan-baker45fb6962019-05-10 11:02:01 -040054 const auto version = spvVersionForTargetEnv(env);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010055 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040056 const auto& group = table->types[typeIndex];
57 if (type != group.type) continue;
58 for (uint64_t index = 0; index < group.count; ++index) {
59 const auto& entry = group.entries[index];
David Neto363bfca2018-06-05 23:07:51 -070060 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -040061 // 1. The target environment satisfies the minimal requirement of the
62 // operand; or
David Neto363bfca2018-06-05 23:07:51 -070063 // 2. There is at least one extension enabling this operand; or
64 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -040065 //
66 // Note that the second rule assumes the extension enabling this operand
67 // is indeed requested in the SPIR-V code; checking that should be
68 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -040069 if (((version >= entry.minVersion && version <= entry.lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -070070 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -040071 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040072 !strncmp(entry.name, name, nameLength)) {
73 *pEntry = &entry;
74 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010075 }
76 }
77 }
78
79 return SPV_ERROR_INVALID_LOOKUP;
80}
81
Lei Zhang1ef6b192018-03-14 13:06:18 -040082spv_result_t spvOperandTableValueLookup(spv_target_env env,
83 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010084 const spv_operand_type_t type,
85 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040086 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040087 if (!table) return SPV_ERROR_INVALID_TABLE;
88 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010089
alan-baker45fb6962019-05-10 11:02:01 -040090 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
Lei Zhang1ef6b192018-03-14 13:06:18 -040091
92 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
93 return lhs.value < rhs.value;
94 };
95
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010096 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040097 const auto& group = table->types[typeIndex];
98 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -040099
100 const auto beg = group.entries;
101 const auto end = group.entries + group.count;
102
103 // We need to loop here because there can exist multiple symbols for the
104 // same operand value, and they can be introduced in different target
105 // environments, which means they can have different minimal version
106 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
107 // version as long as the SPV_KHR_shader_ballot extension is there; but
108 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
109 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
110 // requirements.
111 // Assumes the underlying table is already sorted ascendingly according to
112 // opcode value.
alan-baker45fb6962019-05-10 11:02:01 -0400113 const auto version = spvVersionForTargetEnv(env);
Lei Zhang1ef6b192018-03-14 13:06:18 -0400114 for (auto it = std::lower_bound(beg, end, needle, comp);
115 it != end && it->value == value; ++it) {
David Neto363bfca2018-06-05 23:07:51 -0700116 // We consider the current operand as available as long as
Lei Zhang1ef6b192018-03-14 13:06:18 -0400117 // 1. The target environment satisfies the minimal requirement of the
118 // operand; or
David Neto363bfca2018-06-05 23:07:51 -0700119 // 2. There is at least one extension enabling this operand; or
120 // 3. There is at least one capability enabling this operand.
Lei Zhang1ef6b192018-03-14 13:06:18 -0400121 //
122 // Note that the second rule assumes the extension enabling this operand
123 // is indeed requested in the SPIR-V code; checking that should be
124 // validator's work.
alan-baker45fb6962019-05-10 11:02:01 -0400125 if ((version >= it->minVersion && version <= it->lastVersion) ||
David Neto363bfca2018-06-05 23:07:51 -0700126 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400127 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400128 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100129 }
130 }
131 }
132
133 return SPV_ERROR_INVALID_LOOKUP;
134}
135
Dejan Mircevski50babb22015-09-29 10:56:32 -0400136const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100137 switch (type) {
138 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400139 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400140 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500141 case SPV_OPERAND_TYPE_TYPE_ID:
142 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100143 case SPV_OPERAND_TYPE_RESULT_ID:
144 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400145 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500146 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
147 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100148 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500149 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
150 return "possibly multi-word literal integer";
151 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
152 return "possibly multi-word literal number";
153 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
154 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500155 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
156 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100157 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500158 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100159 return "literal string";
160 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400161 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100162 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
163 return "execution model";
164 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
165 return "addressing model";
166 case SPV_OPERAND_TYPE_MEMORY_MODEL:
167 return "memory model";
168 case SPV_OPERAND_TYPE_EXECUTION_MODE:
169 return "execution mode";
170 case SPV_OPERAND_TYPE_STORAGE_CLASS:
171 return "storage class";
172 case SPV_OPERAND_TYPE_DIMENSIONALITY:
173 return "dimensionality";
174 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500175 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100176 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
177 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400178 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400179 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100180 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400181 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100182 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400183 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100184 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
185 return "linkage type";
186 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500187 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100188 return "access qualifier";
189 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
190 return "function parameter attribute";
191 case SPV_OPERAND_TYPE_DECORATION:
192 return "decoration";
193 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400194 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100195 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
196 return "selection control";
197 case SPV_OPERAND_TYPE_LOOP_CONTROL:
198 return "loop control";
199 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
200 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500201 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500202 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500203 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400204 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100205 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500206 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500207 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100208 case SPV_OPERAND_TYPE_GROUP_OPERATION:
209 return "group operation";
210 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
211 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400212 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100213 return "kernel profiling info";
214 case SPV_OPERAND_TYPE_CAPABILITY:
215 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500216 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400217 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500218 return "image";
David Neto201caf72015-11-04 17:38:17 -0500219 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
220 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500221 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
222 return "debug info flags";
223 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
224 return "debug base type encoding";
225 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
226 return "debug composite type";
227 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
228 return "debug type qualifier";
229 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
230 return "debug operation";
David Neto201caf72015-11-04 17:38:17 -0500231
232 // The next values are for values returned from an instruction, not actually
233 // an operand. So the specific strings don't matter. But let's add them
234 // for completeness and ease of testing.
235 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
236 return "image channel order";
237 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
238 return "image channel data type";
239
David Neto78c3b432015-08-27 13:03:52 -0400240 case SPV_OPERAND_TYPE_NONE:
241 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100242 default:
243 assert(0 && "Unhandled operand type!");
244 break;
245 }
246 return "unknown";
247}
David Neto78c3b432015-08-27 13:03:52 -0400248
Chris Forbes78338d52017-06-27 16:28:22 -0700249void spvPushOperandTypes(const spv_operand_type_t* types,
250 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400251 const spv_operand_type_t* endTypes;
dan sinclair84846b72018-07-10 13:09:46 -0400252 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
253 }
254
Chris Forbes78338d52017-06-27 16:28:22 -0700255 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400256 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700257 }
David Neto78c3b432015-08-27 13:03:52 -0400258}
259
Lei Zhang1ef6b192018-03-14 13:06:18 -0400260void spvPushOperandTypesForMask(spv_target_env env,
261 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700262 const spv_operand_type_t type,
263 const uint32_t mask,
264 spv_operand_pattern_t* pattern) {
265 // Scan from highest bits to lowest bits because we will append in LIFO
266 // fashion, and we need the operands for lower order bits to be consumed first
Lei Zhang16981f82017-09-21 17:24:57 -0400267 for (uint32_t candidate_bit = (1u << 31u); candidate_bit;
268 candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400269 if (candidate_bit & mask) {
270 spv_operand_desc entry = nullptr;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400271 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400272 candidate_bit, &entry)) {
Chris Forbes78338d52017-06-27 16:28:22 -0700273 spvPushOperandTypes(entry->operandTypes, pattern);
David Neto5bf88fc2015-09-17 17:06:10 -0400274 }
275 }
276 }
277}
278
David Neto0dbe1842017-12-03 14:26:16 -0500279bool spvOperandIsConcrete(spv_operand_type_t type) {
280 if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
281 return true;
282 }
283 switch (type) {
284 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
285 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
286 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
287 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
288 case SPV_OPERAND_TYPE_LITERAL_STRING:
289 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
290 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
291 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
292 case SPV_OPERAND_TYPE_MEMORY_MODEL:
293 case SPV_OPERAND_TYPE_EXECUTION_MODE:
294 case SPV_OPERAND_TYPE_STORAGE_CLASS:
295 case SPV_OPERAND_TYPE_DIMENSIONALITY:
296 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
297 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
298 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
299 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
300 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
301 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
302 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
303 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
304 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
305 case SPV_OPERAND_TYPE_DECORATION:
306 case SPV_OPERAND_TYPE_BUILT_IN:
307 case SPV_OPERAND_TYPE_GROUP_OPERATION:
308 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
309 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
310 case SPV_OPERAND_TYPE_CAPABILITY:
David Neto59de6102017-12-03 12:30:08 -0500311 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
312 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
313 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
314 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
David Neto0dbe1842017-12-03 14:26:16 -0500315 return true;
316 default:
317 break;
318 }
319 return false;
320}
321
David Netob5267562016-02-02 12:05:34 -0500322bool spvOperandIsConcreteMask(spv_operand_type_t type) {
David Neto0dbe1842017-12-03 14:26:16 -0500323 switch (type) {
324 case SPV_OPERAND_TYPE_IMAGE:
325 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
326 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
327 case SPV_OPERAND_TYPE_LOOP_CONTROL:
328 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
329 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto59de6102017-12-03 12:30:08 -0500330 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
David Neto0dbe1842017-12-03 14:26:16 -0500331 return true;
332 default:
333 break;
334 }
335 return false;
David Netob5267562016-02-02 12:05:34 -0500336}
337
David Neto78c3b432015-08-27 13:03:52 -0400338bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500339 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
340 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400341}
342
343bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500344 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
345 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400346}
347
David Neto78c3b432015-08-27 13:03:52 -0400348bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
349 spv_operand_pattern_t* pattern) {
350 switch (type) {
351 case SPV_OPERAND_TYPE_VARIABLE_ID:
Chris Forbes78338d52017-06-27 16:28:22 -0700352 pattern->push_back(type);
353 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
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:
Chris Forbes78338d52017-06-27 16:28:22 -0700356 pattern->push_back(type);
357 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_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_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500360 // Represents Zero or more (Literal number, Id) pairs,
361 // where the literal number must be a scalar integer.
Chris Forbes78338d52017-06-27 16:28:22 -0700362 pattern->push_back(type);
363 pattern->push_back(SPV_OPERAND_TYPE_ID);
364 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
David Neto78c3b432015-08-27 13:03:52 -0400365 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400366 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400367 // Represents Zero or more (Id, Literal number) pairs.
Chris Forbes78338d52017-06-27 16:28:22 -0700368 pattern->push_back(type);
369 pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
370 pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
David Neto78c3b432015-08-27 13:03:52 -0400371 return true;
David Neto78c3b432015-08-27 13:03:52 -0400372 default:
373 break;
374 }
375 return false;
376}
377
Dejan Mircevski50babb22015-09-29 10:56:32 -0400378spv_operand_type_t spvTakeFirstMatchableOperand(
379 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400380 assert(!pattern->empty());
381 spv_operand_type_t result;
382 do {
Chris Forbes78338d52017-06-27 16:28:22 -0700383 result = pattern->back();
384 pattern->pop_back();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400385 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400386 return result;
387}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400388
Dejan Mircevski897bff92015-09-29 10:38:18 -0400389spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
390 const spv_operand_pattern_t& pattern) {
Lei Zhang16981f82017-09-21 17:24:57 -0400391 auto it =
392 std::find(pattern.crbegin(), pattern.crend(), SPV_OPERAND_TYPE_RESULT_ID);
Chris Forbes78338d52017-06-27 16:28:22 -0700393 if (it != pattern.crend()) {
Lei Zhang16981f82017-09-21 17:24:57 -0400394 spv_operand_pattern_t alternatePattern(it - pattern.crbegin() + 2,
395 SPV_OPERAND_TYPE_OPTIONAL_CIV);
Chris Forbes78338d52017-06-27 16:28:22 -0700396 alternatePattern[1] = SPV_OPERAND_TYPE_RESULT_ID;
397 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400398 }
Chris Forbes78338d52017-06-27 16:28:22 -0700399
Dejan Mircevski897bff92015-09-29 10:38:18 -0400400 // No result-id found, so just expect CIVs.
Lei Zhang16981f82017-09-21 17:24:57 -0400401 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400402}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500403
404bool spvIsIdType(spv_operand_type_t type) {
405 switch (type) {
406 case SPV_OPERAND_TYPE_ID:
407 case SPV_OPERAND_TYPE_TYPE_ID:
408 case SPV_OPERAND_TYPE_RESULT_ID:
409 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
410 case SPV_OPERAND_TYPE_SCOPE_ID:
411 return true;
412 default:
413 return false;
414 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500415}
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400416
Alastair Donaldson3b130402018-11-26 22:06:21 +0000417bool spvIsInIdType(spv_operand_type_t type) {
418 if (!spvIsIdType(type)) {
419 // If it is not an ID it cannot be an input ID.
420 return false;
421 }
422 switch (type) {
423 // Blacklist non-input IDs.
424 case SPV_OPERAND_TYPE_TYPE_ID:
425 case SPV_OPERAND_TYPE_RESULT_ID:
426 return false;
427 default:
428 return true;
429 }
430}
431
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400432std::function<bool(unsigned)> spvOperandCanBeForwardDeclaredFunction(
433 SpvOp opcode) {
434 std::function<bool(unsigned index)> out;
435 switch (opcode) {
436 case SpvOpExecutionMode:
Lei Zhangefcc33e2018-05-16 08:43:50 -0400437 case SpvOpExecutionModeId:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400438 case SpvOpEntryPoint:
439 case SpvOpName:
440 case SpvOpMemberName:
441 case SpvOpSelectionMerge:
442 case SpvOpDecorate:
443 case SpvOpMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500444 case SpvOpDecorateId:
445 case SpvOpDecorateStringGOOGLE:
446 case SpvOpMemberDecorateStringGOOGLE:
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400447 case SpvOpTypeStruct:
448 case SpvOpBranch:
449 case SpvOpLoopMerge:
450 out = [](unsigned) { return true; };
451 break;
452 case SpvOpGroupDecorate:
453 case SpvOpGroupMemberDecorate:
454 case SpvOpBranchConditional:
455 case SpvOpSwitch:
456 out = [](unsigned index) { return index != 0; };
457 break;
458
459 case SpvOpFunctionCall:
460 // The Function parameter.
461 out = [](unsigned index) { return index == 2; };
462 break;
463
464 case SpvOpPhi:
465 out = [](unsigned index) { return index > 1; };
466 break;
467
468 case SpvOpEnqueueKernel:
469 // The Invoke parameter.
470 out = [](unsigned index) { return index == 8; };
471 break;
472
473 case SpvOpGetKernelNDrangeSubGroupCount:
474 case SpvOpGetKernelNDrangeMaxSubGroupSize:
475 // The Invoke parameter.
476 out = [](unsigned index) { return index == 3; };
477 break;
478
479 case SpvOpGetKernelWorkGroupSize:
480 case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
481 // The Invoke parameter.
482 out = [](unsigned index) { return index == 2; };
483 break;
484 case SpvOpTypeForwardPointer:
485 out = [](unsigned index) { return index == 0; };
486 break;
Jeff Bolz5eab6df2019-01-07 12:19:24 -0600487 case SpvOpTypeArray:
488 out = [](unsigned index) { return index == 1; };
489 break;
Andrey Tuganovb36acbe2017-08-09 14:01:12 -0400490 default:
491 out = [](unsigned) { return false; };
492 break;
493 }
494 return out;
495}