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 | |
47 | // TODO: set the version on a min-necessary basis (just like the translator |
48 | // does) requires some refactoring of MCAssembler::VersionInfoType. |
49 | constexpr uint32_t Major = 1; |
50 | constexpr uint32_t Minor = 0; |
51 | constexpr uint32_t VersionNumber = 0 | (Major << 16) | (Minor << 8); |
52 | // TODO: check if we could use anything other than 0 (spec allows). |
53 | constexpr uint32_t GeneratorMagicNumber = 0; |
54 | // TODO: do not hardcode this as well. |
55 | constexpr uint32_t Bound = 900; |
56 | constexpr uint32_t Schema = 0; |
57 | |
58 | W.write<uint32_t>(Val: MagicNumber); |
59 | W.write<uint32_t>(Val: VersionNumber); |
60 | W.write<uint32_t>(Val: GeneratorMagicNumber); |
61 | W.write<uint32_t>(Val: Bound); |
62 | W.write<uint32_t>(Val: Schema); |
63 | } |
64 | |
65 | uint64_t SPIRVObjectWriter::writeObject(MCAssembler &Asm, |
66 | const MCAsmLayout &Layout) { |
67 | uint64_t StartOffset = W.OS.tell(); |
68 | writeHeader(Asm); |
69 | for (const MCSection &S : Asm) |
70 | Asm.writeSectionData(OS&: W.OS, Section: &S, Layout); |
71 | return W.OS.tell() - StartOffset; |
72 | } |
73 | |
74 | std::unique_ptr<MCObjectWriter> |
75 | llvm::createSPIRVObjectWriter(std::unique_ptr<MCSPIRVObjectTargetWriter> MOTW, |
76 | raw_pwrite_stream &OS) { |
77 | return std::make_unique<SPIRVObjectWriter>(args: std::move(MOTW), args&: OS); |
78 | } |
79 | |