llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchELFStreamer.cpp
WANG Xuerui 4e2dfd3589 [LoongArch] Updates for the LoongArch ELF psABI v2.01 revision
The e_flags of existing object files are all 0x3 which happens to be
compatible. From this commit on, all LoongArch objects produced with
upstream LLVM will be of object file ABI v1, which is already supported
by binutils' master branch (to be released as 2.40), and is allowed by
the same binutils version to interlink with v0 objects so the existing
distributions have time to migrate.

Differential Revision: https://reviews.llvm.org/D134601
2022-10-13 19:12:26 +08:00

91 lines
3.2 KiB
C++

//===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file provides LoongArch specific target streamer methods.
//
//===----------------------------------------------------------------------===//
#include "LoongArchELFStreamer.h"
#include "LoongArchAsmBackend.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCObjectWriter.h"
using namespace llvm;
// This part is for ELF object output.
LoongArchTargetELFStreamer::LoongArchTargetELFStreamer(
MCStreamer &S, const MCSubtargetInfo &STI)
: LoongArchTargetStreamer(S) {
// FIXME: select appropriate ABI.
setTargetABI(STI.getTargetTriple().isArch64Bit() ? LoongArchABI::ABI_LP64D
: LoongArchABI::ABI_ILP32D);
}
MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() {
return static_cast<MCELFStreamer &>(Streamer);
}
void LoongArchTargetELFStreamer::finish() {
LoongArchTargetStreamer::finish();
MCAssembler &MCA = getStreamer().getAssembler();
LoongArchABI::ABI ABI = getTargetABI();
// Figure out the e_flags.
//
// Bitness is already represented with the EI_CLASS byte in the current spec,
// so here we only record the base ABI modifier. Also set the object file ABI
// version to v1, as upstream LLVM cannot handle the previous stack-machine-
// based relocs from day one.
//
// Refer to LoongArch ELF psABI v2.01 for details.
unsigned EFlags = MCA.getELFHeaderEFlags();
EFlags |= ELF::EF_LOONGARCH_OBJABI_V1;
switch (ABI) {
case LoongArchABI::ABI_ILP32S:
case LoongArchABI::ABI_LP64S:
EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT;
break;
case LoongArchABI::ABI_ILP32F:
case LoongArchABI::ABI_LP64F:
EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT;
break;
case LoongArchABI::ABI_ILP32D:
case LoongArchABI::ABI_LP64D:
EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT;
break;
case LoongArchABI::ABI_Unknown:
llvm_unreachable("Improperly initialized target ABI");
}
MCA.setELFHeaderEFlags(EFlags);
}
namespace {
class LoongArchELFStreamer : public MCELFStreamer {
public:
LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> MOW,
std::unique_ptr<MCCodeEmitter> MCE)
: MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
};
} // end namespace
namespace llvm {
MCELFStreamer *createLoongArchELFStreamer(MCContext &C,
std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> MOW,
std::unique_ptr<MCCodeEmitter> MCE,
bool RelaxAll) {
LoongArchELFStreamer *S = new LoongArchELFStreamer(
C, std::move(MAB), std::move(MOW), std::move(MCE));
S->getAssembler().setRelaxAll(RelaxAll);
return S;
}
} // end namespace llvm