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/MCELFObjectWriter.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::emitDirectiveOptionPush() {} |
39 | void LoongArchTargetELFStreamer::emitDirectiveOptionPop() {} |
40 | void LoongArchTargetELFStreamer::emitDirectiveOptionRelax() {} |
41 | void LoongArchTargetELFStreamer::emitDirectiveOptionNoRelax() {} |
42 | |
43 | void LoongArchTargetELFStreamer::finish() { |
44 | LoongArchTargetStreamer::finish(); |
45 | ELFObjectWriter &W = getStreamer().getWriter(); |
46 | LoongArchABI::ABI ABI = getTargetABI(); |
47 | |
48 | // Figure out the e_flags. |
49 | // |
50 | // Bitness is already represented with the EI_CLASS byte in the current spec, |
51 | // so here we only record the base ABI modifier. Also set the object file ABI |
52 | // version to v1, as upstream LLVM cannot handle the previous stack-machine- |
53 | // based relocs from day one. |
54 | // |
55 | // Refer to LoongArch ELF psABI v2.01 for details. |
56 | unsigned EFlags = W.getELFHeaderEFlags(); |
57 | EFlags |= ELF::EF_LOONGARCH_OBJABI_V1; |
58 | switch (ABI) { |
59 | case LoongArchABI::ABI_ILP32S: |
60 | case LoongArchABI::ABI_LP64S: |
61 | EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT; |
62 | break; |
63 | case LoongArchABI::ABI_ILP32F: |
64 | case LoongArchABI::ABI_LP64F: |
65 | EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT; |
66 | break; |
67 | case LoongArchABI::ABI_ILP32D: |
68 | case LoongArchABI::ABI_LP64D: |
69 | EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT; |
70 | break; |
71 | case LoongArchABI::ABI_Unknown: |
72 | llvm_unreachable("Improperly initialized target ABI" ); |
73 | } |
74 | W.setELFHeaderEFlags(EFlags); |
75 | } |
76 | |
77 | namespace { |
78 | class LoongArchELFStreamer : public MCELFStreamer { |
79 | public: |
80 | LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB, |
81 | std::unique_ptr<MCObjectWriter> MOW, |
82 | std::unique_ptr<MCCodeEmitter> MCE) |
83 | : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} |
84 | }; |
85 | } // end namespace |
86 | |
87 | namespace llvm { |
88 | MCELFStreamer *createLoongArchELFStreamer(MCContext &C, |
89 | std::unique_ptr<MCAsmBackend> MAB, |
90 | std::unique_ptr<MCObjectWriter> MOW, |
91 | std::unique_ptr<MCCodeEmitter> MCE) { |
92 | LoongArchELFStreamer *S = new LoongArchELFStreamer( |
93 | C, std::move(MAB), std::move(MOW), std::move(MCE)); |
94 | return S; |
95 | } |
96 | } // end namespace llvm |
97 | |