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