ARMTargetStreamer.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1//===- ARMTargetStreamer.cpp - ARMTargetStreamer class --*- C++ -*---------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the ARMTargetStreamer class. 11// 12//===----------------------------------------------------------------------===// 13#include "llvm/ADT/MapVector.h" 14#include "llvm/MC/MCContext.h" 15#include "llvm/MC/MCExpr.h" 16#include "llvm/MC/MCStreamer.h" 17 18using namespace llvm; 19 20namespace { 21// A class to keep track of assembler-generated constant pools that are use to 22// implement the ldr-pseudo. 23class ConstantPool { 24 typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy; 25 EntryVecTy Entries; 26 27public: 28 // Initialize a new empty constant pool 29 ConstantPool() {} 30 31 // Add a new entry to the constant pool in the next slot. 32 // \param Value is the new entry to put in the constant pool. 33 // 34 // \returns a MCExpr that references the newly inserted value 35 const MCExpr *addEntry(const MCExpr *Value, MCContext &Context); 36 37 // Emit the contents of the constant pool using the provided streamer. 38 void emitEntries(MCStreamer &Streamer); 39 40 // Return true if the constant pool is empty 41 bool empty(); 42}; 43} 44 45namespace llvm { 46class AssemblerConstantPools { 47 // Map type used to keep track of per-Section constant pools used by the 48 // ldr-pseudo opcode. The map associates a section to its constant pool. The 49 // constant pool is a vector of (label, value) pairs. When the ldr 50 // pseudo is parsed we insert a new (label, value) pair into the constant pool 51 // for the current section and add MCSymbolRefExpr to the new label as 52 // an opcode to the ldr. After we have parsed all the user input we 53 // output the (label, value) pairs in each constant pool at the end of the 54 // section. 55 // 56 // We use the MapVector for the map type to ensure stable iteration of 57 // the sections at the end of the parse. We need to iterate over the 58 // sections in a stable order to ensure that we have print the 59 // constant pools in a deterministic order when printing an assembly 60 // file. 61 typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy; 62 ConstantPoolMapTy ConstantPools; 63 64public: 65 AssemblerConstantPools() {} 66 ~AssemblerConstantPools() {} 67 68 void emitAll(MCStreamer &Streamer); 69 void emitForCurrentSection(MCStreamer &Streamer); 70 const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr); 71 72private: 73 ConstantPool *getConstantPool(const MCSection *Section); 74 ConstantPool &getOrCreateConstantPool(const MCSection *Section); 75}; 76} 77 78// 79// ConstantPool implementation 80// 81// Emit the contents of the constant pool using the provided streamer. 82void ConstantPool::emitEntries(MCStreamer &Streamer) { 83 if (Entries.empty()) 84 return; 85 Streamer.EmitCodeAlignment(4); // align to 4-byte address 86 Streamer.EmitDataRegion(MCDR_DataRegion); 87 for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end(); 88 I != E; ++I) { 89 Streamer.EmitLabel(I->first); 90 Streamer.EmitValue(I->second, 4); 91 } 92 Streamer.EmitDataRegion(MCDR_DataRegionEnd); 93 Entries.clear(); 94} 95 96const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context) { 97 MCSymbol *CPEntryLabel = Context.CreateTempSymbol(); 98 99 Entries.push_back(std::make_pair(CPEntryLabel, Value)); 100 return MCSymbolRefExpr::Create(CPEntryLabel, Context); 101} 102 103bool ConstantPool::empty() { return Entries.empty(); } 104 105// 106// AssemblerConstantPools implementation 107// 108ConstantPool * 109AssemblerConstantPools::getConstantPool(const MCSection *Section) { 110 ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); 111 if (CP == ConstantPools.end()) 112 return nullptr; 113 114 return &CP->second; 115} 116 117ConstantPool & 118AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) { 119 return ConstantPools[Section]; 120} 121 122static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section, 123 ConstantPool &CP) { 124 if (!CP.empty()) { 125 Streamer.SwitchSection(Section); 126 CP.emitEntries(Streamer); 127 } 128} 129 130void AssemblerConstantPools::emitAll(MCStreamer &Streamer) { 131 // Dump contents of assembler constant pools. 132 for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(), 133 CPE = ConstantPools.end(); 134 CPI != CPE; ++CPI) { 135 const MCSection *Section = CPI->first; 136 ConstantPool &CP = CPI->second; 137 138 emitConstantPool(Streamer, Section, CP); 139 } 140} 141 142void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { 143 const MCSection *Section = Streamer.getCurrentSection().first; 144 if (ConstantPool *CP = getConstantPool(Section)) { 145 emitConstantPool(Streamer, Section, *CP); 146 } 147} 148 149const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, 150 const MCExpr *Expr) { 151 const MCSection *Section = Streamer.getCurrentSection().first; 152 return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext()); 153} 154 155// 156// ARMTargetStreamer Implemenation 157// 158ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S) 159 : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {} 160 161ARMTargetStreamer::~ARMTargetStreamer() {} 162 163// The constant pool handling is shared by all ARMTargetStreamer 164// implementations. 165const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { 166 return ConstantPools->addEntry(Streamer, Expr); 167} 168 169void ARMTargetStreamer::emitCurrentConstantPool() { 170 ConstantPools->emitForCurrentSection(Streamer); 171} 172 173// finish() - write out any non-empty assembler constant pools. 174void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); } 175 176// The remaining callbacks should be handled separately by each 177// streamer. 178void ARMTargetStreamer::emitFnStart() { 179 llvm_unreachable("unimplemented"); 180} 181void ARMTargetStreamer::emitFnEnd() { 182 llvm_unreachable("unimplemented"); 183} 184void ARMTargetStreamer::emitCantUnwind() { 185 llvm_unreachable("unimplemented"); 186} 187void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) { 188 llvm_unreachable("unimplemented"); 189} 190void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) { 191 llvm_unreachable("unimplemented"); 192} 193void ARMTargetStreamer::emitHandlerData() { 194 llvm_unreachable("unimplemented"); 195} 196void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 197 int64_t Offset) { 198 llvm_unreachable("unimplemented"); 199} 200void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 201 llvm_unreachable("unimplemented"); 202} 203void ARMTargetStreamer::emitPad(int64_t Offset) { 204 llvm_unreachable("unimplemented"); 205} 206void 207ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 208 bool isVector) { 209 llvm_unreachable("unimplemented"); 210} 211void ARMTargetStreamer::emitUnwindRaw( 212 int64_t StackOffset, const SmallVectorImpl<uint8_t> &Opcodes) { 213 llvm_unreachable("unimplemented"); 214} 215void ARMTargetStreamer::switchVendor(StringRef Vendor) { 216 llvm_unreachable("unimplemented"); 217} 218void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 219 llvm_unreachable("unimplemented"); 220} 221void ARMTargetStreamer::emitTextAttribute(unsigned Attribute, 222 StringRef String) { 223 llvm_unreachable("unimplemented"); 224} 225void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute, 226 unsigned IntValue, 227 StringRef StringValue) { 228 llvm_unreachable("unimplemented"); 229} 230void ARMTargetStreamer::emitArch(unsigned Arch) { 231 llvm_unreachable("unimplemented"); 232} 233void ARMTargetStreamer::emitObjectArch(unsigned Arch) { 234 llvm_unreachable("unimplemented"); 235} 236void ARMTargetStreamer::emitFPU(unsigned FPU) { 237 llvm_unreachable("unimplemented"); 238} 239void ARMTargetStreamer::finishAttributeSection() { 240 llvm_unreachable("unimplemented"); 241} 242void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) { 243 llvm_unreachable("unimplemented"); 244} 245void ARMTargetStreamer::AnnotateTLSDescriptorSequence( 246 const MCSymbolRefExpr *SRE) { 247 llvm_unreachable("unimplemented"); 248} 249 250void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 251 llvm_unreachable("unimplemented"); 252} 253