brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · cbd1d42 Raw
88 lines · cpp
1//===- SPIRVBinaryUtils.cpp - MLIR SPIR-V Binary Module Utilities ---------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines common utilities for SPIR-V binary module.10//11//===----------------------------------------------------------------------===//12 13#include "mlir/Target/SPIRV/SPIRVBinaryUtils.h"14#include "llvm/Config/llvm-config.h" // for LLVM_VERSION_MAJOR15#include "llvm/Support/Debug.h"16 17#define DEBUG_TYPE "spirv-binary-utils"18 19using namespace mlir;20 21void spirv::appendModuleHeader(SmallVectorImpl<uint32_t> &header,22                               spirv::Version version, uint32_t idBound) {23  uint32_t majorVersion = 1;24  uint32_t minorVersion = 0;25  switch (version) {26#define MIN_VERSION_CASE(v)                                                    \27  case spirv::Version::V_1_##v:                                                \28    minorVersion = v;                                                          \29    break30 31    MIN_VERSION_CASE(0);32    MIN_VERSION_CASE(1);33    MIN_VERSION_CASE(2);34    MIN_VERSION_CASE(3);35    MIN_VERSION_CASE(4);36    MIN_VERSION_CASE(5);37    MIN_VERSION_CASE(6);38#undef MIN_VERSION_CASE39  }40 41  // See "2.3. Physical Layout of a SPIR-V Module and Instruction" in the SPIR-V42  // spec for the definition of the binary module header.43  //44  // The first five words of a SPIR-V module must be:45  // +-------------------------------------------------------------------------+46  // | Magic number                                                            |47  // +-------------------------------------------------------------------------+48  // | Version number (bytes: 0 | major number | minor number | 0)             |49  // +-------------------------------------------------------------------------+50  // | Generator magic number                                                  |51  // +-------------------------------------------------------------------------+52  // | Bound (all result <id>s in the module guaranteed to be less than it)    |53  // +-------------------------------------------------------------------------+54  // | 0 (reserved for instruction schema)                                     |55  // +-------------------------------------------------------------------------+56  header.push_back(spirv::kMagicNumber);57  header.push_back((majorVersion << 16) | (minorVersion << 8));58  header.push_back((kGeneratorNumber << 16) | LLVM_VERSION_MAJOR);59  header.push_back(idBound); // <id> bound60  header.push_back(0);       // Schema (reserved word)61}62 63/// Returns the word-count-prefixed opcode for an SPIR-V instruction.64uint32_t spirv::getPrefixedOpcode(uint32_t wordCount, spirv::Opcode opcode) {65  assert(((wordCount >> 16) == 0) && "word count out of range!");66  return (wordCount << 16) | static_cast<uint32_t>(opcode);67}68 69void spirv::encodeStringLiteralInto(SmallVectorImpl<uint32_t> &binary,70                                    StringRef literal) {71  // We need to encode the literal and the null termination.72  size_t encodingSize = literal.size() / 4 + 1;73  size_t sizeOfDataToCopy = literal.size();74  if (encodingSize >= kMaxLiteralWordCount) {75    // Reserve one word for the null termination.76    encodingSize = kMaxLiteralWordCount - 1;77    // Do not override the last word (null termination) when copying.78    sizeOfDataToCopy = (encodingSize - 1) * 4;79    LLVM_DEBUG(llvm::dbgs()80               << "Truncating string literal to max size ("81               << (kMaxLiteralWordCount - 1) << "): " << literal << "\n");82  }83  size_t bufferStartSize = binary.size();84  binary.resize(bufferStartSize + encodingSize, 0);85  std::memcpy(binary.data() + bufferStartSize, literal.data(),86              sizeOfDataToCopy);87}88