blob: 38db2a5fb82902bda7794c45a37e5b3f9ca48310 [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"
David Netoba73a7c2016-01-06 13:08:39 -050023
David Neto00fa3932018-02-09 14:29:02 -050024// For now, assume unified1 contains up to SPIR-V 1.3 and no later
25// SPIR-V version.
26// TODO(dneto): Make one set of tables, but with version tags on a
27// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
28
David Neto00fa3932018-02-09 14:29:02 -050029#include "operand.kinds-unified1.inc"
Lei Zhang16981f82017-09-21 17:24:57 -040030
Lei Zhang1ef6b192018-03-14 13:06:18 -040031static const spv_operand_table_t kOperandTable = {
32 ARRAY_SIZE(pygen_variable_OperandInfoTable),
33 pygen_variable_OperandInfoTable};
Lei Zhang063dbea2017-10-25 12:15:51 -040034
35spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
Lei Zhang1ef6b192018-03-14 13:06:18 -040036 spv_target_env) {
Lei Zhang063dbea2017-10-25 12:15:51 -040037 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010038
Lei Zhang1ef6b192018-03-14 13:06:18 -040039 *pOperandTable = &kOperandTable;
40 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010041}
42
Lei Zhang1ef6b192018-03-14 13:06:18 -040043spv_result_t spvOperandTableNameLookup(spv_target_env env,
44 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010045 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040046 const char* name,
47 const size_t nameLength,
48 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040049 if (!table) return SPV_ERROR_INVALID_TABLE;
50 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010051
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010052 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040053 const auto& group = table->types[typeIndex];
54 if (type != group.type) continue;
55 for (uint64_t index = 0; index < group.count; ++index) {
56 const auto& entry = group.entries[index];
Lei Zhang1ef6b192018-03-14 13:06:18 -040057 // We considers the current operand as available as long as
58 // 1. The target environment satisfies the minimal requirement of the
59 // operand; or
60 // 2. There is at least one extension enabling this operand.
61 //
62 // Note that the second rule assumes the extension enabling this operand
63 // is indeed requested in the SPIR-V code; checking that should be
64 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -040065 if ((spvVersionForTargetEnv(env) >= entry.minVersion ||
Lei Zhang1ef6b192018-03-14 13:06:18 -040066 entry.numExtensions > 0u) &&
67 nameLength == strlen(entry.name) &&
Lei Zhangca1bf942016-04-27 16:47:13 -040068 !strncmp(entry.name, name, nameLength)) {
69 *pEntry = &entry;
70 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010071 }
72 }
73 }
74
75 return SPV_ERROR_INVALID_LOOKUP;
76}
77
Lei Zhang1ef6b192018-03-14 13:06:18 -040078spv_result_t spvOperandTableValueLookup(spv_target_env env,
79 const spv_operand_table table,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010080 const spv_operand_type_t type,
81 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040082 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040083 if (!table) return SPV_ERROR_INVALID_TABLE;
84 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010085
Lei Zhang1ef6b192018-03-14 13:06:18 -040086 spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u};
87
88 auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
89 return lhs.value < rhs.value;
90 };
91
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010092 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040093 const auto& group = table->types[typeIndex];
94 if (type != group.type) continue;
Lei Zhang1ef6b192018-03-14 13:06:18 -040095
96 const auto beg = group.entries;
97 const auto end = group.entries + group.count;
98
99 // We need to loop here because there can exist multiple symbols for the
100 // same operand value, and they can be introduced in different target
101 // environments, which means they can have different minimal version
102 // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
103 // version as long as the SPV_KHR_shader_ballot extension is there; but
104 // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
105 // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
106 // requirements.
107 // Assumes the underlying table is already sorted ascendingly according to
108 // opcode value.
109 for (auto it = std::lower_bound(beg, end, needle, comp);
110 it != end && it->value == value; ++it) {
111 // We considers the current operand as available as long as
112 // 1. The target environment satisfies the minimal requirement of the
113 // operand; or
114 // 2. There is at least one extension enabling this operand.
115 //
116 // Note that the second rule assumes the extension enabling this operand
117 // is indeed requested in the SPIR-V code; checking that should be
118 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -0400119 if (spvVersionForTargetEnv(env) >= it->minVersion ||
Lei Zhang1ef6b192018-03-14 13:06:18 -0400120 it->numExtensions > 0u) {
121 *pEntry = it;
Lei Zhangca1bf942016-04-27 16:47:13 -0400122 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100123 }
124 }
125 }
126
127 return SPV_ERROR_INVALID_LOOKUP;
128}
129
Dejan Mircevski50babb22015-09-29 10:56:32 -0400130const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100131 switch (type) {
132 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400133 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400134 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500135 case SPV_OPERAND_TYPE_TYPE_ID:
136 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100137 case SPV_OPERAND_TYPE_RESULT_ID:
138 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400139 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500140 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
141 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100142 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500143 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
144 return "possibly multi-word literal integer";
145 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
146 return "possibly multi-word literal number";
147 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
148 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500149 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
150 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100151 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500152 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100153 return "literal string";
154 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400155 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100156 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
157 return "execution model";
158 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
159 return "addressing model";
160 case SPV_OPERAND_TYPE_MEMORY_MODEL:
161 return "memory model";
162 case SPV_OPERAND_TYPE_EXECUTION_MODE:
163 return "execution mode";
164 case SPV_OPERAND_TYPE_STORAGE_CLASS:
165 return "storage class";
166 case SPV_OPERAND_TYPE_DIMENSIONALITY:
167 return "dimensionality";
168 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500169 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100170 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
171 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400172 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400173 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100174 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400175 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100176 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400177 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100178 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
179 return "linkage type";
180 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500181 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100182 return "access qualifier";
183 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
184 return "function parameter attribute";
185 case SPV_OPERAND_TYPE_DECORATION:
186 return "decoration";
187 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400188 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100189 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
190 return "selection control";
191 case SPV_OPERAND_TYPE_LOOP_CONTROL:
192 return "loop control";
193 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
194 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500195 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500196 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500197 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400198 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100199 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500200 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500201 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100202 case SPV_OPERAND_TYPE_GROUP_OPERATION:
203 return "group operation";
204 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
205 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400206 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100207 return "kernel profiling info";
208 case SPV_OPERAND_TYPE_CAPABILITY:
209 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500210 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400211 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500212 return "image";
David Neto201caf72015-11-04 17:38:17 -0500213 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
214 return "context-insensitive value";
David Neto59de6102017-12-03 12:30:08 -0500215 case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
216 return "debug info flags";
217 case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
218 return "debug base type encoding";
219 case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
220 return "debug composite type";
221 case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
222 return "debug type qualifier";
223 case SPV_OPERAND_TYPE_DEBUG_OPERATION:
224 return "debug operation";
David Neto201caf72015-11-04 17:38:17 -0500225
226 // The next values are for values returned from an instruction, not actually
227 // an operand. So the specific strings don't matter. But let's add them
228 // for completeness and ease of testing.
229 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
230 return "image channel order";
231 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
232 return "image channel data type";
233
David Neto78c3b432015-08-27 13:03:52 -0400234 case SPV_OPERAND_TYPE_NONE:
235 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100236 default:
237 assert(0 && "Unhandled operand type!");
238 break;
239 }
240 return "unknown";
241}
David Neto78c3b432015-08-27 13:03:52 -0400242
Chris Forbes78338d52017-06-27 16:28:22 -0700243void spvPushOperandTypes(const spv_operand_type_t* types,
244 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400245 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400246 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400247 ;
Chris Forbes78338d52017-06-27 16:28:22 -0700248 while (endTypes-- != types) {
Lei Zhang16981f82017-09-21 17:24:57 -0400249 pattern->push_back(*endTypes);
Chris Forbes78338d52017-06-27 16:28:22 -0700250 }
David Neto78c3b432015-08-27 13:03:52 -0400251}
252
Lei Zhang1ef6b192018-03-14 13:06:18 -0400253void spvPushOperandTypesForMask(spv_target_env env,
254 const spv_operand_table operandTable,
Chris Forbes78338d52017-06-27 16:28:22 -0700255 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;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400264 if (SPV_SUCCESS == spvOperandTableValueLookup(env, operandTable, type,
David Neto5bf88fc2015-09-17 17:06:10 -0400265 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}