Coverage Report

Created: 2025-08-29 07:31

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