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