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 53namespace 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. 61extern bool SPIRVUseTextFormat; 62#endif 63 64class SPIRVFunction; 65class SPIRVBasicBlock; 66 67class SPIRVDecoder { 68public: 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 87class SPIRVEncoder { 88public: 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. 94class SPIRVNL { 95 friend spv_ostream &operator<<(spv_ostream &O, const SPIRVNL &E); 96}; 97 98template<typename T> 99const SPIRVDecoder& 100DecodeBinary(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 108template<typename T> 109const SPIRVDecoder& 110operator>>(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 123template<typename T> 124const SPIRVDecoder& 125operator>>(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 132template<typename IterTy> 133const SPIRVDecoder& 134operator>>(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 140template<typename T> 141const SPIRVDecoder& 142operator>>(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 148template<typename T> 149const SPIRVEncoder& 150operator<<(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 162template<typename T> 163const SPIRVEncoder& 164operator<<(const SPIRVEncoder& O, T* P) { 165 return O << P->getId(); 166} 167 168template<typename T> 169const SPIRVEncoder& 170operator<<(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 176template<typename IterTy> 177const SPIRVEncoder& 178operator<<(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) \ 185const SPIRVEncoder& \ 186operator<<(const SPIRVEncoder& O, Type V); \ 187const SPIRVDecoder& \ 188operator>>(const SPIRVDecoder& I, Type &V); 189 190SPIRV_DEC_ENCDEC(Op) 191SPIRV_DEC_ENCDEC(Capability) 192SPIRV_DEC_ENCDEC(Decoration) 193SPIRV_DEC_ENCDEC(OCLExtOpKind) 194SPIRV_DEC_ENCDEC(LinkageType) 195 196const SPIRVEncoder& 197operator<<(const SPIRVEncoder&O, const std::string& Str); 198const SPIRVDecoder& 199operator>>(const SPIRVDecoder&I, std::string& Str); 200 201} // namespace SPIRV 202#endif 203