xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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