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