1*0fca6ea1SDimitry Andric //===-- XtensaTargetStreamer.cpp - Xtensa Target Streamer Methods ---------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric // This file provides Xtensa specific target streamer methods. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #include "XtensaTargetStreamer.h" 14*0fca6ea1SDimitry Andric #include "XtensaInstPrinter.h" 15*0fca6ea1SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 16*0fca6ea1SDimitry Andric #include "llvm/MC/MCAssembler.h" 17*0fca6ea1SDimitry Andric #include "llvm/MC/MCContext.h" 18*0fca6ea1SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 19*0fca6ea1SDimitry Andric #include "llvm/MC/MCSectionELF.h" 20*0fca6ea1SDimitry Andric #include "llvm/Support/Casting.h" 21*0fca6ea1SDimitry Andric #include "llvm/Support/FormattedStream.h" 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric using namespace llvm; 24*0fca6ea1SDimitry Andric 25*0fca6ea1SDimitry Andric static std::string getLiteralSectionName(StringRef CSectionName) { 26*0fca6ea1SDimitry Andric std::size_t Pos = CSectionName.find(".text"); 27*0fca6ea1SDimitry Andric std::string SectionName; 28*0fca6ea1SDimitry Andric if (Pos != std::string::npos) { 29*0fca6ea1SDimitry Andric SectionName = CSectionName.substr(0, Pos); 30*0fca6ea1SDimitry Andric 31*0fca6ea1SDimitry Andric if (Pos > 0) 32*0fca6ea1SDimitry Andric SectionName += ".text"; 33*0fca6ea1SDimitry Andric 34*0fca6ea1SDimitry Andric CSectionName = CSectionName.drop_front(Pos); 35*0fca6ea1SDimitry Andric CSectionName.consume_front(".text"); 36*0fca6ea1SDimitry Andric 37*0fca6ea1SDimitry Andric SectionName += ".literal"; 38*0fca6ea1SDimitry Andric SectionName += CSectionName; 39*0fca6ea1SDimitry Andric } else { 40*0fca6ea1SDimitry Andric SectionName = CSectionName; 41*0fca6ea1SDimitry Andric SectionName += ".literal"; 42*0fca6ea1SDimitry Andric } 43*0fca6ea1SDimitry Andric return SectionName; 44*0fca6ea1SDimitry Andric } 45*0fca6ea1SDimitry Andric 46*0fca6ea1SDimitry Andric XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S) 47*0fca6ea1SDimitry Andric : MCTargetStreamer(S) {} 48*0fca6ea1SDimitry Andric 49*0fca6ea1SDimitry Andric XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S, 50*0fca6ea1SDimitry Andric formatted_raw_ostream &OS) 51*0fca6ea1SDimitry Andric : XtensaTargetStreamer(S), OS(OS) {} 52*0fca6ea1SDimitry Andric 53*0fca6ea1SDimitry Andric void XtensaTargetAsmStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value, 54*0fca6ea1SDimitry Andric bool SwitchLiteralSection, SMLoc L) { 55*0fca6ea1SDimitry Andric SmallString<60> Str; 56*0fca6ea1SDimitry Andric raw_svector_ostream LiteralStr(Str); 57*0fca6ea1SDimitry Andric 58*0fca6ea1SDimitry Andric LiteralStr << "\t.literal " << LblSym->getName() << ", "; 59*0fca6ea1SDimitry Andric 60*0fca6ea1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Value)) { 61*0fca6ea1SDimitry Andric LiteralStr << CE->getValue() << "\n"; 62*0fca6ea1SDimitry Andric } else if (auto SRE = dyn_cast<MCSymbolRefExpr>(Value)) { 63*0fca6ea1SDimitry Andric const MCSymbol &Sym = SRE->getSymbol(); 64*0fca6ea1SDimitry Andric LiteralStr << Sym.getName() << "\n"; 65*0fca6ea1SDimitry Andric } else { 66*0fca6ea1SDimitry Andric llvm_unreachable("unexpected constant pool entry type"); 67*0fca6ea1SDimitry Andric } 68*0fca6ea1SDimitry Andric 69*0fca6ea1SDimitry Andric OS << LiteralStr.str(); 70*0fca6ea1SDimitry Andric } 71*0fca6ea1SDimitry Andric 72*0fca6ea1SDimitry Andric void XtensaTargetAsmStreamer::emitLiteralPosition() { 73*0fca6ea1SDimitry Andric OS << "\t.literal_position\n"; 74*0fca6ea1SDimitry Andric } 75*0fca6ea1SDimitry Andric 76*0fca6ea1SDimitry Andric void XtensaTargetAsmStreamer::startLiteralSection(MCSection *BaseSection) { 77*0fca6ea1SDimitry Andric emitLiteralPosition(); 78*0fca6ea1SDimitry Andric } 79*0fca6ea1SDimitry Andric 80*0fca6ea1SDimitry Andric XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S) 81*0fca6ea1SDimitry Andric : XtensaTargetStreamer(S) {} 82*0fca6ea1SDimitry Andric 83*0fca6ea1SDimitry Andric void XtensaTargetELFStreamer::emitLiteral(MCSymbol *LblSym, const MCExpr *Value, 84*0fca6ea1SDimitry Andric bool SwitchLiteralSection, SMLoc L) { 85*0fca6ea1SDimitry Andric MCStreamer &OutStreamer = getStreamer(); 86*0fca6ea1SDimitry Andric if (SwitchLiteralSection) { 87*0fca6ea1SDimitry Andric MCContext &Context = OutStreamer.getContext(); 88*0fca6ea1SDimitry Andric auto *CS = static_cast<MCSectionELF *>(OutStreamer.getCurrentSectionOnly()); 89*0fca6ea1SDimitry Andric std::string SectionName = getLiteralSectionName(CS->getName()); 90*0fca6ea1SDimitry Andric 91*0fca6ea1SDimitry Andric MCSection *ConstSection = Context.getELFSection( 92*0fca6ea1SDimitry Andric SectionName, ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); 93*0fca6ea1SDimitry Andric 94*0fca6ea1SDimitry Andric OutStreamer.pushSection(); 95*0fca6ea1SDimitry Andric OutStreamer.switchSection(ConstSection); 96*0fca6ea1SDimitry Andric } 97*0fca6ea1SDimitry Andric 98*0fca6ea1SDimitry Andric OutStreamer.emitLabel(LblSym, L); 99*0fca6ea1SDimitry Andric OutStreamer.emitValue(Value, 4, L); 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric if (SwitchLiteralSection) { 102*0fca6ea1SDimitry Andric OutStreamer.popSection(); 103*0fca6ea1SDimitry Andric } 104*0fca6ea1SDimitry Andric } 105*0fca6ea1SDimitry Andric 106*0fca6ea1SDimitry Andric void XtensaTargetELFStreamer::startLiteralSection(MCSection *BaseSection) { 107*0fca6ea1SDimitry Andric MCContext &Context = getStreamer().getContext(); 108*0fca6ea1SDimitry Andric 109*0fca6ea1SDimitry Andric std::string SectionName = getLiteralSectionName(BaseSection->getName()); 110*0fca6ea1SDimitry Andric 111*0fca6ea1SDimitry Andric MCSection *ConstSection = Context.getELFSection( 112*0fca6ea1SDimitry Andric SectionName, ELF::SHT_PROGBITS, ELF::SHF_EXECINSTR | ELF::SHF_ALLOC); 113*0fca6ea1SDimitry Andric 114*0fca6ea1SDimitry Andric ConstSection->setAlignment(Align(4)); 115*0fca6ea1SDimitry Andric } 116*0fca6ea1SDimitry Andric 117*0fca6ea1SDimitry Andric MCELFStreamer &XtensaTargetELFStreamer::getStreamer() { 118*0fca6ea1SDimitry Andric return static_cast<MCELFStreamer &>(Streamer); 119*0fca6ea1SDimitry Andric } 120