1d1f36da9SWeining Lu //===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===// 2d1f36da9SWeining Lu // 3d1f36da9SWeining Lu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4d1f36da9SWeining Lu // See https://llvm.org/LICENSE.txt for license information. 5d1f36da9SWeining Lu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6d1f36da9SWeining Lu // 7d1f36da9SWeining Lu //===----------------------------------------------------------------------===// 8d1f36da9SWeining Lu // 9d1f36da9SWeining Lu // This file provides LoongArch specific target streamer methods. 10d1f36da9SWeining Lu // 11d1f36da9SWeining Lu //===----------------------------------------------------------------------===// 12d1f36da9SWeining Lu 13d1f36da9SWeining Lu #include "LoongArchELFStreamer.h" 14d1f36da9SWeining Lu #include "LoongArchAsmBackend.h" 154f2fde78SWeining Lu #include "LoongArchBaseInfo.h" 16d1f36da9SWeining Lu #include "llvm/BinaryFormat/ELF.h" 17d1f36da9SWeining Lu #include "llvm/MC/MCAssembler.h" 18d1f36da9SWeining Lu #include "llvm/MC/MCCodeEmitter.h" 1925bea3ebSSergei Barannikov #include "llvm/MC/MCELFObjectWriter.h" 20d1f36da9SWeining Lu 21d1f36da9SWeining Lu using namespace llvm; 22d1f36da9SWeining Lu 23d1f36da9SWeining Lu // This part is for ELF object output. 24d1f36da9SWeining Lu LoongArchTargetELFStreamer::LoongArchTargetELFStreamer( 25d1f36da9SWeining Lu MCStreamer &S, const MCSubtargetInfo &STI) 26d1f36da9SWeining Lu : LoongArchTargetStreamer(S) { 274f2fde78SWeining Lu auto &MAB = static_cast<LoongArchAsmBackend &>( 284f2fde78SWeining Lu getStreamer().getAssembler().getBackend()); 294f2fde78SWeining Lu setTargetABI(LoongArchABI::computeTargetABI( 3070608c24Swanglei STI.getTargetTriple(), STI.getFeatureBits(), 3170608c24Swanglei MAB.getTargetOptions().getABIName())); 32d1f36da9SWeining Lu } 33d1f36da9SWeining Lu 34d1f36da9SWeining Lu MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() { 35d1f36da9SWeining Lu return static_cast<MCELFStreamer &>(Streamer); 36d1f36da9SWeining Lu } 37d1f36da9SWeining Lu 38*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionPush() {} 39*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionPop() {} 40*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionRelax() {} 41*1a787b3cSwanglei void LoongArchTargetELFStreamer::emitDirectiveOptionNoRelax() {} 42*1a787b3cSwanglei 43d1f36da9SWeining Lu void LoongArchTargetELFStreamer::finish() { 44d1f36da9SWeining Lu LoongArchTargetStreamer::finish(); 45c473e75aSFangrui Song ELFObjectWriter &W = getStreamer().getWriter(); 46d1f36da9SWeining Lu LoongArchABI::ABI ABI = getTargetABI(); 47d1f36da9SWeining Lu 484e2dfd35SWANG Xuerui // Figure out the e_flags. 49d1f36da9SWeining Lu // 504e2dfd35SWANG Xuerui // Bitness is already represented with the EI_CLASS byte in the current spec, 514e2dfd35SWANG Xuerui // so here we only record the base ABI modifier. Also set the object file ABI 524e2dfd35SWANG Xuerui // version to v1, as upstream LLVM cannot handle the previous stack-machine- 534e2dfd35SWANG Xuerui // based relocs from day one. 544e2dfd35SWANG Xuerui // 554e2dfd35SWANG Xuerui // Refer to LoongArch ELF psABI v2.01 for details. 56c473e75aSFangrui Song unsigned EFlags = W.getELFHeaderEFlags(); 574e2dfd35SWANG Xuerui EFlags |= ELF::EF_LOONGARCH_OBJABI_V1; 58d1f36da9SWeining Lu switch (ABI) { 59d1f36da9SWeining Lu case LoongArchABI::ABI_ILP32S: 604e2dfd35SWANG Xuerui case LoongArchABI::ABI_LP64S: 614e2dfd35SWANG Xuerui EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT; 62d1f36da9SWeining Lu break; 63d1f36da9SWeining Lu case LoongArchABI::ABI_ILP32F: 644e2dfd35SWANG Xuerui case LoongArchABI::ABI_LP64F: 654e2dfd35SWANG Xuerui EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT; 66d1f36da9SWeining Lu break; 67d1f36da9SWeining Lu case LoongArchABI::ABI_ILP32D: 68d1f36da9SWeining Lu case LoongArchABI::ABI_LP64D: 694e2dfd35SWANG Xuerui EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT; 70d1f36da9SWeining Lu break; 71d1f36da9SWeining Lu case LoongArchABI::ABI_Unknown: 72d1f36da9SWeining Lu llvm_unreachable("Improperly initialized target ABI"); 73d1f36da9SWeining Lu } 74c473e75aSFangrui Song W.setELFHeaderEFlags(EFlags); 75d1f36da9SWeining Lu } 76d1f36da9SWeining Lu 77d1f36da9SWeining Lu namespace { 78d1f36da9SWeining Lu class LoongArchELFStreamer : public MCELFStreamer { 79d1f36da9SWeining Lu public: 80d1f36da9SWeining Lu LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB, 81d1f36da9SWeining Lu std::unique_ptr<MCObjectWriter> MOW, 82d1f36da9SWeining Lu std::unique_ptr<MCCodeEmitter> MCE) 83d1f36da9SWeining Lu : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {} 84d1f36da9SWeining Lu }; 85d1f36da9SWeining Lu } // end namespace 86d1f36da9SWeining Lu 87d1f36da9SWeining Lu namespace llvm { 88d1f36da9SWeining Lu MCELFStreamer *createLoongArchELFStreamer(MCContext &C, 89d1f36da9SWeining Lu std::unique_ptr<MCAsmBackend> MAB, 90d1f36da9SWeining Lu std::unique_ptr<MCObjectWriter> MOW, 914e340356SFangrui Song std::unique_ptr<MCCodeEmitter> MCE) { 92d1f36da9SWeining Lu LoongArchELFStreamer *S = new LoongArchELFStreamer( 93d1f36da9SWeining Lu C, std::move(MAB), std::move(MOW), std::move(MCE)); 94d1f36da9SWeining Lu return S; 95d1f36da9SWeining Lu } 96d1f36da9SWeining Lu } // end namespace llvm 97