1 //=== HexagonMCELFStreamer.cpp - Hexagon subclass of MCELFStreamer -------===// 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 is a stub that parses a MCInst bundle and passes the 10 // instructions on to the real streamer. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/HexagonMCELFStreamer.h" 15 #include "HexagonTargetStreamer.h" 16 #include "MCTargetDesc/HexagonMCChecker.h" 17 #include "MCTargetDesc/HexagonMCInstrInfo.h" 18 #include "MCTargetDesc/HexagonMCShuffler.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/BinaryFormat/ELF.h" 21 #include "llvm/MC/MCAsmBackend.h" 22 #include "llvm/MC/MCAssembler.h" 23 #include "llvm/MC/MCCodeEmitter.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCExpr.h" 26 #include "llvm/MC/MCInst.h" 27 #include "llvm/MC/MCObjectStreamer.h" 28 #include "llvm/MC/MCObjectWriter.h" 29 #include "llvm/MC/MCSection.h" 30 #include "llvm/MC/MCSectionELF.h" 31 #include "llvm/MC/MCStreamer.h" 32 #include "llvm/MC/MCSubtargetInfo.h" 33 #include "llvm/MC/MCSymbol.h" 34 #include "llvm/MC/MCSymbolELF.h" 35 #include "llvm/Support/Casting.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/ErrorHandling.h" 38 #include "llvm/Support/HexagonAttributes.h" 39 #include "llvm/Support/MathExtras.h" 40 #include <cassert> 41 #include <cstdint> 42 43 #define DEBUG_TYPE "hexagonmcelfstreamer" 44 45 using namespace llvm; 46 47 static cl::opt<unsigned> GPSize 48 ("gpsize", cl::NotHidden, 49 cl::desc("Global Pointer Addressing Size. The default size is 8."), 50 cl::Prefix, 51 cl::init(8)); 52 53 HexagonMCELFStreamer::HexagonMCELFStreamer( 54 MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 55 std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter) 56 : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)), 57 MCII(createHexagonMCInstrInfo()) {} 58 59 HexagonMCELFStreamer::HexagonMCELFStreamer( 60 MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 61 std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter, 62 MCAssembler *Assembler) 63 : MCELFStreamer(Context, std::move(TAB), std::move(OW), std::move(Emitter)), 64 MCII(createHexagonMCInstrInfo()) {} 65 66 void HexagonMCELFStreamer::emitInstruction(const MCInst &MCB, 67 const MCSubtargetInfo &STI) { 68 assert(MCB.getOpcode() == Hexagon::BUNDLE); 69 assert(HexagonMCInstrInfo::bundleSize(MCB) <= HEXAGON_PACKET_SIZE); 70 assert(HexagonMCInstrInfo::bundleSize(MCB) > 0); 71 72 // At this point, MCB is a bundle 73 // Iterate through the bundle and assign addends for the instructions 74 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) { 75 MCInst *MCI = const_cast<MCInst *>(I.getInst()); 76 EmitSymbol(*MCI); 77 } 78 79 MCObjectStreamer::emitInstruction(MCB, STI); 80 } 81 82 void HexagonMCELFStreamer::EmitSymbol(const MCInst &Inst) { 83 // Scan for values. 84 for (unsigned i = Inst.getNumOperands(); i--;) 85 if (Inst.getOperand(i).isExpr()) 86 visitUsedExpr(*Inst.getOperand(i).getExpr()); 87 } 88 89 // EmitCommonSymbol and EmitLocalCommonSymbol are extended versions of the 90 // functions found in MCELFStreamer.cpp taking AccessSize as an additional 91 // parameter. 92 void HexagonMCELFStreamer::HexagonMCEmitCommonSymbol(MCSymbol *Symbol, 93 uint64_t Size, 94 Align ByteAlignment, 95 unsigned AccessSize) { 96 getAssembler().registerSymbol(*Symbol); 97 StringRef sbss[4] = {".sbss.1", ".sbss.2", ".sbss.4", ".sbss.8"}; 98 99 auto ELFSymbol = cast<MCSymbolELF>(Symbol); 100 if (!ELFSymbol->isBindingSet()) 101 ELFSymbol->setBinding(ELF::STB_GLOBAL); 102 103 ELFSymbol->setType(ELF::STT_OBJECT); 104 105 if (ELFSymbol->getBinding() == ELF::STB_LOCAL) { 106 StringRef SectionName = 107 ((AccessSize == 0) || (Size == 0) || (Size > GPSize)) 108 ? ".bss" 109 : sbss[(Log2_64(AccessSize))]; 110 MCSection &Section = *getAssembler().getContext().getELFSection( 111 SectionName, ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 112 MCSectionSubPair P = getCurrentSection(); 113 switchSection(&Section); 114 115 if (ELFSymbol->isUndefined()) { 116 emitValueToAlignment(ByteAlignment, 0, 1, 0); 117 emitLabel(Symbol); 118 emitZeros(Size); 119 } 120 121 // Update the maximum alignment of the section if necessary. 122 Section.ensureMinAlignment(ByteAlignment); 123 124 switchSection(P.first, P.second); 125 } else { 126 if (ELFSymbol->declareCommon(Size, ByteAlignment)) 127 report_fatal_error("Symbol: " + Symbol->getName() + 128 " redeclared as different type"); 129 if ((AccessSize) && (Size <= GPSize)) { 130 uint64_t SectionIndex = 131 (AccessSize <= GPSize) 132 ? ELF::SHN_HEXAGON_SCOMMON + llvm::bit_width(AccessSize) 133 : (unsigned)ELF::SHN_HEXAGON_SCOMMON; 134 ELFSymbol->setIndex(SectionIndex); 135 } 136 } 137 138 ELFSymbol->setSize(MCConstantExpr::create(Size, getContext())); 139 } 140 141 void HexagonMCELFStreamer::HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, 142 uint64_t Size, 143 Align ByteAlignment, 144 unsigned AccessSize) { 145 getAssembler().registerSymbol(*Symbol); 146 auto ELFSymbol = cast<MCSymbolELF>(Symbol); 147 ELFSymbol->setBinding(ELF::STB_LOCAL); 148 ELFSymbol->setExternal(false); 149 HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, AccessSize); 150 } 151 152 static unsigned featureToArchVersion(unsigned Feature) { 153 switch (Feature) { 154 case Hexagon::ArchV5: 155 return 5; 156 case Hexagon::ArchV55: 157 return 55; 158 case Hexagon::ArchV60: 159 case Hexagon::ExtensionHVXV60: 160 return 60; 161 case Hexagon::ArchV62: 162 case Hexagon::ExtensionHVXV62: 163 return 62; 164 case Hexagon::ArchV65: 165 case Hexagon::ExtensionHVXV65: 166 return 65; 167 case Hexagon::ArchV66: 168 case Hexagon::ExtensionHVXV66: 169 return 66; 170 case Hexagon::ArchV67: 171 case Hexagon::ExtensionHVXV67: 172 return 67; 173 case Hexagon::ArchV68: 174 case Hexagon::ExtensionHVXV68: 175 return 68; 176 case Hexagon::ArchV69: 177 case Hexagon::ExtensionHVXV69: 178 return 69; 179 case Hexagon::ArchV71: 180 case Hexagon::ExtensionHVXV71: 181 return 71; 182 case Hexagon::ArchV73: 183 case Hexagon::ExtensionHVXV73: 184 return 73; 185 } 186 llvm_unreachable("Expected valid arch feature"); 187 return 0; 188 } 189 190 void HexagonTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) { 191 auto Features = STI.getFeatureBits(); 192 unsigned Arch = featureToArchVersion(Hexagon_MC::getArchVersion(Features)); 193 std::optional<unsigned> HVXArch = Hexagon_MC::getHVXVersion(Features); 194 emitAttribute(HexagonAttrs::ARCH, Arch); 195 if (HVXArch) 196 emitAttribute(HexagonAttrs::HVXARCH, featureToArchVersion(*HVXArch)); 197 if (Features.test(Hexagon::ExtensionHVXIEEEFP)) 198 emitAttribute(HexagonAttrs::HVXIEEEFP, 1); 199 if (Features.test(Hexagon::ExtensionHVXQFloat)) 200 emitAttribute(HexagonAttrs::HVXQFLOAT, 1); 201 if (Features.test(Hexagon::ExtensionZReg)) 202 emitAttribute(HexagonAttrs::ZREG, 1); 203 if (Features.test(Hexagon::ExtensionAudio)) 204 emitAttribute(HexagonAttrs::AUDIO, 1); 205 if (Features.test(Hexagon::FeatureCabac)) 206 emitAttribute(HexagonAttrs::CABAC, 1); 207 } 208 209 namespace llvm { 210 MCStreamer *createHexagonELFStreamer(Triple const &TT, MCContext &Context, 211 std::unique_ptr<MCAsmBackend> MAB, 212 std::unique_ptr<MCObjectWriter> OW, 213 std::unique_ptr<MCCodeEmitter> CE) { 214 return new HexagonMCELFStreamer(Context, std::move(MAB), std::move(OW), 215 std::move(CE)); 216 } 217 218 } // end namespace llvm 219