Coverage Report

Created: 2026-09-14 06:31

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
171
const char* spvGeneratorStr(uint32_t generator) {
52
171
  auto where = std::find_if(
53
171
      std::begin(vendor_tools), std::end(vendor_tools),
54
2.39k
      [generator](const VendorTool& vt) { return generator == vt.value; });
55
171
  if (where != std::end(vendor_tools)) return where->vendor_tool;
56
0
  return "Unknown";
57
171
}
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
438k
                    uint16_t* pOpcode) {
65
438k
  if (pWordCount) {
66
438k
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
67
438k
  }
68
438k
  if (pOpcode) {
69
438k
    *pOpcode = 0x0000ffff & word;
70
438k
  }
71
438k
}
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.4k
const char* spvOpcodeString(const uint32_t opcode) {
91
46.4k
  const spvtools::InstructionDesc* desc = nullptr;
92
46.4k
  if (SPV_SUCCESS !=
93
46.4k
      spvtools::LookupOpcode(static_cast<spv::Op>(opcode), &desc)) {
94
0
    assert(0 && "Unreachable!");
95
0
    return "unknown";
96
0
  }
97
46.4k
  return desc->name().data();
98
46.4k
}
99
100
46.4k
const char* spvOpcodeString(const spv::Op opcode) {
101
46.4k
  return spvOpcodeString(static_cast<uint32_t>(opcode));
102
46.4k
}
103
104
2.20k
int32_t spvOpcodeIsScalarType(const spv::Op opcode) {
105
2.20k
  switch (opcode) {
106
744
    case spv::Op::OpTypeInt:
107
1.68k
    case spv::Op::OpTypeFloat:
108
2.10k
    case spv::Op::OpTypeBool:
109
2.10k
      return true;
110
106
    default:
111
106
      return false;
112
2.20k
  }
113
2.20k
}
114
115
10.0k
int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
116
10.0k
  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
10.0k
    default:
129
10.0k
      return false;
130
10.0k
  }
131
10.0k
}
132
133
404k
int32_t spvOpcodeIsConstant(const spv::Op opcode) {
134
404k
  switch (opcode) {
135
578
    case spv::Op::OpConstantTrue:
136
900
    case spv::Op::OpConstantFalse:
137
36.0k
    case spv::Op::OpConstant:
138
41.5k
    case spv::Op::OpConstantComposite:
139
41.5k
    case spv::Op::OpConstantCompositeReplicateEXT:
140
41.5k
    case spv::Op::OpConstantSampler:
141
41.5k
    case spv::Op::OpConstantNull:
142
41.5k
    case spv::Op::OpConstantFunctionPointerINTEL:
143
41.5k
    case spv::Op::OpConstantStringAMDX:
144
41.6k
    case spv::Op::OpSpecConstantTrue:
145
41.6k
    case spv::Op::OpSpecConstantFalse:
146
41.9k
    case spv::Op::OpSpecConstant:
147
41.9k
    case spv::Op::OpSpecConstantComposite:
148
41.9k
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
149
42.1k
    case spv::Op::OpSpecConstantOp:
150
42.1k
    case spv::Op::OpSpecConstantStringAMDX:
151
42.1k
    case spv::Op::OpGraphConstantARM:
152
42.1k
    case spv::Op::OpAsmTargetINTEL:
153
42.1k
    case spv::Op::OpAsmINTEL:
154
42.1k
    case spv::Op::OpSpecConstantArchitectureINTEL:
155
42.1k
    case spv::Op::OpSpecConstantTargetINTEL:
156
42.1k
    case spv::Op::OpSpecConstantCapabilitiesINTEL:
157
42.1k
    case spv::Op::OpConstantSizeOfEXT:
158
42.1k
    case spv::Op::OpConstantDataKHR:
159
42.1k
    case spv::Op::OpSpecConstantDataKHR:
160
42.1k
      return true;
161
362k
    default:
162
362k
      return false;
163
404k
  }
164
404k
}
165
166
2.01k
bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
167
2.01k
  return opcode == spv::Op::OpUndef || opcode == spv::Op::OpPoisonKHR ||
168
2.01k
         spvOpcodeIsConstant(opcode);
169
2.01k
}
170
171
3.43k
int32_t spvOpcodeIsComposite(const spv::Op opcode) {
172
3.43k
  switch (opcode) {
173
1.01k
    case spv::Op::OpTypeVector:
174
1.16k
    case spv::Op::OpTypeMatrix:
175
1.17k
    case spv::Op::OpTypeArray:
176
1.25k
    case spv::Op::OpTypeStruct:
177
1.25k
    case spv::Op::OpTypeRuntimeArray:
178
1.25k
    case spv::Op::OpTypeCooperativeMatrixNV:
179
1.25k
    case spv::Op::OpTypeCooperativeMatrixKHR:
180
1.25k
    case spv::Op::OpTypeVectorIdEXT:
181
1.25k
      return true;
182
2.17k
    default:
183
2.17k
      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.2k
int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
216
24.2k
  switch (opcode) {
217
17.5k
    case spv::Op::OpVariable:
218
17.5k
    case spv::Op::OpUntypedVariableKHR:
219
23.2k
    case spv::Op::OpAccessChain:
220
23.2k
    case spv::Op::OpInBoundsAccessChain:
221
23.2k
    case spv::Op::OpUntypedAccessChainKHR:
222
23.2k
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
223
23.2k
    case spv::Op::OpBufferPointerEXT:
224
24.2k
    case spv::Op::OpFunctionParameter:
225
24.2k
    case spv::Op::OpImageTexelPointer:
226
24.2k
    case spv::Op::OpUntypedImageTexelPointerEXT:
227
24.2k
    case spv::Op::OpCopyObject:
228
24.2k
    case spv::Op::OpRawAccessChainNV:
229
24.2k
    case spv::Op::OpAllocateNodePayloadsAMDX:
230
24.2k
      return true;
231
0
    default:
232
0
      return false;
233
24.2k
  }
234
24.2k
}
235
236
1.37M
int32_t spvOpcodeGeneratesType(spv::Op op) {
237
1.37M
  switch (op) {
238
7.40k
    case spv::Op::OpTypeVoid:
239
12.5k
    case spv::Op::OpTypeBool:
240
36.6k
    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
119k
    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
232k
bool spvOpcodeIsDecoration(const spv::Op opcode) {
288
232k
  switch (opcode) {
289
2.67k
    case spv::Op::OpDecorate:
290
2.67k
    case spv::Op::OpDecorateId:
291
3.97k
    case spv::Op::OpMemberDecorate:
292
3.97k
    case spv::Op::OpMemberDecorateIdEXT:
293
3.97k
    case spv::Op::OpGroupDecorate:
294
3.97k
    case spv::Op::OpGroupMemberDecorate:
295
3.97k
    case spv::Op::OpDecorateStringGOOGLE:
296
3.97k
    case spv::Op::OpMemberDecorateStringGOOGLE:
297
3.97k
      return true;
298
228k
    default:
299
228k
      break;
300
232k
  }
301
228k
  return false;
302
232k
}
303
304
235k
bool spvOpcodeIsLoad(const spv::Op opcode) {
305
235k
  switch (opcode) {
306
20.0k
    case spv::Op::OpLoad:
307
24.8k
    case spv::Op::OpImageSampleExplicitLod:
308
24.8k
    case spv::Op::OpImageSampleImplicitLod:
309
24.8k
    case spv::Op::OpImageSampleDrefImplicitLod:
310
24.8k
    case spv::Op::OpImageSampleDrefExplicitLod:
311
24.8k
    case spv::Op::OpImageSampleProjImplicitLod:
312
24.8k
    case spv::Op::OpImageSampleProjExplicitLod:
313
24.8k
    case spv::Op::OpImageSampleProjDrefImplicitLod:
314
24.8k
    case spv::Op::OpImageSampleProjDrefExplicitLod:
315
24.8k
    case spv::Op::OpImageSampleFootprintNV:
316
24.8k
    case spv::Op::OpImageFetch:
317
24.8k
    case spv::Op::OpImageGather:
318
24.8k
    case spv::Op::OpImageDrefGather:
319
25.0k
    case spv::Op::OpImageRead:
320
25.0k
    case spv::Op::OpImageSparseSampleImplicitLod:
321
25.0k
    case spv::Op::OpImageSparseSampleExplicitLod:
322
25.0k
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
323
25.0k
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
324
25.0k
    case spv::Op::OpImageSparseFetch:
325
25.0k
    case spv::Op::OpImageSparseGather:
326
25.0k
    case spv::Op::OpImageSparseDrefGather:
327
25.1k
    case spv::Op::OpImageSparseRead:
328
25.1k
      return true;
329
210k
    default:
330
210k
      return false;
331
235k
  }
332
235k
}
333
334
840k
bool spvOpcodeIsBranch(spv::Op opcode) {
335
840k
  switch (opcode) {
336
80.5k
    case spv::Op::OpBranch:
337
127k
    case spv::Op::OpBranchConditional:
338
132k
    case spv::Op::OpSwitch:
339
132k
      return true;
340
708k
    default:
341
708k
      return false;
342
840k
  }
343
840k
}
344
345
530k
bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) {
346
530k
  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
530k
    default:
368
530k
      return false;
369
530k
  }
370
530k
}
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
288k
bool spvOpcodeIsReturn(spv::Op opcode) {
379
288k
  switch (opcode) {
380
2.19k
    case spv::Op::OpReturn:
381
3.62k
    case spv::Op::OpReturnValue:
382
3.62k
      return true;
383
284k
    default:
384
284k
      return false;
385
288k
  }
386
288k
}
387
388
279k
bool spvOpcodeIsAbort(spv::Op opcode) {
389
279k
  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
279k
    default:
399
279k
      return false;
400
279k
  }
401
279k
}
402
403
275k
bool spvOpcodeIsReturnOrAbort(spv::Op opcode) {
404
275k
  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
405
275k
}
406
407
286k
bool spvOpcodeIsBlockTerminator(spv::Op opcode) {
408
286k
  return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
409
286k
}
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
26.8k
bool spvOpcodeIsScalarizable(spv::Op opcode) {
477
26.8k
  switch (opcode) {
478
3.47k
    case spv::Op::OpPhi:
479
3.47k
    case spv::Op::OpCopyObject:
480
3.48k
    case spv::Op::OpConvertFToU:
481
3.48k
    case spv::Op::OpConvertFToS:
482
4.54k
    case spv::Op::OpConvertSToF:
483
4.55k
    case spv::Op::OpConvertUToF:
484
4.55k
    case spv::Op::OpUConvert:
485
4.57k
    case spv::Op::OpSConvert:
486
4.65k
    case spv::Op::OpFConvert:
487
4.65k
    case spv::Op::OpQuantizeToF16:
488
4.65k
    case spv::Op::OpVectorInsertDynamic:
489
4.65k
    case spv::Op::OpSNegate:
490
4.76k
    case spv::Op::OpFNegate:
491
5.69k
    case spv::Op::OpIAdd:
492
8.20k
    case spv::Op::OpFAdd:
493
8.21k
    case spv::Op::OpISub:
494
8.61k
    case spv::Op::OpFSub:
495
8.62k
    case spv::Op::OpIMul:
496
10.0k
    case spv::Op::OpFMul:
497
10.0k
    case spv::Op::OpUDiv:
498
10.0k
    case spv::Op::OpSDiv:
499
11.4k
    case spv::Op::OpFDiv:
500
11.4k
    case spv::Op::OpUMod:
501
11.4k
    case spv::Op::OpSRem:
502
11.4k
    case spv::Op::OpSMod:
503
11.4k
    case spv::Op::OpFRem:
504
11.4k
    case spv::Op::OpFMod:
505
13.4k
    case spv::Op::OpVectorTimesScalar:
506
13.4k
    case spv::Op::OpIAddCarry:
507
13.4k
    case spv::Op::OpISubBorrow:
508
13.4k
    case spv::Op::OpUMulExtended:
509
13.4k
    case spv::Op::OpSMulExtended:
510
13.4k
    case spv::Op::OpShiftRightLogical:
511
13.4k
    case spv::Op::OpShiftRightArithmetic:
512
13.4k
    case spv::Op::OpShiftLeftLogical:
513
13.4k
    case spv::Op::OpBitwiseOr:
514
13.4k
    case spv::Op::OpBitwiseAnd:
515
13.4k
    case spv::Op::OpNot:
516
13.4k
    case spv::Op::OpBitFieldInsert:
517
13.4k
    case spv::Op::OpBitFieldSExtract:
518
13.4k
    case spv::Op::OpBitFieldUExtract:
519
13.4k
    case spv::Op::OpBitReverse:
520
13.4k
    case spv::Op::OpBitCount:
521
13.4k
    case spv::Op::OpIsNan:
522
13.4k
    case spv::Op::OpIsInf:
523
13.4k
    case spv::Op::OpIsFinite:
524
13.4k
    case spv::Op::OpIsNormal:
525
13.4k
    case spv::Op::OpSignBitSet:
526
13.4k
    case spv::Op::OpLessOrGreater:
527
13.4k
    case spv::Op::OpOrdered:
528
13.4k
    case spv::Op::OpUnordered:
529
13.4k
    case spv::Op::OpLogicalEqual:
530
13.4k
    case spv::Op::OpLogicalNotEqual:
531
13.4k
    case spv::Op::OpLogicalOr:
532
13.4k
    case spv::Op::OpLogicalAnd:
533
13.4k
    case spv::Op::OpLogicalNot:
534
13.4k
    case spv::Op::OpSelect:
535
13.4k
    case spv::Op::OpIEqual:
536
13.4k
    case spv::Op::OpINotEqual:
537
13.4k
    case spv::Op::OpUGreaterThan:
538
13.8k
    case spv::Op::OpSGreaterThan:
539
13.8k
    case spv::Op::OpUGreaterThanEqual:
540
13.8k
    case spv::Op::OpSGreaterThanEqual:
541
13.8k
    case spv::Op::OpULessThan:
542
14.1k
    case spv::Op::OpSLessThan:
543
14.1k
    case spv::Op::OpULessThanEqual:
544
14.5k
    case spv::Op::OpSLessThanEqual:
545
14.6k
    case spv::Op::OpFOrdEqual:
546
14.6k
    case spv::Op::OpFUnordEqual:
547
14.6k
    case spv::Op::OpFOrdNotEqual:
548
14.6k
    case spv::Op::OpFUnordNotEqual:
549
15.0k
    case spv::Op::OpFOrdLessThan:
550
15.0k
    case spv::Op::OpFUnordLessThan:
551
15.6k
    case spv::Op::OpFOrdGreaterThan:
552
15.6k
    case spv::Op::OpFUnordGreaterThan:
553
15.6k
    case spv::Op::OpFOrdLessThanEqual:
554
15.6k
    case spv::Op::OpFUnordLessThanEqual:
555
15.6k
    case spv::Op::OpFOrdGreaterThanEqual:
556
15.6k
    case spv::Op::OpFUnordGreaterThanEqual:
557
15.6k
      return true;
558
11.2k
    default:
559
11.2k
      return false;
560
26.8k
  }
561
26.8k
}
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
110k
bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) {
581
110k
  switch (opcode) {
582
0
    case spv::Op::OpPtrEqual:
583
0
    case spv::Op::OpPtrNotEqual:
584
2.73k
    case spv::Op::OpIAdd:
585
7.54k
    case spv::Op::OpFAdd:
586
7.59k
    case spv::Op::OpIMul:
587
10.0k
    case spv::Op::OpFMul:
588
11.0k
    case spv::Op::OpDot:
589
11.0k
    case spv::Op::OpIAddCarry:
590
11.0k
    case spv::Op::OpUMulExtended:
591
11.0k
    case spv::Op::OpSMulExtended:
592
11.0k
    case spv::Op::OpBitwiseOr:
593
11.0k
    case spv::Op::OpBitwiseXor:
594
11.0k
    case spv::Op::OpBitwiseAnd:
595
11.0k
    case spv::Op::OpOrdered:
596
11.0k
    case spv::Op::OpUnordered:
597
11.0k
    case spv::Op::OpLogicalEqual:
598
11.0k
    case spv::Op::OpLogicalNotEqual:
599
11.0k
    case spv::Op::OpLogicalOr:
600
11.0k
    case spv::Op::OpLogicalAnd:
601
11.0k
    case spv::Op::OpIEqual:
602
11.0k
    case spv::Op::OpINotEqual:
603
11.3k
    case spv::Op::OpFOrdEqual:
604
11.3k
    case spv::Op::OpFUnordEqual:
605
11.3k
    case spv::Op::OpFOrdNotEqual:
606
11.3k
    case spv::Op::OpFUnordNotEqual:
607
11.3k
      return true;
608
99.0k
    default:
609
99.0k
      return false;
610
110k
  }
611
110k
}
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.4k
    case spv::Op::OpExtInst:
653
23.4k
    case spv::Op::OpExtInstWithForwardRefsKHR:
654
23.4k
      return true;
655
1.13M
    default:
656
1.13M
      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
5.96k
bool spvOpcodeGeneratesUntypedPointer(spv::Op opcode) {
724
5.96k
  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
5.96k
    default:
732
5.96k
      return false;
733
5.96k
  }
734
5.96k
}