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 111 MCSection *CrntSection = getCurrentSection().first; 112 MCSection *Section = getAssembler().getContext().getELFSection( 113 SectionName, ELF::SHT_NOBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC); 114 SwitchSection(Section); 115 AssignFragment(Symbol, getCurrentFragment()); 116 117 MCELFStreamer::EmitCommonSymbol(Symbol, Size, ByteAlignment); 118 SwitchSection(CrntSection); 119 } else { 120 if (ELFSymbol->declareCommon(Size, ByteAlignment)) 121 report_fatal_error("Symbol: " + Symbol->getName() + 122 " redeclared as different type"); 123 if ((AccessSize) && (Size <= GPSize)) { 124 uint64_t SectionIndex = 125 (AccessSize <= GPSize) 126 ? ELF::SHN_HEXAGON_SCOMMON + (Log2_64(AccessSize) + 1) 127 : (unsigned)ELF::SHN_HEXAGON_SCOMMON; 128 ELFSymbol->setIndex(SectionIndex); 129 } 130 } 131 132 ELFSymbol->setSize(MCConstantExpr::create(Size, getContext())); 133 } 134 135 void HexagonMCELFStreamer::HexagonMCEmitLocalCommonSymbol( 136 MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, 137 unsigned AccessSize) { 138 getAssembler().registerSymbol(*Symbol); 139 auto ELFSymbol = cast<MCSymbolELF>(Symbol); 140 ELFSymbol->setBinding(ELF::STB_LOCAL); 141 ELFSymbol->setExternal(false); 142 HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, AccessSize); 143 } 144 145 namespace llvm { 146 MCStreamer *createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB, 147 raw_pwrite_stream &OS, MCCodeEmitter *CE) { 148 return new HexagonMCELFStreamer(Context, MAB, OS, CE); 149 } 150 } 151