Coverage Report

Created: 2026-09-13 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/shaderc/third_party/spirv-tools/source/opcode.cpp
Line
Count
Source
1
// Copyright (c) 2015-2022 The Khronos Group Inc.
2
// Modifications Copyright (C) 2020-2024 Advanced Micro Devices, Inc. All
3
// rights reserved.
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
//     http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16
17
#include "source/opcode.h"
18
19
#include <assert.h>
20
#include <string.h>
21
22
#include <algorithm>
23
#include <cstdlib>
24
25
#include "source/instruction.h"
26
#include "source/macro.h"
27
#include "source/spirv_constant.h"
28
#include "source/spirv_endian.h"
29
#include "source/spirv_target_env.h"
30
#include "source/table2.h"
31
#include "spirv-tools/libspirv.h"
32
33
namespace {
34
35
// Represents a vendor tool entry in the SPIR-V XML Registry.
36
struct VendorTool {
37
  uint32_t value;
38
  const char* vendor;
39
  const char* tool;         // Might be empty string.
40
  const char* vendor_tool;  // Combination of vendor and tool.
41
};
42
43
const VendorTool vendor_tools[] = {
44
#include "generators.inc"
45
};
46
47
}  // anonymous namespace
48
49
// TODO(dneto): Move this to another file.  It doesn't belong with opcode
50
// processing.
51
168
const char* spvGeneratorStr(uint32_t generator) {
52
168
  auto where = std::find_if(
53
168
      std::begin(vendor_tools), std::end(vendor_tools),
54
2.35k
      [generator](const VendorTool& vt) { return generator == vt.value; });
55
168
  if (where != std::end(vendor_tools)) return where->vendor_tool;
56
0
  return "Unknown";
57
168
}
58
59
0
uint32_t spvOpcodeMake(uint16_t wordCount, spv::Op opcode) {
60
0
  return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
61
0
}
62
63
void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount,
64
440k
                    uint16_t* pOpcode) {
65
440k
  if (pWordCount) {
66
440k
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
67
440k
  }
68
440k
  if (pOpcode) {
69
440k
    *pOpcode = 0x0000ffff & word;
70
440k
  }
71
440k
}
72
73
void spvInstructionCopy(const uint32_t* words, const spv::Op opcode,
74
                        const uint16_t wordCount, const spv_endianness_t endian,
75
0
                        spv_instruction_t* pInst) {
76
0
  pInst->opcode = opcode;
77
0
  pInst->words.resize(wordCount);
78
0
  for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
79
0
    pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
80
0
    if (!wordIndex) {
81
0
      uint16_t thisWordCount;
82
0
      uint16_t thisOpcode;
83
0
      spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
84
0
      assert(opcode == static_cast<spv::Op>(thisOpcode) &&
85
0
             wordCount == thisWordCount && "Endianness failed!");
86
0
    }
87
0
  }
88
0
}
89
90
46.5k
const char* spvOpcodeString(const uint32_t opcode) {
91
46.5k
  const spvtools::InstructionDesc* desc = nullptr;
92
46.5k
  if (SPV_SUCCESS !=
93
46.5k
      spvtools::LookupOpcode(static_cast<spv::Op>(opcode), &desc)) {
94
0
    assert(0 && "Unreachable!");
95
0
    return "unknown";
96
0
  }
97
46.5k
  return desc->name().data();
98
46.5k
}
99
100
46.5k
const char* spvOpcodeString(const spv::Op opcode) {
101
46.5k
  return spvOpcodeString(static_cast<uint32_t>(opcode));
102
46.5k
}
103
104
2.21k
int32_t spvOpcodeIsScalarType(const spv::Op opcode) {
105
2.21k
  switch (opcode) {
106
736
    case spv::Op::OpTypeInt:
107
1.67k
    case spv::Op::OpTypeFloat:
108
2.10k
    case spv::Op::OpTypeBool:
109
2.10k
      return true;
110
108
    default:
111
108
      return false;
112
2.21k
  }
113
2.21k
}
114
115
9.73k
int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
116
9.73k
  switch (opcode) {
117
2
    case spv::Op::OpSpecConstantTrue:
118
2
    case spv::Op::OpSpecConstantFalse:
119
22
    case spv::Op::OpSpecConstant:
120
22
    case spv::Op::OpSpecConstantComposite:
121
22
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
122
22
    case spv::Op::OpSpecConstantOp:
123
22
    case spv::Op::OpSpecConstantArchitectureINTEL:
124
22
    case spv::Op::OpSpecConstantTargetINTEL:
125
22
    case spv::Op::OpSpecConstantCapabilitiesINTEL:
126
22
    case spv::Op::OpSpecConstantDataKHR:
127
22
      return true;
128
9.70k
    default:
129
9.70k
      return false;
130
9.73k
  }
131
9.73k
}
132
133
406k
int32_t spvOpcodeIsConstant(const spv::Op opcode) {
134
406k
  switch (opcode) {
135
554
    case spv::Op::OpConstantTrue:
136
878
    case spv::Op::OpConstantFalse:
137
36.0k
    case spv::Op::OpConstant:
138
41.2k
    case spv::Op::OpConstantComposite:
139
41.2k
    case spv::Op::OpConstantCompositeReplicateEXT:
140
41.2k
    case spv::Op::OpConstantSampler:
141
41.2k
    case spv::Op::OpConstantNull:
142
41.2k
    case spv::Op::OpConstantFunctionPointerINTEL:
143
41.2k
    case spv::Op::OpConstantStringAMDX:
144
41.3k
    case spv::Op::OpSpecConstantTrue:
145
41.3k
    case spv::Op::OpSpecConstantFalse:
146
41.6k
    case spv::Op::OpSpecConstant:
147
41.6k
    case spv::Op::OpSpecConstantComposite:
148
41.6k
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
149
41.7k
    case spv::Op::OpSpecConstantOp:
150
41.7k
    case spv::Op::OpSpecConstantStringAMDX:
151
41.7k
    case spv::Op::OpGraphConstantARM:
152
41.7k
    case spv::Op::OpAsmTargetINTEL:
153
41.7k
    case spv::Op::OpAsmINTEL:
154
41.7k
    case spv::Op::OpSpecConstantArchitectureINTEL:
155
41.7k
    case spv::Op::OpSpecConstantTargetINTEL:
156
41.7k
    case spv::Op::OpSpecConstantCapabilitiesINTEL:
157
41.7k
    case spv::Op::OpConstantSizeOfEXT:
158
41.7k
    case spv::Op::OpConstantDataKHR:
159
41.7k
    case spv::Op::OpSpecConstantDataKHR:
160
41.7k
      return true;
161
364k
    default:
162
364k
      return false;
163
406k
  }
164
406k
}
165
166
1.86k
bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
167
1.86k
  return opcode == spv::Op::OpUndef || opcode == spv::Op::OpPoisonKHR ||
168
1.86k
         spvOpcodeIsConstant(opcode);
169
1.86k
}
170
171
3.43k
int32_t spvOpcodeIsComposite(const spv::Op opcode) {
172
3.43k
  switch (opcode) {
173
992
    case spv::Op::OpTypeVector:
174
1.13k
    case spv::Op::OpTypeMatrix:
175
1.15k
    case spv::Op::OpTypeArray:
176
1.21k
    case spv::Op::OpTypeStruct:
177
1.21k
    case spv::Op::OpTypeRuntimeArray:
178
1.21k
    case spv::Op::OpTypeCooperativeMatrixNV:
179
1.21k
    case spv::Op::OpTypeCooperativeMatrixKHR:
180
1.21k
    case spv::Op::OpTypeVectorIdEXT:
181
1.21k
      return true;
182
2.22k
    default:
183
2.22k
      return false;
184
3.43k
  }
185
3.43k
}
186
187
0
bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) {
188
0
  switch (opcode) {
189
0
    case spv::Op::OpVariable:
190
0
    case spv::Op::OpUntypedVariableKHR:
191
0
    case spv::Op::OpAccessChain:
192
0
    case spv::Op::OpInBoundsAccessChain:
193
0
    case spv::Op::OpUntypedAccessChainKHR:
194
0
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
195
0
    case spv::Op::OpBufferPointerEXT:
196
0
    case spv::Op::OpFunctionParameter:
197
0
    case spv::Op::OpImageTexelPointer:
198
0
    case spv::Op::OpUntypedImageTexelPointerEXT:
199
0
    case spv::Op::OpCopyObject:
200
0
    case spv::Op::OpAllocateNodePayloadsAMDX:
201
0
    case spv::Op::OpSelect:
202
0
    case spv::Op::OpPhi:
203
0
    case spv::Op::OpFunctionCall:
204
0
    case spv::Op::OpPtrAccessChain:
205
0
    case spv::Op::OpUntypedPtrAccessChainKHR:
206
0
    case spv::Op::OpLoad:
207
0
    case spv::Op::OpConstantNull:
208
0
    case spv::Op::OpRawAccessChainNV:
209
0
      return true;
210
0
    default:
211
0
      return false;
212
0
  }
213
0
}
214
215
24.4k
int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
216
24.4k
  switch (opcode) {
217
17.7k
    case spv::Op::OpVariable:
218
17.7k
    case spv::Op::OpUntypedVariableKHR:
219
23.5k
    case spv::Op::OpAccessChain:
220
23.5k
    case spv::Op::OpInBoundsAccessChain:
221
23.5k
    case spv::Op::OpUntypedAccessChainKHR:
222
23.5k
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
223
23.5k
    case spv::Op::OpBufferPointerEXT:
224
24.4k
    case spv::Op::OpFunctionParameter:
225
24.4k
    case spv::Op::OpImageTexelPointer:
226
24.4k
    case spv::Op::OpUntypedImageTexelPointerEXT:
227
24.4k
    case spv::Op::OpCopyObject:
228
24.4k
    case spv::Op::OpRawAccessChainNV:
229
24.4k
    case spv::Op::OpAllocateNodePayloadsAMDX:
230
24.4k
      return true;
231
0
    default:
232
0
      return false;
233
24.4k
  }
234
24.4k
}
235
236
1.37M
int32_t spvOpcodeGeneratesType(spv::Op op) {
237
1.37M
  switch (op) {
238
7.24k
    case spv::Op::OpTypeVoid:
239
12.3k
    case spv::Op::OpTypeBool:
240
36.5k
    case spv::Op::OpTypeInt:
241
56.6k
    case spv::Op::OpTypeFloat:
242
102k
    case spv::Op::OpTypeVector:
243
108k
    case spv::Op::OpTypeMatrix:
244
119k
    case spv::Op::OpTypeImage:
245
120k
    case spv::Op::OpTypeSampler:
246
126k
    case spv::Op::OpTypeSampledImage:
247
129k
    case spv::Op::OpTypeArray:
248
130k
    case spv::Op::OpTypeRuntimeArray:
249
142k
    case spv::Op::OpTypeStruct:
250
142k
    case spv::Op::OpTypeOpaque:
251
215k
    case spv::Op::OpTypePointer:
252
227k
    case spv::Op::OpTypeFunction:
253
227k
    case spv::Op::OpTypeEvent:
254
227k
    case spv::Op::OpTypeDeviceEvent:
255
227k
    case spv::Op::OpTypeReserveId:
256
227k
    case spv::Op::OpTypeQueue:
257
227k
    case spv::Op::OpTypePipe:
258
227k
    case spv::Op::OpTypePipeStorage:
259
227k
    case spv::Op::OpTypeNamedBarrier:
260
228k
    case spv::Op::OpTypeAccelerationStructureNV:
261
228k
    case spv::Op::OpTypeCooperativeMatrixNV:
262
228k
    case spv::Op::OpTypeCooperativeMatrixKHR:
263
228k
    case spv::Op::OpTypeVectorIdEXT:
264
    // case spv::Op::OpTypeAccelerationStructureKHR: covered by
265
    // spv::Op::OpTypeAccelerationStructureNV
266
228k
    case spv::Op::OpTypeRayQueryKHR:
267
228k
    case spv::Op::OpTypeHitObjectNV:
268
228k
    case spv::Op::OpTypeHitObjectEXT:
269
228k
    case spv::Op::OpTypeUntypedPointerKHR:
270
228k
    case spv::Op::OpTypeNodePayloadArrayAMDX:
271
228k
    case spv::Op::OpTypeTensorLayoutNV:
272
228k
    case spv::Op::OpTypeTensorViewNV:
273
228k
    case spv::Op::OpTypeTensorARM:
274
228k
    case spv::Op::OpTypeTaskSequenceINTEL:
275
228k
    case spv::Op::OpTypeGraphARM:
276
228k
    case spv::Op::OpTypeBufferEXT:
277
228k
      return true;
278
1.14M
    default:
279
      // In particular, OpTypeForwardPointer does not generate a type,
280
      // but declares a storage class for a pointer type generated
281
      // by a different instruction.
282
1.14M
      break;
283
1.37M
  }
284
1.14M
  return 0;
285
1.37M
}
286
287
234k
bool spvOpcodeIsDecoration(const spv::Op opcode) {
288
234k
  switch (opcode) {
289
2.70k
    case spv::Op::OpDecorate:
290
2.70k
    case spv::Op::OpDecorateId:
291
4.02k
    case spv::Op::OpMemberDecorate:
292
4.02k
    case spv::Op::OpMemberDecorateIdEXT:
293
4.02k
    case spv::Op::OpGroupDecorate:
294
4.02k
    case spv::Op::OpGroupMemberDecorate:
295
4.02k
    case spv::Op::OpDecorateStringGOOGLE:
296
4.02k
    case spv::Op::OpMemberDecorateStringGOOGLE:
297
4.02k
      return true;
298
230k
    default:
299
230k
      break;
300
234k
  }
301
230k
  return false;
302
234k
}
303
304
238k
bool spvOpcodeIsLoad(const spv::Op opcode) {
305
238k
  switch (opcode) {
306
20.2k
    case spv::Op::OpLoad:
307
25.1k
    case spv::Op::OpImageSampleExplicitLod:
308
25.1k
    case spv::Op::OpImageSampleImplicitLod:
309
25.1k
    case spv::Op::OpImageSampleDrefImplicitLod:
310
25.1k
    case spv::Op::OpImageSampleDrefExplicitLod:
311
25.1k
    case spv::Op::OpImageSampleProjImplicitLod:
312
25.1k
    case spv::Op::OpImageSampleProjExplicitLod:
313
25.1k
    case spv::Op::OpImageSampleProjDrefImplicitLod:
314
25.1k
    case spv::Op::OpImageSampleProjDrefExplicitLod:
315
25.1k
    case spv::Op::OpImageSampleFootprintNV:
316
25.1k
    case spv::Op::OpImageFetch:
317
25.1k
    case spv::Op::OpImageGather:
318
25.1k
    case spv::Op::OpImageDrefGather:
319
25.3k
    case spv::Op::OpImageRead:
320
25.3k
    case spv::Op::OpImageSparseSampleImplicitLod:
321
25.3k
    case spv::Op::OpImageSparseSampleExplicitLod:
322
25.3k
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
323
25.3k
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
324
25.3k
    case spv::Op::OpImageSparseFetch:
325
25.3k
    case spv::Op::OpImageSparseGather:
326
25.3k
    case spv::Op::OpImageSparseDrefGather:
327
25.4k
    case spv::Op::OpImageSparseRead:
328
25.4k
      return true;
329
213k
    default:
330
213k
      return false;
331
238k
  }
332
238k
}
333
334
851k
bool spvOpcodeIsBranch(spv::Op opcode) {
335
851k
  switch (opcode) {
336
81.7k
    case spv::Op::OpBranch:
337
129k
    case spv::Op::OpBranchConditional:
338
134k
    case spv::Op::OpSwitch:
339
134k
      return true;
340
717k
    default:
341
717k
      return false;
342
851k
  }
343
851k
}
344
345
538k
bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) {
346
538k
  switch (opcode) {
347
0
    case spv::Op::OpAtomicLoad:
348
0
    case spv::Op::OpAtomicExchange:
349
0
    case spv::Op::OpAtomicCompareExchange:
350
0
    case spv::Op::OpAtomicCompareExchangeWeak:
351
0
    case spv::Op::OpAtomicIIncrement:
352
0
    case spv::Op::OpAtomicIDecrement:
353
0
    case spv::Op::OpAtomicIAdd:
354
0
    case spv::Op::OpAtomicFAddEXT:
355
0
    case spv::Op::OpAtomicISub:
356
0
    case spv::Op::OpAtomicSMin:
357
0
    case spv::Op::OpAtomicUMin:
358
0
    case spv::Op::OpAtomicFMinEXT:
359
0
    case spv::Op::OpAtomicSMax:
360
0
    case spv::Op::OpAtomicUMax:
361
0
    case spv::Op::OpAtomicFMaxEXT:
362
0
    case spv::Op::OpAtomicAnd:
363
0
    case spv::Op::OpAtomicOr:
364
0
    case spv::Op::OpAtomicXor:
365
0
    case spv::Op::OpAtomicFlagTestAndSet:
366
0
      return true;
367
538k
    default:
368
538k
      return false;
369
538k
  }
370
538k
}
371
372
0
bool spvOpcodeIsAtomicOp(const spv::Op opcode) {
373
0
  return (spvOpcodeIsAtomicWithLoad(opcode) ||
374
0
          opcode == spv::Op::OpAtomicStore ||
375
0
          opcode == spv::Op::OpAtomicFlagClear);
376
0
}
377
378
290k
bool spvOpcodeIsReturn(spv::Op opcode) {
379
290k
  switch (opcode) {
380
2.12k
    case spv::Op::OpReturn:
381
3.57k
    case spv::Op::OpReturnValue:
382
3.57k
      return true;
383
287k
    default:
384
287k
      return false;
385
290k
  }
386
290k
}
387
388
281k
bool spvOpcodeIsAbort(spv::Op opcode) {
389
281k
  switch (opcode) {
390
0
    case spv::Op::OpKill:
391
0
    case spv::Op::OpUnreachable:
392
0
    case spv::Op::OpTerminateInvocation:
393
0
    case spv::Op::OpTerminateRayKHR:
394
0
    case spv::Op::OpIgnoreIntersectionKHR:
395
0
    case spv::Op::OpEmitMeshTasksEXT:
396
0
    case spv::Op::OpAbortKHR:
397
0
      return true;
398
281k
    default:
399
281k
      return false;
400
281k
  }
401
281k
}
402
403
278k
bool spvOpcodeIsReturnOrAbort(spv::Op opcode) {
404
278k
  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
405
278k
}
406
407
289k
bool spvOpcodeIsBlockTerminator(spv::Op opcode) {
408
289k
  return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
409
289k
}
410
411
0
bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) {
412
0
  switch (opcode) {
413
0
    case spv::Op::OpTypeImage:
414
0
    case spv::Op::OpTypeSampler:
415
0
    case spv::Op::OpTypeSampledImage:
416
0
    case spv::Op::OpTypeOpaque:
417
0
    case spv::Op::OpTypeEvent:
418
0
    case spv::Op::OpTypeDeviceEvent:
419
0
    case spv::Op::OpTypeReserveId:
420
0
    case spv::Op::OpTypeQueue:
421
0
    case spv::Op::OpTypePipe:
422
0
    case spv::Op::OpTypeForwardPointer:
423
0
    case spv::Op::OpTypePipeStorage:
424
0
    case spv::Op::OpTypeNamedBarrier:
425
0
      return true;
426
0
    default:
427
0
      return false;
428
0
  }
429
0
}
430
431
106k
bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) {
432
106k
  switch (opcode) {
433
0
    case spv::Op::OpGroupNonUniformElect:
434
0
    case spv::Op::OpGroupNonUniformAll:
435
0
    case spv::Op::OpGroupNonUniformAny:
436
0
    case spv::Op::OpGroupNonUniformAllEqual:
437
0
    case spv::Op::OpGroupNonUniformBroadcast:
438
0
    case spv::Op::OpGroupNonUniformBroadcastFirst:
439
0
    case spv::Op::OpGroupNonUniformBallot:
440
0
    case spv::Op::OpGroupNonUniformInverseBallot:
441
0
    case spv::Op::OpGroupNonUniformBallotBitExtract:
442
0
    case spv::Op::OpGroupNonUniformBallotBitCount:
443
0
    case spv::Op::OpGroupNonUniformBallotFindLSB:
444
0
    case spv::Op::OpGroupNonUniformBallotFindMSB:
445
0
    case spv::Op::OpGroupNonUniformShuffle:
446
0
    case spv::Op::OpGroupNonUniformShuffleXor:
447
0
    case spv::Op::OpGroupNonUniformShuffleUp:
448
0
    case spv::Op::OpGroupNonUniformShuffleDown:
449
0
    case spv::Op::OpGroupNonUniformIAdd:
450
0
    case spv::Op::OpGroupNonUniformFAdd:
451
0
    case spv::Op::OpGroupNonUniformIMul:
452
0
    case spv::Op::OpGroupNonUniformFMul:
453
0
    case spv::Op::OpGroupNonUniformSMin:
454
0
    case spv::Op::OpGroupNonUniformUMin:
455
0
    case spv::Op::OpGroupNonUniformFMin:
456
0
    case spv::Op::OpGroupNonUniformSMax:
457
0
    case spv::Op::OpGroupNonUniformUMax:
458
0
    case spv::Op::OpGroupNonUniformFMax:
459
0
    case spv::Op::OpGroupNonUniformBitwiseAnd:
460
0
    case spv::Op::OpGroupNonUniformBitwiseOr:
461
0
    case spv::Op::OpGroupNonUniformBitwiseXor:
462
0
    case spv::Op::OpGroupNonUniformLogicalAnd:
463
0
    case spv::Op::OpGroupNonUniformLogicalOr:
464
0
    case spv::Op::OpGroupNonUniformLogicalXor:
465
0
    case spv::Op::OpGroupNonUniformQuadBroadcast:
466
0
    case spv::Op::OpGroupNonUniformQuadSwap:
467
0
    case spv::Op::OpGroupNonUniformRotateKHR:
468
0
    case spv::Op::OpGroupNonUniformQuadAllKHR:
469
0
    case spv::Op::OpGroupNonUniformQuadAnyKHR:
470
0
      return true;
471
106k
    default:
472
106k
      return false;
473
106k
  }
474
106k
}
475
476
27.2k
bool spvOpcodeIsScalarizable(spv::Op opcode) {
477
27.2k
  switch (opcode) {
478
3.54k
    case spv::Op::OpPhi:
479
3.54k
    case spv::Op::OpCopyObject:
480
3.55k
    case spv::Op::OpConvertFToU:
481
3.55k
    case spv::Op::OpConvertFToS:
482
4.64k
    case spv::Op::OpConvertSToF:
483
4.65k
    case spv::Op::OpConvertUToF:
484
4.65k
    case spv::Op::OpUConvert:
485
4.66k
    case spv::Op::OpSConvert:
486
4.75k
    case spv::Op::OpFConvert:
487
4.75k
    case spv::Op::OpQuantizeToF16:
488
4.75k
    case spv::Op::OpVectorInsertDynamic:
489
4.75k
    case spv::Op::OpSNegate:
490
4.86k
    case spv::Op::OpFNegate:
491
5.80k
    case spv::Op::OpIAdd:
492
8.34k
    case spv::Op::OpFAdd:
493
8.35k
    case spv::Op::OpISub:
494
8.76k
    case spv::Op::OpFSub:
495
8.78k
    case spv::Op::OpIMul:
496
10.2k
    case spv::Op::OpFMul:
497
10.2k
    case spv::Op::OpUDiv:
498
10.2k
    case spv::Op::OpSDiv:
499
11.6k
    case spv::Op::OpFDiv:
500
11.6k
    case spv::Op::OpUMod:
501
11.6k
    case spv::Op::OpSRem:
502
11.6k
    case spv::Op::OpSMod:
503
11.6k
    case spv::Op::OpFRem:
504
11.6k
    case spv::Op::OpFMod:
505
13.6k
    case spv::Op::OpVectorTimesScalar:
506
13.6k
    case spv::Op::OpIAddCarry:
507
13.6k
    case spv::Op::OpISubBorrow:
508
13.6k
    case spv::Op::OpUMulExtended:
509
13.6k
    case spv::Op::OpSMulExtended:
510
13.6k
    case spv::Op::OpShiftRightLogical:
511
13.6k
    case spv::Op::OpShiftRightArithmetic:
512
13.6k
    case spv::Op::OpShiftLeftLogical:
513
13.6k
    case spv::Op::OpBitwiseOr:
514
13.6k
    case spv::Op::OpBitwiseAnd:
515
13.6k
    case spv::Op::OpNot:
516
13.6k
    case spv::Op::OpBitFieldInsert:
517
13.6k
    case spv::Op::OpBitFieldSExtract:
518
13.6k
    case spv::Op::OpBitFieldUExtract:
519
13.6k
    case spv::Op::OpBitReverse:
520
13.6k
    case spv::Op::OpBitCount:
521
13.6k
    case spv::Op::OpIsNan:
522
13.6k
    case spv::Op::OpIsInf:
523
13.6k
    case spv::Op::OpIsFinite:
524
13.6k
    case spv::Op::OpIsNormal:
525
13.6k
    case spv::Op::OpSignBitSet:
526
13.6k
    case spv::Op::OpLessOrGreater:
527
13.6k
    case spv::Op::OpOrdered:
528
13.6k
    case spv::Op::OpUnordered:
529
13.6k
    case spv::Op::OpLogicalEqual:
530
13.6k
    case spv::Op::OpLogicalNotEqual:
531
13.6k
    case spv::Op::OpLogicalOr:
532
13.6k
    case spv::Op::OpLogicalAnd:
533
13.6k
    case spv::Op::OpLogicalNot:
534
13.6k
    case spv::Op::OpSelect:
535
13.6k
    case spv::Op::OpIEqual:
536
13.6k
    case spv::Op::OpINotEqual:
537
13.7k
    case spv::Op::OpUGreaterThan:
538
14.1k
    case spv::Op::OpSGreaterThan:
539
14.1k
    case spv::Op::OpUGreaterThanEqual:
540
14.1k
    case spv::Op::OpSGreaterThanEqual:
541
14.1k
    case spv::Op::OpULessThan:
542
14.4k
    case spv::Op::OpSLessThan:
543
14.4k
    case spv::Op::OpULessThanEqual:
544
14.7k
    case spv::Op::OpSLessThanEqual:
545
14.8k
    case spv::Op::OpFOrdEqual:
546
14.8k
    case spv::Op::OpFUnordEqual:
547
14.8k
    case spv::Op::OpFOrdNotEqual:
548
14.8k
    case spv::Op::OpFUnordNotEqual:
549
15.3k
    case spv::Op::OpFOrdLessThan:
550
15.3k
    case spv::Op::OpFUnordLessThan:
551
15.8k
    case spv::Op::OpFOrdGreaterThan:
552
15.8k
    case spv::Op::OpFUnordGreaterThan:
553
15.8k
    case spv::Op::OpFOrdLessThanEqual:
554
15.8k
    case spv::Op::OpFUnordLessThanEqual:
555
15.8k
    case spv::Op::OpFOrdGreaterThanEqual:
556
15.8k
    case spv::Op::OpFUnordGreaterThanEqual:
557
15.8k
      return true;
558
11.3k
    default:
559
11.3k
      return false;
560
27.2k
  }
561
27.2k
}
562
563
12.8k
bool spvOpcodeIsDebug(spv::Op opcode) {
564
12.8k
  switch (opcode) {
565
0
    case spv::Op::OpName:
566
0
    case spv::Op::OpMemberName:
567
0
    case spv::Op::OpSource:
568
0
    case spv::Op::OpSourceContinued:
569
0
    case spv::Op::OpSourceExtension:
570
0
    case spv::Op::OpString:
571
0
    case spv::Op::OpLine:
572
0
    case spv::Op::OpNoLine:
573
0
    case spv::Op::OpModuleProcessed:
574
0
      return true;
575
12.8k
    default:
576
12.8k
      return false;
577
12.8k
  }
578
12.8k
}
579
580
111k
bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) {
581
111k
  switch (opcode) {
582
0
    case spv::Op::OpPtrEqual:
583
0
    case spv::Op::OpPtrNotEqual:
584
2.79k
    case spv::Op::OpIAdd:
585
7.64k
    case spv::Op::OpFAdd:
586
7.69k
    case spv::Op::OpIMul:
587
10.2k
    case spv::Op::OpFMul:
588
11.2k
    case spv::Op::OpDot:
589
11.2k
    case spv::Op::OpIAddCarry:
590
11.2k
    case spv::Op::OpUMulExtended:
591
11.2k
    case spv::Op::OpSMulExtended:
592
11.2k
    case spv::Op::OpBitwiseOr:
593
11.2k
    case spv::Op::OpBitwiseXor:
594
11.2k
    case spv::Op::OpBitwiseAnd:
595
11.2k
    case spv::Op::OpOrdered:
596
11.2k
    case spv::Op::OpUnordered:
597
11.2k
    case spv::Op::OpLogicalEqual:
598
11.2k
    case spv::Op::OpLogicalNotEqual:
599
11.2k
    case spv::Op::OpLogicalOr:
600
11.2k
    case spv::Op::OpLogicalAnd:
601
11.2k
    case spv::Op::OpIEqual:
602
11.2k
    case spv::Op::OpINotEqual:
603
11.5k
    case spv::Op::OpFOrdEqual:
604
11.5k
    case spv::Op::OpFUnordEqual:
605
11.5k
    case spv::Op::OpFOrdNotEqual:
606
11.5k
    case spv::Op::OpFUnordNotEqual:
607
11.5k
      return true;
608
100k
    default:
609
100k
      return false;
610
111k
  }
611
111k
}
612
613
0
bool spvOpcodeIsLinearAlgebra(spv::Op opcode) {
614
0
  switch (opcode) {
615
0
    case spv::Op::OpTranspose:
616
0
    case spv::Op::OpVectorTimesScalar:
617
0
    case spv::Op::OpMatrixTimesScalar:
618
0
    case spv::Op::OpVectorTimesMatrix:
619
0
    case spv::Op::OpMatrixTimesVector:
620
0
    case spv::Op::OpMatrixTimesMatrix:
621
0
    case spv::Op::OpOuterProduct:
622
0
    case spv::Op::OpDot:
623
0
      return true;
624
0
    default:
625
0
      return false;
626
0
  }
627
0
}
628
629
0
bool spvOpcodeIsImageSample(const spv::Op opcode) {
630
0
  switch (opcode) {
631
0
    case spv::Op::OpImageSampleImplicitLod:
632
0
    case spv::Op::OpImageSampleExplicitLod:
633
0
    case spv::Op::OpImageSampleDrefImplicitLod:
634
0
    case spv::Op::OpImageSampleDrefExplicitLod:
635
0
    case spv::Op::OpImageSampleProjImplicitLod:
636
0
    case spv::Op::OpImageSampleProjExplicitLod:
637
0
    case spv::Op::OpImageSampleProjDrefImplicitLod:
638
0
    case spv::Op::OpImageSampleProjDrefExplicitLod:
639
0
    case spv::Op::OpImageSparseSampleImplicitLod:
640
0
    case spv::Op::OpImageSparseSampleExplicitLod:
641
0
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
642
0
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
643
0
    case spv::Op::OpImageSampleFootprintNV:
644
0
      return true;
645
0
    default:
646
0
      return false;
647
0
  }
648
0
}
649
650
1.16M
bool spvIsExtendedInstruction(const spv::Op opcode) {
651
1.16M
  switch (opcode) {
652
23.9k
    case spv::Op::OpExtInst:
653
23.9k
    case spv::Op::OpExtInstWithForwardRefsKHR:
654
23.9k
      return true;
655
1.14M
    default:
656
1.14M
      return false;
657
1.16M
  }
658
1.16M
}
659
660
0
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) {
661
0
  switch (opcode) {
662
0
    case spv::Op::OpMemoryBarrier:
663
0
      return {1};
664
0
    case spv::Op::OpAtomicStore:
665
0
    case spv::Op::OpControlBarrier:
666
0
    case spv::Op::OpAtomicFlagClear:
667
0
    case spv::Op::OpMemoryNamedBarrier:
668
0
      return {2};
669
0
    case spv::Op::OpAtomicLoad:
670
0
    case spv::Op::OpAtomicExchange:
671
0
    case spv::Op::OpAtomicIIncrement:
672
0
    case spv::Op::OpAtomicIDecrement:
673
0
    case spv::Op::OpAtomicIAdd:
674
0
    case spv::Op::OpAtomicFAddEXT:
675
0
    case spv::Op::OpAtomicISub:
676
0
    case spv::Op::OpAtomicSMin:
677
0
    case spv::Op::OpAtomicUMin:
678
0
    case spv::Op::OpAtomicSMax:
679
0
    case spv::Op::OpAtomicUMax:
680
0
    case spv::Op::OpAtomicAnd:
681
0
    case spv::Op::OpAtomicOr:
682
0
    case spv::Op::OpAtomicXor:
683
0
    case spv::Op::OpAtomicFlagTestAndSet:
684
0
      return {4};
685
0
    case spv::Op::OpAtomicCompareExchange:
686
0
    case spv::Op::OpAtomicCompareExchangeWeak:
687
0
      return {4, 5};
688
0
    default:
689
0
      return {};
690
0
  }
691
0
}
692
693
0
bool spvOpcodeIsAccessChain(spv::Op opcode) {
694
0
  switch (opcode) {
695
0
    case spv::Op::OpAccessChain:
696
0
    case spv::Op::OpInBoundsAccessChain:
697
0
    case spv::Op::OpPtrAccessChain:
698
0
    case spv::Op::OpInBoundsPtrAccessChain:
699
0
    case spv::Op::OpRawAccessChainNV:
700
0
      return true;
701
0
    default:
702
0
      return false;
703
0
  }
704
0
}
705
706
0
bool spvOpcodeIsBit(spv::Op opcode) {
707
0
  switch (opcode) {
708
0
    case spv::Op::OpShiftRightLogical:
709
0
    case spv::Op::OpShiftRightArithmetic:
710
0
    case spv::Op::OpShiftLeftLogical:
711
0
    case spv::Op::OpBitwiseOr:
712
0
    case spv::Op::OpBitwiseXor:
713
0
    case spv::Op::OpBitwiseAnd:
714
0
    case spv::Op::OpNot:
715
0
    case spv::Op::OpBitReverse:
716
0
    case spv::Op::OpBitCount:
717
0
      return true;
718
0
    default:
719
0
      return false;
720
0
  }
721
0
}
722
723
6.03k
bool spvOpcodeGeneratesUntypedPointer(spv::Op opcode) {
724
6.03k
  switch (opcode) {
725
0
    case spv::Op::OpUntypedVariableKHR:
726
0
    case spv::Op::OpUntypedAccessChainKHR:
727
0
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
728
0
    case spv::Op::OpUntypedPtrAccessChainKHR:
729
0
    case spv::Op::OpUntypedInBoundsPtrAccessChainKHR:
730
0
      return true;
731
6.03k
    default:
732
6.03k
      return false;
733
6.03k
  }
734
6.03k
}