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/MCStreamer.h" 15 #include "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCContext.h" 17 18 using namespace llvm; 19 20 namespace { 21 // A class to keep track of assembler-generated constant pools that are use to 22 // implement the ldr-pseudo. 23 class ConstantPool { 24 typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy; 25 EntryVecTy Entries; 26 27 public: 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 45 namespace llvm { 46 class 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 64 public: 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 72 private: 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. 82 void 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 96 const 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 103 bool ConstantPool::empty() { return Entries.empty(); } 104 105 // 106 // AssemblerConstantPools implementation 107 // 108 ConstantPool * 109 AssemblerConstantPools::getConstantPool(const MCSection *Section) { 110 ConstantPoolMapTy::iterator CP = ConstantPools.find(Section); 111 if (CP == ConstantPools.end()) 112 return 0; 113 114 return &CP->second; 115 } 116 117 ConstantPool & 118 AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) { 119 return ConstantPools[Section]; 120 } 121 122 static 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 130 void 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 142 void 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 149 const 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 // 158 ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S) 159 : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {} 160 161 ARMTargetStreamer::~ARMTargetStreamer() {} 162 163 // The constant pool handling is shared by all ARMTargetStreamer 164 // implementations. 165 const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { 166 return ConstantPools->addEntry(Streamer, Expr); 167 } 168 169 void ARMTargetStreamer::emitCurrentConstantPool() { 170 ConstantPools->emitForCurrentSection(Streamer); 171 } 172 173 // finish() - write out any non-empty assembler constant pools. 174 void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); } 175 176 // The remaining callbacks should be handled separately by each 177 // streamer. 178 void ARMTargetStreamer::emitFnStart() { 179 llvm_unreachable("unimplemented"); 180 } 181 void ARMTargetStreamer::emitFnEnd() { 182 llvm_unreachable("unimplemented"); 183 } 184 void ARMTargetStreamer::emitCantUnwind() { 185 llvm_unreachable("unimplemented"); 186 } 187 void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) { 188 llvm_unreachable("unimplemented"); 189 } 190 void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) { 191 llvm_unreachable("unimplemented"); 192 } 193 void ARMTargetStreamer::emitHandlerData() { 194 llvm_unreachable("unimplemented"); 195 } 196 void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 197 int64_t Offset) { 198 llvm_unreachable("unimplemented"); 199 } 200 void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 201 llvm_unreachable("unimplemented"); 202 } 203 void ARMTargetStreamer::emitPad(int64_t Offset) { 204 llvm_unreachable("unimplemented"); 205 } 206 void 207 ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 208 bool isVector) { 209 llvm_unreachable("unimplemented"); 210 } 211 void ARMTargetStreamer::emitUnwindRaw( 212 int64_t StackOffset, const SmallVectorImpl<uint8_t> &Opcodes) { 213 llvm_unreachable("unimplemented"); 214 } 215 void ARMTargetStreamer::switchVendor(StringRef Vendor) { 216 llvm_unreachable("unimplemented"); 217 } 218 void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 219 llvm_unreachable("unimplemented"); 220 } 221 void ARMTargetStreamer::emitTextAttribute(unsigned Attribute, 222 StringRef String) { 223 llvm_unreachable("unimplemented"); 224 } 225 void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute, 226 unsigned IntValue, 227 StringRef StringValue) { 228 llvm_unreachable("unimplemented"); 229 } 230 void ARMTargetStreamer::emitArch(unsigned Arch) { 231 llvm_unreachable("unimplemented"); 232 } 233 void ARMTargetStreamer::emitObjectArch(unsigned Arch) { 234 llvm_unreachable("unimplemented"); 235 } 236 void ARMTargetStreamer::emitFPU(unsigned FPU) { 237 llvm_unreachable("unimplemented"); 238 } 239 void ARMTargetStreamer::finishAttributeSection() { 240 llvm_unreachable("unimplemented"); 241 } 242 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) { 243 llvm_unreachable("unimplemented"); 244 } 245 void ARMTargetStreamer::AnnotateTLSDescriptorSequence( 246 const MCSymbolRefExpr *SRE) { 247 llvm_unreachable("unimplemented"); 248 } 249