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(), MAB.getTargetOptions().getABIName())); 31 } 32 33 MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { 34 return static_cast<MCELFStreamer &>(Streamer); 35 } 36 37 void 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 71 namespace { 72 class LoongArchELFStreamer : public MCELFStreamer { 73 public: 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 81 namespace llvm { 82 MCELFStreamer *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