| //===- llvm/MC/MCSPIRVObjectWriter.cpp - SPIR-V Object Writer ----*- C++ *-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "llvm/MC/MCAssembler.h" |
| #include "llvm/MC/MCSPIRVObjectWriter.h" |
| #include "llvm/MC/MCSection.h" |
| #include "llvm/MC/MCValue.h" |
| #include "llvm/Support/EndianStream.h" |
| |
| using namespace llvm; |
| |
| namespace { |
| class SPIRVObjectWriter : public MCObjectWriter { |
| ::support::endian::Writer W; |
| |
| /// The target specific SPIR-V writer instance. |
| std::unique_ptr<MCSPIRVObjectTargetWriter> TargetObjectWriter; |
| |
| public: |
| SPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, |
| raw_pwrite_stream &OS) |
| : W(OS, support::little), TargetObjectWriter(std::move(MOTW)) {} |
| |
| ~SPIRVObjectWriter() override {} |
| |
| private: |
| void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, |
| const MCFragment *Fragment, const MCFixup &Fixup, |
| MCValue Target, uint64_t &FixedValue) override {} |
| |
| void executePostLayoutBinding(MCAssembler &Asm, |
| const MCAsmLayout &Layout) override {} |
| |
| uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; |
| void writeHeader(const MCAssembler &Asm); |
| }; |
| } // namespace |
| |
| void SPIRVObjectWriter::writeHeader(const MCAssembler &Asm) { |
| constexpr uint32_t MagicNumber = 0x07230203; |
| |
| // TODO: set the version on a min-necessary basis (just like the translator |
| // does) requires some refactoring of MCAssembler::VersionInfoType. |
| constexpr uint32_t Major = 1; |
| constexpr uint32_t Minor = 0; |
| constexpr uint32_t VersionNumber = 0 | (Major << 16) | (Minor << 8); |
| // TODO: check if we could use anything other than 0 (spec allows). |
| constexpr uint32_t GeneratorMagicNumber = 0; |
| // TODO: do not hardcode this as well. |
| constexpr uint32_t Bound = 900; |
| constexpr uint32_t Schema = 0; |
| |
| W.write<uint32_t>(MagicNumber); |
| W.write<uint32_t>(VersionNumber); |
| W.write<uint32_t>(GeneratorMagicNumber); |
| W.write<uint32_t>(Bound); |
| W.write<uint32_t>(Schema); |
| } |
| |
| uint64_t SPIRVObjectWriter::writeObject(MCAssembler &Asm, |
| const MCAsmLayout &Layout) { |
| uint64_t StartOffset = W.OS.tell(); |
| writeHeader(Asm); |
| for (const MCSection &S : Asm) |
| Asm.writeSectionData(W.OS, &S, Layout); |
| return W.OS.tell() - StartOffset; |
| } |
| |
| std::unique_ptr<MCObjectWriter> |
| llvm::createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, |
| raw_pwrite_stream &OS) { |
| return std::make_unique<SPIRVObjectWriter>(std::move(MOTW), OS); |
| } |