xref: /llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp (revision 1a787b3c8e71eeb333825ec4b76c7440290142e4)
1d1f36da9SWeining Lu //===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===//
2d1f36da9SWeining Lu //
3d1f36da9SWeining Lu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4d1f36da9SWeining Lu // See https://llvm.org/LICENSE.txt for license information.
5d1f36da9SWeining Lu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d1f36da9SWeining Lu //
7d1f36da9SWeining Lu //===----------------------------------------------------------------------===//
8d1f36da9SWeining Lu //
9d1f36da9SWeining Lu // This file provides LoongArch specific target streamer methods.
10d1f36da9SWeining Lu //
11d1f36da9SWeining Lu //===----------------------------------------------------------------------===//
12d1f36da9SWeining Lu 
13d1f36da9SWeining Lu #include "LoongArchELFStreamer.h"
14d1f36da9SWeining Lu #include "LoongArchAsmBackend.h"
154f2fde78SWeining Lu #include "LoongArchBaseInfo.h"
16d1f36da9SWeining Lu #include "llvm/BinaryFormat/ELF.h"
17d1f36da9SWeining Lu #include "llvm/MC/MCAssembler.h"
18d1f36da9SWeining Lu #include "llvm/MC/MCCodeEmitter.h"
1925bea3ebSSergei Barannikov #include "llvm/MC/MCELFObjectWriter.h"
20d1f36da9SWeining Lu 
21d1f36da9SWeining Lu using namespace llvm;
22d1f36da9SWeining Lu 
23d1f36da9SWeining Lu // This part is for ELF object output.
24d1f36da9SWeining Lu LoongArchTargetELFStreamer::LoongArchTargetELFStreamer(
25d1f36da9SWeining Lu     MCStreamer &S, const MCSubtargetInfo &STI)
26d1f36da9SWeining Lu     : LoongArchTargetStreamer(S) {
274f2fde78SWeining Lu   auto &MAB = static_cast<LoongArchAsmBackend &>(
284f2fde78SWeining Lu       getStreamer().getAssembler().getBackend());
294f2fde78SWeining Lu   setTargetABI(LoongArchABI::computeTargetABI(
3070608c24Swanglei       STI.getTargetTriple(), STI.getFeatureBits(),
3170608c24Swanglei       MAB.getTargetOptions().getABIName()));
32d1f36da9SWeining Lu }
33d1f36da9SWeining Lu 
34d1f36da9SWeining Lu MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() {
35d1f36da9SWeining Lu   return static_cast<MCELFStreamer &>(Streamer);
36d1f36da9SWeining Lu }
37d1f36da9SWeining Lu 
38*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionPush() {}
39*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionPop() {}
40*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionRelax() {}
41*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionNoRelax() {}
42*1a787b3cSwanglei 
43d1f36da9SWeining Lu void LoongArchTargetELFStreamer::finish() {
44d1f36da9SWeining Lu   LoongArchTargetStreamer::finish();
45c473e75aSFangrui Song   ELFObjectWriter &W = getStreamer().getWriter();
46d1f36da9SWeining Lu   LoongArchABI::ABI ABI = getTargetABI();
47d1f36da9SWeining Lu 
484e2dfd35SWANG Xuerui   // Figure out the e_flags.
49d1f36da9SWeining Lu   //
504e2dfd35SWANG Xuerui   // Bitness is already represented with the EI_CLASS byte in the current spec,
514e2dfd35SWANG Xuerui   // so here we only record the base ABI modifier. Also set the object file ABI
524e2dfd35SWANG Xuerui   // version to v1, as upstream LLVM cannot handle the previous stack-machine-
534e2dfd35SWANG Xuerui   // based relocs from day one.
544e2dfd35SWANG Xuerui   //
554e2dfd35SWANG Xuerui   // Refer to LoongArch ELF psABI v2.01 for details.
56c473e75aSFangrui Song   unsigned EFlags = W.getELFHeaderEFlags();
574e2dfd35SWANG Xuerui   EFlags |= ELF::EF_LOONGARCH_OBJABI_V1;
58d1f36da9SWeining Lu   switch (ABI) {
59d1f36da9SWeining Lu   case LoongArchABI::ABI_ILP32S:
604e2dfd35SWANG Xuerui   case LoongArchABI::ABI_LP64S:
614e2dfd35SWANG Xuerui     EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT;
62d1f36da9SWeining Lu     break;
63d1f36da9SWeining Lu   case LoongArchABI::ABI_ILP32F:
644e2dfd35SWANG Xuerui   case LoongArchABI::ABI_LP64F:
654e2dfd35SWANG Xuerui     EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT;
66d1f36da9SWeining Lu     break;
67d1f36da9SWeining Lu   case LoongArchABI::ABI_ILP32D:
68d1f36da9SWeining Lu   case LoongArchABI::ABI_LP64D:
694e2dfd35SWANG Xuerui     EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT;
70d1f36da9SWeining Lu     break;
71d1f36da9SWeining Lu   case LoongArchABI::ABI_Unknown:
72d1f36da9SWeining Lu     llvm_unreachable("Improperly initialized target ABI");
73d1f36da9SWeining Lu   }
74c473e75aSFangrui Song   W.setELFHeaderEFlags(EFlags);
75d1f36da9SWeining Lu }
76d1f36da9SWeining Lu 
77d1f36da9SWeining Lu namespace {
78d1f36da9SWeining Lu class LoongArchELFStreamer : public MCELFStreamer {
79d1f36da9SWeining Lu public:
80d1f36da9SWeining Lu   LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
81d1f36da9SWeining Lu                        std::unique_ptr<MCObjectWriter> MOW,
82d1f36da9SWeining Lu                        std::unique_ptr<MCCodeEmitter> MCE)
83d1f36da9SWeining Lu       : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
84d1f36da9SWeining Lu };
85d1f36da9SWeining Lu } // end namespace
86d1f36da9SWeining Lu 
87d1f36da9SWeining Lu namespace llvm {
88d1f36da9SWeining Lu MCELFStreamer *createLoongArchELFStreamer(MCContext &C,
89d1f36da9SWeining Lu                                           std::unique_ptr<MCAsmBackend> MAB,
90d1f36da9SWeining Lu                                           std::unique_ptr<MCObjectWriter> MOW,
914e340356SFangrui Song                                           std::unique_ptr<MCCodeEmitter> MCE) {
92d1f36da9SWeining Lu   LoongArchELFStreamer *S = new LoongArchELFStreamer(
93d1f36da9SWeining Lu       C, std::move(MAB), std::move(MOW), std::move(MCE));
94d1f36da9SWeining Lu   return S;
95d1f36da9SWeining Lu }
96d1f36da9SWeining Lu } // end namespace llvm
97