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
getLiteralSectionName(StringRef CSectionName)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
XtensaTargetStreamer(MCStreamer & S)46*0fca6ea1SDimitry Andric XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S)
47*0fca6ea1SDimitry Andric : MCTargetStreamer(S) {}
48*0fca6ea1SDimitry Andric
XtensaTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS)49*0fca6ea1SDimitry Andric XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S,
50*0fca6ea1SDimitry Andric formatted_raw_ostream &OS)
51*0fca6ea1SDimitry Andric : XtensaTargetStreamer(S), OS(OS) {}
52*0fca6ea1SDimitry Andric
emitLiteral(MCSymbol * LblSym,const MCExpr * Value,bool SwitchLiteralSection,SMLoc L)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
emitLiteralPosition()72*0fca6ea1SDimitry Andric void XtensaTargetAsmStreamer::emitLiteralPosition() {
73*0fca6ea1SDimitry Andric OS << "\t.literal_position\n";
74*0fca6ea1SDimitry Andric }
75*0fca6ea1SDimitry Andric
startLiteralSection(MCSection * BaseSection)76*0fca6ea1SDimitry Andric void XtensaTargetAsmStreamer::startLiteralSection(MCSection *BaseSection) {
77*0fca6ea1SDimitry Andric emitLiteralPosition();
78*0fca6ea1SDimitry Andric }
79*0fca6ea1SDimitry Andric
XtensaTargetELFStreamer(MCStreamer & S)80*0fca6ea1SDimitry Andric XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S)
81*0fca6ea1SDimitry Andric : XtensaTargetStreamer(S) {}
82*0fca6ea1SDimitry Andric
emitLiteral(MCSymbol * LblSym,const MCExpr * Value,bool SwitchLiteralSection,SMLoc L)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
startLiteralSection(MCSection * BaseSection)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
getStreamer()117*0fca6ea1SDimitry Andric MCELFStreamer &XtensaTargetELFStreamer::getStreamer() {
118*0fca6ea1SDimitry Andric return static_cast<MCELFStreamer &>(Streamer);
119*0fca6ea1SDimitry Andric }
120