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-exception 6 // 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 "mlir/Dialect/SPIRV/IR/SPIRVTypes.h" 15 16 using namespace mlir; 17 18 void spirv::appendModuleHeader(SmallVectorImpl<uint32_t> &header, 19 spirv::Version version, uint32_t idBound) { 20 uint32_t majorVersion = 1; 21 uint32_t minorVersion = 0; 22 switch (version) { 23 #define MIN_VERSION_CASE(v) \ 24 case spirv::Version::V_1_##v: \ 25 minorVersion = v; \ 26 break 27 28 MIN_VERSION_CASE(0); 29 MIN_VERSION_CASE(1); 30 MIN_VERSION_CASE(2); 31 MIN_VERSION_CASE(3); 32 MIN_VERSION_CASE(4); 33 MIN_VERSION_CASE(5); 34 #undef MIN_VERSION_CASE 35 } 36 37 // See "2.3. Physical Layout of a SPIR-V Module and Instruction" in the SPIR-V 38 // spec for the definition of the binary module header. 39 // 40 // The first five words of a SPIR-V module must be: 41 // +-------------------------------------------------------------------------+ 42 // | Magic number | 43 // +-------------------------------------------------------------------------+ 44 // | Version number (bytes: 0 | major number | minor number | 0) | 45 // +-------------------------------------------------------------------------+ 46 // | Generator magic number | 47 // +-------------------------------------------------------------------------+ 48 // | Bound (all result <id>s in the module guaranteed to be less than it) | 49 // +-------------------------------------------------------------------------+ 50 // | 0 (reserved for instruction schema) | 51 // +-------------------------------------------------------------------------+ 52 header.push_back(spirv::kMagicNumber); 53 header.push_back((majorVersion << 16) | (minorVersion << 8)); 54 header.push_back(kGeneratorNumber); 55 header.push_back(idBound); // <id> bound 56 header.push_back(0); // Schema (reserved word) 57 } 58 59 /// Returns the word-count-prefixed opcode for an SPIR-V instruction. 60 uint32_t spirv::getPrefixedOpcode(uint32_t wordCount, spirv::Opcode opcode) { 61 assert(((wordCount >> 16) == 0) && "word count out of range!"); 62 return (wordCount << 16) | static_cast<uint32_t>(opcode); 63 } 64 65 void spirv::encodeStringLiteralInto(SmallVectorImpl<uint32_t> &binary, 66 StringRef literal) { 67 // We need to encode the literal and the null termination. 68 auto encodingSize = literal.size() / 4 + 1; 69 auto bufferStartSize = binary.size(); 70 binary.resize(bufferStartSize + encodingSize, 0); 71 std::memcpy(binary.data() + bufferStartSize, literal.data(), literal.size()); 72 } 73