1 //=== HexagonMCELFStreamer.cpp - Hexagon subclass of MCELFStreamer -------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a stub that parses a MCInst bundle and passes the 11 // instructions on to the real streamer. 12 // 13 //===----------------------------------------------------------------------===// 14 #define DEBUG_TYPE "hexagonmcelfstreamer" 15 16 #include "Hexagon.h" 17 #include "HexagonMCELFStreamer.h" 18 #include "MCTargetDesc/HexagonBaseInfo.h" 19 #include "MCTargetDesc/HexagonMCShuffler.h" 20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/MC/MCAssembler.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/MC/MCSectionELF.h" 24 #include "llvm/MC/MCStreamer.h" 25 #include "llvm/MC/MCSymbol.h" 26 #include "llvm/MC/MCSymbolELF.h" 27 #include "llvm/Support/CommandLine.h" 28 #include "llvm/Support/Debug.h" 29 #include "llvm/Support/raw_ostream.h" 30 31 using namespace llvm; 32 33 static cl::opt<unsigned> 34 GPSize("gpsize", cl::NotHidden, 35 cl::desc("Global Pointer Addressing Size. The default size is 8."), 36 cl::Prefix, cl::init(8)); 37 38 void HexagonMCELFStreamer::EmitInstruction(const MCInst &MCK, 39 const MCSubtargetInfo &STI) { 40 MCInst HMI = HexagonMCInstrInfo::createBundle(); 41 MCInst *MCB; 42 43 if (MCK.getOpcode() != Hexagon::BUNDLE) { 44 HMI.addOperand(MCOperand::createInst(&MCK)); 45 MCB = &HMI; 46 } else 47 MCB = const_cast<MCInst *>(&MCK); 48 49 // Examines packet and pad the packet, if needed, when an 50 // end-loop is in the bundle. 51 HexagonMCInstrInfo::padEndloop(getContext(), *MCB); 52 HexagonMCShuffle(*MCII, STI, *MCB); 53 54 assert(HexagonMCInstrInfo::bundleSize(*MCB) <= HEXAGON_PACKET_SIZE); 55 bool Extended = false; 56 for (auto &I : HexagonMCInstrInfo::bundleInstructions(*MCB)) { 57 MCInst *MCI = const_cast<MCInst *>(I.getInst()); 58 if (Extended) { 59 if (HexagonMCInstrInfo::isDuplex(*MCII, *MCI)) { 60 MCInst *SubInst = const_cast<MCInst *>(MCI->getOperand(1).getInst()); 61 HexagonMCInstrInfo::clampExtended(*MCII, getContext(), *SubInst); 62 } else { 63 HexagonMCInstrInfo::clampExtended(*MCII, getContext(), *MCI); 64 } 65 Extended = false; 66 } else { 67 Extended = HexagonMCInstrInfo::isImmext(*MCI); 68 } 69 } 70 71 // At this point, MCB is a bundle 72 // Iterate through the bundle and assign addends for the instructions 73 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MCB)) { 74 MCInst *MCI = const_cast<MCInst *>(I.getInst()); 75 EmitSymbol(*MCI); 76 } 77 MCObjectStreamer::EmitInstruction(*MCB, STI); 78 } 79 80 void HexagonMCELFStreamer::EmitSymbol(const MCInst &Inst) { 81 // Scan for values. 82 for (unsigned i = Inst.getNumOperands(); i--;) 83 if (Inst.getOperand(i).isExpr()) 84 visitUsedExpr(*Inst.getOperand(i).getExpr()); 85 } 86 87 // EmitCommonSymbol and EmitLocalCommonSymbol are extended versions of the 88 // functions found in MCELFStreamer.cpp taking AccessSize as an additional 89 // parameter. 90 void HexagonMCELFStreamer::HexagonMCEmitCommonSymbol(MCSymbol *Symbol, 91 uint64_t Size, 92 unsigned ByteAlignment, 93 unsigned AccessSize) { 94 getAssembler().registerSymbol(*Symbol); 95 StringRef sbss[4] = {".sbss.1", ".sbss.2", ".sbss.4", ".sbss.8"}; 96 97 auto ELFSymbol = cast<MCSymbolELF>(Symbol); 98 if (!ELFSymbol->isBindingSet()) { 99 ELFSymbol->setBinding(ELF::STB_GLOBAL); 100 ELFSymbol->setExternal(true); 101 } 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 EmitValueToAlignment(ByteAlignment, 0, 1, 0); 116 EmitLabel(Symbol); 117 EmitZeros(Size); 118 119 // Update the maximum alignment of the section if necessary. 120 if (ByteAlignment > Section.getAlignment()) 121 Section.setAlignment(ByteAlignment); 122 123 SwitchSection(P.first, P.second); 124 } else { 125 if (ELFSymbol->declareCommon(Size, ByteAlignment)) 126 report_fatal_error("Symbol: " + Symbol->getName() + 127 " redeclared as different type"); 128 if ((AccessSize) && (Size <= GPSize)) { 129 uint64_t SectionIndex = 130 (AccessSize <= GPSize) 131 ? ELF::SHN_HEXAGON_SCOMMON + (Log2_64(AccessSize) + 1) 132 : (unsigned)ELF::SHN_HEXAGON_SCOMMON; 133 ELFSymbol->setIndex(SectionIndex); 134 } 135 } 136 137 ELFSymbol->setSize(MCConstantExpr::create(Size, getContext())); 138 } 139 140 void HexagonMCELFStreamer::HexagonMCEmitLocalCommonSymbol( 141 MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, 142 unsigned AccessSize) { 143 getAssembler().registerSymbol(*Symbol); 144 auto ELFSymbol = cast<MCSymbolELF>(Symbol); 145 ELFSymbol->setBinding(ELF::STB_LOCAL); 146 ELFSymbol->setExternal(false); 147 HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, AccessSize); 148 } 149 150 namespace llvm { 151 MCStreamer *createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB, 152 raw_pwrite_stream &OS, MCCodeEmitter *CE) { 153 return new HexagonMCELFStreamer(Context, MAB, OS, CE); 154 } 155 } 156