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