Index: lib/Target/RISCV/MCTargetDesc/CMakeLists.txt =================================================================== --- lib/Target/RISCV/MCTargetDesc/CMakeLists.txt +++ lib/Target/RISCV/MCTargetDesc/CMakeLists.txt @@ -5,4 +5,6 @@ RISCVMCCodeEmitter.cpp RISCVMCExpr.cpp RISCVMCTargetDesc.cpp + RISCVTargetStreamer.cpp + RISCVELFStreamer.cpp ) Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.h @@ -0,0 +1,24 @@ +//===-- RISCVELFStreamer.h - RISCV ELF Target Streamer ---------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_RISCVELFSTREAMER_H +#define LLVM_LIB_TARGET_RISCV_RISCVELFSTREAMER_H + +#include "RISCVTargetStreamer.h" +#include "llvm/MC/MCELFStreamer.h" + +namespace llvm { + +class RISCVTargetELFStreamer : public RISCVTargetStreamer { +public: + MCELFStreamer &getStreamer(); + RISCVTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI); +}; +} +#endif Index: lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVELFStreamer.cpp @@ -0,0 +1,39 @@ +//===-- RISCVELFStreamer.cpp - RISCV ELF Target Streamer Methods ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides RISCV specific target streamer methods. +// +//===----------------------------------------------------------------------===// + +#include "RISCVMCTargetDesc.h" +#include "RISCVELFStreamer.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCSubtargetInfo.h" + +using namespace llvm; + +// This part is for ELF object output. +RISCVTargetELFStreamer::RISCVTargetELFStreamer(MCStreamer &S, + const MCSubtargetInfo &STI) + : RISCVTargetStreamer(S) { + MCAssembler &MCA = getStreamer().getAssembler(); + + const FeatureBitset &Features = STI.getFeatureBits(); + + unsigned EFlags = MCA.getELFHeaderEFlags(); + + if (Features[RISCV::FeatureStdExtC]) + EFlags |= ELF::EF_RISCV_RVC; + + MCA.setELFHeaderEFlags(EFlags); +} + +MCELFStreamer &RISCVTargetELFStreamer::getStreamer() { + return static_cast(Streamer); +} Index: lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp @@ -14,6 +14,8 @@ #include "RISCVMCTargetDesc.h" #include "InstPrinter/RISCVInstPrinter.h" #include "RISCVMCAsmInfo.h" +#include "RISCVELFStreamer.h" +#include "RISCVTargetStreamer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInstrInfo.h" @@ -67,6 +69,14 @@ return new RISCVInstPrinter(MAI, MII, MRI); } +static MCTargetStreamer * +createRISCVObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { + const Triple &TT = STI.getTargetTriple(); + if (TT.isOSBinFormatELF()) + return new RISCVTargetELFStreamer(S, STI); + return new RISCVTargetStreamer(S); +} + extern "C" void LLVMInitializeRISCVTargetMC() { for (Target *T : {&getTheRISCV32Target(), &getTheRISCV64Target()}) { TargetRegistry::RegisterMCAsmInfo(*T, createRISCVMCAsmInfo); @@ -76,5 +86,7 @@ TargetRegistry::RegisterMCCodeEmitter(*T, createRISCVMCCodeEmitter); TargetRegistry::RegisterMCInstPrinter(*T, createRISCVMCInstPrinter); TargetRegistry::RegisterMCSubtargetInfo(*T, createRISCVMCSubtargetInfo); + TargetRegistry::RegisterObjectTargetStreamer( + *T, createRISCVObjectTargetStreamer); } } Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.h @@ -0,0 +1,22 @@ +//===-- RISCVTargetStreamer.h - RISCV Target Streamer ----------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_RISCV_RISCVTARGETSTREAMER_H +#define LLVM_LIB_TARGET_RISCV_RISCVTARGETSTREAMER_H + +#include "llvm/MC/MCStreamer.h" + +namespace llvm { + +class RISCVTargetStreamer : public MCTargetStreamer { +public: + RISCVTargetStreamer(MCStreamer &S); +}; +} +#endif Index: lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp =================================================================== --- /dev/null +++ lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp @@ -0,0 +1,19 @@ +//===-- RISCVTargetStreamer.cpp - RISCV Target Streamer Methods -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides RISCV specific target streamer methods. +// +//===----------------------------------------------------------------------===// + +#include "RISCVTargetStreamer.h" + +using namespace llvm; + +RISCVTargetStreamer::RISCVTargetStreamer(MCStreamer &S) + : MCTargetStreamer(S) {} Index: test/MC/RISCV/elf-flags.s =================================================================== --- /dev/null +++ test/MC/RISCV/elf-flags.s @@ -0,0 +1,13 @@ +# RUN: llvm-mc -triple=riscv32 -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVI %s +# RUN: llvm-mc -triple=riscv64 -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVI %s +# RUN: llvm-mc -triple=riscv32 -mattr=+c -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVIC %s +# RUN: llvm-mc -triple=riscv64 -mattr=+c -filetype=obj < %s | llvm-readobj -file-headers - | FileCheck -check-prefixes=CHECK-RVIC %s + +# CHECK-RVI: Flags [ (0x0) +# CHECK-RVI-NEXT: ] + +# CHECK-RVIC: Flags [ (0x1) +# CHECK-RVIC-NEXT: EF_RISCV_RVC (0x1) +# CHECK-RVIC-NEXT: ] + +nop