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 31using namespace llvm; 32 33static 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 38void 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 80void 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. 90void 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 135void 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 145namespace llvm { 146MCStreamer *createHexagonELFStreamer(MCContext &Context, MCAsmBackend &MAB, 147 raw_pwrite_stream &OS, MCCodeEmitter *CE) { 148 return new HexagonMCELFStreamer(Context, MAB, OS, CE); 149} 150} 151