120 lines · cpp
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-exception6//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 23using namespace llvm;24 25static 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 46XtensaTargetStreamer::XtensaTargetStreamer(MCStreamer &S)47 : MCTargetStreamer(S) {}48 49XtensaTargetAsmStreamer::XtensaTargetAsmStreamer(MCStreamer &S,50 formatted_raw_ostream &OS)51 : XtensaTargetStreamer(S), OS(OS) {}52 53void 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 72void XtensaTargetAsmStreamer::emitLiteralPosition() {73 OS << "\t.literal_position\n";74}75 76void XtensaTargetAsmStreamer::startLiteralSection(MCSection *BaseSection) {77 emitLiteralPosition();78}79 80XtensaTargetELFStreamer::XtensaTargetELFStreamer(MCStreamer &S)81 : XtensaTargetStreamer(S) {}82 83void 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 106void 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 117MCELFStreamer &XtensaTargetELFStreamer::getStreamer() {118 return static_cast<MCELFStreamer &>(Streamer);119}120