Coverage Report

Created: 2025-07-18 06:38

/src/shaderc/third_party/spirv-tools/source/opcode.cpp
Line
Count
Source (jump to first uncovered line)
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
878
const char* spvGeneratorStr(uint32_t generator) {
52
878
  auto where = std::find_if(
53
878
      std::begin(vendor_tools), std::end(vendor_tools),
54
12.2k
      [generator](const VendorTool& vt) { return generator == vt.value; });
55
878
  if (where != std::end(vendor_tools)) return where->vendor_tool;
56
0
  return "Unknown";
57
878
}
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
801k
                    uint16_t* pOpcode) {
65
801k
  if (pWordCount) {
66
801k
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
67
801k
  }
68
801k
  if (pOpcode) {
69
801k
    *pOpcode = 0x0000ffff & word;
70
801k
  }
71
801k
}
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
83.6k
const char* spvOpcodeString(const uint32_t opcode) {
91
83.6k
  const spvtools::InstructionDesc* desc = nullptr;
92
83.6k
  if (SPV_SUCCESS !=
93
83.6k
      spvtools::LookupOpcode(static_cast<spv::Op>(opcode), &desc)) {
94
0
    assert(0 && "Unreachable!");
95
0
    return "unknown";
96
0
  }
97
83.6k
  return desc->name().data();
98
83.6k
}
99
100
83.6k
const char* spvOpcodeString(const spv::Op opcode) {
101
83.6k
  return spvOpcodeString(static_cast<uint32_t>(opcode));
102
83.6k
}
103
104
3.97k
int32_t spvOpcodeIsScalarType(const spv::Op opcode) {
105
3.97k
  switch (opcode) {
106
1.39k
    case spv::Op::OpTypeInt:
107
3.06k
    case spv::Op::OpTypeFloat:
108
3.84k
    case spv::Op::OpTypeBool:
109
3.84k
      return true;
110
130
    default:
111
130
      return false;
112
3.97k
  }
113
3.97k
}
114
115
9.63k
int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
116
9.63k
  switch (opcode) {
117
2
    case spv::Op::OpSpecConstantTrue:
118
2
    case spv::Op::OpSpecConstantFalse:
119
26
    case spv::Op::OpSpecConstant:
120
30
    case spv::Op::OpSpecConstantComposite:
121
30
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
122
30
    case spv::Op::OpSpecConstantOp:
123
30
      return true;
124
9.60k
    default:
125
9.60k
      return false;
126
9.63k
  }
127
9.63k
}
128
129
749k
int32_t spvOpcodeIsConstant(const spv::Op opcode) {
130
749k
  switch (opcode) {
131
1.12k
    case spv::Op::OpConstantTrue:
132
1.86k
    case spv::Op::OpConstantFalse:
133
59.5k
    case spv::Op::OpConstant:
134
66.8k
    case spv::Op::OpConstantComposite:
135
66.8k
    case spv::Op::OpConstantCompositeReplicateEXT:
136
66.8k
    case spv::Op::OpConstantSampler:
137
66.8k
    case spv::Op::OpConstantNull:
138
66.8k
    case spv::Op::OpConstantFunctionPointerINTEL:
139
66.8k
    case spv::Op::OpConstantStringAMDX:
140
66.9k
    case spv::Op::OpSpecConstantTrue:
141
66.9k
    case spv::Op::OpSpecConstantFalse:
142
67.3k
    case spv::Op::OpSpecConstant:
143
67.3k
    case spv::Op::OpSpecConstantComposite:
144
67.3k
    case spv::Op::OpSpecConstantCompositeReplicateEXT:
145
67.5k
    case spv::Op::OpSpecConstantOp:
146
67.5k
    case spv::Op::OpSpecConstantStringAMDX:
147
67.5k
      return true;
148
681k
    default:
149
681k
      return false;
150
749k
  }
151
749k
}
152
153
3.10k
bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
154
3.10k
  return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode);
155
3.10k
}
156
157
134
bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode) {
158
134
  switch (opcode) {
159
16
    case spv::Op::OpSpecConstantTrue:
160
16
    case spv::Op::OpSpecConstantFalse:
161
124
    case spv::Op::OpSpecConstant:
162
124
      return true;
163
10
    default:
164
10
      return false;
165
134
  }
166
134
}
167
168
4.48k
int32_t spvOpcodeIsComposite(const spv::Op opcode) {
169
4.48k
  switch (opcode) {
170
1.49k
    case spv::Op::OpTypeVector:
171
1.57k
    case spv::Op::OpTypeMatrix:
172
1.61k
    case spv::Op::OpTypeArray:
173
1.61k
    case spv::Op::OpTypeStruct:
174
1.61k
    case spv::Op::OpTypeRuntimeArray:
175
1.61k
    case spv::Op::OpTypeCooperativeMatrixNV:
176
1.61k
    case spv::Op::OpTypeCooperativeMatrixKHR:
177
1.61k
    case spv::Op::OpTypeCooperativeVectorNV:
178
1.61k
      return true;
179
2.87k
    default:
180
2.87k
      return false;
181
4.48k
  }
182
4.48k
}
183
184
0
bool spvOpcodeReturnsLogicalVariablePointer(const spv::Op opcode) {
185
0
  switch (opcode) {
186
0
    case spv::Op::OpVariable:
187
0
    case spv::Op::OpUntypedVariableKHR:
188
0
    case spv::Op::OpAccessChain:
189
0
    case spv::Op::OpInBoundsAccessChain:
190
0
    case spv::Op::OpUntypedAccessChainKHR:
191
0
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
192
0
    case spv::Op::OpFunctionParameter:
193
0
    case spv::Op::OpImageTexelPointer:
194
0
    case spv::Op::OpCopyObject:
195
0
    case spv::Op::OpAllocateNodePayloadsAMDX:
196
0
    case spv::Op::OpSelect:
197
0
    case spv::Op::OpPhi:
198
0
    case spv::Op::OpFunctionCall:
199
0
    case spv::Op::OpPtrAccessChain:
200
0
    case spv::Op::OpUntypedPtrAccessChainKHR:
201
0
    case spv::Op::OpLoad:
202
0
    case spv::Op::OpConstantNull:
203
0
    case spv::Op::OpRawAccessChainNV:
204
0
      return true;
205
0
    default:
206
0
      return false;
207
0
  }
208
0
}
209
210
39.0k
int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
211
39.0k
  switch (opcode) {
212
30.3k
    case spv::Op::OpVariable:
213
30.3k
    case spv::Op::OpUntypedVariableKHR:
214
37.7k
    case spv::Op::OpAccessChain:
215
37.7k
    case spv::Op::OpInBoundsAccessChain:
216
37.7k
    case spv::Op::OpUntypedAccessChainKHR:
217
37.7k
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
218
39.0k
    case spv::Op::OpFunctionParameter:
219
39.0k
    case spv::Op::OpImageTexelPointer:
220
39.0k
    case spv::Op::OpCopyObject:
221
39.0k
    case spv::Op::OpRawAccessChainNV:
222
39.0k
    case spv::Op::OpAllocateNodePayloadsAMDX:
223
39.0k
      return true;
224
0
    default:
225
0
      return false;
226
39.0k
  }
227
39.0k
}
228
229
2.49M
int32_t spvOpcodeGeneratesType(spv::Op op) {
230
2.49M
  switch (op) {
231
34.2k
    case spv::Op::OpTypeVoid:
232
48.4k
    case spv::Op::OpTypeBool:
233
99.4k
    case spv::Op::OpTypeInt:
234
137k
    case spv::Op::OpTypeFloat:
235
219k
    case spv::Op::OpTypeVector:
236
228k
    case spv::Op::OpTypeMatrix:
237
248k
    case spv::Op::OpTypeImage:
238
250k
    case spv::Op::OpTypeSampler:
239
259k
    case spv::Op::OpTypeSampledImage:
240
272k
    case spv::Op::OpTypeArray:
241
273k
    case spv::Op::OpTypeRuntimeArray:
242
298k
    case spv::Op::OpTypeStruct:
243
298k
    case spv::Op::OpTypeOpaque:
244
446k
    case spv::Op::OpTypePointer:
245
483k
    case spv::Op::OpTypeFunction:
246
483k
    case spv::Op::OpTypeEvent:
247
483k
    case spv::Op::OpTypeDeviceEvent:
248
483k
    case spv::Op::OpTypeReserveId:
249
483k
    case spv::Op::OpTypeQueue:
250
483k
    case spv::Op::OpTypePipe:
251
483k
    case spv::Op::OpTypePipeStorage:
252
483k
    case spv::Op::OpTypeNamedBarrier:
253
483k
    case spv::Op::OpTypeAccelerationStructureNV:
254
483k
    case spv::Op::OpTypeCooperativeMatrixNV:
255
483k
    case spv::Op::OpTypeCooperativeMatrixKHR:
256
483k
    case spv::Op::OpTypeCooperativeVectorNV:
257
    // case spv::Op::OpTypeAccelerationStructureKHR: covered by
258
    // spv::Op::OpTypeAccelerationStructureNV
259
483k
    case spv::Op::OpTypeRayQueryKHR:
260
483k
    case spv::Op::OpTypeHitObjectNV:
261
483k
    case spv::Op::OpTypeUntypedPointerKHR:
262
483k
    case spv::Op::OpTypeNodePayloadArrayAMDX:
263
483k
    case spv::Op::OpTypeTensorLayoutNV:
264
483k
    case spv::Op::OpTypeTensorViewNV:
265
483k
    case spv::Op::OpTypeTensorARM:
266
483k
    case spv::Op::OpTypeTaskSequenceINTEL:
267
483k
      return true;
268
2.00M
    default:
269
      // In particular, OpTypeForwardPointer does not generate a type,
270
      // but declares a storage class for a pointer type generated
271
      // by a different instruction.
272
2.00M
      break;
273
2.49M
  }
274
2.00M
  return 0;
275
2.49M
}
276
277
252k
bool spvOpcodeIsDecoration(const spv::Op opcode) {
278
252k
  switch (opcode) {
279
246
    case spv::Op::OpDecorate:
280
246
    case spv::Op::OpDecorateId:
281
328
    case spv::Op::OpMemberDecorate:
282
328
    case spv::Op::OpGroupDecorate:
283
328
    case spv::Op::OpGroupMemberDecorate:
284
328
    case spv::Op::OpDecorateStringGOOGLE:
285
328
    case spv::Op::OpMemberDecorateStringGOOGLE:
286
328
      return true;
287
251k
    default:
288
251k
      break;
289
252k
  }
290
251k
  return false;
291
252k
}
292
293
340k
bool spvOpcodeIsLoad(const spv::Op opcode) {
294
340k
  switch (opcode) {
295
31.4k
    case spv::Op::OpLoad:
296
37.7k
    case spv::Op::OpImageSampleExplicitLod:
297
37.7k
    case spv::Op::OpImageSampleImplicitLod:
298
37.7k
    case spv::Op::OpImageSampleDrefImplicitLod:
299
37.7k
    case spv::Op::OpImageSampleDrefExplicitLod:
300
37.7k
    case spv::Op::OpImageSampleProjImplicitLod:
301
37.7k
    case spv::Op::OpImageSampleProjExplicitLod:
302
37.7k
    case spv::Op::OpImageSampleProjDrefImplicitLod:
303
37.7k
    case spv::Op::OpImageSampleProjDrefExplicitLod:
304
37.7k
    case spv::Op::OpImageSampleFootprintNV:
305
37.7k
    case spv::Op::OpImageFetch:
306
37.7k
    case spv::Op::OpImageGather:
307
37.7k
    case spv::Op::OpImageDrefGather:
308
38.2k
    case spv::Op::OpImageRead:
309
38.2k
    case spv::Op::OpImageSparseSampleImplicitLod:
310
38.2k
    case spv::Op::OpImageSparseSampleExplicitLod:
311
38.2k
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
312
38.2k
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
313
38.2k
    case spv::Op::OpImageSparseFetch:
314
38.2k
    case spv::Op::OpImageSparseGather:
315
38.2k
    case spv::Op::OpImageSparseDrefGather:
316
38.4k
    case spv::Op::OpImageSparseRead:
317
38.4k
      return true;
318
301k
    default:
319
301k
      return false;
320
340k
  }
321
340k
}
322
323
1.18M
bool spvOpcodeIsBranch(spv::Op opcode) {
324
1.18M
  switch (opcode) {
325
102k
    case spv::Op::OpBranch:
326
157k
    case spv::Op::OpBranchConditional:
327
163k
    case spv::Op::OpSwitch:
328
163k
      return true;
329
1.02M
    default:
330
1.02M
      return false;
331
1.18M
  }
332
1.18M
}
333
334
745k
bool spvOpcodeIsAtomicWithLoad(const spv::Op opcode) {
335
745k
  switch (opcode) {
336
0
    case spv::Op::OpAtomicLoad:
337
0
    case spv::Op::OpAtomicExchange:
338
0
    case spv::Op::OpAtomicCompareExchange:
339
0
    case spv::Op::OpAtomicCompareExchangeWeak:
340
0
    case spv::Op::OpAtomicIIncrement:
341
0
    case spv::Op::OpAtomicIDecrement:
342
48
    case spv::Op::OpAtomicIAdd:
343
48
    case spv::Op::OpAtomicFAddEXT:
344
48
    case spv::Op::OpAtomicISub:
345
48
    case spv::Op::OpAtomicSMin:
346
48
    case spv::Op::OpAtomicUMin:
347
48
    case spv::Op::OpAtomicFMinEXT:
348
48
    case spv::Op::OpAtomicSMax:
349
48
    case spv::Op::OpAtomicUMax:
350
48
    case spv::Op::OpAtomicFMaxEXT:
351
48
    case spv::Op::OpAtomicAnd:
352
48
    case spv::Op::OpAtomicOr:
353
48
    case spv::Op::OpAtomicXor:
354
48
    case spv::Op::OpAtomicFlagTestAndSet:
355
48
      return true;
356
745k
    default:
357
745k
      return false;
358
745k
  }
359
745k
}
360
361
0
bool spvOpcodeIsAtomicOp(const spv::Op opcode) {
362
0
  return (spvOpcodeIsAtomicWithLoad(opcode) ||
363
0
          opcode == spv::Op::OpAtomicStore ||
364
0
          opcode == spv::Op::OpAtomicFlagClear);
365
0
}
366
367
471k
bool spvOpcodeIsReturn(spv::Op opcode) {
368
471k
  switch (opcode) {
369
12.0k
    case spv::Op::OpReturn:
370
13.9k
    case spv::Op::OpReturnValue:
371
13.9k
      return true;
372
457k
    default:
373
457k
      return false;
374
471k
  }
375
471k
}
376
377
450k
bool spvOpcodeIsAbort(spv::Op opcode) {
378
450k
  switch (opcode) {
379
0
    case spv::Op::OpKill:
380
2
    case spv::Op::OpUnreachable:
381
2
    case spv::Op::OpTerminateInvocation:
382
2
    case spv::Op::OpTerminateRayKHR:
383
2
    case spv::Op::OpIgnoreIntersectionKHR:
384
2
    case spv::Op::OpEmitMeshTasksEXT:
385
2
      return true;
386
450k
    default:
387
450k
      return false;
388
450k
  }
389
450k
}
390
391
452k
bool spvOpcodeIsReturnOrAbort(spv::Op opcode) {
392
452k
  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
393
452k
}
394
395
466k
bool spvOpcodeIsBlockTerminator(spv::Op opcode) {
396
466k
  return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
397
466k
}
398
399
0
bool spvOpcodeIsBaseOpaqueType(spv::Op opcode) {
400
0
  switch (opcode) {
401
0
    case spv::Op::OpTypeImage:
402
0
    case spv::Op::OpTypeSampler:
403
0
    case spv::Op::OpTypeSampledImage:
404
0
    case spv::Op::OpTypeOpaque:
405
0
    case spv::Op::OpTypeEvent:
406
0
    case spv::Op::OpTypeDeviceEvent:
407
0
    case spv::Op::OpTypeReserveId:
408
0
    case spv::Op::OpTypeQueue:
409
0
    case spv::Op::OpTypePipe:
410
0
    case spv::Op::OpTypeForwardPointer:
411
0
    case spv::Op::OpTypePipeStorage:
412
0
    case spv::Op::OpTypeNamedBarrier:
413
0
      return true;
414
0
    default:
415
0
      return false;
416
0
  }
417
0
}
418
419
196k
bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) {
420
196k
  switch (opcode) {
421
0
    case spv::Op::OpGroupNonUniformElect:
422
0
    case spv::Op::OpGroupNonUniformAll:
423
0
    case spv::Op::OpGroupNonUniformAny:
424
0
    case spv::Op::OpGroupNonUniformAllEqual:
425
0
    case spv::Op::OpGroupNonUniformBroadcast:
426
0
    case spv::Op::OpGroupNonUniformBroadcastFirst:
427
0
    case spv::Op::OpGroupNonUniformBallot:
428
0
    case spv::Op::OpGroupNonUniformInverseBallot:
429
0
    case spv::Op::OpGroupNonUniformBallotBitExtract:
430
0
    case spv::Op::OpGroupNonUniformBallotBitCount:
431
0
    case spv::Op::OpGroupNonUniformBallotFindLSB:
432
0
    case spv::Op::OpGroupNonUniformBallotFindMSB:
433
0
    case spv::Op::OpGroupNonUniformShuffle:
434
0
    case spv::Op::OpGroupNonUniformShuffleXor:
435
0
    case spv::Op::OpGroupNonUniformShuffleUp:
436
0
    case spv::Op::OpGroupNonUniformShuffleDown:
437
0
    case spv::Op::OpGroupNonUniformIAdd:
438
0
    case spv::Op::OpGroupNonUniformFAdd:
439
0
    case spv::Op::OpGroupNonUniformIMul:
440
0
    case spv::Op::OpGroupNonUniformFMul:
441
0
    case spv::Op::OpGroupNonUniformSMin:
442
0
    case spv::Op::OpGroupNonUniformUMin:
443
0
    case spv::Op::OpGroupNonUniformFMin:
444
0
    case spv::Op::OpGroupNonUniformSMax:
445
0
    case spv::Op::OpGroupNonUniformUMax:
446
0
    case spv::Op::OpGroupNonUniformFMax:
447
0
    case spv::Op::OpGroupNonUniformBitwiseAnd:
448
0
    case spv::Op::OpGroupNonUniformBitwiseOr:
449
0
    case spv::Op::OpGroupNonUniformBitwiseXor:
450
0
    case spv::Op::OpGroupNonUniformLogicalAnd:
451
0
    case spv::Op::OpGroupNonUniformLogicalOr:
452
0
    case spv::Op::OpGroupNonUniformLogicalXor:
453
0
    case spv::Op::OpGroupNonUniformQuadBroadcast:
454
0
    case spv::Op::OpGroupNonUniformQuadSwap:
455
0
    case spv::Op::OpGroupNonUniformRotateKHR:
456
0
    case spv::Op::OpGroupNonUniformQuadAllKHR:
457
0
    case spv::Op::OpGroupNonUniformQuadAnyKHR:
458
0
      return true;
459
196k
    default:
460
196k
      return false;
461
196k
  }
462
196k
}
463
464
34.9k
bool spvOpcodeIsScalarizable(spv::Op opcode) {
465
34.9k
  switch (opcode) {
466
4.53k
    case spv::Op::OpPhi:
467
4.53k
    case spv::Op::OpCopyObject:
468
4.71k
    case spv::Op::OpConvertFToU:
469
4.73k
    case spv::Op::OpConvertFToS:
470
6.12k
    case spv::Op::OpConvertSToF:
471
6.13k
    case spv::Op::OpConvertUToF:
472
6.13k
    case spv::Op::OpUConvert:
473
6.15k
    case spv::Op::OpSConvert:
474
6.15k
    case spv::Op::OpFConvert:
475
6.15k
    case spv::Op::OpQuantizeToF16:
476
6.15k
    case spv::Op::OpVectorInsertDynamic:
477
6.16k
    case spv::Op::OpSNegate:
478
6.30k
    case spv::Op::OpFNegate:
479
7.57k
    case spv::Op::OpIAdd:
480
10.4k
    case spv::Op::OpFAdd:
481
10.4k
    case spv::Op::OpISub:
482
10.9k
    case spv::Op::OpFSub:
483
11.0k
    case spv::Op::OpIMul:
484
12.8k
    case spv::Op::OpFMul:
485
12.8k
    case spv::Op::OpUDiv:
486
12.8k
    case spv::Op::OpSDiv:
487
14.5k
    case spv::Op::OpFDiv:
488
14.6k
    case spv::Op::OpUMod:
489
14.6k
    case spv::Op::OpSRem:
490
14.6k
    case spv::Op::OpSMod:
491
14.6k
    case spv::Op::OpFRem:
492
14.6k
    case spv::Op::OpFMod:
493
17.2k
    case spv::Op::OpVectorTimesScalar:
494
17.2k
    case spv::Op::OpIAddCarry:
495
17.2k
    case spv::Op::OpISubBorrow:
496
17.2k
    case spv::Op::OpUMulExtended:
497
17.2k
    case spv::Op::OpSMulExtended:
498
17.2k
    case spv::Op::OpShiftRightLogical:
499
17.2k
    case spv::Op::OpShiftRightArithmetic:
500
17.2k
    case spv::Op::OpShiftLeftLogical:
501
17.2k
    case spv::Op::OpBitwiseOr:
502
17.2k
    case spv::Op::OpBitwiseAnd:
503
17.2k
    case spv::Op::OpNot:
504
17.2k
    case spv::Op::OpBitFieldInsert:
505
17.2k
    case spv::Op::OpBitFieldSExtract:
506
17.2k
    case spv::Op::OpBitFieldUExtract:
507
17.2k
    case spv::Op::OpBitReverse:
508
17.2k
    case spv::Op::OpBitCount:
509
17.2k
    case spv::Op::OpIsNan:
510
17.2k
    case spv::Op::OpIsInf:
511
17.2k
    case spv::Op::OpIsFinite:
512
17.2k
    case spv::Op::OpIsNormal:
513
17.2k
    case spv::Op::OpSignBitSet:
514
17.2k
    case spv::Op::OpLessOrGreater:
515
17.2k
    case spv::Op::OpOrdered:
516
17.2k
    case spv::Op::OpUnordered:
517
17.2k
    case spv::Op::OpLogicalEqual:
518
17.2k
    case spv::Op::OpLogicalNotEqual:
519
17.2k
    case spv::Op::OpLogicalOr:
520
17.2k
    case spv::Op::OpLogicalAnd:
521
17.2k
    case spv::Op::OpLogicalNot:
522
17.3k
    case spv::Op::OpSelect:
523
17.3k
    case spv::Op::OpIEqual:
524
17.3k
    case spv::Op::OpINotEqual:
525
17.4k
    case spv::Op::OpUGreaterThan:
526
17.7k
    case spv::Op::OpSGreaterThan:
527
17.7k
    case spv::Op::OpUGreaterThanEqual:
528
17.7k
    case spv::Op::OpSGreaterThanEqual:
529
17.7k
    case spv::Op::OpULessThan:
530
18.2k
    case spv::Op::OpSLessThan:
531
18.2k
    case spv::Op::OpULessThanEqual:
532
18.6k
    case spv::Op::OpSLessThanEqual:
533
18.7k
    case spv::Op::OpFOrdEqual:
534
18.7k
    case spv::Op::OpFUnordEqual:
535
18.7k
    case spv::Op::OpFOrdNotEqual:
536
18.7k
    case spv::Op::OpFUnordNotEqual:
537
19.3k
    case spv::Op::OpFOrdLessThan:
538
19.3k
    case spv::Op::OpFUnordLessThan:
539
19.9k
    case spv::Op::OpFOrdGreaterThan:
540
19.9k
    case spv::Op::OpFUnordGreaterThan:
541
19.9k
    case spv::Op::OpFOrdLessThanEqual:
542
19.9k
    case spv::Op::OpFUnordLessThanEqual:
543
19.9k
    case spv::Op::OpFOrdGreaterThanEqual:
544
19.9k
    case spv::Op::OpFUnordGreaterThanEqual:
545
19.9k
      return true;
546
15.0k
    default:
547
15.0k
      return false;
548
34.9k
  }
549
34.9k
}
550
551
25.5k
bool spvOpcodeIsDebug(spv::Op opcode) {
552
25.5k
  switch (opcode) {
553
0
    case spv::Op::OpName:
554
0
    case spv::Op::OpMemberName:
555
0
    case spv::Op::OpSource:
556
0
    case spv::Op::OpSourceContinued:
557
0
    case spv::Op::OpSourceExtension:
558
0
    case spv::Op::OpString:
559
0
    case spv::Op::OpLine:
560
0
    case spv::Op::OpNoLine:
561
0
    case spv::Op::OpModuleProcessed:
562
0
      return true;
563
25.5k
    default:
564
25.5k
      return false;
565
25.5k
  }
566
25.5k
}
567
568
0
bool spvOpcodeIsCommutativeBinaryOperator(spv::Op opcode) {
569
0
  switch (opcode) {
570
0
    case spv::Op::OpPtrEqual:
571
0
    case spv::Op::OpPtrNotEqual:
572
0
    case spv::Op::OpIAdd:
573
0
    case spv::Op::OpFAdd:
574
0
    case spv::Op::OpIMul:
575
0
    case spv::Op::OpFMul:
576
0
    case spv::Op::OpDot:
577
0
    case spv::Op::OpIAddCarry:
578
0
    case spv::Op::OpUMulExtended:
579
0
    case spv::Op::OpSMulExtended:
580
0
    case spv::Op::OpBitwiseOr:
581
0
    case spv::Op::OpBitwiseXor:
582
0
    case spv::Op::OpBitwiseAnd:
583
0
    case spv::Op::OpOrdered:
584
0
    case spv::Op::OpUnordered:
585
0
    case spv::Op::OpLogicalEqual:
586
0
    case spv::Op::OpLogicalNotEqual:
587
0
    case spv::Op::OpLogicalOr:
588
0
    case spv::Op::OpLogicalAnd:
589
0
    case spv::Op::OpIEqual:
590
0
    case spv::Op::OpINotEqual:
591
0
    case spv::Op::OpFOrdEqual:
592
0
    case spv::Op::OpFUnordEqual:
593
0
    case spv::Op::OpFOrdNotEqual:
594
0
    case spv::Op::OpFUnordNotEqual:
595
0
      return true;
596
0
    default:
597
0
      return false;
598
0
  }
599
0
}
600
601
0
bool spvOpcodeIsLinearAlgebra(spv::Op opcode) {
602
0
  switch (opcode) {
603
0
    case spv::Op::OpTranspose:
604
0
    case spv::Op::OpVectorTimesScalar:
605
0
    case spv::Op::OpMatrixTimesScalar:
606
0
    case spv::Op::OpVectorTimesMatrix:
607
0
    case spv::Op::OpMatrixTimesVector:
608
0
    case spv::Op::OpMatrixTimesMatrix:
609
0
    case spv::Op::OpOuterProduct:
610
0
    case spv::Op::OpDot:
611
0
      return true;
612
0
    default:
613
0
      return false;
614
0
  }
615
0
}
616
617
0
bool spvOpcodeIsImageSample(const spv::Op opcode) {
618
0
  switch (opcode) {
619
0
    case spv::Op::OpImageSampleImplicitLod:
620
0
    case spv::Op::OpImageSampleExplicitLod:
621
0
    case spv::Op::OpImageSampleDrefImplicitLod:
622
0
    case spv::Op::OpImageSampleDrefExplicitLod:
623
0
    case spv::Op::OpImageSampleProjImplicitLod:
624
0
    case spv::Op::OpImageSampleProjExplicitLod:
625
0
    case spv::Op::OpImageSampleProjDrefImplicitLod:
626
0
    case spv::Op::OpImageSampleProjDrefExplicitLod:
627
0
    case spv::Op::OpImageSparseSampleImplicitLod:
628
0
    case spv::Op::OpImageSparseSampleExplicitLod:
629
0
    case spv::Op::OpImageSparseSampleDrefImplicitLod:
630
0
    case spv::Op::OpImageSparseSampleDrefExplicitLod:
631
0
    case spv::Op::OpImageSampleFootprintNV:
632
0
      return true;
633
0
    default:
634
0
      return false;
635
0
  }
636
0
}
637
638
1.97M
bool spvIsExtendedInstruction(const spv::Op opcode) {
639
1.97M
  switch (opcode) {
640
31.1k
    case spv::Op::OpExtInst:
641
31.1k
    case spv::Op::OpExtInstWithForwardRefsKHR:
642
31.1k
      return true;
643
1.94M
    default:
644
1.94M
      return false;
645
1.97M
  }
646
1.97M
}
647
648
0
std::vector<uint32_t> spvOpcodeMemorySemanticsOperandIndices(spv::Op opcode) {
649
0
  switch (opcode) {
650
0
    case spv::Op::OpMemoryBarrier:
651
0
      return {1};
652
0
    case spv::Op::OpAtomicStore:
653
0
    case spv::Op::OpControlBarrier:
654
0
    case spv::Op::OpAtomicFlagClear:
655
0
    case spv::Op::OpMemoryNamedBarrier:
656
0
      return {2};
657
0
    case spv::Op::OpAtomicLoad:
658
0
    case spv::Op::OpAtomicExchange:
659
0
    case spv::Op::OpAtomicIIncrement:
660
0
    case spv::Op::OpAtomicIDecrement:
661
0
    case spv::Op::OpAtomicIAdd:
662
0
    case spv::Op::OpAtomicFAddEXT:
663
0
    case spv::Op::OpAtomicISub:
664
0
    case spv::Op::OpAtomicSMin:
665
0
    case spv::Op::OpAtomicUMin:
666
0
    case spv::Op::OpAtomicSMax:
667
0
    case spv::Op::OpAtomicUMax:
668
0
    case spv::Op::OpAtomicAnd:
669
0
    case spv::Op::OpAtomicOr:
670
0
    case spv::Op::OpAtomicXor:
671
0
    case spv::Op::OpAtomicFlagTestAndSet:
672
0
      return {4};
673
0
    case spv::Op::OpAtomicCompareExchange:
674
0
    case spv::Op::OpAtomicCompareExchangeWeak:
675
0
      return {4, 5};
676
0
    default:
677
0
      return {};
678
0
  }
679
0
}
680
681
0
bool spvOpcodeIsAccessChain(spv::Op opcode) {
682
0
  switch (opcode) {
683
0
    case spv::Op::OpAccessChain:
684
0
    case spv::Op::OpInBoundsAccessChain:
685
0
    case spv::Op::OpPtrAccessChain:
686
0
    case spv::Op::OpInBoundsPtrAccessChain:
687
0
    case spv::Op::OpRawAccessChainNV:
688
0
      return true;
689
0
    default:
690
0
      return false;
691
0
  }
692
0
}
693
694
0
bool spvOpcodeIsBit(spv::Op opcode) {
695
0
  switch (opcode) {
696
0
    case spv::Op::OpShiftRightLogical:
697
0
    case spv::Op::OpShiftRightArithmetic:
698
0
    case spv::Op::OpShiftLeftLogical:
699
0
    case spv::Op::OpBitwiseOr:
700
0
    case spv::Op::OpBitwiseXor:
701
0
    case spv::Op::OpBitwiseAnd:
702
0
    case spv::Op::OpNot:
703
0
    case spv::Op::OpBitReverse:
704
0
    case spv::Op::OpBitCount:
705
0
      return true;
706
0
    default:
707
0
      return false;
708
0
  }
709
0
}
710
711
7.83k
bool spvOpcodeGeneratesUntypedPointer(spv::Op opcode) {
712
7.83k
  switch (opcode) {
713
0
    case spv::Op::OpUntypedVariableKHR:
714
0
    case spv::Op::OpUntypedAccessChainKHR:
715
0
    case spv::Op::OpUntypedInBoundsAccessChainKHR:
716
0
    case spv::Op::OpUntypedPtrAccessChainKHR:
717
0
    case spv::Op::OpUntypedInBoundsPtrAccessChainKHR:
718
0
      return true;
719
7.83k
    default:
720
7.83k
      return false;
721
7.83k
  }
722
7.83k
}