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