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