1 //===- ARMTargetStreamer.cpp - ARMTargetStreamer class --*- C++ -*---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the ARMTargetStreamer class.
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"
21 // A class to keep track of assembler-generated constant pools that are use to
22 // implement the ldr-pseudo.
24 typedef SmallVector<std::pair<MCSymbol *, const MCExpr *>, 4> EntryVecTy;
28 // Initialize a new empty constant pool
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.
34 // \returns a MCExpr that references the newly inserted value
35 const MCExpr *addEntry(const MCExpr *Value, MCContext &Context);
37 // Emit the contents of the constant pool using the provided streamer.
38 void emitEntries(MCStreamer &Streamer);
40 // Return true if the constant pool is empty
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
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
61 typedef MapVector<const MCSection *, ConstantPool> ConstantPoolMapTy;
62 ConstantPoolMapTy ConstantPools;
65 AssemblerConstantPools() {}
66 ~AssemblerConstantPools() {}
68 void emitAll(MCStreamer &Streamer);
69 void emitForCurrentSection(MCStreamer &Streamer);
70 const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr);
73 ConstantPool *getConstantPool(const MCSection *Section);
74 ConstantPool &getOrCreateConstantPool(const MCSection *Section);
79 // ConstantPool implementation
81 // Emit the contents of the constant pool using the provided streamer.
82 void ConstantPool::emitEntries(MCStreamer &Streamer) {
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();
89 Streamer.EmitLabel(I->first);
90 Streamer.EmitValue(I->second, 4);
92 Streamer.EmitDataRegion(MCDR_DataRegionEnd);
96 const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context) {
97 MCSymbol *CPEntryLabel = Context.CreateTempSymbol();
99 Entries.push_back(std::make_pair(CPEntryLabel, Value));
100 return MCSymbolRefExpr::Create(CPEntryLabel, Context);
103 bool ConstantPool::empty() { return Entries.empty(); }
106 // AssemblerConstantPools implementation
109 AssemblerConstantPools::getConstantPool(const MCSection *Section) {
110 ConstantPoolMapTy::iterator CP = ConstantPools.find(Section);
111 if (CP == ConstantPools.end())
118 AssemblerConstantPools::getOrCreateConstantPool(const MCSection *Section) {
119 return ConstantPools[Section];
122 static void emitConstantPool(MCStreamer &Streamer, const MCSection *Section,
125 Streamer.SwitchSection(Section);
126 CP.emitEntries(Streamer);
130 void AssemblerConstantPools::emitAll(MCStreamer &Streamer) {
131 // Dump contents of assembler constant pools.
132 for (ConstantPoolMapTy::iterator CPI = ConstantPools.begin(),
133 CPE = ConstantPools.end();
135 const MCSection *Section = CPI->first;
136 ConstantPool &CP = CPI->second;
138 emitConstantPool(Streamer, Section, CP);
142 void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) {
143 const MCSection *Section = Streamer.getCurrentSection().first;
144 if (ConstantPool *CP = getConstantPool(Section)) {
145 emitConstantPool(Streamer, Section, *CP);
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());
156 // ARMTargetStreamer Implemenation
158 ARMTargetStreamer::ARMTargetStreamer(MCStreamer &S)
159 : MCTargetStreamer(S), ConstantPools(new AssemblerConstantPools()) {}
161 ARMTargetStreamer::~ARMTargetStreamer() {}
163 // The constant pool handling is shared by all ARMTargetStreamer
165 const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) {
166 return ConstantPools->addEntry(Streamer, Expr);
169 void ARMTargetStreamer::emitCurrentConstantPool() {
170 ConstantPools->emitForCurrentSection(Streamer);
173 // finish() - write out any non-empty assembler constant pools.
174 void ARMTargetStreamer::finish() { ConstantPools->emitAll(Streamer); }
176 // The remaining callbacks should be handled separately by each
178 void ARMTargetStreamer::emitFnStart() {
179 llvm_unreachable("unimplemented");
181 void ARMTargetStreamer::emitFnEnd() {
182 llvm_unreachable("unimplemented");
184 void ARMTargetStreamer::emitCantUnwind() {
185 llvm_unreachable("unimplemented");
187 void ARMTargetStreamer::emitPersonality(const MCSymbol *Personality) {
188 llvm_unreachable("unimplemented");
190 void ARMTargetStreamer::emitPersonalityIndex(unsigned Index) {
191 llvm_unreachable("unimplemented");
193 void ARMTargetStreamer::emitHandlerData() {
194 llvm_unreachable("unimplemented");
196 void ARMTargetStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
198 llvm_unreachable("unimplemented");
200 void ARMTargetStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
201 llvm_unreachable("unimplemented");
203 void ARMTargetStreamer::emitPad(int64_t Offset) {
204 llvm_unreachable("unimplemented");
207 ARMTargetStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
209 llvm_unreachable("unimplemented");
211 void ARMTargetStreamer::emitUnwindRaw(
212 int64_t StackOffset, const SmallVectorImpl<uint8_t> &Opcodes) {
213 llvm_unreachable("unimplemented");
215 void ARMTargetStreamer::switchVendor(StringRef Vendor) {
216 llvm_unreachable("unimplemented");
218 void ARMTargetStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
219 llvm_unreachable("unimplemented");
221 void ARMTargetStreamer::emitTextAttribute(unsigned Attribute,
223 llvm_unreachable("unimplemented");
225 void ARMTargetStreamer::emitIntTextAttribute(unsigned Attribute,
227 StringRef StringValue) {
228 llvm_unreachable("unimplemented");
230 void ARMTargetStreamer::emitArch(unsigned Arch) {
231 llvm_unreachable("unimplemented");
233 void ARMTargetStreamer::emitObjectArch(unsigned Arch) {
234 llvm_unreachable("unimplemented");
236 void ARMTargetStreamer::emitFPU(unsigned FPU) {
237 llvm_unreachable("unimplemented");
239 void ARMTargetStreamer::finishAttributeSection() {
240 llvm_unreachable("unimplemented");
242 void ARMTargetStreamer::emitInst(uint32_t Inst, char Suffix) {
243 llvm_unreachable("unimplemented");
245 void ARMTargetStreamer::AnnotateTLSDescriptorSequence(
246 const MCSymbolRefExpr *SRE) {
247 llvm_unreachable("unimplemented");