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