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