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 21 using namespace llvm; 22 23 // This part is for ELF object output. 24 LoongArchTargetELFStreamer::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(), STI.getFeatureBits(), 31 MAB.getTargetOptions().getABIName())); 32 } 33 34 MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { 35 return static_cast<MCELFStreamer &>(Streamer); 36 } 37 38 void LoongArchTargetELFStreamer::finish() { 39 LoongArchTargetStreamer::finish(); 40 ELFObjectWriter &W = getStreamer().getWriter(); 41 LoongArchABI::ABI ABI = getTargetABI(); 42 43 // Figure out the e_flags. 44 // 45 // Bitness is already represented with the EI_CLASS byte in the current spec, 46 // so here we only record the base ABI modifier. Also set the object file ABI 47 // version to v1, as upstream LLVM cannot handle the previous stack-machine- 48 // based relocs from day one. 49 // 50 // Refer to LoongArch ELF psABI v2.01 for details. 51 unsigned EFlags = W.getELFHeaderEFlags(); 52 EFlags |= ELF::EF_LOONGARCH_OBJABI_V1; 53 switch (ABI) { 54 case LoongArchABI::ABI_ILP32S: 55 case LoongArchABI::ABI_LP64S: 56 EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT; 57 break; 58 case LoongArchABI::ABI_ILP32F: 59 case LoongArchABI::ABI_LP64F: 60 EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT; 61 break; 62 case LoongArchABI::ABI_ILP32D: 63 case LoongArchABI::ABI_LP64D: 64 EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT; 65 break; 66 case LoongArchABI::ABI_Unknown: 67 llvm_unreachable("Improperly initialized target ABI"); 68 } 69 W.setELFHeaderEFlags(EFlags); 70 } 71 72 namespace { 73 class LoongArchELFStreamer : public MCELFStreamer { 74 public: 75 LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB, 76 std::unique_ptr<MCObjectWriter> MOW, 77 std::unique_ptr<MCCodeEmitter> MCE) 78 : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} 79 }; 80 } // end namespace 81 82 namespace llvm { 83 MCELFStreamer *createLoongArchELFStreamer(MCContext &C, 84 std::unique_ptr<MCAsmBackend> MAB, 85 std::unique_ptr<MCObjectWriter> MOW, 86 std::unique_ptr<MCCodeEmitter> MCE) { 87 LoongArchELFStreamer *S = new LoongArchELFStreamer( 88 C, std::move(MAB), std::move(MOW), std::move(MCE)); 89 return S; 90 } 91 } // end namespace llvm 92