// Copyright (c) 2015 The Khronos Group Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and/or associated documentation files (the
// "Materials"), to deal in the Materials without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Materials, and to
// permit persons to whom the Materials are furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Materials.
//
// MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS
// KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS
// SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT
//    https://www.khronos.org/registry/
//
// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.

#include "opcode.h"

#include <assert.h>
#include <string.h>

#include <cstdlib>

#include "endian.h"
#include "instruction.h"
#include "libspirv/libspirv.h"
#include "spirv_constant.h"
#include "spirv_operands.h"

namespace {

// Descriptions of each opcode.  Each entry describes the format of the
// instruction that follows a particular opcode.
//
// Most fields are initialized statically by including an automatically
// generated file.
// The operandTypes fields are initialized during spvOpcodeInitialize().
//
// TODO(dneto): Some of the macros are quite unreadable.  We could make
// good use of constexpr functions, but some compilers don't support that yet.
const spv_opcode_desc_t opcodeTableEntries[] = {
#define EmptyList \
  {}
#define List(...) \
  { __VA_ARGS__ }
#define Capability(X) SPV_CAPABILITY_AS_MASK(SpvCapability##X)
#define Capability2(X, Y) Capability(X) | Capability(Y)
#define SpvCapabilityNone \
  0  // Needed so Capability(None) still expands to valid syntax.
#define Instruction(Name, HasResult, HasType, NumLogicalOperands,        \
                    NumCapabilities, CapabilityRequired, IsVariable,     \
                    LogicalArgsList)                                     \
  {#Name,     SpvOp##Name, (NumCapabilities) ? (CapabilityRequired) : 0, \
   0,         {}, /* Filled in later. Operand list, including            \
                     result id and type id, if needed */                 \
   HasResult, HasType,     LogicalArgsList},
#include "opcode.inc"
#undef EmptyList
#undef List
#undef Capability
#undef Capability2
#undef CapabilityNone
#undef Instruction
};

// Opcode API

// Converts the given operand class enum (from the SPIR-V document generation
// logic) to the operand type required by the parser.  The SPV_OPERAND_TYPE_NONE
// value indicates there is no current operand and no further operands.
// This only applies to logical operands.
spv_operand_type_t convertOperandClassToType(SpvOp opcode,
                                             OperandClass operandClass) {
  // The spec document generator uses OptionalOperandLiteral for several kinds
  // of repeating values.  Our parser needs more specific information about
  // what is being repeated.
  if (operandClass == OperandOptionalLiteral) {
    switch (opcode) {
      case SpvOpLoad:
      case SpvOpStore:
      case SpvOpCopyMemory:
      case SpvOpCopyMemorySized:
        // Expect an optional mask.  When the Aligned bit is set in the mask,
        // we will later add the expectation of a literal number operand.
        return SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS;
      case SpvOpExecutionMode:
        return SPV_OPERAND_TYPE_VARIABLE_EXECUTION_MODE;
      default:
        break;
    }
  } else if (operandClass == OperandVariableLiterals) {
    if (opcode == SpvOpConstant || opcode == SpvOpSpecConstant) {
      // The number type is determined by the type Id operand.
      return SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
    }
  }

  switch (operandClass) {
    case OperandNone:
      return SPV_OPERAND_TYPE_NONE;
    case OperandId:
      return SPV_OPERAND_TYPE_ID;
    case OperandOptionalId:
      return SPV_OPERAND_TYPE_OPTIONAL_ID;
    case OperandOptionalImage:
      return SPV_OPERAND_TYPE_OPTIONAL_IMAGE;
    case OperandVariableIds:
      if (opcode == SpvOpSpecConstantOp) {
        // These are the operands to the specialization constant opcode.
        // The assembler and binary parser set up the extra Id and literal
        // arguments when processing the opcode operand.  So don't add
        // an operand type for them here.
        return SPV_OPERAND_TYPE_NONE;
      }
      return SPV_OPERAND_TYPE_VARIABLE_ID;
    // The spec only uses OptionalLiteral for an optional literal number.
    case OperandOptionalLiteral:
      return SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER;
    case OperandOptionalLiteralString:
      return SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING;
    // This is only used for sequences of literal numbers.
    case OperandVariableLiterals:
      return SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER;
    case OperandLiteralNumber:
      if (opcode == SpvOpExtInst) {
        // We use a special operand type for the extension instruction number.
        // For now, we assume there is only one LiteraNumber argument to
        // OpExtInst, and it is the extension instruction argument.
        // See the ExtInst entry in opcode.inc
        // TODO(dneto): Use a function to confirm the assumption, and to verify
        // that the index into the operandClass is 1, as expected.
        return SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER;
      } else if (opcode == SpvOpSpecConstantOp) {
        // Use a special operand type for the opcode operand, so we can
        // use mnemonic names instead of the numbers.  For example, the
        // assembler should accept "IAdd" instead of the numeric value of
        // SpvOpIAdd.
        return SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER;
      }
      return SPV_OPERAND_TYPE_LITERAL_INTEGER;
    case OperandLiteralString:
      return SPV_OPERAND_TYPE_LITERAL_STRING;
    case OperandSource:
      return SPV_OPERAND_TYPE_SOURCE_LANGUAGE;
    case OperandExecutionModel:
      return SPV_OPERAND_TYPE_EXECUTION_MODEL;
    case OperandAddressing:
      return SPV_OPERAND_TYPE_ADDRESSING_MODEL;
    case OperandMemory:
      return SPV_OPERAND_TYPE_MEMORY_MODEL;
    case OperandExecutionMode:
      return SPV_OPERAND_TYPE_EXECUTION_MODE;
    case OperandStorage:
      return SPV_OPERAND_TYPE_STORAGE_CLASS;
    case OperandDimensionality:
      return SPV_OPERAND_TYPE_DIMENSIONALITY;
    case OperandSamplerAddressingMode:
      return SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE;
    case OperandSamplerFilterMode:
      return SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE;
    case OperandSamplerImageFormat:
      return SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT;
    case OperandImageChannelOrder:
      // This is only used to describe the value generated by OpImageQueryOrder.
      // It is not used as an operand.
      break;
    case OperandImageChannelDataType:
      // This is only used to describe the value generated by
      // OpImageQueryFormat. It is not used as an operand.
      break;
    case OperandImageOperands:
      // This is not used in opcode.inc. It only exists to generate the
      // corresponding spec section. In parsing, image operands meld into the
      // OperandOptionalImage case.
      break;
    case OperandFPFastMath:
      return SPV_OPERAND_TYPE_FP_FAST_MATH_MODE;
    case OperandFPRoundingMode:
      return SPV_OPERAND_TYPE_FP_ROUNDING_MODE;
    case OperandLinkageType:
      return SPV_OPERAND_TYPE_LINKAGE_TYPE;
    case OperandAccessQualifier:
      return SPV_OPERAND_TYPE_ACCESS_QUALIFIER;
    case OperandFuncParamAttr:
      return SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE;
    case OperandDecoration:
      return SPV_OPERAND_TYPE_DECORATION;
    case OperandBuiltIn:
      return SPV_OPERAND_TYPE_BUILT_IN;
    case OperandSelect:
      return SPV_OPERAND_TYPE_SELECTION_CONTROL;
    case OperandLoop:
      return SPV_OPERAND_TYPE_LOOP_CONTROL;
    case OperandFunction:
      return SPV_OPERAND_TYPE_FUNCTION_CONTROL;
    case OperandMemorySemantics:
      return SPV_OPERAND_TYPE_MEMORY_SEMANTICS;
    case OperandMemoryAccess:
      // This case does not occur in the table for SPIR-V 0.99 Rev 32.
      // We expect that it will become SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS,
      // and we can remove the special casing above for memory operation
      // instructions.
      break;
    case OperandScope:
      return SPV_OPERAND_TYPE_EXECUTION_SCOPE;
    case OperandGroupOperation:
      return SPV_OPERAND_TYPE_GROUP_OPERATION;
    case OperandKernelEnqueueFlags:
      return SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS;
    case OperandKernelProfilingInfo:
      return SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO;
    case OperandCapability:
      return SPV_OPERAND_TYPE_CAPABILITY;

    // Used by GroupMemberDecorate
    case OperandVariableIdLiteral:
      return SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER;

    // Used by Switch
    case OperandVariableLiteralId:
      return SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID;

    // These exceptional cases shouldn't occur.
    case OperandCount:
    default:
      break;
  }
  assert(0 && "Unexpected operand class");
  return SPV_OPERAND_TYPE_NONE;
}

}  // anonymous namespace

// Finish populating the opcodeTableEntries array.
void spvOpcodeTableInitialize(spv_opcode_desc_t* entries,
                              uint32_t num_entries) {
  // Compute the operandTypes field for each entry.
  for (uint32_t i = 0; i < num_entries; ++i) {
    spv_opcode_desc_t& opcode = entries[i];
    opcode.numTypes = 0;
    // Type ID always comes first, if present.
    if (opcode.hasType)
      opcode.operandTypes[opcode.numTypes++] = SPV_OPERAND_TYPE_TYPE_ID;
    // Result ID always comes next, if present
    if (opcode.hasResult)
      opcode.operandTypes[opcode.numTypes++] = SPV_OPERAND_TYPE_RESULT_ID;
    const uint16_t maxNumOperands =
        sizeof(opcode.operandTypes) / sizeof(opcode.operandTypes[0]);
    const uint16_t maxNumClasses =
        sizeof(opcode.operandClass) / sizeof(opcode.operandClass[0]);
    for (uint16_t classIndex = 0;
         opcode.numTypes < maxNumOperands && classIndex < maxNumClasses;
         classIndex++) {
      const OperandClass operandClass = opcode.operandClass[classIndex];
      const auto operandType =
          convertOperandClassToType(opcode.opcode, operandClass);
      opcode.operandTypes[opcode.numTypes++] = operandType;
      // The OperandNone value is not explicitly represented in the .inc file.
      // However, it is the zero value, and is created via implicit value
      // initialization.  It converts to SPV_OPERAND_TYPE_NONE.
      // The SPV_OPERAND_TYPE_NONE operand type indicates no current or futher
      // operands.
      if (operandType == SPV_OPERAND_TYPE_NONE) {
        opcode.numTypes--;
        break;
      }
    }

    // We should have written the terminating SPV_OPERAND_TYPE_NONE entry, but
    // also without overflowing.
    assert((opcode.numTypes < maxNumOperands) &&
           "Operand class list is too long.  Expand "
           "spv_opcode_desc_t.operandClass");
  }
}

const char* spvGeneratorStr(uint32_t generator) {
  switch (generator) {
    case SPV_GENERATOR_KHRONOS:
      return "Khronos";
    case SPV_GENERATOR_LUNARG:
      return "LunarG";
    case SPV_GENERATOR_VALVE:
      return "Valve";
    case SPV_GENERATOR_CODEPLAY:
      return "Codeplay Software Ltd.";
    case SPV_GENERATOR_NVIDIA:
      return "NVIDIA";
    case SPV_GENERATOR_ARM:
      return "ARM";
    case SPV_GENERATOR_KHRONOS_LLVM_TRANSLATOR:
      return "Khronos LLVM/SPIR-V Translator";
    case SPV_GENERATOR_KHRONOS_ASSEMBLER:
      return "Khronos SPIR-V Tools Assembler";
    default:
      return "Unknown";
  }
}

uint32_t spvOpcodeMake(uint16_t wordCount, SpvOp opcode) {
  return ((uint32_t)opcode) | (((uint32_t)wordCount) << 16);
}

void spvOpcodeSplit(const uint32_t word, uint16_t* pWordCount, SpvOp* pOpcode) {
  if (pWordCount) {
    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
  }
  if (pOpcode) {
    *pOpcode = (SpvOp)(0x0000ffff & word);
  }
}

spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable) {
  if (!pInstTable) return SPV_ERROR_INVALID_POINTER;

  const uint32_t size = sizeof(opcodeTableEntries);
  spv_opcode_desc_t* copied_entries =
      static_cast<spv_opcode_desc_t*>(::malloc(size));
  if (!copied_entries) return SPV_ERROR_OUT_OF_MEMORY;
  ::memcpy(copied_entries, opcodeTableEntries, size);

  const uint32_t count = sizeof(opcodeTableEntries) / sizeof(spv_opcode_desc_t);
  spv_opcode_table_t* table = new spv_opcode_table_t{count, copied_entries};

  spvOpcodeTableInitialize(copied_entries, count);

  *pInstTable = table;

  return SPV_SUCCESS;
}

spv_result_t spvOpcodeTableNameLookup(const spv_opcode_table table,
                                      const char* name,
                                      spv_opcode_desc* pEntry) {
  if (!name || !pEntry) return SPV_ERROR_INVALID_POINTER;
  if (!table) return SPV_ERROR_INVALID_TABLE;

  // TODO: This lookup of the Opcode table is suboptimal! Binary sort would be
  // preferable but the table requires sorting on the Opcode name, but it's
  // static
  // const initialized and matches the order of the spec.
  const size_t nameLength = strlen(name);
  for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
    if (nameLength == strlen(table->entries[opcodeIndex].name) &&
        !strncmp(name, table->entries[opcodeIndex].name, nameLength)) {
      // NOTE: Found out Opcode!
      *pEntry = &table->entries[opcodeIndex];
      return SPV_SUCCESS;
    }
  }

  return SPV_ERROR_INVALID_LOOKUP;
}

spv_result_t spvOpcodeTableValueLookup(const spv_opcode_table table,
                                       const SpvOp opcode,
                                       spv_opcode_desc* pEntry) {
  if (!table) return SPV_ERROR_INVALID_TABLE;
  if (!pEntry) return SPV_ERROR_INVALID_POINTER;

  // TODO: As above this lookup is not optimal.
  for (uint64_t opcodeIndex = 0; opcodeIndex < table->count; ++opcodeIndex) {
    if (opcode == table->entries[opcodeIndex].opcode) {
      // NOTE: Found the Opcode!
      *pEntry = &table->entries[opcodeIndex];
      return SPV_SUCCESS;
    }
  }

  return SPV_ERROR_INVALID_LOOKUP;
}

int32_t spvOpcodeRequiresCapabilities(spv_opcode_desc entry) {
  return entry->capabilities != 0;
}

void spvInstructionCopy(const uint32_t* words, const SpvOp opcode,
                        const uint16_t wordCount, const spv_endianness_t endian,
                        spv_instruction_t* pInst) {
  pInst->opcode = opcode;
  pInst->words.resize(wordCount);
  for (uint16_t wordIndex = 0; wordIndex < wordCount; ++wordIndex) {
    pInst->words[wordIndex] = spvFixWord(words[wordIndex], endian);
    if (!wordIndex) {
      uint16_t thisWordCount;
      SpvOp thisOpcode;
      spvOpcodeSplit(pInst->words[wordIndex], &thisWordCount, &thisOpcode);
      assert(opcode == thisOpcode && wordCount == thisWordCount &&
             "Endianness failed!");
    }
  }
}

const char* spvOpcodeString(const SpvOp opcode) {
// Use the syntax table so it's sure to be complete.
#define Instruction(Name, ...) \
  case SpvOp##Name:            \
    return #Name;
  switch (opcode) {
#include "opcode.inc"
    default:
      assert(0 && "Unreachable!");
  }
  return "unknown";
#undef Instruction
}

int32_t spvOpcodeIsScalarType(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsConstant(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpConstantTrue:
    case SpvOpConstantFalse:
    case SpvOpConstant:
    case SpvOpConstantComposite:
    case SpvOpConstantSampler:
    // case SpvOpConstantNull:
    case SpvOpConstantNull:
    case SpvOpSpecConstantTrue:
    case SpvOpSpecConstantFalse:
    case SpvOpSpecConstant:
    case SpvOpSpecConstantComposite:
      // case SpvOpSpecConstantOp:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsComposite(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeVector:
    case SpvOpTypeMatrix:
    case SpvOpTypeArray:
    case SpvOpTypeStruct:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeAreTypesEqual(const spv_instruction_t* pTypeInst0,
                               const spv_instruction_t* pTypeInst1) {
  if (pTypeInst0->opcode != pTypeInst1->opcode) return false;
  if (pTypeInst0->words[1] != pTypeInst1->words[1]) return false;
  return true;
}

int32_t spvOpcodeIsPointer(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpVariable:
    case SpvOpAccessChain:
    case SpvOpInBoundsAccessChain:
    case SpvOpFunctionParameter:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsObject(const SpvOp opcode) {
  switch (opcode) {
    case SpvOpConstantTrue:
    case SpvOpConstantFalse:
    case SpvOpConstant:
    case SpvOpConstantComposite:
    // TODO: case SpvOpConstantSampler:
    case SpvOpConstantNull:
    case SpvOpSpecConstantTrue:
    case SpvOpSpecConstantFalse:
    case SpvOpSpecConstant:
    case SpvOpSpecConstantComposite:
    // TODO: case SpvOpSpecConstantOp:
    case SpvOpVariable:
    case SpvOpAccessChain:
    case SpvOpInBoundsAccessChain:
    case SpvOpConvertFToU:
    case SpvOpConvertFToS:
    case SpvOpConvertSToF:
    case SpvOpConvertUToF:
    case SpvOpUConvert:
    case SpvOpSConvert:
    case SpvOpFConvert:
    case SpvOpConvertPtrToU:
    // TODO: case SpvOpConvertUToPtr:
    case SpvOpPtrCastToGeneric:
    // TODO: case SpvOpGenericCastToPtr:
    case SpvOpBitcast:
    // TODO: case SpvOpGenericCastToPtrExplicit:
    case SpvOpSatConvertSToU:
    case SpvOpSatConvertUToS:
    case SpvOpVectorExtractDynamic:
    case SpvOpCompositeConstruct:
    case SpvOpCompositeExtract:
    case SpvOpCopyObject:
    case SpvOpTranspose:
    case SpvOpSNegate:
    case SpvOpFNegate:
    case SpvOpNot:
    case SpvOpIAdd:
    case SpvOpFAdd:
    case SpvOpISub:
    case SpvOpFSub:
    case SpvOpIMul:
    case SpvOpFMul:
    case SpvOpUDiv:
    case SpvOpSDiv:
    case SpvOpFDiv:
    case SpvOpUMod:
    case SpvOpSRem:
    case SpvOpSMod:
    case SpvOpVectorTimesScalar:
    case SpvOpMatrixTimesScalar:
    case SpvOpVectorTimesMatrix:
    case SpvOpMatrixTimesVector:
    case SpvOpMatrixTimesMatrix:
    case SpvOpOuterProduct:
    case SpvOpDot:
    case SpvOpShiftRightLogical:
    case SpvOpShiftRightArithmetic:
    case SpvOpShiftLeftLogical:
    case SpvOpBitwiseOr:
    case SpvOpBitwiseXor:
    case SpvOpBitwiseAnd:
    case SpvOpAny:
    case SpvOpAll:
    case SpvOpIsNan:
    case SpvOpIsInf:
    case SpvOpIsFinite:
    case SpvOpIsNormal:
    case SpvOpSignBitSet:
    case SpvOpLessOrGreater:
    case SpvOpOrdered:
    case SpvOpUnordered:
    case SpvOpLogicalOr:
    case SpvOpLogicalAnd:
    case SpvOpSelect:
    case SpvOpIEqual:
    case SpvOpFOrdEqual:
    case SpvOpFUnordEqual:
    case SpvOpINotEqual:
    case SpvOpFOrdNotEqual:
    case SpvOpFUnordNotEqual:
    case SpvOpULessThan:
    case SpvOpSLessThan:
    case SpvOpFOrdLessThan:
    case SpvOpFUnordLessThan:
    case SpvOpUGreaterThan:
    case SpvOpSGreaterThan:
    case SpvOpFOrdGreaterThan:
    case SpvOpFUnordGreaterThan:
    case SpvOpULessThanEqual:
    case SpvOpSLessThanEqual:
    case SpvOpFOrdLessThanEqual:
    case SpvOpFUnordLessThanEqual:
    case SpvOpUGreaterThanEqual:
    case SpvOpSGreaterThanEqual:
    case SpvOpFOrdGreaterThanEqual:
    case SpvOpFUnordGreaterThanEqual:
    case SpvOpDPdx:
    case SpvOpDPdy:
    case SpvOpFwidth:
    case SpvOpDPdxFine:
    case SpvOpDPdyFine:
    case SpvOpFwidthFine:
    case SpvOpDPdxCoarse:
    case SpvOpDPdyCoarse:
    case SpvOpFwidthCoarse:
    case SpvOpReturnValue:
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeIsBasicTypeNullable(SpvOp opcode) {
  switch (opcode) {
    case SpvOpTypeBool:
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
    case SpvOpTypePointer:
    case SpvOpTypeEvent:
    case SpvOpTypeDeviceEvent:
    case SpvOpTypeReserveId:
    case SpvOpTypeQueue:
      return true;
    default:
      return false;
  }
}

int32_t spvInstructionIsInBasicBlock(const spv_instruction_t* pFirstInst,
                                     const spv_instruction_t* pInst) {
  while (pFirstInst != pInst) {
    if (SpvOpFunction == pInst->opcode) break;
    pInst--;
  }
  if (SpvOpFunction != pInst->opcode) return false;
  return true;
}

int32_t spvOpcodeIsValue(SpvOp opcode) {
  if (spvOpcodeIsPointer(opcode)) return true;
  if (spvOpcodeIsConstant(opcode)) return true;
  switch (opcode) {
    case SpvOpLoad:
      // TODO: Other Opcode's resulting in a value
      return true;
    default:
      return false;
  }
}

int32_t spvOpcodeGeneratesType(SpvOp op) {
  switch (op) {
    case SpvOpTypeVoid:
    case SpvOpTypeBool:
    case SpvOpTypeInt:
    case SpvOpTypeFloat:
    case SpvOpTypeVector:
    case SpvOpTypeMatrix:
    case SpvOpTypeImage:
    case SpvOpTypeSampler:
    case SpvOpTypeSampledImage:
    case SpvOpTypeArray:
    case SpvOpTypeRuntimeArray:
    case SpvOpTypeStruct:
    case SpvOpTypeOpaque:
    case SpvOpTypePointer:
    case SpvOpTypeFunction:
    case SpvOpTypeEvent:
    case SpvOpTypeDeviceEvent:
    case SpvOpTypeReserveId:
    case SpvOpTypeQueue:
    case SpvOpTypePipe:
      return true;
    default:
      // In particular, OpTypeForwardPointer does not generate a type,
      // but declares a storage class for a pointer type generated
      // by a different instruction.
      break;
  }
  return 0;
}
