Coverage Report

Created: 2026-01-09 07:38

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