144 lines · cpp
1//===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===//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#include "CSKYTargetStreamer.h"10#include "MCTargetDesc/CSKYMCAsmInfo.h"11#include "llvm/CodeGen/MachineFrameInfo.h"12#include "llvm/CodeGen/TargetSubtargetInfo.h"13#include "llvm/MC/MCContext.h"14#include "llvm/MC/MCSectionELF.h"15#include "llvm/Support/FormattedStream.h"16 17using namespace llvm;18 19//20// ConstantPool implementation21//22// Emit the contents of the constant pool using the provided streamer.23void CSKYConstantPool::emitAll(MCStreamer &Streamer) {24 if (Entries.empty())25 return;26 27 if (CurrentSection != nullptr)28 Streamer.switchSection(CurrentSection);29 30 Streamer.emitDataRegion(MCDR_DataRegion);31 for (const ConstantPoolEntry &Entry : Entries) {32 Streamer.emitCodeAlignment(33 Align(Entry.Size),34 Streamer.getContext().getSubtargetInfo()); // align naturally35 Streamer.emitLabel(Entry.Label);36 Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc);37 }38 Streamer.emitDataRegion(MCDR_DataRegionEnd);39 Entries.clear();40}41 42const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer,43 const MCExpr *Value, unsigned Size,44 SMLoc Loc, const MCExpr *AdjustExpr) {45 if (CurrentSection == nullptr)46 CurrentSection = Streamer.getCurrentSectionOnly();47 48 auto &Context = Streamer.getContext();49 50 const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value);51 52 // Check if there is existing entry for the same constant. If so, reuse it.53 auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end();54 if (Itr != CachedEntries.end())55 return Itr->second;56 57 MCSymbol *CPEntryLabel = Context.createTempSymbol();58 const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context);59 60 if (AdjustExpr) {61 auto *CSKYExpr = cast<MCSpecifierExpr>(Value);62 63 Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context);64 Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context);65 Value = MCSpecifierExpr::create(Value, CSKYExpr->getSpecifier(), Context);66 }67 68 Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc));69 70 if (C)71 CachedEntries[C->getValue()] = SymRef;72 return SymRef;73}74 75bool CSKYConstantPool::empty() { return Entries.empty(); }76 77void CSKYConstantPool::clearCache() {78 CurrentSection = nullptr;79 CachedEntries.clear();80}81 82CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S)83 : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {}84 85const MCExpr *86CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc,87 const MCExpr *AdjustExpr) {88 uint8_t ELFRefKind = CSKY::S_Invalid;89 ConstantCounter++;90 91 const MCExpr *OrigExpr = Expr;92 93 if (auto *CE = dyn_cast<MCSpecifierExpr>(Expr)) {94 Expr = CE->getSubExpr();95 ELFRefKind = CE->getSpecifier();96 }97 98 if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {99 const MCSymbol *Sym = &SymExpr->getSymbol();100 101 SymbolIndex Index = {Sym, ELFRefKind};102 103 if (ConstantMap.find(Index) == ConstantMap.end()) {104 ConstantMap[Index] =105 ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr);106 }107 return ConstantMap[Index];108 }109 110 return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr);111}112 113void CSKYTargetStreamer::emitCurrentConstantPool() {114 ConstantPool->emitAll(Streamer);115 ConstantPool->clearCache();116}117 118// finish() - write out any non-empty assembler constant pools.119void CSKYTargetStreamer::finish() {120 if (ConstantCounter != 0) {121 ConstantPool->emitAll(Streamer);122 }123 124 finishAttributeSection();125}126 127void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {}128 129void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {}130void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute,131 StringRef String) {}132void CSKYTargetStreamer::finishAttributeSection() {}133 134void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {135 OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n";136}137 138void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute,139 StringRef String) {140 OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n";141}142 143void CSKYTargetAsmStreamer::finishAttributeSection() {}144