blob: b6dacc568d840f80e049cf29c9e5775bb38f7578 [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//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and/or associated documentation files (the
5// "Materials"), to deal in the Materials without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Materials, and to
8// permit persons to whom the Materials are furnished to do so, subject to
9// the following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Materials.
13//
14// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
15// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
16// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
17// https://www.khronos.org/registry/
18//
19// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
26
27#include "operand.h"
28
29#include <assert.h>
30#include <string.h>
31
Lei Zhangca1bf942016-04-27 16:47:13 -040032#include "macro.h"
David Netoba73a7c2016-01-06 13:08:39 -050033
Lei Zhang4f293b72016-03-21 16:36:14 -040034// Pull in operand info tables automatically generated from JSON grammar.
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040035namespace v1_0 {
Lei Zhang10dba912016-04-14 14:05:53 -040036#include "operand.kinds-1.0.inc"
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040037} // namespace v1_0
38namespace v1_1 {
Lei Zhang10dba912016-04-14 14:05:53 -040039#include "operand.kinds-1.1.inc"
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040040} // namespace v1_1
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010041
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040042spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
43 spv_target_env env) {
Lei Zhang40056702015-09-11 14:31:27 -040044 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010045
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040046 static const spv_operand_table_t table_1_0 = {
47 ARRAY_SIZE(v1_0::pygen_variable_OperandInfoTable),
48 v1_0::pygen_variable_OperandInfoTable};
49 static const spv_operand_table_t table_1_1 = {
50 ARRAY_SIZE(v1_1::pygen_variable_OperandInfoTable),
51 v1_1::pygen_variable_OperandInfoTable};
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010052
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040053 switch (env) {
54 case SPV_ENV_UNIVERSAL_1_0:
55 case SPV_ENV_VULKAN_1_0:
David Netoc2967012016-08-05 18:19:30 -040056 case SPV_ENV_OPENCL_2_1:
57 case SPV_ENV_OPENGL_4_0:
58 case SPV_ENV_OPENGL_4_1:
59 case SPV_ENV_OPENGL_4_2:
60 case SPV_ENV_OPENGL_4_3:
61 case SPV_ENV_OPENGL_4_5:
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040062 *pOperandTable = &table_1_0;
63 return SPV_SUCCESS;
64 case SPV_ENV_UNIVERSAL_1_1:
David Netoc2967012016-08-05 18:19:30 -040065 case SPV_ENV_OPENCL_2_2:
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040066 *pOperandTable = &table_1_1;
67 return SPV_SUCCESS;
68 }
69 assert(0 && "Unknown spv_target_env in spvOperandTableGet()");
70 return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010071}
72
Dejan Mircevski3e6b2df2016-01-07 11:00:38 -050073#undef ARRAY_SIZE
74
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010075spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
76 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040077 const char* name,
78 const size_t nameLength,
79 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040080 if (!table) return SPV_ERROR_INVALID_TABLE;
81 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010082
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010083 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040084 const auto& group = table->types[typeIndex];
85 if (type != group.type) continue;
86 for (uint64_t index = 0; index < group.count; ++index) {
87 const auto& entry = group.entries[index];
88 if (nameLength == strlen(entry.name) &&
89 !strncmp(entry.name, name, nameLength)) {
90 *pEntry = &entry;
91 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010092 }
93 }
94 }
95
96 return SPV_ERROR_INVALID_LOOKUP;
97}
98
99spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
100 const spv_operand_type_t type,
101 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -0400102 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400103 if (!table) return SPV_ERROR_INVALID_TABLE;
104 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100105
106 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -0400107 const auto& group = table->types[typeIndex];
108 if (type != group.type) continue;
109 for (uint64_t index = 0; index < group.count; ++index) {
110 const auto& entry = group.entries[index];
111 if (value == entry.value) {
112 *pEntry = &entry;
113 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100114 }
115 }
116 }
117
118 return SPV_ERROR_INVALID_LOOKUP;
119}
120
Dejan Mircevski50babb22015-09-29 10:56:32 -0400121const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100122 switch (type) {
123 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400124 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400125 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500126 case SPV_OPERAND_TYPE_TYPE_ID:
127 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100128 case SPV_OPERAND_TYPE_RESULT_ID:
129 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400130 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500131 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
132 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100133 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500134 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
135 return "possibly multi-word literal integer";
136 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
137 return "possibly multi-word literal number";
138 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
139 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500140 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
141 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100142 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500143 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100144 return "literal string";
145 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400146 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100147 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
148 return "execution model";
149 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
150 return "addressing model";
151 case SPV_OPERAND_TYPE_MEMORY_MODEL:
152 return "memory model";
153 case SPV_OPERAND_TYPE_EXECUTION_MODE:
154 return "execution mode";
155 case SPV_OPERAND_TYPE_STORAGE_CLASS:
156 return "storage class";
157 case SPV_OPERAND_TYPE_DIMENSIONALITY:
158 return "dimensionality";
159 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500160 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100161 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
162 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400163 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400164 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100165 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400166 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100167 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400168 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100169 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
170 return "linkage type";
171 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500172 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100173 return "access qualifier";
174 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
175 return "function parameter attribute";
176 case SPV_OPERAND_TYPE_DECORATION:
177 return "decoration";
178 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400179 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100180 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
181 return "selection control";
182 case SPV_OPERAND_TYPE_LOOP_CONTROL:
183 return "loop control";
184 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
185 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500186 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500187 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500188 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400189 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100190 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500191 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500192 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100193 case SPV_OPERAND_TYPE_GROUP_OPERATION:
194 return "group operation";
195 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
196 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400197 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100198 return "kernel profiling info";
199 case SPV_OPERAND_TYPE_CAPABILITY:
200 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500201 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400202 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500203 return "image";
David Neto201caf72015-11-04 17:38:17 -0500204 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
205 return "context-insensitive value";
206
207 // The next values are for values returned from an instruction, not actually
208 // an operand. So the specific strings don't matter. But let's add them
209 // for completeness and ease of testing.
210 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
211 return "image channel order";
212 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
213 return "image channel data type";
214
David Neto78c3b432015-08-27 13:03:52 -0400215 case SPV_OPERAND_TYPE_NONE:
216 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100217 default:
218 assert(0 && "Unhandled operand type!");
219 break;
220 }
221 return "unknown";
222}
David Neto78c3b432015-08-27 13:03:52 -0400223
224void spvPrependOperandTypes(const spv_operand_type_t* types,
225 spv_operand_pattern_t* pattern) {
226 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400227 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400228 ;
229 pattern->insert(pattern->begin(), types, endTypes);
230}
231
David Neto5bf88fc2015-09-17 17:06:10 -0400232void spvPrependOperandTypesForMask(const spv_operand_table operandTable,
233 const spv_operand_type_t type,
234 const uint32_t mask,
235 spv_operand_pattern_t* pattern) {
236 // Scan from highest bits to lowest bits because we will prepend in LIFO
237 // fashion, and we need the operands for lower order bits to appear first.
Jamie Madill34cb0032016-04-29 14:36:00 -0400238 for (uint32_t candidate_bit = (1u << 31u); candidate_bit; 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)) {
243 spvPrependOperandTypes(entry->operandTypes, pattern);
244 }
245 }
246 }
247}
248
David Netob5267562016-02-02 12:05:34 -0500249bool spvOperandIsConcreteMask(spv_operand_type_t type) {
250 return SPV_OPERAND_TYPE_FIRST_CONCRETE_MASK_TYPE <= type &&
251 type <= SPV_OPERAND_TYPE_LAST_CONCRETE_MASK_TYPE;
252}
253
David Neto78c3b432015-08-27 13:03:52 -0400254bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500255 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
256 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400257}
258
259bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500260 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
261 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400262}
263
David Neto78c3b432015-08-27 13:03:52 -0400264bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
265 spv_operand_pattern_t* pattern) {
266 switch (type) {
267 case SPV_OPERAND_TYPE_VARIABLE_ID:
268 pattern->insert(pattern->begin(), {SPV_OPERAND_TYPE_OPTIONAL_ID, type});
269 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400270 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
David Neto78c3b432015-08-27 13:03:52 -0400271 pattern->insert(pattern->begin(),
Lei Zhang6483bd72015-10-14 17:02:39 -0400272 {SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, type});
David Neto78c3b432015-08-27 13:03:52 -0400273 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400274 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500275 // Represents Zero or more (Literal number, Id) pairs,
276 // where the literal number must be a scalar integer.
David Neto78c3b432015-08-27 13:03:52 -0400277 pattern->insert(pattern->begin(),
David Neto201caf72015-11-04 17:38:17 -0500278 {SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER,
279 SPV_OPERAND_TYPE_ID, type});
David Neto78c3b432015-08-27 13:03:52 -0400280 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400281 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400282 // Represents Zero or more (Id, Literal number) pairs.
David Neto201caf72015-11-04 17:38:17 -0500283 pattern->insert(pattern->begin(),
284 {SPV_OPERAND_TYPE_OPTIONAL_ID,
285 SPV_OPERAND_TYPE_LITERAL_INTEGER, type});
David Neto78c3b432015-08-27 13:03:52 -0400286 return true;
David Neto78c3b432015-08-27 13:03:52 -0400287 default:
288 break;
289 }
290 return false;
291}
292
Dejan Mircevski50babb22015-09-29 10:56:32 -0400293spv_operand_type_t spvTakeFirstMatchableOperand(
294 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400295 assert(!pattern->empty());
296 spv_operand_type_t result;
297 do {
298 result = pattern->front();
299 pattern->pop_front();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400300 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400301 return result;
302}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400303
Dejan Mircevski897bff92015-09-29 10:38:18 -0400304spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
305 const spv_operand_pattern_t& pattern) {
306 spv_operand_pattern_t alternatePattern;
307 for (const auto& operand : pattern) {
308 if (operand == SPV_OPERAND_TYPE_RESULT_ID) {
309 alternatePattern.push_back(operand);
310 alternatePattern.push_back(SPV_OPERAND_TYPE_OPTIONAL_CIV);
311 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400312 }
Dejan Mircevski897bff92015-09-29 10:38:18 -0400313 alternatePattern.push_back(SPV_OPERAND_TYPE_OPTIONAL_CIV);
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400314 }
Dejan Mircevski897bff92015-09-29 10:38:18 -0400315 // No result-id found, so just expect CIVs.
316 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400317}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500318
319bool spvIsIdType(spv_operand_type_t type) {
320 switch (type) {
321 case SPV_OPERAND_TYPE_ID:
322 case SPV_OPERAND_TYPE_TYPE_ID:
323 case SPV_OPERAND_TYPE_RESULT_ID:
324 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
325 case SPV_OPERAND_TYPE_SCOPE_ID:
326 return true;
327 default:
328 return false;
329 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500330}