181ad6265SDimitry Andric //===-- CSKYTargetStreamer.h - CSKY Target Streamer ----------*- C++ -*----===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric 981ad6265SDimitry Andric #include "CSKYTargetStreamer.h" 1081ad6265SDimitry Andric #include "CSKYSubtarget.h" 1181ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 1281ad6265SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 1381ad6265SDimitry Andric #include "llvm/MC/MCContext.h" 1481ad6265SDimitry Andric #include "llvm/MC/MCSectionELF.h" 1581ad6265SDimitry Andric #include "llvm/Support/FormattedStream.h" 1681ad6265SDimitry Andric 1781ad6265SDimitry Andric using namespace llvm; 1881ad6265SDimitry Andric 1981ad6265SDimitry Andric // 2081ad6265SDimitry Andric // ConstantPool implementation 2181ad6265SDimitry Andric // 2281ad6265SDimitry Andric // Emit the contents of the constant pool using the provided streamer. 2381ad6265SDimitry Andric void CSKYConstantPool::emitAll(MCStreamer &Streamer) { 2481ad6265SDimitry Andric if (Entries.empty()) 2581ad6265SDimitry Andric return; 2681ad6265SDimitry Andric 2781ad6265SDimitry Andric if (CurrentSection != nullptr) 2881ad6265SDimitry Andric Streamer.switchSection(CurrentSection); 2981ad6265SDimitry Andric 3081ad6265SDimitry Andric Streamer.emitDataRegion(MCDR_DataRegion); 3181ad6265SDimitry Andric for (const ConstantPoolEntry &Entry : Entries) { 3281ad6265SDimitry Andric Streamer.emitCodeAlignment( 33*bdd1243dSDimitry Andric Align(Entry.Size), 3481ad6265SDimitry Andric Streamer.getContext().getSubtargetInfo()); // align naturally 3581ad6265SDimitry Andric Streamer.emitLabel(Entry.Label); 3681ad6265SDimitry Andric Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc); 3781ad6265SDimitry Andric } 3881ad6265SDimitry Andric Streamer.emitDataRegion(MCDR_DataRegionEnd); 3981ad6265SDimitry Andric Entries.clear(); 4081ad6265SDimitry Andric } 4181ad6265SDimitry Andric 4281ad6265SDimitry Andric const MCExpr *CSKYConstantPool::addEntry(MCStreamer &Streamer, 4381ad6265SDimitry Andric const MCExpr *Value, unsigned Size, 4481ad6265SDimitry Andric SMLoc Loc, const MCExpr *AdjustExpr) { 4581ad6265SDimitry Andric if (CurrentSection == nullptr) 4681ad6265SDimitry Andric CurrentSection = Streamer.getCurrentSectionOnly(); 4781ad6265SDimitry Andric 4881ad6265SDimitry Andric auto &Context = Streamer.getContext(); 4981ad6265SDimitry Andric 5081ad6265SDimitry Andric const MCConstantExpr *C = dyn_cast<MCConstantExpr>(Value); 5181ad6265SDimitry Andric 5281ad6265SDimitry Andric // Check if there is existing entry for the same constant. If so, reuse it. 5381ad6265SDimitry Andric auto Itr = C ? CachedEntries.find(C->getValue()) : CachedEntries.end(); 5481ad6265SDimitry Andric if (Itr != CachedEntries.end()) 5581ad6265SDimitry Andric return Itr->second; 5681ad6265SDimitry Andric 5781ad6265SDimitry Andric MCSymbol *CPEntryLabel = Context.createTempSymbol(); 5881ad6265SDimitry Andric const auto SymRef = MCSymbolRefExpr::create(CPEntryLabel, Context); 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric if (AdjustExpr) { 6181ad6265SDimitry Andric const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value); 6281ad6265SDimitry Andric 6381ad6265SDimitry Andric Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context); 6481ad6265SDimitry Andric Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context); 6581ad6265SDimitry Andric Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), Context); 6681ad6265SDimitry Andric } 6781ad6265SDimitry Andric 6881ad6265SDimitry Andric Entries.push_back(ConstantPoolEntry(CPEntryLabel, Value, Size, Loc)); 6981ad6265SDimitry Andric 7081ad6265SDimitry Andric if (C) 7181ad6265SDimitry Andric CachedEntries[C->getValue()] = SymRef; 7281ad6265SDimitry Andric return SymRef; 7381ad6265SDimitry Andric } 7481ad6265SDimitry Andric 7581ad6265SDimitry Andric bool CSKYConstantPool::empty() { return Entries.empty(); } 7681ad6265SDimitry Andric 7781ad6265SDimitry Andric void CSKYConstantPool::clearCache() { 7881ad6265SDimitry Andric CurrentSection = nullptr; 7981ad6265SDimitry Andric CachedEntries.clear(); 8081ad6265SDimitry Andric } 8181ad6265SDimitry Andric 8281ad6265SDimitry Andric CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S) 8381ad6265SDimitry Andric : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {} 8481ad6265SDimitry Andric 8581ad6265SDimitry Andric const MCExpr * 8681ad6265SDimitry Andric CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc, 8781ad6265SDimitry Andric const MCExpr *AdjustExpr) { 8881ad6265SDimitry Andric auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid; 8981ad6265SDimitry Andric ConstantCounter++; 9081ad6265SDimitry Andric 9181ad6265SDimitry Andric const MCExpr *OrigExpr = Expr; 9281ad6265SDimitry Andric 9381ad6265SDimitry Andric if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) { 9481ad6265SDimitry Andric Expr = CE->getSubExpr(); 9581ad6265SDimitry Andric ELFRefKind = CE->getKind(); 9681ad6265SDimitry Andric } 9781ad6265SDimitry Andric 9881ad6265SDimitry Andric if (const MCSymbolRefExpr *SymExpr = dyn_cast<MCSymbolRefExpr>(Expr)) { 9981ad6265SDimitry Andric const MCSymbol *Sym = &SymExpr->getSymbol(); 10081ad6265SDimitry Andric 10181ad6265SDimitry Andric SymbolIndex Index = {Sym, ELFRefKind}; 10281ad6265SDimitry Andric 10381ad6265SDimitry Andric if (ConstantMap.find(Index) == ConstantMap.end()) { 10481ad6265SDimitry Andric ConstantMap[Index] = 10581ad6265SDimitry Andric ConstantPool->addEntry(getStreamer(), OrigExpr, 4, Loc, AdjustExpr); 10681ad6265SDimitry Andric } 10781ad6265SDimitry Andric return ConstantMap[Index]; 10881ad6265SDimitry Andric } 10981ad6265SDimitry Andric 11081ad6265SDimitry Andric return ConstantPool->addEntry(getStreamer(), Expr, 4, Loc, AdjustExpr); 11181ad6265SDimitry Andric } 11281ad6265SDimitry Andric 11381ad6265SDimitry Andric void CSKYTargetStreamer::emitCurrentConstantPool() { 11481ad6265SDimitry Andric ConstantPool->emitAll(Streamer); 11581ad6265SDimitry Andric ConstantPool->clearCache(); 11681ad6265SDimitry Andric } 11781ad6265SDimitry Andric 11881ad6265SDimitry Andric // finish() - write out any non-empty assembler constant pools. 11981ad6265SDimitry Andric void CSKYTargetStreamer::finish() { 12081ad6265SDimitry Andric if (ConstantCounter != 0) { 12181ad6265SDimitry Andric ConstantPool->emitAll(Streamer); 12281ad6265SDimitry Andric } 12381ad6265SDimitry Andric 12481ad6265SDimitry Andric finishAttributeSection(); 12581ad6265SDimitry Andric } 12681ad6265SDimitry Andric 12781ad6265SDimitry Andric void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {} 12881ad6265SDimitry Andric 12981ad6265SDimitry Andric void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} 13081ad6265SDimitry Andric void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute, 13181ad6265SDimitry Andric StringRef String) {} 13281ad6265SDimitry Andric void CSKYTargetStreamer::finishAttributeSection() {} 13381ad6265SDimitry Andric 13481ad6265SDimitry Andric void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 13581ad6265SDimitry Andric OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n"; 13681ad6265SDimitry Andric } 13781ad6265SDimitry Andric 13881ad6265SDimitry Andric void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 13981ad6265SDimitry Andric StringRef String) { 14081ad6265SDimitry Andric OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n"; 14181ad6265SDimitry Andric } 14281ad6265SDimitry Andric 14381ad6265SDimitry Andric void CSKYTargetAsmStreamer::finishAttributeSection() {} 144