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