OSDN Git Service

am 0d041145: am 19c6fbb3: Merge "Adds the ability to run the llvm test suite in-tree."
[android-x86/external-llvm.git] / lib / Target / ARM / MCTargetDesc / ARMTargetStreamer.cpp
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
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 nullptr;
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
250 void ARMTargetStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
251   llvm_unreachable("unimplemented");
252 }