blob: 621c743007f310dc04e4e29716167a06a759df9f [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>
19
Lei Zhangca1bf942016-04-27 16:47:13 -040020#include "macro.h"
David Netoba73a7c2016-01-06 13:08:39 -050021
Lei Zhang4f293b72016-03-21 16:36:14 -040022// Pull in operand info tables automatically generated from JSON grammar.
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040023namespace v1_0 {
Lei Zhang10dba912016-04-14 14:05:53 -040024#include "operand.kinds-1.0.inc"
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040025} // namespace v1_0
26namespace v1_1 {
Lei Zhang10dba912016-04-14 14:05:53 -040027#include "operand.kinds-1.1.inc"
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040028} // namespace v1_1
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010029
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040030spv_result_t spvOperandTableGet(spv_operand_table* pOperandTable,
31 spv_target_env env) {
Lei Zhang40056702015-09-11 14:31:27 -040032 if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010033
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040034 static const spv_operand_table_t table_1_0 = {
35 ARRAY_SIZE(v1_0::pygen_variable_OperandInfoTable),
36 v1_0::pygen_variable_OperandInfoTable};
37 static const spv_operand_table_t table_1_1 = {
38 ARRAY_SIZE(v1_1::pygen_variable_OperandInfoTable),
39 v1_1::pygen_variable_OperandInfoTable};
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:
David Netoc2967012016-08-05 18:19:30 -040044 case SPV_ENV_OPENCL_2_1:
45 case SPV_ENV_OPENGL_4_0:
46 case SPV_ENV_OPENGL_4_1:
47 case SPV_ENV_OPENGL_4_2:
48 case SPV_ENV_OPENGL_4_3:
49 case SPV_ENV_OPENGL_4_5:
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040050 *pOperandTable = &table_1_0;
51 return SPV_SUCCESS;
52 case SPV_ENV_UNIVERSAL_1_1:
David Netoc2967012016-08-05 18:19:30 -040053 case SPV_ENV_OPENCL_2_2:
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040054 *pOperandTable = &table_1_1;
55 return SPV_SUCCESS;
56 }
57 assert(0 && "Unknown spv_target_env in spvOperandTableGet()");
58 return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010059}
60
Dejan Mircevski3e6b2df2016-01-07 11:00:38 -050061#undef ARRAY_SIZE
62
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010063spv_result_t spvOperandTableNameLookup(const spv_operand_table table,
64 const spv_operand_type_t type,
David Neto388c40d2015-09-16 16:42:56 -040065 const char* name,
66 const size_t nameLength,
67 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040068 if (!table) return SPV_ERROR_INVALID_TABLE;
69 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010070
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010071 for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
Lei Zhangca1bf942016-04-27 16:47:13 -040072 const auto& group = table->types[typeIndex];
73 if (type != group.type) continue;
74 for (uint64_t index = 0; index < group.count; ++index) {
75 const auto& entry = group.entries[index];
76 if (nameLength == strlen(entry.name) &&
77 !strncmp(entry.name, name, nameLength)) {
78 *pEntry = &entry;
79 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010080 }
81 }
82 }
83
84 return SPV_ERROR_INVALID_LOOKUP;
85}
86
87spv_result_t spvOperandTableValueLookup(const spv_operand_table table,
88 const spv_operand_type_t type,
89 const uint32_t value,
Dejan Mircevski50babb22015-09-29 10:56:32 -040090 spv_operand_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040091 if (!table) return SPV_ERROR_INVALID_TABLE;
92 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010093
94 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;
97 for (uint64_t index = 0; index < group.count; ++index) {
98 const auto& entry = group.entries[index];
99 if (value == entry.value) {
100 *pEntry = &entry;
101 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100102 }
103 }
104 }
105
106 return SPV_ERROR_INVALID_LOOKUP;
107}
108
Dejan Mircevski50babb22015-09-29 10:56:32 -0400109const char* spvOperandTypeStr(spv_operand_type_t type) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100110 switch (type) {
111 case SPV_OPERAND_TYPE_ID:
David Netofadbf622015-09-14 17:07:11 -0400112 case SPV_OPERAND_TYPE_OPTIONAL_ID:
David Netofadbf622015-09-14 17:07:11 -0400113 return "ID";
David Neto201caf72015-11-04 17:38:17 -0500114 case SPV_OPERAND_TYPE_TYPE_ID:
115 return "type ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100116 case SPV_OPERAND_TYPE_RESULT_ID:
117 return "result ID";
Lei Zhang6483bd72015-10-14 17:02:39 -0400118 case SPV_OPERAND_TYPE_LITERAL_INTEGER:
David Neto201caf72015-11-04 17:38:17 -0500119 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
120 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100121 return "literal number";
David Neto201caf72015-11-04 17:38:17 -0500122 case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
123 return "possibly multi-word literal integer";
124 case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
125 return "possibly multi-word literal number";
126 case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
127 return "extension instruction number";
David Neto0f166be2015-11-11 01:56:49 -0500128 case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
129 return "OpSpecConstantOp opcode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100130 case SPV_OPERAND_TYPE_LITERAL_STRING:
David Neto201caf72015-11-04 17:38:17 -0500131 case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100132 return "literal string";
133 case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
Dejan Mircevskid2c81cf2015-10-09 11:06:10 -0400134 return "source language";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100135 case SPV_OPERAND_TYPE_EXECUTION_MODEL:
136 return "execution model";
137 case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
138 return "addressing model";
139 case SPV_OPERAND_TYPE_MEMORY_MODEL:
140 return "memory model";
141 case SPV_OPERAND_TYPE_EXECUTION_MODE:
142 return "execution mode";
143 case SPV_OPERAND_TYPE_STORAGE_CLASS:
144 return "storage class";
145 case SPV_OPERAND_TYPE_DIMENSIONALITY:
146 return "dimensionality";
147 case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
David Netod9ad0502015-11-24 18:37:24 -0500148 return "sampler addressing mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100149 case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
150 return "sampler filter mode";
David Netob30a0c52015-09-16 15:56:43 -0400151 case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
Dejan Mircevski971b3442015-10-13 12:54:47 -0400152 return "image format";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100153 case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400154 return "floating-point fast math mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100155 case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
Dejan Mircevski355cc0c2015-10-13 15:02:03 -0400156 return "floating-point rounding mode";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100157 case SPV_OPERAND_TYPE_LINKAGE_TYPE:
158 return "linkage type";
159 case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
David Neto2889a0c2016-02-15 13:50:00 -0500160 case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100161 return "access qualifier";
162 case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
163 return "function parameter attribute";
164 case SPV_OPERAND_TYPE_DECORATION:
165 return "decoration";
166 case SPV_OPERAND_TYPE_BUILT_IN:
Dejan Mircevskid7b0f832015-10-13 15:39:38 -0400167 return "built-in";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100168 case SPV_OPERAND_TYPE_SELECTION_CONTROL:
169 return "selection control";
170 case SPV_OPERAND_TYPE_LOOP_CONTROL:
171 return "loop control";
172 case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
173 return "function control";
David Neto64a9be92015-11-18 15:48:32 -0500174 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
David Netod9ad0502015-11-24 18:37:24 -0500175 return "memory semantics ID";
David Neto201caf72015-11-04 17:38:17 -0500176 case SPV_OPERAND_TYPE_MEMORY_ACCESS:
David Neto78c3b432015-08-27 13:03:52 -0400177 case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100178 return "memory access";
David Neto64a9be92015-11-18 15:48:32 -0500179 case SPV_OPERAND_TYPE_SCOPE_ID:
David Netod9ad0502015-11-24 18:37:24 -0500180 return "scope ID";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100181 case SPV_OPERAND_TYPE_GROUP_OPERATION:
182 return "group operation";
183 case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
184 return "kernel enqeue flags";
David Neto47994822015-08-27 13:11:01 -0400185 case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100186 return "kernel profiling info";
187 case SPV_OPERAND_TYPE_CAPABILITY:
188 return "capability";
David Neto201caf72015-11-04 17:38:17 -0500189 case SPV_OPERAND_TYPE_IMAGE:
David Netoee1b3bb2015-09-18 11:19:18 -0400190 case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
David Netod9ad0502015-11-24 18:37:24 -0500191 return "image";
David Neto201caf72015-11-04 17:38:17 -0500192 case SPV_OPERAND_TYPE_OPTIONAL_CIV:
193 return "context-insensitive value";
194
195 // The next values are for values returned from an instruction, not actually
196 // an operand. So the specific strings don't matter. But let's add them
197 // for completeness and ease of testing.
198 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
199 return "image channel order";
200 case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
201 return "image channel data type";
202
David Neto78c3b432015-08-27 13:03:52 -0400203 case SPV_OPERAND_TYPE_NONE:
204 return "NONE";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100205 default:
206 assert(0 && "Unhandled operand type!");
207 break;
208 }
209 return "unknown";
210}
David Neto78c3b432015-08-27 13:03:52 -0400211
212void spvPrependOperandTypes(const spv_operand_type_t* types,
213 spv_operand_pattern_t* pattern) {
214 const spv_operand_type_t* endTypes;
Dejan Mircevski50babb22015-09-29 10:56:32 -0400215 for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes)
David Neto78c3b432015-08-27 13:03:52 -0400216 ;
217 pattern->insert(pattern->begin(), types, endTypes);
218}
219
David Neto5bf88fc2015-09-17 17:06:10 -0400220void spvPrependOperandTypesForMask(const spv_operand_table operandTable,
221 const spv_operand_type_t type,
222 const uint32_t mask,
223 spv_operand_pattern_t* pattern) {
224 // Scan from highest bits to lowest bits because we will prepend in LIFO
225 // fashion, and we need the operands for lower order bits to appear first.
Jamie Madill34cb0032016-04-29 14:36:00 -0400226 for (uint32_t candidate_bit = (1u << 31u); candidate_bit; candidate_bit >>= 1) {
David Neto5bf88fc2015-09-17 17:06:10 -0400227 if (candidate_bit & mask) {
228 spv_operand_desc entry = nullptr;
229 if (SPV_SUCCESS == spvOperandTableValueLookup(operandTable, type,
230 candidate_bit, &entry)) {
231 spvPrependOperandTypes(entry->operandTypes, pattern);
232 }
233 }
234 }
235}
236
David Netob5267562016-02-02 12:05:34 -0500237bool spvOperandIsConcreteMask(spv_operand_type_t type) {
238 return SPV_OPERAND_TYPE_FIRST_CONCRETE_MASK_TYPE <= type &&
239 type <= SPV_OPERAND_TYPE_LAST_CONCRETE_MASK_TYPE;
240}
241
David Neto78c3b432015-08-27 13:03:52 -0400242bool spvOperandIsOptional(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500243 return SPV_OPERAND_TYPE_FIRST_OPTIONAL_TYPE <= type &&
244 type <= SPV_OPERAND_TYPE_LAST_OPTIONAL_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400245}
246
247bool spvOperandIsVariable(spv_operand_type_t type) {
David Neto201caf72015-11-04 17:38:17 -0500248 return SPV_OPERAND_TYPE_FIRST_VARIABLE_TYPE <= type &&
249 type <= SPV_OPERAND_TYPE_LAST_VARIABLE_TYPE;
David Neto78c3b432015-08-27 13:03:52 -0400250}
251
David Neto78c3b432015-08-27 13:03:52 -0400252bool spvExpandOperandSequenceOnce(spv_operand_type_t type,
253 spv_operand_pattern_t* pattern) {
254 switch (type) {
255 case SPV_OPERAND_TYPE_VARIABLE_ID:
256 pattern->insert(pattern->begin(), {SPV_OPERAND_TYPE_OPTIONAL_ID, type});
257 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400258 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
David Neto78c3b432015-08-27 13:03:52 -0400259 pattern->insert(pattern->begin(),
Lei Zhang6483bd72015-10-14 17:02:39 -0400260 {SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER, type});
David Neto78c3b432015-08-27 13:03:52 -0400261 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400262 case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
David Neto201caf72015-11-04 17:38:17 -0500263 // Represents Zero or more (Literal number, Id) pairs,
264 // where the literal number must be a scalar integer.
David Neto78c3b432015-08-27 13:03:52 -0400265 pattern->insert(pattern->begin(),
David Neto201caf72015-11-04 17:38:17 -0500266 {SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER,
267 SPV_OPERAND_TYPE_ID, type});
David Neto78c3b432015-08-27 13:03:52 -0400268 return true;
Lei Zhang6483bd72015-10-14 17:02:39 -0400269 case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
David Neto561dc4e2015-09-25 14:23:29 -0400270 // Represents Zero or more (Id, Literal number) pairs.
David Neto201caf72015-11-04 17:38:17 -0500271 pattern->insert(pattern->begin(),
272 {SPV_OPERAND_TYPE_OPTIONAL_ID,
273 SPV_OPERAND_TYPE_LITERAL_INTEGER, type});
David Neto78c3b432015-08-27 13:03:52 -0400274 return true;
David Neto78c3b432015-08-27 13:03:52 -0400275 default:
276 break;
277 }
278 return false;
279}
280
Dejan Mircevski50babb22015-09-29 10:56:32 -0400281spv_operand_type_t spvTakeFirstMatchableOperand(
282 spv_operand_pattern_t* pattern) {
David Neto78c3b432015-08-27 13:03:52 -0400283 assert(!pattern->empty());
284 spv_operand_type_t result;
285 do {
286 result = pattern->front();
287 pattern->pop_front();
Dejan Mircevski50babb22015-09-29 10:56:32 -0400288 } while (spvExpandOperandSequenceOnce(result, pattern));
David Neto78c3b432015-08-27 13:03:52 -0400289 return result;
290}
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400291
Dejan Mircevski897bff92015-09-29 10:38:18 -0400292spv_operand_pattern_t spvAlternatePatternFollowingImmediate(
293 const spv_operand_pattern_t& pattern) {
294 spv_operand_pattern_t alternatePattern;
295 for (const auto& operand : pattern) {
296 if (operand == SPV_OPERAND_TYPE_RESULT_ID) {
297 alternatePattern.push_back(operand);
298 alternatePattern.push_back(SPV_OPERAND_TYPE_OPTIONAL_CIV);
299 return alternatePattern;
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400300 }
Dejan Mircevski897bff92015-09-29 10:38:18 -0400301 alternatePattern.push_back(SPV_OPERAND_TYPE_OPTIONAL_CIV);
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400302 }
Dejan Mircevski897bff92015-09-29 10:38:18 -0400303 // No result-id found, so just expect CIVs.
304 return {SPV_OPERAND_TYPE_OPTIONAL_CIV};
Dejan Mircevski903f9d62015-09-28 17:04:39 -0400305}
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500306
307bool spvIsIdType(spv_operand_type_t type) {
308 switch (type) {
309 case SPV_OPERAND_TYPE_ID:
310 case SPV_OPERAND_TYPE_TYPE_ID:
311 case SPV_OPERAND_TYPE_RESULT_ID:
312 case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
313 case SPV_OPERAND_TYPE_SCOPE_ID:
314 return true;
315 default:
316 return false;
317 }
Dejan Mircevski961f5dc2016-01-15 11:25:11 -0500318}