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