1 //===- llvm/MC/MCSPIRVObjectWriter.cpp - SPIR-V Object Writer ----*- C++ *-===// 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 #include "llvm/MC/MCAssembler.h" 10 #include "llvm/MC/MCSPIRVObjectWriter.h" 11 #include "llvm/MC/MCSection.h" 12 #include "llvm/MC/MCValue.h" 13 #include "llvm/Support/EndianStream.h" 14 15 using namespace llvm; 16 17 class SPIRVObjectWriter : public MCObjectWriter { 18 ::support::endian::Writer W; 19 20 /// The target specific SPIR-V writer instance. 21 std::unique_ptr<MCSPIRVObjectTargetWriter> TargetObjectWriter; 22 23 public: 24 SPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, 25 raw_pwrite_stream &OS) 26 : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {} 27 28 ~SPIRVObjectWriter() override {} 29 30 private: 31 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 32 const MCFragment *Fragment, const MCFixup &Fixup, 33 MCValue Target, uint64_t &FixedValue) override {} 34 35 void executePostLayoutBinding(MCAssembler &Asm, 36 const MCAsmLayout &Layout) override {} 37 38 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 39 void writeHeader(const MCAssembler &Asm); 40 }; 41 42 void SPIRVObjectWriter::writeHeader(const MCAssembler &Asm) { 43 constexpr uint32_t MagicNumber = 0x07230203; 44 45 // TODO: set the version on a min-necessary basis (just like the translator 46 // does) requires some refactoring of MCAssembler::VersionInfoType. 47 constexpr uint32_t Major = 1; 48 constexpr uint32_t Minor = 0; 49 constexpr uint32_t VersionNumber = 0 | (Major << 16) | (Minor << 8); 50 // TODO: check if we could use anything other than 0 (spec allows). 51 constexpr uint32_t GeneratorMagicNumber = 0; 52 // TODO: do not hardcode this as well. 53 constexpr uint32_t Bound = 900; 54 constexpr uint32_t Schema = 0; 55 56 W.write<uint32_t>(MagicNumber); 57 W.write<uint32_t>(VersionNumber); 58 W.write<uint32_t>(GeneratorMagicNumber); 59 W.write<uint32_t>(Bound); 60 W.write<uint32_t>(Schema); 61 } 62 63 uint64_t SPIRVObjectWriter::writeObject(MCAssembler &Asm, 64 const MCAsmLayout &Layout) { 65 uint64_t StartOffset = W.OS.tell(); 66 writeHeader(Asm); 67 for (const MCSection &S : Asm) 68 Asm.writeSectionData(W.OS, &S, Layout); 69 return W.OS.tell() - StartOffset; 70 } 71 72 std::unique_ptr<MCObjectWriter> 73 llvm::createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, 74 raw_pwrite_stream &OS) { 75 return std::make_unique<SPIRVObjectWriter>(std::move(MOTW), OS); 76 } 77