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 "CSKYSubtarget.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 17 using namespace llvm; 18 19 // 20 // ConstantPool implementation 21 // 22 // Emit the contents of the constant pool using the provided streamer. 23 void 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 naturally 35 Streamer.emitLabel(Entry.Label); 36 Streamer.emitValue(Entry.Value, Entry.Size, Entry.Loc); 37 } 38 Streamer.emitDataRegion(MCDR_DataRegionEnd); 39 Entries.clear(); 40 } 41 42 const 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 const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Value); 62 63 Value = MCBinaryExpr::createSub(AdjustExpr, SymRef, Context); 64 Value = MCBinaryExpr::createSub(CSKYExpr->getSubExpr(), Value, Context); 65 Value = CSKYMCExpr::create(Value, CSKYExpr->getKind(), 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 75 bool CSKYConstantPool::empty() { return Entries.empty(); } 76 77 void CSKYConstantPool::clearCache() { 78 CurrentSection = nullptr; 79 CachedEntries.clear(); 80 } 81 82 CSKYTargetStreamer::CSKYTargetStreamer(MCStreamer &S) 83 : MCTargetStreamer(S), ConstantPool(new CSKYConstantPool()) {} 84 85 const MCExpr * 86 CSKYTargetStreamer::addConstantPoolEntry(const MCExpr *Expr, SMLoc Loc, 87 const MCExpr *AdjustExpr) { 88 auto ELFRefKind = CSKYMCExpr::VK_CSKY_Invalid; 89 ConstantCounter++; 90 91 const MCExpr *OrigExpr = Expr; 92 93 if (const CSKYMCExpr *CE = dyn_cast<CSKYMCExpr>(Expr)) { 94 Expr = CE->getSubExpr(); 95 ELFRefKind = CE->getKind(); 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 113 void CSKYTargetStreamer::emitCurrentConstantPool() { 114 ConstantPool->emitAll(Streamer); 115 ConstantPool->clearCache(); 116 } 117 118 // finish() - write out any non-empty assembler constant pools. 119 void CSKYTargetStreamer::finish() { 120 if (ConstantCounter != 0) { 121 ConstantPool->emitAll(Streamer); 122 } 123 124 finishAttributeSection(); 125 } 126 127 void CSKYTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {} 128 129 void CSKYTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {} 130 void CSKYTargetStreamer::emitTextAttribute(unsigned Attribute, 131 StringRef String) {} 132 void CSKYTargetStreamer::finishAttributeSection() {} 133 134 void CSKYTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 135 OS << "\t.csky_attribute\t" << Attribute << ", " << Twine(Value) << "\n"; 136 } 137 138 void CSKYTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 139 StringRef String) { 140 OS << "\t.csky_attribute\t" << Attribute << ", \"" << String << "\"\n"; 141 } 142 143 void CSKYTargetAsmStreamer::finishAttributeSection() {} 144