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