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