blob: 871c3372646337799a2eefbdbc4d576dd90d021b [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
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010015#include "opcode.h"
16
17#include <assert.h>
18#include <string.h>
19
David Neto5a0b5ca2016-12-09 14:01:43 -050020#include <algorithm>
Lei Zhang972788b2015-11-12 13:48:30 -050021#include <cstdlib>
22
Lei Zhang923f6c12015-11-11 12:45:23 -050023#include "instruction.h"
Lei Zhangca1bf942016-04-27 16:47:13 -040024#include "macro.h"
David Neto5a703352016-02-17 14:44:00 -050025#include "spirv-tools/libspirv.h"
Lei Zhangaa056cd2015-11-11 14:24:04 -050026#include "spirv_constant.h"
David Neto4c215712015-12-22 15:08:41 -050027#include "spirv_endian.h"
Lei Zhang923f6c12015-11-11 12:45:23 -050028
David Neto78c3b432015-08-27 13:03:52 -040029namespace {
Lei Zhang16981f82017-09-21 17:24:57 -040030struct OpcodeDescPtrLen {
31 const spv_opcode_desc_t* ptr;
32 uint32_t len;
33};
David Neto78c3b432015-08-27 13:03:52 -040034
David Neto00fa3932018-02-09 14:29:02 -050035// For now, assume unified1 contains up to SPIR-V 1.3 and no later
36// SPIR-V version.
37// TODO(dneto): Make one set of tables, but with version tags on a
38// per-item basis. https://github.com/KhronosGroup/SPIRV-Tools/issues/1195
39
40#include "core.insts-1.0.inc" // defines kOpcodeTableEntries_1_0
41#include "core.insts-1.1.inc" // defines kOpcodeTableEntries_1_1
42#include "core.insts-1.2.inc" // defines kOpcodeTableEntries_1_2
43#include "core.insts-unified1.inc" // defines kOpcodeTableEntries_1_3
Lei Zhang16981f82017-09-21 17:24:57 -040044
Lei Zhang063dbea2017-10-25 12:15:51 -040045static const spv_opcode_table_t kTable_1_0 = {
46 ARRAY_SIZE(kOpcodeTableEntries_1_0), kOpcodeTableEntries_1_0};
47static const spv_opcode_table_t kTable_1_1 = {
48 ARRAY_SIZE(kOpcodeTableEntries_1_1), kOpcodeTableEntries_1_1};
49static const spv_opcode_table_t kTable_1_2 = {
50 ARRAY_SIZE(kOpcodeTableEntries_1_2), kOpcodeTableEntries_1_2};
David Neto00fa3932018-02-09 14:29:02 -050051static const spv_opcode_table_t kTable_1_3 = {
52 ARRAY_SIZE(kOpcodeTableEntries_1_3), kOpcodeTableEntries_1_3};
David Neto78c3b432015-08-27 13:03:52 -040053
David Neto5a0b5ca2016-12-09 14:01:43 -050054// Represents a vendor tool entry in the SPIR-V XML Regsitry.
55struct VendorTool {
56 uint32_t value;
57 const char* vendor;
Lei Zhang16981f82017-09-21 17:24:57 -040058 const char* tool; // Might be empty string.
59 const char* vendor_tool; // Combiantion of vendor and tool.
David Neto5a0b5ca2016-12-09 14:01:43 -050060};
61
62const VendorTool vendor_tools[] = {
63#include "generators.inc"
64};
65
Lei Zhanga94701d2015-09-14 10:05:37 -040066} // anonymous namespace
David Neto78c3b432015-08-27 13:03:52 -040067
David Neto5a0b5ca2016-12-09 14:01:43 -050068// TODO(dneto): Move this to another file. It doesn't belong with opcode
69// processing.
Lei Zhang1a0334e2015-11-02 09:41:20 -050070const char* spvGeneratorStr(uint32_t generator) {
David Neto5a0b5ca2016-12-09 14:01:43 -050071 auto where = std::find_if(
72 std::begin(vendor_tools), std::end(vendor_tools),
73 [generator](const VendorTool& vt) { return generator == vt.value; });
74 if (where != std::end(vendor_tools)) return where->vendor_tool;
75 return "Unknown";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010076}
77
Lei Zhangb36e7042015-10-28 13:40:52 -040078uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010079 return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
80}
81
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040082void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount,
83 uint16_t* pOpcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010084 if (pWordCount) {
85 *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
86 }
87 if (pOpcode) {
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040088 *pOpcode = 0x0000ffff & word;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010089 }
90}
91
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040092spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable,
93 spv_target_env env) {
Lei Zhang40056702015-09-11 14:31:27 -040094 if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010095
Lei Zhang16981f82017-09-21 17:24:57 -040096 // Descriptions of each opcode. Each entry describes the format of the
97 // instruction that follows a particular opcode.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010098
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -040099 switch (env) {
100 case SPV_ENV_UNIVERSAL_1_0:
101 case SPV_ENV_VULKAN_1_0:
Pierre Moreau12447d82017-11-30 00:49:23 +0100102 case SPV_ENV_OPENCL_1_2:
103 case SPV_ENV_OPENCL_EMBEDDED_1_2:
104 case SPV_ENV_OPENCL_2_0:
105 case SPV_ENV_OPENCL_EMBEDDED_2_0:
David Netoc2967012016-08-05 18:19:30 -0400106 case SPV_ENV_OPENCL_2_1:
Pierre Moreau12447d82017-11-30 00:49:23 +0100107 case SPV_ENV_OPENCL_EMBEDDED_2_1:
David Netoc2967012016-08-05 18:19:30 -0400108 case SPV_ENV_OPENGL_4_0:
109 case SPV_ENV_OPENGL_4_1:
110 case SPV_ENV_OPENGL_4_2:
111 case SPV_ENV_OPENGL_4_3:
112 case SPV_ENV_OPENGL_4_5:
Lei Zhang063dbea2017-10-25 12:15:51 -0400113 *pInstTable = &kTable_1_0;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -0400114 return SPV_SUCCESS;
115 case SPV_ENV_UNIVERSAL_1_1:
Lei Zhang063dbea2017-10-25 12:15:51 -0400116 *pInstTable = &kTable_1_1;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -0400117 return SPV_SUCCESS;
David Netodbc20492017-03-14 12:43:41 -0400118 case SPV_ENV_UNIVERSAL_1_2:
119 case SPV_ENV_OPENCL_2_2:
Pierre Moreau12447d82017-11-30 00:49:23 +0100120 case SPV_ENV_OPENCL_EMBEDDED_2_2:
Lei Zhang063dbea2017-10-25 12:15:51 -0400121 *pInstTable = &kTable_1_2;
David Netodbc20492017-03-14 12:43:41 -0400122 return SPV_SUCCESS;
David Neto00fa3932018-02-09 14:29:02 -0500123 case SPV_ENV_UNIVERSAL_1_3:
124 case SPV_ENV_VULKAN_1_1:
125 *pInstTable = &kTable_1_3;
126 return SPV_SUCCESS;
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -0400127 }
128 assert(0 && "Unknown spv_target_env in spvOpcodeTableGet()");
129 return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100130}
131
132spv_result_t spvOpcodeTableNameLookup(const spv_opcode_table table,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500133 const char* name,
134 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400135 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
136 if (!table) return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100137
138 // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
139 // preferable but the table requires sorting on the Opcode name, but it's
140 // static
141 // const initialized and matches the order of the spec.
142 const size_t nameLength = strlen(name);
143 for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
144 if (nameLength == strlen(table->entries[opcodeIndex].name) &&
145 !strncmp(name, table->entries[opcodeIndex].name, nameLength)) {
146 // NOTE: Found out Opcode!
147 *pEntry = &table->entries[opcodeIndex];
148 return SPV_SUCCESS;
149 }
150 }
151
152 return SPV_ERROR_INVALID_LOOKUP;
153}
154
155spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table,
Lei Zhangb36e7042015-10-28 13:40:52 -0400156 const SpvOp opcode,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500157 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400158 if (!table) return SPV_ERROR_INVALID_TABLE;
159 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100160
Jesus Carabanof063f912017-10-27 15:28:50 +0300161 const auto beg = table->entries;
162 const auto end = table->entries + table->count;
163 spv_opcode_desc_t value{"", opcode, 0, nullptr, 0, {}, 0, 0};
164 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
165 return lhs.opcode < rhs.opcode;
166 };
167 auto it = std::lower_bound(beg, end, value, comp);
Diego Novillod2938e42017-11-08 12:40:02 -0500168 if (it != end && it->opcode == opcode) {
Jesus Carabanof063f912017-10-27 15:28:50 +0300169 *pEntry = it;
170 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100171 }
172
173 return SPV_ERROR_INVALID_LOOKUP;
174}
175
Lei Zhang1a0334e2015-11-02 09:41:20 -0500176void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100177 const uint16_t wordCount, const spv_endianness_t endian,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500178 spv_instruction_t* pInst) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100179 pInst->opcode = opcode;
David Netob5dc8fc2015-10-06 16:22:00 -0400180 pInst->words.resize(wordCount);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100181 for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
182 pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
183 if (!wordIndex) {
184 uint16_t thisWordCount;
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400185 uint16_t thisOpcode;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100186 spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400187 assert(opcode == static_cast<SpvOp>(thisOpcode) &&
188 wordCount == thisWordCount && "Endianness failed!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100189 }
190 }
191}
192
Lei Zhang1a0334e2015-11-02 09:41:20 -0500193const char* spvOpcodeString(const SpvOp opcode) {
Dejan Mircevskicb3c49e2016-04-07 14:41:34 -0400194 // Use the latest SPIR-V version, which should be backward-compatible with all
195 // previous ones.
Jesus Carabanof063f912017-10-27 15:28:50 +0300196
David Neto00fa3932018-02-09 14:29:02 -0500197 const auto beg = kOpcodeTableEntries_1_3;
Diego Novillod2938e42017-11-08 12:40:02 -0500198 const auto end =
David Neto00fa3932018-02-09 14:29:02 -0500199 kOpcodeTableEntries_1_3 + ARRAY_SIZE(kOpcodeTableEntries_1_3);
Jesus Carabanof063f912017-10-27 15:28:50 +0300200 spv_opcode_desc_t value{"", opcode, 0, nullptr, 0, {}, 0, 0};
201 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
202 return lhs.opcode < rhs.opcode;
203 };
204 auto it = std::lower_bound(beg, end, value, comp);
Diego Novillod2938e42017-11-08 12:40:02 -0500205 if (it != end && it->opcode == opcode) {
Jesus Carabanof063f912017-10-27 15:28:50 +0300206 return it->name;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100207 }
Lei Zhang16981f82017-09-21 17:24:57 -0400208
Lei Zhang4f293b72016-03-21 16:36:14 -0400209 assert(0 && "Unreachable!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100210 return "unknown";
211}
212
Lei Zhangb36e7042015-10-28 13:40:52 -0400213int32_t spvOpcodeIsScalarType(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100214 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400215 case SpvOpTypeInt:
216 case SpvOpTypeFloat:
Dejan Mircevski276a7242016-01-21 15:55:43 -0500217 case SpvOpTypeBool:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100218 return true;
219 default:
220 return false;
221 }
222}
223
Lei Zhangb36e7042015-10-28 13:40:52 -0400224int32_t spvOpcodeIsConstant(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100225 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400226 case SpvOpConstantTrue:
227 case SpvOpConstantFalse:
228 case SpvOpConstant:
229 case SpvOpConstantComposite:
230 case SpvOpConstantSampler:
Lei Zhangb36e7042015-10-28 13:40:52 -0400231 case SpvOpConstantNull:
232 case SpvOpSpecConstantTrue:
233 case SpvOpSpecConstantFalse:
234 case SpvOpSpecConstant:
235 case SpvOpSpecConstantComposite:
Dejan Mircevski3fb26762016-04-04 15:55:05 -0400236 case SpvOpSpecConstantOp:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100237 return true;
238 default:
239 return false;
240 }
241}
242
David Neto1f3fb502016-09-14 11:57:20 -0400243bool spvOpcodeIsConstantOrUndef(const SpvOp opcode) {
244 return opcode == SpvOpUndef || spvOpcodeIsConstant(opcode);
245}
246
Aliya Pazylbekovaedb52642017-02-24 20:43:28 -0500247bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode) {
248 switch (opcode) {
249 case SpvOpSpecConstantTrue:
250 case SpvOpSpecConstantFalse:
251 case SpvOpSpecConstant:
252 return true;
253 default:
254 return false;
255 }
256}
257
Lei Zhangb36e7042015-10-28 13:40:52 -0400258int32_t spvOpcodeIsComposite(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100259 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400260 case SpvOpTypeVector:
261 case SpvOpTypeMatrix:
262 case SpvOpTypeArray:
263 case SpvOpTypeStruct:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100264 return true;
265 default:
266 return false;
267 }
268}
269
Ehsan Nasiri23af06c2017-02-01 15:37:39 -0500270bool spvOpcodeReturnsLogicalVariablePointer(const SpvOp opcode) {
271 switch (opcode) {
272 case SpvOpVariable:
273 case SpvOpAccessChain:
274 case SpvOpInBoundsAccessChain:
275 case SpvOpFunctionParameter:
276 case SpvOpImageTexelPointer:
277 case SpvOpCopyObject:
278 case SpvOpSelect:
279 case SpvOpPhi:
280 case SpvOpFunctionCall:
281 case SpvOpPtrAccessChain:
282 case SpvOpLoad:
283 case SpvOpConstantNull:
284 return true;
285 default:
286 return false;
287 }
288}
289
Florian Ziesche66fcb452016-03-02 22:17:54 +0100290int32_t spvOpcodeReturnsLogicalPointer(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100291 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400292 case SpvOpVariable:
293 case SpvOpAccessChain:
294 case SpvOpInBoundsAccessChain:
295 case SpvOpFunctionParameter:
Florian Ziesche66fcb452016-03-02 22:17:54 +0100296 case SpvOpImageTexelPointer:
297 case SpvOpCopyObject:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100298 return true;
299 default:
300 return false;
301 }
302}
303
Lei Zhangb36e7042015-10-28 13:40:52 -0400304int32_t spvOpcodeGeneratesType(SpvOp op) {
Lei Zhang1a0334e2015-11-02 09:41:20 -0500305 switch (op) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400306 case SpvOpTypeVoid:
307 case SpvOpTypeBool:
308 case SpvOpTypeInt:
309 case SpvOpTypeFloat:
310 case SpvOpTypeVector:
311 case SpvOpTypeMatrix:
312 case SpvOpTypeImage:
313 case SpvOpTypeSampler:
314 case SpvOpTypeSampledImage:
315 case SpvOpTypeArray:
316 case SpvOpTypeRuntimeArray:
317 case SpvOpTypeStruct:
318 case SpvOpTypeOpaque:
319 case SpvOpTypePointer:
320 case SpvOpTypeFunction:
321 case SpvOpTypeEvent:
322 case SpvOpTypeDeviceEvent:
323 case SpvOpTypeReserveId:
324 case SpvOpTypeQueue:
325 case SpvOpTypePipe:
Andrey Tuganov4ef3b3e2017-02-28 11:53:47 -0500326 case SpvOpTypePipeStorage:
327 case SpvOpTypeNamedBarrier:
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400328 return true;
David Netoaef608c2015-11-02 14:59:02 -0500329 default:
330 // In particular, OpTypeForwardPointer does not generate a type,
331 // but declares a storage class for a pointer type generated
332 // by a different instruction.
333 break;
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400334 }
335 return 0;
336}
Steven Perroneb4653a2017-11-13 15:31:43 -0500337
338bool spvOpcodeIsDecoration(const SpvOp opcode) {
Steven Perron28c41552017-11-10 20:26:55 -0500339 switch (opcode) {
Steven Perroneb4653a2017-11-13 15:31:43 -0500340 case SpvOpDecorate:
341 case SpvOpDecorateId:
342 case SpvOpMemberDecorate:
343 case SpvOpGroupDecorate:
344 case SpvOpGroupMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500345 case SpvOpDecorateStringGOOGLE:
346 case SpvOpMemberDecorateStringGOOGLE:
Steven Perroneb4653a2017-11-13 15:31:43 -0500347 return true;
348 default:
349 break;
350 }
351 return false;
352}
Steven Perron28c41552017-11-10 20:26:55 -0500353
354bool spvOpcodeIsLoad(const SpvOp opcode) {
355 switch (opcode) {
356 case SpvOpLoad:
357 case SpvOpImageSampleExplicitLod:
358 case SpvOpImageSampleImplicitLod:
359 case SpvOpImageSampleDrefImplicitLod:
360 case SpvOpImageSampleDrefExplicitLod:
361 case SpvOpImageSampleProjImplicitLod:
362 case SpvOpImageSampleProjExplicitLod:
363 case SpvOpImageSampleProjDrefImplicitLod:
364 case SpvOpImageSampleProjDrefExplicitLod:
365 case SpvOpImageFetch:
366 case SpvOpImageGather:
367 case SpvOpImageDrefGather:
368 case SpvOpImageRead:
369 case SpvOpImageSparseSampleImplicitLod:
370 case SpvOpImageSparseSampleExplicitLod:
371 case SpvOpImageSparseSampleDrefExplicitLod:
372 case SpvOpImageSparseSampleDrefImplicitLod:
373 case SpvOpImageSparseFetch:
374 case SpvOpImageSparseGather:
375 case SpvOpImageSparseDrefGather:
376 case SpvOpImageSparseRead:
377 return true;
378 default:
379 return false;
380 }
381}
382
Diego Novillo74327842017-11-17 08:59:25 -0500383bool spvOpcodeIsBranch(SpvOp opcode) {
384 switch (opcode) {
385 case SpvOpBranch:
386 case SpvOpBranchConditional:
387 case SpvOpSwitch:
388 return true;
389 default:
390 return false;
391 }
392}
393
Steven Perron28c41552017-11-10 20:26:55 -0500394bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
395 switch (opcode) {
396 case SpvOpAtomicLoad:
397 case SpvOpAtomicStore:
398 case SpvOpAtomicExchange:
399 case SpvOpAtomicCompareExchange:
400 case SpvOpAtomicCompareExchangeWeak:
401 case SpvOpAtomicIIncrement:
402 case SpvOpAtomicIDecrement:
403 case SpvOpAtomicIAdd:
404 case SpvOpAtomicISub:
405 case SpvOpAtomicSMin:
406 case SpvOpAtomicUMin:
407 case SpvOpAtomicSMax:
408 case SpvOpAtomicUMax:
409 case SpvOpAtomicAnd:
410 case SpvOpAtomicOr:
411 case SpvOpAtomicXor:
412 case SpvOpAtomicFlagTestAndSet:
413 case SpvOpAtomicFlagClear:
414 return true;
415 default:
416 return false;
417 }
418}
Diego Novillo74327842017-11-17 08:59:25 -0500419
420bool spvOpcodeIsReturn(SpvOp opcode) {
421 switch (opcode) {
422 case SpvOpReturn:
423 case SpvOpReturnValue:
424 return true;
425 default:
426 return false;
427 }
428}
429
Diego Novillo5f100782018-01-03 15:25:03 -0500430bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
431 return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
432 opcode == SpvOpUnreachable;
433}
434
Diego Novillo74327842017-11-17 08:59:25 -0500435bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
Diego Novillo5f100782018-01-03 15:25:03 -0500436 return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
Diego Novillo74327842017-11-17 08:59:25 -0500437}
Steven Perron79a00642017-12-11 13:10:24 -0500438
439bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
440 switch (opcode) {
441 case SpvOpTypeImage:
442 case SpvOpTypeSampler:
443 case SpvOpTypeSampledImage:
444 case SpvOpTypeOpaque:
445 case SpvOpTypeEvent:
446 case SpvOpTypeDeviceEvent:
447 case SpvOpTypeReserveId:
448 case SpvOpTypeQueue:
449 case SpvOpTypePipe:
450 case SpvOpTypeForwardPointer:
451 case SpvOpTypePipeStorage:
452 case SpvOpTypeNamedBarrier:
453 return true;
454 default:
455 return false;
456 }
457}