1 | //===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===// |
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 | // This file provides LoongArch specific target streamer methods. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "LoongArchELFStreamer.h" |
14 | #include "LoongArchAsmBackend.h" |
15 | #include "LoongArchBaseInfo.h" |
16 | #include "llvm/BinaryFormat/ELF.h" |
17 | #include "llvm/MC/MCAssembler.h" |
18 | #include "llvm/MC/MCCodeEmitter.h" |
19 | #include "llvm/MC/MCObjectWriter.h" |
20 | |
21 | using namespace llvm; |
22 | |
23 | // This part is for ELF object output. |
24 | LoongArchTargetELFStreamer::LoongArchTargetELFStreamer( |
25 | MCStreamer &S, const MCSubtargetInfo &STI) |
26 | : LoongArchTargetStreamer(S) { |
27 | auto &MAB = static_cast<LoongArchAsmBackend &>( |
28 | getStreamer().getAssembler().getBackend()); |
29 | setTargetABI(LoongArchABI::computeTargetABI( |
30 | TT: STI.getTargetTriple(), FeatureBits: STI.getFeatureBits(), |
31 | ABIName: MAB.getTargetOptions().getABIName())); |
32 | } |
33 | |
34 | MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { |
35 | return static_cast<MCELFStreamer &>(Streamer); |
36 | } |
37 | |
38 | void LoongArchTargetELFStreamer::finish() { |
39 | LoongArchTargetStreamer::finish(); |
40 | ELFObjectWriter &W = getStreamer().getWriter(); |
41 | LoongArchABI::ABI ABI = getTargetABI(); |
42 | |
43 | // Figure out the e_flags. |
44 | // |
45 | // Bitness is already represented with the EI_CLASS byte in the current spec, |
46 | // so here we only record the base ABI modifier. Also set the object file ABI |
47 | // version to v1, as upstream LLVM cannot handle the previous stack-machine- |
48 | // based relocs from day one. |
49 | // |
50 | // Refer to LoongArch ELF psABI v2.01 for details. |
51 | unsigned EFlags = W.getELFHeaderEFlags(); |
52 | EFlags |= ELF::EF_LOONGARCH_OBJABI_V1; |
53 | switch (ABI) { |
54 | case LoongArchABI::ABI_ILP32S: |
55 | case LoongArchABI::ABI_LP64S: |
56 | EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT; |
57 | break; |
58 | case LoongArchABI::ABI_ILP32F: |
59 | case LoongArchABI::ABI_LP64F: |
60 | EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT; |
61 | break; |
62 | case LoongArchABI::ABI_ILP32D: |
63 | case LoongArchABI::ABI_LP64D: |
64 | EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT; |
65 | break; |
66 | case LoongArchABI::ABI_Unknown: |
67 | llvm_unreachable("Improperly initialized target ABI" ); |
68 | } |
69 | W.setELFHeaderEFlags(EFlags); |
70 | } |
71 | |
72 | namespace { |
73 | class LoongArchELFStreamer : public MCELFStreamer { |
74 | public: |
75 | LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB, |
76 | std::unique_ptr<MCObjectWriter> MOW, |
77 | std::unique_ptr<MCCodeEmitter> MCE) |
78 | : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} |
79 | }; |
80 | } // end namespace |
81 | |
82 | namespace llvm { |
83 | MCELFStreamer *createLoongArchELFStreamer(MCContext &C, |
84 | std::unique_ptr<MCAsmBackend> MAB, |
85 | std::unique_ptr<MCObjectWriter> MOW, |
86 | std::unique_ptr<MCCodeEmitter> MCE) { |
87 | LoongArchELFStreamer *S = new LoongArchELFStreamer( |
88 | C, std::move(MAB), std::move(MOW), std::move(MCE)); |
89 | return S; |
90 | } |
91 | } // end namespace llvm |
92 | |