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 | namespace { |
18 | class SPIRVObjectWriter : public MCObjectWriter { |
19 | ::support::endian::Writer W; |
20 | |
21 | /// The target specific SPIR-V writer instance. |
22 | std::unique_ptr<MCSPIRVObjectTargetWriter> TargetObjectWriter; |
23 | |
24 | public: |
25 | SPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, |
26 | raw_pwrite_stream &OS) |
27 | : W(OS, llvm::endianness::little), TargetObjectWriter(std::move(MOTW)) {} |
28 | |
29 | ~SPIRVObjectWriter() override {} |
30 | |
31 | private: |
32 | void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, |
33 | const MCFragment *Fragment, const MCFixup &Fixup, |
34 | MCValue Target, uint64_t &FixedValue) override {} |
35 | |
36 | void executePostLayoutBinding(MCAssembler &Asm, |
37 | const MCAsmLayout &Layout) override {} |
38 | |
39 | uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; |
40 | void writeHeader(const MCAssembler &Asm); |
41 | }; |
42 | } // namespace |
43 | |
44 | void SPIRVObjectWriter::(const MCAssembler &Asm) { |
45 | constexpr uint32_t MagicNumber = 0x07230203; |
46 | constexpr uint32_t GeneratorID = 43; |
47 | constexpr uint32_t GeneratorMagicNumber = |
48 | (GeneratorID << 16) | (LLVM_VERSION_MAJOR); |
49 | constexpr uint32_t Schema = 0; |
50 | const MCAssembler::VersionInfoType &VIT = Asm.getVersionInfo(); |
51 | uint32_t VersionNumber = 0 | (VIT.Major << 16) | (VIT.Minor << 8); |
52 | uint32_t Bound = VIT.Update; |
53 | |
54 | W.write<uint32_t>(Val: MagicNumber); |
55 | W.write<uint32_t>(Val: VersionNumber); |
56 | W.write<uint32_t>(Val: GeneratorMagicNumber); |
57 | W.write<uint32_t>(Val: Bound); |
58 | W.write<uint32_t>(Val: Schema); |
59 | } |
60 | |
61 | uint64_t SPIRVObjectWriter::writeObject(MCAssembler &Asm, |
62 | const MCAsmLayout &Layout) { |
63 | uint64_t StartOffset = W.OS.tell(); |
64 | writeHeader(Asm); |
65 | for (const MCSection &S : Asm) |
66 | Asm.writeSectionData(OS&: W.OS, Section: &S, Layout); |
67 | return W.OS.tell() - StartOffset; |
68 | } |
69 | |
70 | std::unique_ptr<MCObjectWriter> |
71 | llvm::createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, |
72 | raw_pwrite_stream &OS) { |
73 | return std::make_unique<SPIRVObjectWriter>(args: std::move(MOTW), args&: OS); |
74 | } |
75 | |