1 //===- SPIRVStream.h Class to represent a SPIR-V Stream --------*- C++ -*-===// 2 // 3 // The LLVM/SPIRV Translator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 // Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved. 9 // 10 // Permission is hereby granted, free of charge, to any person obtaining a 11 // copy of this software and associated documentation files (the "Software"), 12 // to deal with the Software without restriction, including without limitation 13 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 // and/or sell copies of the Software, and to permit persons to whom the 15 // Software is furnished to do so, subject to the following conditions: 16 // 17 // Redistributions of source code must retain the above copyright notice, 18 // this list of conditions and the following disclaimers. 19 // Redistributions in binary form must reproduce the above copyright notice, 20 // this list of conditions and the following disclaimers in the documentation 21 // and/or other materials provided with the distribution. 22 // Neither the names of Advanced Micro Devices, Inc., nor the names of its 23 // contributors may be used to endorse or promote products derived from this 24 // Software without specific prior written permission. 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 31 // THE SOFTWARE. 32 // 33 //===----------------------------------------------------------------------===// 34 /// \file 35 /// 36 /// This file defines Word class for SPIR-V. 37 /// 38 //===----------------------------------------------------------------------===// 39 40 #ifndef SPIRVSTREAM_H 41 #define SPIRVSTREAM_H 42 43 #include "SPIRVDebug.h" 44 #include "SPIRVModule.h" 45 #include "SPIRVExtInst.h" 46 #include <algorithm> 47 #include <cstdint> 48 #include <iostream> 49 #include <iterator> 50 #include <vector> 51 #include <string> 52 53 namespace SPIRV{ 54 55 #ifndef _SPIRV_SUPPORT_TEXT_FMT 56 #define _SPIRV_SUPPORT_TEXT_FMT 57 #endif 58 59 #ifdef _SPIRV_SUPPORT_TEXT_FMT 60 // Use textual format for SPIRV. 61 extern bool SPIRVUseTextFormat; 62 #endif 63 64 class SPIRVFunction; 65 class SPIRVBasicBlock; 66 67 class SPIRVDecoder { 68 public: 69 SPIRVDecoder(std::istream& InputStream, SPIRVModule& Module) 70 :IS(InputStream), M(Module), WordCount(0), OpCode(OpNop), 71 Scope(NULL){} 72 SPIRVDecoder(std::istream& InputStream, SPIRVFunction& F); 73 SPIRVDecoder(std::istream& InputStream, SPIRVBasicBlock &BB); 74 75 void setScope(SPIRVEntry *); 76 bool getWordCountAndOpCode(); 77 SPIRVEntry *getEntry(); 78 void validate()const; 79 80 std::istream &IS; 81 SPIRVModule &M; 82 SPIRVWord WordCount; 83 Op OpCode; 84 SPIRVEntry *Scope; // A function or basic block 85 }; 86 87 class SPIRVEncoder { 88 public: 89 explicit SPIRVEncoder(spv_ostream &OutputStream) : OS(OutputStream) {} 90 spv_ostream &OS; 91 }; 92 93 /// Output a new line in text mode. Do nothing in binary mode. 94 class SPIRVNL { 95 friend spv_ostream &operator<<(spv_ostream &O, const SPIRVNL &E); 96 }; 97 98 template<typename T> 99 const SPIRVDecoder& 100 DecodeBinary(const SPIRVDecoder& I, T &V) { 101 uint32_t W; 102 I.IS.read(reinterpret_cast<char*>(&W), sizeof(W)); 103 V = static_cast<T>(W); 104 SPIRVDBG(spvdbgs() << "Read word: W = " << W << " V = " << V << '\n'); 105 return I; 106 } 107 108 template<typename T> 109 const SPIRVDecoder& 110 operator>>(const SPIRVDecoder& I, T &V) { 111 #ifdef _SPIRV_SUPPORT_TEXT_FMT 112 if (SPIRVUseTextFormat) { 113 uint32_t W; 114 I.IS >> W; 115 V = static_cast<T>(W); 116 SPIRVDBG(spvdbgs() << "Read word: W = " << W << " V = " << V << '\n'); 117 return I; 118 } 119 #endif 120 return DecodeBinary(I, V); 121 } 122 123 template<typename T> 124 const SPIRVDecoder& 125 operator>>(const SPIRVDecoder& I, T *&P) { 126 SPIRVId Id; 127 I >> Id; 128 P = static_cast<T*>(I.M.getEntry(Id)); 129 return I; 130 } 131 132 template<typename IterTy> 133 const SPIRVDecoder& 134 operator>>(const SPIRVDecoder& Decoder, const std::pair<IterTy,IterTy> &Range) { 135 for (IterTy I = Range.first, E = Range.second; I != E; ++I) 136 Decoder >> *I; 137 return Decoder; 138 } 139 140 template<typename T> 141 const SPIRVDecoder& 142 operator>>(const SPIRVDecoder& I, std::vector<T> &V) { 143 for (size_t i = 0, e = V.size(); i != e; ++i) 144 I >> V[i]; 145 return I; 146 } 147 148 template<typename T> 149 const SPIRVEncoder& 150 operator<<(const SPIRVEncoder& O, T V) { 151 #ifdef _SPIRV_SUPPORT_TEXT_FMT 152 if (SPIRVUseTextFormat) { 153 O.OS << V << " "; 154 return O; 155 } 156 #endif 157 uint32_t W = static_cast<uint32_t>(V); 158 O.OS.write(reinterpret_cast<char*>(&W), sizeof(W)); 159 return O; 160 } 161 162 template<typename T> 163 const SPIRVEncoder& 164 operator<<(const SPIRVEncoder& O, T* P) { 165 return O << P->getId(); 166 } 167 168 template<typename T> 169 const SPIRVEncoder& 170 operator<<(const SPIRVEncoder& O, const std::vector<T>& V) { 171 for (size_t i = 0, e = V.size(); i != e; ++i) 172 O << V[i]; 173 return O; 174 } 175 176 template<typename IterTy> 177 const SPIRVEncoder& 178 operator<<(const SPIRVEncoder& Encoder, const std::pair<IterTy,IterTy> &Range) { 179 for (IterTy I = Range.first, E = Range.second; I != E; ++I) 180 Encoder << *I; 181 return Encoder; 182 } 183 184 #define SPIRV_DEC_ENCDEC(Type) \ 185 const SPIRVEncoder& \ 186 operator<<(const SPIRVEncoder& O, Type V); \ 187 const SPIRVDecoder& \ 188 operator>>(const SPIRVDecoder& I, Type &V); 189 190 SPIRV_DEC_ENCDEC(Op) 191 SPIRV_DEC_ENCDEC(Capability) 192 SPIRV_DEC_ENCDEC(Decoration) 193 SPIRV_DEC_ENCDEC(OCLExtOpKind) 194 SPIRV_DEC_ENCDEC(LinkageType) 195 196 const SPIRVEncoder& 197 operator<<(const SPIRVEncoder&O, const std::string& Str); 198 const SPIRVDecoder& 199 operator>>(const SPIRVDecoder&I, std::string& Str); 200 201 } // namespace SPIRV 202 #endif 203