blob: da096a4044bd7e8599ffec63f6676b36665d2e62 [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/opcode.h"
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010016
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
dan sinclaireda2cfb2018-08-03 15:06:09 -040023#include "source/instruction.h"
24#include "source/macro.h"
25#include "source/spirv_constant.h"
26#include "source/spirv_endian.h"
27#include "source/spirv_target_env.h"
David Neto5a703352016-02-17 14:44:00 -050028#include "spirv-tools/libspirv.h"
Lei Zhang923f6c12015-11-11 12:45:23 -050029
David Neto78c3b432015-08-27 13:03:52 -040030namespace {
Lei Zhang16981f82017-09-21 17:24:57 -040031struct OpcodeDescPtrLen {
32 const spv_opcode_desc_t* ptr;
33 uint32_t len;
34};
David Neto78c3b432015-08-27 13:03:52 -040035
dan sinclaireda2cfb2018-08-03 15:06:09 -040036#include "core.insts-unified1.inc"
Lei Zhang16981f82017-09-21 17:24:57 -040037
Lei Zhang1ef6b192018-03-14 13:06:18 -040038static const spv_opcode_table_t kOpcodeTable = {ARRAY_SIZE(kOpcodeTableEntries),
39 kOpcodeTableEntries};
David Neto78c3b432015-08-27 13:03:52 -040040
David Neto5a0b5ca2016-12-09 14:01:43 -050041// Represents a vendor tool entry in the SPIR-V XML Regsitry.
42struct VendorTool {
43 uint32_t value;
44 const char* vendor;
Lei Zhang16981f82017-09-21 17:24:57 -040045 const char* tool; // Might be empty string.
46 const char* vendor_tool; // Combiantion of vendor and tool.
David Neto5a0b5ca2016-12-09 14:01:43 -050047};
48
49const VendorTool vendor_tools[] = {
50#include "generators.inc"
51};
52
Lei Zhanga94701d2015-09-14 10:05:37 -040053} // anonymous namespace
David Neto78c3b432015-08-27 13:03:52 -040054
David Neto5a0b5ca2016-12-09 14:01:43 -050055// TODO(dneto): Move this to another file. It doesn't belong with opcode
56// processing.
Lei Zhang1a0334e2015-11-02 09:41:20 -050057const char* spvGeneratorStr(uint32_t generator) {
David Neto5a0b5ca2016-12-09 14:01:43 -050058 auto where = std::find_if(
59 std::begin(vendor_tools), std::end(vendor_tools),
60 [generator](const VendorTool& vt) { return generator == vt.value; });
61 if (where != std::end(vendor_tools)) return where->vendor_tool;
62 return "Unknown";
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010063}
64
Lei Zhangb36e7042015-10-28 13:40:52 -040065uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010066 return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
67}
68
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040069void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount,
70 uint16_t* pOpcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010071 if (pWordCount) {
72 *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
73 }
74 if (pOpcode) {
Lei Zhang6fa3f8a2016-03-31 17:26:31 -040075 *pOpcode = 0x0000ffff & word;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010076 }
77}
78
Lei Zhang1ef6b192018-03-14 13:06:18 -040079spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable, spv_target_env) {
Lei Zhang40056702015-09-11 14:31:27 -040080 if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010081
Lei Zhang16981f82017-09-21 17:24:57 -040082 // Descriptions of each opcode. Each entry describes the format of the
83 // instruction that follows a particular opcode.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010084
Lei Zhang1ef6b192018-03-14 13:06:18 -040085 *pInstTable = &kOpcodeTable;
86 return SPV_SUCCESS;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010087}
88
Lei Zhang1ef6b192018-03-14 13:06:18 -040089spv_result_t spvOpcodeTableNameLookup(spv_target_env env,
90 const spv_opcode_table table,
Lei Zhang1a0334e2015-11-02 09:41:20 -050091 const char* name,
92 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -040093 if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
94 if (!table) return SPV_ERROR_INVALID_TABLE;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010095
96 // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
97 // preferable but the table requires sorting on the Opcode name, but it's
Lei Zhang1ef6b192018-03-14 13:06:18 -040098 // static const initialized and matches the order of the spec.
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +010099 const size_t nameLength = strlen(name);
100 for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400101 const spv_opcode_desc_t& entry = table->entries[opcodeIndex];
102 // We considers the current opcode as available as long as
103 // 1. The target environment satisfies the minimal requirement of the
104 // opcode; or
105 // 2. There is at least one extension enabling this opcode.
106 //
107 // Note that the second rule assumes the extension enabling this instruction
108 // is indeed requested in the SPIR-V code; checking that should be
109 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -0400110 if ((spvVersionForTargetEnv(env) >= entry.minVersion ||
David Neto8d65c892018-06-19 09:54:33 -0400111 entry.numExtensions > 0u || entry.numCapabilities > 0u) &&
Lei Zhang1ef6b192018-03-14 13:06:18 -0400112 nameLength == strlen(entry.name) &&
113 !strncmp(name, entry.name, nameLength)) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100114 // NOTE: Found out Opcode!
Lei Zhang1ef6b192018-03-14 13:06:18 -0400115 *pEntry = &entry;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100116 return SPV_SUCCESS;
117 }
118 }
119
120 return SPV_ERROR_INVALID_LOOKUP;
121}
122
Lei Zhang1ef6b192018-03-14 13:06:18 -0400123spv_result_t spvOpcodeTableValueLookup(spv_target_env env,
124 const spv_opcode_table table,
Lei Zhangb36e7042015-10-28 13:40:52 -0400125 const SpvOp opcode,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500126 spv_opcode_desc* pEntry) {
Lei Zhang40056702015-09-11 14:31:27 -0400127 if (!table) return SPV_ERROR_INVALID_TABLE;
128 if (!pEntry) return SPV_ERROR_INVALID_POINTER;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100129
Jesus Carabanof063f912017-10-27 15:28:50 +0300130 const auto beg = table->entries;
131 const auto end = table->entries + table->count;
Lei Zhang1ef6b192018-03-14 13:06:18 -0400132
133 spv_opcode_desc_t needle = {"", opcode, 0, nullptr, 0, {},
134 false, false, 0, nullptr, ~0u};
135
Jesus Carabanof063f912017-10-27 15:28:50 +0300136 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
137 return lhs.opcode < rhs.opcode;
138 };
Lei Zhang1ef6b192018-03-14 13:06:18 -0400139
140 // We need to loop here because there can exist multiple symbols for the same
141 // opcode value, and they can be introduced in different target environments,
142 // which means they can have different minimal version requirements.
143 // Assumes the underlying table is already sorted ascendingly according to
144 // opcode value.
145 for (auto it = std::lower_bound(beg, end, needle, comp);
146 it != end && it->opcode == opcode; ++it) {
147 // We considers the current opcode as available as long as
148 // 1. The target environment satisfies the minimal requirement of the
149 // opcode; or
150 // 2. There is at least one extension enabling this opcode.
151 //
152 // Note that the second rule assumes the extension enabling this instruction
153 // is indeed requested in the SPIR-V code; checking that should be
154 // validator's work.
Lei Zhangddbaf322018-03-28 16:42:44 -0400155 if (spvVersionForTargetEnv(env) >= it->minVersion ||
David Neto8d65c892018-06-19 09:54:33 -0400156 it->numExtensions > 0u || it->numCapabilities > 0u) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400157 *pEntry = it;
158 return SPV_SUCCESS;
159 }
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100160 }
161
162 return SPV_ERROR_INVALID_LOOKUP;
163}
164
Lei Zhang1a0334e2015-11-02 09:41:20 -0500165void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100166 const uint16_t wordCount, const spv_endianness_t endian,
Lei Zhang1a0334e2015-11-02 09:41:20 -0500167 spv_instruction_t* pInst) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100168 pInst->opcode = opcode;
David Netob5dc8fc2015-10-06 16:22:00 -0400169 pInst->words.resize(wordCount);
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100170 for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
171 pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
172 if (!wordIndex) {
173 uint16_t thisWordCount;
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400174 uint16_t thisOpcode;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100175 spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
Lei Zhang6fa3f8a2016-03-31 17:26:31 -0400176 assert(opcode == static_cast<SpvOp>(thisOpcode) &&
177 wordCount == thisWordCount && "Endianness failed!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100178 }
179 }
180}
181
Lei Zhang1a0334e2015-11-02 09:41:20 -0500182const char* spvOpcodeString(const SpvOp opcode) {
Lei Zhang1ef6b192018-03-14 13:06:18 -0400183 const auto beg = kOpcodeTableEntries;
184 const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries);
185 spv_opcode_desc_t needle = {"", opcode, 0, nullptr, 0, {},
186 false, false, 0, nullptr, ~0u};
Jesus Carabanof063f912017-10-27 15:28:50 +0300187 auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
188 return lhs.opcode < rhs.opcode;
189 };
Lei Zhang1ef6b192018-03-14 13:06:18 -0400190 auto it = std::lower_bound(beg, end, needle, comp);
Diego Novillod2938e42017-11-08 12:40:02 -0500191 if (it != end && it->opcode == opcode) {
Jesus Carabanof063f912017-10-27 15:28:50 +0300192 return it->name;
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100193 }
Lei Zhang16981f82017-09-21 17:24:57 -0400194
Lei Zhang4f293b72016-03-21 16:36:14 -0400195 assert(0 && "Unreachable!");
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100196 return "unknown";
197}
198
Lei Zhangb36e7042015-10-28 13:40:52 -0400199int32_t spvOpcodeIsScalarType(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100200 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400201 case SpvOpTypeInt:
202 case SpvOpTypeFloat:
Dejan Mircevski276a7242016-01-21 15:55:43 -0500203 case SpvOpTypeBool:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100204 return true;
205 default:
206 return false;
207 }
208}
209
Alan Baker0a2ee652018-03-23 14:18:54 -0400210int32_t spvOpcodeIsSpecConstant(const SpvOp opcode) {
211 switch (opcode) {
212 case SpvOpSpecConstantTrue:
213 case SpvOpSpecConstantFalse:
214 case SpvOpSpecConstant:
215 case SpvOpSpecConstantComposite:
216 case SpvOpSpecConstantOp:
217 return true;
218 default:
219 return false;
220 }
221}
222
Lei Zhangb36e7042015-10-28 13:40:52 -0400223int32_t spvOpcodeIsConstant(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100224 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400225 case SpvOpConstantTrue:
226 case SpvOpConstantFalse:
227 case SpvOpConstant:
228 case SpvOpConstantComposite:
229 case SpvOpConstantSampler:
Lei Zhangb36e7042015-10-28 13:40:52 -0400230 case SpvOpConstantNull:
231 case SpvOpSpecConstantTrue:
232 case SpvOpSpecConstantFalse:
233 case SpvOpSpecConstant:
234 case SpvOpSpecConstantComposite:
Dejan Mircevski3fb26762016-04-04 15:55:05 -0400235 case SpvOpSpecConstantOp:
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100236 return true;
237 default:
238 return false;
239 }
240}
241
David Neto1f3fb502016-09-14 11:57:20 -0400242bool spvOpcodeIsConstantOrUndef(const SpvOp opcode) {
243 return opcode == SpvOpUndef || spvOpcodeIsConstant(opcode);
244}
245
Aliya Pazylbekovaedb52642017-02-24 20:43:28 -0500246bool spvOpcodeIsScalarSpecConstant(const SpvOp opcode) {
247 switch (opcode) {
248 case SpvOpSpecConstantTrue:
249 case SpvOpSpecConstantFalse:
250 case SpvOpSpecConstant:
251 return true;
252 default:
253 return false;
254 }
255}
256
Lei Zhangb36e7042015-10-28 13:40:52 -0400257int32_t spvOpcodeIsComposite(const SpvOp opcode) {
Kenneth Benzie (Benie)83e5a292015-05-22 18:26:19 +0100258 switch (opcode) {
Lei Zhangb36e7042015-10-28 13:40:52 -0400259 case SpvOpTypeVector:
260 case SpvOpTypeMatrix:
261 case SpvOpTypeArray:
262 case SpvOpTypeStruct:
Jeff Bolz002ef362019-02-25 16:43:11 -0600263 case SpvOpTypeCooperativeMatrixNV:
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:
alelenv1c1e7492018-10-25 11:07:46 -0700328 case SpvOpTypeAccelerationStructureNV:
Jeff Bolz002ef362019-02-25 16:43:11 -0600329 case SpvOpTypeCooperativeMatrixNV:
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400330 return true;
David Netoaef608c2015-11-02 14:59:02 -0500331 default:
332 // In particular, OpTypeForwardPointer does not generate a type,
333 // but declares a storage class for a pointer type generated
334 // by a different instruction.
335 break;
Andrew Woloszyn537e7762015-09-29 11:28:34 -0400336 }
337 return 0;
338}
Steven Perroneb4653a2017-11-13 15:31:43 -0500339
340bool spvOpcodeIsDecoration(const SpvOp opcode) {
Steven Perron28c41552017-11-10 20:26:55 -0500341 switch (opcode) {
Steven Perroneb4653a2017-11-13 15:31:43 -0500342 case SpvOpDecorate:
343 case SpvOpDecorateId:
344 case SpvOpMemberDecorate:
345 case SpvOpGroupDecorate:
346 case SpvOpGroupMemberDecorate:
David Neto5f69f752018-03-05 13:34:13 -0500347 case SpvOpDecorateStringGOOGLE:
348 case SpvOpMemberDecorateStringGOOGLE:
Steven Perroneb4653a2017-11-13 15:31:43 -0500349 return true;
350 default:
351 break;
352 }
353 return false;
354}
Steven Perron28c41552017-11-10 20:26:55 -0500355
356bool spvOpcodeIsLoad(const SpvOp opcode) {
357 switch (opcode) {
358 case SpvOpLoad:
359 case SpvOpImageSampleExplicitLod:
360 case SpvOpImageSampleImplicitLod:
361 case SpvOpImageSampleDrefImplicitLod:
362 case SpvOpImageSampleDrefExplicitLod:
363 case SpvOpImageSampleProjImplicitLod:
364 case SpvOpImageSampleProjExplicitLod:
365 case SpvOpImageSampleProjDrefImplicitLod:
366 case SpvOpImageSampleProjDrefExplicitLod:
367 case SpvOpImageFetch:
368 case SpvOpImageGather:
369 case SpvOpImageDrefGather:
370 case SpvOpImageRead:
371 case SpvOpImageSparseSampleImplicitLod:
372 case SpvOpImageSparseSampleExplicitLod:
373 case SpvOpImageSparseSampleDrefExplicitLod:
374 case SpvOpImageSparseSampleDrefImplicitLod:
375 case SpvOpImageSparseFetch:
376 case SpvOpImageSparseGather:
377 case SpvOpImageSparseDrefGather:
378 case SpvOpImageSparseRead:
379 return true;
380 default:
381 return false;
382 }
383}
384
Diego Novillo74327842017-11-17 08:59:25 -0500385bool spvOpcodeIsBranch(SpvOp opcode) {
386 switch (opcode) {
387 case SpvOpBranch:
388 case SpvOpBranchConditional:
389 case SpvOpSwitch:
390 return true;
391 default:
392 return false;
393 }
394}
395
greg-lunarge5455642018-10-12 06:46:35 -0600396bool spvOpcodeIsAtomicWithLoad(const SpvOp opcode) {
Steven Perron28c41552017-11-10 20:26:55 -0500397 switch (opcode) {
398 case SpvOpAtomicLoad:
Steven Perron28c41552017-11-10 20:26:55 -0500399 case SpvOpAtomicExchange:
400 case SpvOpAtomicCompareExchange:
401 case SpvOpAtomicCompareExchangeWeak:
402 case SpvOpAtomicIIncrement:
403 case SpvOpAtomicIDecrement:
404 case SpvOpAtomicIAdd:
405 case SpvOpAtomicISub:
406 case SpvOpAtomicSMin:
407 case SpvOpAtomicUMin:
408 case SpvOpAtomicSMax:
409 case SpvOpAtomicUMax:
410 case SpvOpAtomicAnd:
411 case SpvOpAtomicOr:
412 case SpvOpAtomicXor:
413 case SpvOpAtomicFlagTestAndSet:
Steven Perron28c41552017-11-10 20:26:55 -0500414 return true;
415 default:
416 return false;
417 }
418}
Diego Novillo74327842017-11-17 08:59:25 -0500419
greg-lunarge5455642018-10-12 06:46:35 -0600420bool spvOpcodeIsAtomicOp(const SpvOp opcode) {
421 return (spvOpcodeIsAtomicWithLoad(opcode) || opcode == SpvOpAtomicStore ||
422 opcode == SpvOpAtomicFlagClear);
423}
424
Diego Novillo74327842017-11-17 08:59:25 -0500425bool spvOpcodeIsReturn(SpvOp opcode) {
426 switch (opcode) {
427 case SpvOpReturn:
428 case SpvOpReturnValue:
429 return true;
430 default:
431 return false;
432 }
433}
434
Diego Novillo5f100782018-01-03 15:25:03 -0500435bool spvOpcodeIsReturnOrAbort(SpvOp opcode) {
436 return spvOpcodeIsReturn(opcode) || opcode == SpvOpKill ||
437 opcode == SpvOpUnreachable;
438}
439
Diego Novillo74327842017-11-17 08:59:25 -0500440bool spvOpcodeIsBlockTerminator(SpvOp opcode) {
Diego Novillo5f100782018-01-03 15:25:03 -0500441 return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
Diego Novillo74327842017-11-17 08:59:25 -0500442}
Steven Perron79a00642017-12-11 13:10:24 -0500443
444bool spvOpcodeIsBaseOpaqueType(SpvOp opcode) {
445 switch (opcode) {
446 case SpvOpTypeImage:
447 case SpvOpTypeSampler:
448 case SpvOpTypeSampledImage:
449 case SpvOpTypeOpaque:
450 case SpvOpTypeEvent:
451 case SpvOpTypeDeviceEvent:
452 case SpvOpTypeReserveId:
453 case SpvOpTypeQueue:
454 case SpvOpTypePipe:
455 case SpvOpTypeForwardPointer:
456 case SpvOpTypePipeStorage:
457 case SpvOpTypeNamedBarrier:
458 return true;
459 default:
460 return false;
461 }
462}
Alan Baker09c206b2018-04-17 10:18:59 -0400463
464bool spvOpcodeIsNonUniformGroupOperation(SpvOp opcode) {
465 switch (opcode) {
466 case SpvOpGroupNonUniformElect:
467 case SpvOpGroupNonUniformAll:
468 case SpvOpGroupNonUniformAny:
469 case SpvOpGroupNonUniformAllEqual:
470 case SpvOpGroupNonUniformBroadcast:
471 case SpvOpGroupNonUniformBroadcastFirst:
472 case SpvOpGroupNonUniformBallot:
473 case SpvOpGroupNonUniformInverseBallot:
474 case SpvOpGroupNonUniformBallotBitExtract:
475 case SpvOpGroupNonUniformBallotBitCount:
476 case SpvOpGroupNonUniformBallotFindLSB:
477 case SpvOpGroupNonUniformBallotFindMSB:
478 case SpvOpGroupNonUniformShuffle:
479 case SpvOpGroupNonUniformShuffleXor:
480 case SpvOpGroupNonUniformShuffleUp:
481 case SpvOpGroupNonUniformShuffleDown:
482 case SpvOpGroupNonUniformIAdd:
483 case SpvOpGroupNonUniformFAdd:
484 case SpvOpGroupNonUniformIMul:
485 case SpvOpGroupNonUniformFMul:
486 case SpvOpGroupNonUniformSMin:
487 case SpvOpGroupNonUniformUMin:
488 case SpvOpGroupNonUniformFMin:
489 case SpvOpGroupNonUniformSMax:
490 case SpvOpGroupNonUniformUMax:
491 case SpvOpGroupNonUniformFMax:
492 case SpvOpGroupNonUniformBitwiseAnd:
493 case SpvOpGroupNonUniformBitwiseOr:
494 case SpvOpGroupNonUniformBitwiseXor:
495 case SpvOpGroupNonUniformLogicalAnd:
496 case SpvOpGroupNonUniformLogicalOr:
497 case SpvOpGroupNonUniformLogicalXor:
498 case SpvOpGroupNonUniformQuadBroadcast:
499 case SpvOpGroupNonUniformQuadSwap:
500 return true;
501 default:
502 return false;
503 }
504}
Steven Perron2c0ce872018-04-23 11:13:07 -0400505
506bool spvOpcodeIsScalarizable(SpvOp opcode) {
507 switch (opcode) {
508 case SpvOpPhi:
509 case SpvOpCopyObject:
510 case SpvOpConvertFToU:
511 case SpvOpConvertFToS:
512 case SpvOpConvertSToF:
513 case SpvOpConvertUToF:
514 case SpvOpUConvert:
515 case SpvOpSConvert:
516 case SpvOpFConvert:
517 case SpvOpQuantizeToF16:
518 case SpvOpVectorInsertDynamic:
519 case SpvOpSNegate:
520 case SpvOpFNegate:
521 case SpvOpIAdd:
522 case SpvOpFAdd:
523 case SpvOpISub:
524 case SpvOpFSub:
525 case SpvOpIMul:
526 case SpvOpFMul:
527 case SpvOpUDiv:
528 case SpvOpSDiv:
529 case SpvOpFDiv:
530 case SpvOpUMod:
531 case SpvOpSRem:
532 case SpvOpSMod:
533 case SpvOpFRem:
534 case SpvOpFMod:
535 case SpvOpVectorTimesScalar:
536 case SpvOpIAddCarry:
537 case SpvOpISubBorrow:
538 case SpvOpUMulExtended:
539 case SpvOpSMulExtended:
540 case SpvOpShiftRightLogical:
541 case SpvOpShiftRightArithmetic:
542 case SpvOpShiftLeftLogical:
543 case SpvOpBitwiseOr:
544 case SpvOpBitwiseAnd:
545 case SpvOpNot:
546 case SpvOpBitFieldInsert:
547 case SpvOpBitFieldSExtract:
548 case SpvOpBitFieldUExtract:
549 case SpvOpBitReverse:
550 case SpvOpBitCount:
551 case SpvOpIsNan:
552 case SpvOpIsInf:
553 case SpvOpIsFinite:
554 case SpvOpIsNormal:
555 case SpvOpSignBitSet:
556 case SpvOpLessOrGreater:
557 case SpvOpOrdered:
558 case SpvOpUnordered:
559 case SpvOpLogicalEqual:
560 case SpvOpLogicalNotEqual:
561 case SpvOpLogicalOr:
562 case SpvOpLogicalAnd:
563 case SpvOpLogicalNot:
564 case SpvOpSelect:
565 case SpvOpIEqual:
566 case SpvOpINotEqual:
567 case SpvOpUGreaterThan:
568 case SpvOpSGreaterThan:
569 case SpvOpUGreaterThanEqual:
570 case SpvOpSGreaterThanEqual:
571 case SpvOpULessThan:
572 case SpvOpSLessThan:
573 case SpvOpULessThanEqual:
574 case SpvOpSLessThanEqual:
575 case SpvOpFOrdEqual:
576 case SpvOpFUnordEqual:
577 case SpvOpFOrdNotEqual:
578 case SpvOpFUnordNotEqual:
579 case SpvOpFOrdLessThan:
580 case SpvOpFUnordLessThan:
581 case SpvOpFOrdGreaterThan:
582 case SpvOpFUnordGreaterThan:
583 case SpvOpFOrdLessThanEqual:
584 case SpvOpFUnordLessThanEqual:
585 case SpvOpFOrdGreaterThanEqual:
586 case SpvOpFUnordGreaterThanEqual:
587 return true;
588 default:
589 return false;
590 }
591}
Ryan Harrison11c7a9e2018-11-20 16:12:28 -0500592
593bool spvOpcodeIsDebug(SpvOp opcode) {
594 switch (opcode) {
595 case SpvOpName:
596 case SpvOpMemberName:
597 case SpvOpSource:
598 case SpvOpSourceContinued:
599 case SpvOpSourceExtension:
600 case SpvOpString:
601 case SpvOpLine:
602 case SpvOpNoLine:
603 return true;
604 default:
605 return false;
606 }
607}