Add the align_to_end option to .bundle_lock in the MC implementation of aligned
[oota-llvm.git] / include / llvm / MC / MCAssembler.h
1 //===- MCAssembler.h - Object File Generation -------------------*- 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 #ifndef LLVM_MC_MCASSEMBLER_H
11 #define LLVM_MC_MCASSEMBLER_H
12
13 #include "llvm/ADT/DenseMap.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallString.h"
16 #include "llvm/ADT/ilist.h"
17 #include "llvm/ADT/ilist_node.h"
18 #include "llvm/MC/MCFixup.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/DataTypes.h"
22 #include <vector> // FIXME: Shouldn't be needed.
23
24 namespace llvm {
25 class raw_ostream;
26 class MCAsmLayout;
27 class MCAssembler;
28 class MCContext;
29 class MCCodeEmitter;
30 class MCExpr;
31 class MCFragment;
32 class MCObjectWriter;
33 class MCSection;
34 class MCSectionData;
35 class MCSymbol;
36 class MCSymbolData;
37 class MCValue;
38 class MCAsmBackend;
39
40 class MCFragment : public ilist_node<MCFragment> {
41   friend class MCAsmLayout;
42
43   MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
44   void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
45
46 public:
47   enum FragmentType {
48     FT_Align,
49     FT_Data,
50     FT_Fill,
51     FT_Inst,
52     FT_Org,
53     FT_Dwarf,
54     FT_DwarfFrame,
55     FT_LEB
56   };
57
58 private:
59   FragmentType Kind;
60
61   /// Parent - The data for the section this fragment is in.
62   MCSectionData *Parent;
63
64   /// Atom - The atom this fragment is in, as represented by it's defining
65   /// symbol. Atom's are only used by backends which set
66   /// \see MCAsmBackend::hasReliableSymbolDifference().
67   MCSymbolData *Atom;
68
69   /// @name Assembler Backend Data
70   /// @{
71   //
72   // FIXME: This could all be kept private to the assembler implementation.
73
74   /// Offset - The offset of this fragment in its section. This is ~0 until
75   /// initialized.
76   uint64_t Offset;
77
78   /// LayoutOrder - The layout order of this fragment.
79   unsigned LayoutOrder;
80
81   /// @}
82
83 protected:
84   MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
85
86 public:
87   // Only for sentinel.
88   MCFragment();
89   virtual ~MCFragment();
90
91   FragmentType getKind() const { return Kind; }
92
93   MCSectionData *getParent() const { return Parent; }
94   void setParent(MCSectionData *Value) { Parent = Value; }
95
96   MCSymbolData *getAtom() const { return Atom; }
97   void setAtom(MCSymbolData *Value) { Atom = Value; }
98
99   unsigned getLayoutOrder() const { return LayoutOrder; }
100   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
101
102   /// \brief Does this fragment have instructions emitted into it? By default
103   /// this is false, but specific fragment types may set it to true.
104   virtual bool hasInstructions() const { return false; }
105
106   /// \brief Should this fragment be placed at the end of an aligned bundle?
107   virtual bool alignToBundleEnd() const { return false; }
108
109   /// \brief Get the padding size that must be inserted before this fragment.
110   /// Used for bundling. By default, no padding is inserted.
111   /// Note that padding size is restricted to 8 bits. This is an optimization
112   /// to reduce the amount of space used for each fragment. In practice, larger
113   /// padding should never be required.
114   virtual uint8_t getBundlePadding() const {
115     return 0;
116   }
117
118   /// \brief Set the padding size for this fragment. By default it's a no-op,
119   /// and only some fragments have a meaningful implementation.
120   virtual void setBundlePadding(uint8_t N) {
121   }
122
123   void dump();
124 };
125
126 class MCEncodedFragment : public MCFragment {
127   virtual void anchor();
128
129   uint8_t BundlePadding;
130 public:
131   MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
132     : MCFragment(FType, SD), BundlePadding(0)
133   {
134   }
135   virtual ~MCEncodedFragment();
136
137   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
138   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
139
140   virtual SmallVectorImpl<char> &getContents() = 0;
141   virtual const SmallVectorImpl<char> &getContents() const = 0;
142
143   virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
144   virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
145
146   virtual fixup_iterator fixup_begin() = 0;
147   virtual const_fixup_iterator fixup_begin() const  = 0;
148   virtual fixup_iterator fixup_end() = 0;
149   virtual const_fixup_iterator fixup_end() const = 0;
150
151   virtual uint8_t getBundlePadding() const {
152     return BundlePadding;
153   }
154
155   virtual void setBundlePadding(uint8_t N) {
156     BundlePadding = N;
157   }
158
159   static bool classof(const MCFragment *F) {
160     MCFragment::FragmentType Kind = F->getKind();
161     return Kind == MCFragment::FT_Inst || Kind == MCFragment::FT_Data;
162   }
163 };
164
165 class MCDataFragment : public MCEncodedFragment {
166   virtual void anchor();
167
168   /// \brief Does this fragment contain encoded instructions anywhere in it?
169   bool HasInstructions;
170
171   /// \brief Should this fragment be aligned to the end of a bundle?
172   bool AlignToBundleEnd;
173
174   SmallVector<char, 32> Contents;
175
176   /// Fixups - The list of fixups in this fragment.
177   SmallVector<MCFixup, 4> Fixups;
178 public:
179   MCDataFragment(MCSectionData *SD = 0)
180     : MCEncodedFragment(FT_Data, SD),
181       HasInstructions(false), AlignToBundleEnd(false)
182   {
183   }
184
185   virtual SmallVectorImpl<char> &getContents() { return Contents; }
186   virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
187
188   SmallVectorImpl<MCFixup> &getFixups() {
189     return Fixups;
190   }
191
192   const SmallVectorImpl<MCFixup> &getFixups() const {
193     return Fixups;
194   }
195
196   virtual bool hasInstructions() const { return HasInstructions; }
197   virtual void setHasInstructions(bool V) { HasInstructions = V; }
198
199   virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
200   virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
201
202   fixup_iterator fixup_begin() { return Fixups.begin(); }
203   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
204
205   fixup_iterator fixup_end() {return Fixups.end();}
206   const_fixup_iterator fixup_end() const {return Fixups.end();}
207
208   static bool classof(const MCFragment *F) {
209     return F->getKind() == MCFragment::FT_Data;
210   }
211 };
212
213 class MCInstFragment : public MCEncodedFragment {
214   virtual void anchor();
215
216   /// Inst - The instruction this is a fragment for.
217   MCInst Inst;
218
219   /// Contents - Binary data for the currently encoded instruction.
220   SmallVector<char, 8> Contents;
221
222   /// Fixups - The list of fixups in this fragment.
223   SmallVector<MCFixup, 1> Fixups;
224
225 public:
226   MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
227     : MCEncodedFragment(FT_Inst, SD), Inst(_Inst) {
228   }
229
230   virtual SmallVectorImpl<char> &getContents() { return Contents; }
231   virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
232
233   unsigned getInstSize() const { return Contents.size(); }
234   const MCInst &getInst() const { return Inst; }
235   void setInst(const MCInst& Value) { Inst = Value; }
236
237   SmallVectorImpl<MCFixup> &getFixups() {
238     return Fixups;
239   }
240
241   const SmallVectorImpl<MCFixup> &getFixups() const {
242     return Fixups;
243   }
244
245   virtual bool hasInstructions() const { return true; }
246
247   fixup_iterator fixup_begin() { return Fixups.begin(); }
248   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
249
250   fixup_iterator fixup_end() {return Fixups.end();}
251   const_fixup_iterator fixup_end() const {return Fixups.end();}
252
253   static bool classof(const MCFragment *F) {
254     return F->getKind() == MCFragment::FT_Inst;
255   }
256 };
257
258 class MCAlignFragment : public MCFragment {
259   virtual void anchor();
260
261   /// Alignment - The alignment to ensure, in bytes.
262   unsigned Alignment;
263
264   /// Value - Value to use for filling padding bytes.
265   int64_t Value;
266
267   /// ValueSize - The size of the integer (in bytes) of \p Value.
268   unsigned ValueSize;
269
270   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
271   /// cannot be satisfied in this width then this fragment is ignored.
272   unsigned MaxBytesToEmit;
273
274   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
275   /// of using the provided value. The exact interpretation of this flag is
276   /// target dependent.
277   bool EmitNops : 1;
278
279 public:
280   MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
281                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
282     : MCFragment(FT_Align, SD), Alignment(_Alignment),
283       Value(_Value),ValueSize(_ValueSize),
284       MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
285
286   /// @name Accessors
287   /// @{
288
289   unsigned getAlignment() const { return Alignment; }
290
291   int64_t getValue() const { return Value; }
292
293   unsigned getValueSize() const { return ValueSize; }
294
295   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
296
297   bool hasEmitNops() const { return EmitNops; }
298   void setEmitNops(bool Value) { EmitNops = Value; }
299
300   /// @}
301
302   static bool classof(const MCFragment *F) {
303     return F->getKind() == MCFragment::FT_Align;
304   }
305 };
306
307 class MCFillFragment : public MCFragment {
308   virtual void anchor();
309
310   /// Value - Value to use for filling bytes.
311   int64_t Value;
312
313   /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
314   /// this is a virtual fill fragment.
315   unsigned ValueSize;
316
317   /// Size - The number of bytes to insert.
318   uint64_t Size;
319
320 public:
321   MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
322                  MCSectionData *SD = 0)
323     : MCFragment(FT_Fill, SD),
324       Value(_Value), ValueSize(_ValueSize), Size(_Size) {
325     assert((!ValueSize || (Size % ValueSize) == 0) &&
326            "Fill size must be a multiple of the value size!");
327   }
328
329   /// @name Accessors
330   /// @{
331
332   int64_t getValue() const { return Value; }
333
334   unsigned getValueSize() const { return ValueSize; }
335
336   uint64_t getSize() const { return Size; }
337
338   /// @}
339
340   static bool classof(const MCFragment *F) {
341     return F->getKind() == MCFragment::FT_Fill;
342   }
343 };
344
345 class MCOrgFragment : public MCFragment {
346   virtual void anchor();
347
348   /// Offset - The offset this fragment should start at.
349   const MCExpr *Offset;
350
351   /// Value - Value to use for filling bytes.
352   int8_t Value;
353
354 public:
355   MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0)
356     : MCFragment(FT_Org, SD),
357       Offset(&_Offset), Value(_Value) {}
358
359   /// @name Accessors
360   /// @{
361
362   const MCExpr &getOffset() const { return *Offset; }
363
364   uint8_t getValue() const { return Value; }
365
366   /// @}
367
368   static bool classof(const MCFragment *F) {
369     return F->getKind() == MCFragment::FT_Org;
370   }
371 };
372
373 class MCLEBFragment : public MCFragment {
374   virtual void anchor();
375
376   /// Value - The value this fragment should contain.
377   const MCExpr *Value;
378
379   /// IsSigned - True if this is a sleb128, false if uleb128.
380   bool IsSigned;
381
382   SmallString<8> Contents;
383 public:
384   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
385     : MCFragment(FT_LEB, SD),
386       Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
387
388   /// @name Accessors
389   /// @{
390
391   const MCExpr &getValue() const { return *Value; }
392
393   bool isSigned() const { return IsSigned; }
394
395   SmallString<8> &getContents() { return Contents; }
396   const SmallString<8> &getContents() const { return Contents; }
397
398   /// @}
399
400   static bool classof(const MCFragment *F) {
401     return F->getKind() == MCFragment::FT_LEB;
402   }
403 };
404
405 class MCDwarfLineAddrFragment : public MCFragment {
406   virtual void anchor();
407
408   /// LineDelta - the value of the difference between the two line numbers
409   /// between two .loc dwarf directives.
410   int64_t LineDelta;
411
412   /// AddrDelta - The expression for the difference of the two symbols that
413   /// make up the address delta between two .loc dwarf directives.
414   const MCExpr *AddrDelta;
415
416   SmallString<8> Contents;
417
418 public:
419   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
420                       MCSectionData *SD)
421     : MCFragment(FT_Dwarf, SD),
422       LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
423
424   /// @name Accessors
425   /// @{
426
427   int64_t getLineDelta() const { return LineDelta; }
428
429   const MCExpr &getAddrDelta() const { return *AddrDelta; }
430
431   SmallString<8> &getContents() { return Contents; }
432   const SmallString<8> &getContents() const { return Contents; }
433
434   /// @}
435
436   static bool classof(const MCFragment *F) {
437     return F->getKind() == MCFragment::FT_Dwarf;
438   }
439 };
440
441 class MCDwarfCallFrameFragment : public MCFragment {
442   virtual void anchor();
443
444   /// AddrDelta - The expression for the difference of the two symbols that
445   /// make up the address delta between two .cfi_* dwarf directives.
446   const MCExpr *AddrDelta;
447
448   SmallString<8> Contents;
449
450 public:
451   MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,  MCSectionData *SD)
452     : MCFragment(FT_DwarfFrame, SD),
453       AddrDelta(&_AddrDelta) { Contents.push_back(0); }
454
455   /// @name Accessors
456   /// @{
457
458   const MCExpr &getAddrDelta() const { return *AddrDelta; }
459
460   SmallString<8> &getContents() { return Contents; }
461   const SmallString<8> &getContents() const { return Contents; }
462
463   /// @}
464
465   static bool classof(const MCFragment *F) {
466     return F->getKind() == MCFragment::FT_DwarfFrame;
467   }
468 };
469
470 // FIXME: Should this be a separate class, or just merged into MCSection? Since
471 // we anticipate the fast path being through an MCAssembler, the only reason to
472 // keep it out is for API abstraction.
473 class MCSectionData : public ilist_node<MCSectionData> {
474   friend class MCAsmLayout;
475
476   MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
477   void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
478
479 public:
480   typedef iplist<MCFragment> FragmentListType;
481
482   typedef FragmentListType::const_iterator const_iterator;
483   typedef FragmentListType::iterator iterator;
484
485   typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
486   typedef FragmentListType::reverse_iterator reverse_iterator;
487
488   /// \brief Express the state of bundle locked groups while emitting code.
489   enum BundleLockStateType {
490     NotBundleLocked,
491     BundleLocked,
492     BundleLockedAlignToEnd
493   };
494 private:
495   FragmentListType Fragments;
496   const MCSection *Section;
497
498   /// Ordinal - The section index in the assemblers section list.
499   unsigned Ordinal;
500
501   /// LayoutOrder - The index of this section in the layout order.
502   unsigned LayoutOrder;
503
504   /// Alignment - The maximum alignment seen in this section.
505   unsigned Alignment;
506
507   /// \brief Keeping track of bundle-locked state.
508   BundleLockStateType BundleLockState; 
509
510   /// \brief We've seen a bundle_lock directive but not its first instruction
511   /// yet.
512   bool BundleGroupBeforeFirstInst;
513
514   /// @name Assembler Backend Data
515   /// @{
516   //
517   // FIXME: This could all be kept private to the assembler implementation.
518
519   /// HasInstructions - Whether this section has had instructions emitted into
520   /// it.
521   unsigned HasInstructions : 1;
522
523   /// @}
524
525 public:
526   // Only for use as sentinel.
527   MCSectionData();
528   MCSectionData(const MCSection &Section, MCAssembler *A = 0);
529
530   const MCSection &getSection() const { return *Section; }
531
532   unsigned getAlignment() const { return Alignment; }
533   void setAlignment(unsigned Value) { Alignment = Value; }
534
535   bool hasInstructions() const { return HasInstructions; }
536   void setHasInstructions(bool Value) { HasInstructions = Value; }
537
538   unsigned getOrdinal() const { return Ordinal; }
539   void setOrdinal(unsigned Value) { Ordinal = Value; }
540
541   unsigned getLayoutOrder() const { return LayoutOrder; }
542   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
543
544   /// @name Fragment Access
545   /// @{
546
547   const FragmentListType &getFragmentList() const { return Fragments; }
548   FragmentListType &getFragmentList() { return Fragments; }
549
550   iterator begin() { return Fragments.begin(); }
551   const_iterator begin() const { return Fragments.begin(); }
552
553   iterator end() { return Fragments.end(); }
554   const_iterator end() const { return Fragments.end(); }
555
556   reverse_iterator rbegin() { return Fragments.rbegin(); }
557   const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
558
559   reverse_iterator rend() { return Fragments.rend(); }
560   const_reverse_iterator rend() const { return Fragments.rend(); }
561
562   size_t size() const { return Fragments.size(); }
563
564   bool empty() const { return Fragments.empty(); }
565
566   bool isBundleLocked() const {
567     return BundleLockState != NotBundleLocked;
568   }
569
570   BundleLockStateType getBundleLockState() const {
571     return BundleLockState;
572   }
573
574   void setBundleLockState(BundleLockStateType NewState) {
575     BundleLockState = NewState;
576   }
577
578   bool isBundleGroupBeforeFirstInst() const {
579     return BundleGroupBeforeFirstInst;
580   }
581
582   void setBundleGroupBeforeFirstInst(bool IsFirst) {
583     BundleGroupBeforeFirstInst = IsFirst;
584   }
585
586   void dump();
587
588   /// @}
589 };
590
591 // FIXME: Same concerns as with SectionData.
592 class MCSymbolData : public ilist_node<MCSymbolData> {
593 public:
594   const MCSymbol *Symbol;
595
596   /// Fragment - The fragment this symbol's value is relative to, if any.
597   MCFragment *Fragment;
598
599   /// Offset - The offset to apply to the fragment address to form this symbol's
600   /// value.
601   uint64_t Offset;
602
603   /// IsExternal - True if this symbol is visible outside this translation
604   /// unit.
605   unsigned IsExternal : 1;
606
607   /// IsPrivateExtern - True if this symbol is private extern.
608   unsigned IsPrivateExtern : 1;
609
610   /// CommonSize - The size of the symbol, if it is 'common', or 0.
611   //
612   // FIXME: Pack this in with other fields? We could put it in offset, since a
613   // common symbol can never get a definition.
614   uint64_t CommonSize;
615
616   /// SymbolSize - An expression describing how to calculate the size of
617   /// a symbol. If a symbol has no size this field will be NULL.
618   const MCExpr *SymbolSize;
619
620   /// CommonAlign - The alignment of the symbol, if it is 'common'.
621   //
622   // FIXME: Pack this in with other fields?
623   unsigned CommonAlign;
624
625   /// Flags - The Flags field is used by object file implementations to store
626   /// additional per symbol information which is not easily classified.
627   uint32_t Flags;
628
629   /// Index - Index field, for use by the object file implementation.
630   uint64_t Index;
631
632 public:
633   // Only for use as sentinel.
634   MCSymbolData();
635   MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
636                MCAssembler *A = 0);
637
638   /// @name Accessors
639   /// @{
640
641   const MCSymbol &getSymbol() const { return *Symbol; }
642
643   MCFragment *getFragment() const { return Fragment; }
644   void setFragment(MCFragment *Value) { Fragment = Value; }
645
646   uint64_t getOffset() const { return Offset; }
647   void setOffset(uint64_t Value) { Offset = Value; }
648
649   /// @}
650   /// @name Symbol Attributes
651   /// @{
652
653   bool isExternal() const { return IsExternal; }
654   void setExternal(bool Value) { IsExternal = Value; }
655
656   bool isPrivateExtern() const { return IsPrivateExtern; }
657   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
658
659   /// isCommon - Is this a 'common' symbol.
660   bool isCommon() const { return CommonSize != 0; }
661
662   /// setCommon - Mark this symbol as being 'common'.
663   ///
664   /// \param Size - The size of the symbol.
665   /// \param Align - The alignment of the symbol.
666   void setCommon(uint64_t Size, unsigned Align) {
667     CommonSize = Size;
668     CommonAlign = Align;
669   }
670
671   /// getCommonSize - Return the size of a 'common' symbol.
672   uint64_t getCommonSize() const {
673     assert(isCommon() && "Not a 'common' symbol!");
674     return CommonSize;
675   }
676
677   void setSize(const MCExpr *SS) {
678     SymbolSize = SS;
679   }
680
681   const MCExpr *getSize() const {
682     return SymbolSize;
683   }
684
685
686   /// getCommonAlignment - Return the alignment of a 'common' symbol.
687   unsigned getCommonAlignment() const {
688     assert(isCommon() && "Not a 'common' symbol!");
689     return CommonAlign;
690   }
691
692   /// getFlags - Get the (implementation defined) symbol flags.
693   uint32_t getFlags() const { return Flags; }
694
695   /// setFlags - Set the (implementation defined) symbol flags.
696   void setFlags(uint32_t Value) { Flags = Value; }
697
698   /// modifyFlags - Modify the flags via a mask
699   void modifyFlags(uint32_t Value, uint32_t Mask) {
700     Flags = (Flags & ~Mask) | Value;
701   }
702
703   /// getIndex - Get the (implementation defined) index.
704   uint64_t getIndex() const { return Index; }
705
706   /// setIndex - Set the (implementation defined) index.
707   void setIndex(uint64_t Value) { Index = Value; }
708
709   /// @}
710
711   void dump();
712 };
713
714 // FIXME: This really doesn't belong here. See comments below.
715 struct IndirectSymbolData {
716   MCSymbol *Symbol;
717   MCSectionData *SectionData;
718 };
719
720 // FIXME: Ditto this. Purely so the Streamer and the ObjectWriter can talk
721 // to one another.
722 struct DataRegionData {
723   // This enum should be kept in sync w/ the mach-o definition in
724   // llvm/Object/MachOFormat.h.
725   enum KindTy { Data = 1, JumpTable8, JumpTable16, JumpTable32 } Kind;
726   MCSymbol *Start;
727   MCSymbol *End;
728 };
729
730 class MCAssembler {
731   friend class MCAsmLayout;
732
733 public:
734   typedef iplist<MCSectionData> SectionDataListType;
735   typedef iplist<MCSymbolData> SymbolDataListType;
736
737   typedef SectionDataListType::const_iterator const_iterator;
738   typedef SectionDataListType::iterator iterator;
739
740   typedef SymbolDataListType::const_iterator const_symbol_iterator;
741   typedef SymbolDataListType::iterator symbol_iterator;
742
743   typedef std::vector<IndirectSymbolData>::const_iterator
744     const_indirect_symbol_iterator;
745   typedef std::vector<IndirectSymbolData>::iterator indirect_symbol_iterator;
746
747   typedef std::vector<DataRegionData>::const_iterator
748     const_data_region_iterator;
749   typedef std::vector<DataRegionData>::iterator data_region_iterator;
750
751 private:
752   MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
753   void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
754
755   MCContext &Context;
756
757   MCAsmBackend &Backend;
758
759   MCCodeEmitter &Emitter;
760
761   MCObjectWriter &Writer;
762
763   raw_ostream &OS;
764
765   iplist<MCSectionData> Sections;
766
767   iplist<MCSymbolData> Symbols;
768
769   /// The map of sections to their associated assembler backend data.
770   //
771   // FIXME: Avoid this indirection?
772   DenseMap<const MCSection*, MCSectionData*> SectionMap;
773
774   /// The map of symbols to their associated assembler backend data.
775   //
776   // FIXME: Avoid this indirection?
777   DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
778
779   std::vector<IndirectSymbolData> IndirectSymbols;
780
781   std::vector<DataRegionData> DataRegions;
782   /// The set of function symbols for which a .thumb_func directive has
783   /// been seen.
784   //
785   // FIXME: We really would like this in target specific code rather than
786   // here. Maybe when the relocation stuff moves to target specific,
787   // this can go with it? The streamer would need some target specific
788   // refactoring too.
789   SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
790
791   /// \brief The bundle alignment size currently set in the assembler.
792   ///
793   /// By default it's 0, which means bundling is disabled.
794   unsigned BundleAlignSize;
795
796   unsigned RelaxAll : 1;
797   unsigned NoExecStack : 1;
798   unsigned SubsectionsViaSymbols : 1;
799
800 private:
801   /// Evaluate a fixup to a relocatable expression and the value which should be
802   /// placed into the fixup.
803   ///
804   /// \param Layout The layout to use for evaluation.
805   /// \param Fixup The fixup to evaluate.
806   /// \param DF The fragment the fixup is inside.
807   /// \param Target [out] On return, the relocatable expression the fixup
808   /// evaluates to.
809   /// \param Value [out] On return, the value of the fixup as currently laid
810   /// out.
811   /// \return Whether the fixup value was fully resolved. This is true if the
812   /// \p Value result is fixed, otherwise the value may change due to
813   /// relocation.
814   bool evaluateFixup(const MCAsmLayout &Layout,
815                      const MCFixup &Fixup, const MCFragment *DF,
816                      MCValue &Target, uint64_t &Value) const;
817
818   /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
819   /// (increased in size, in order to hold its value correctly).
820   bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCInstFragment *DF,
821                             const MCAsmLayout &Layout) const;
822
823   /// Check whether the given fragment needs relaxation.
824   bool fragmentNeedsRelaxation(const MCInstFragment *IF,
825                                const MCAsmLayout &Layout) const;
826
827   /// \brief Perform one layout iteration and return true if any offsets
828   /// were adjusted.
829   bool layoutOnce(MCAsmLayout &Layout);
830
831   /// \brief Perform one layout iteration of the given section and return true
832   /// if any offsets were adjusted.
833   bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
834
835   bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
836
837   bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
838
839   bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
840   bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
841                                    MCDwarfCallFrameFragment &DF);
842
843   /// finishLayout - Finalize a layout, including fragment lowering.
844   void finishLayout(MCAsmLayout &Layout);
845
846   uint64_t handleFixup(const MCAsmLayout &Layout,
847                        MCFragment &F, const MCFixup &Fixup);
848
849 public:
850   /// Compute the effective fragment size assuming it is laid out at the given
851   /// \p SectionAddress and \p FragmentOffset.
852   uint64_t computeFragmentSize(const MCAsmLayout &Layout,
853                                const MCFragment &F) const;
854
855   /// Find the symbol which defines the atom containing the given symbol, or
856   /// null if there is no such symbol.
857   const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;
858
859   /// Check whether a particular symbol is visible to the linker and is required
860   /// in the symbol table, or whether it can be discarded by the assembler. This
861   /// also effects whether the assembler treats the label as potentially
862   /// defining a separate atom.
863   bool isSymbolLinkerVisible(const MCSymbol &SD) const;
864
865   /// Emit the section contents using the given object writer.
866   void writeSectionData(const MCSectionData *Section,
867                         const MCAsmLayout &Layout) const;
868
869   /// Check whether a given symbol has been flagged with .thumb_func.
870   bool isThumbFunc(const MCSymbol *Func) const {
871     return ThumbFuncs.count(Func);
872   }
873
874   /// Flag a function symbol as the target of a .thumb_func directive.
875   void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
876
877 public:
878   /// Construct a new assembler instance.
879   ///
880   /// \param OS The stream to output to.
881   //
882   // FIXME: How are we going to parameterize this? Two obvious options are stay
883   // concrete and require clients to pass in a target like object. The other
884   // option is to make this abstract, and have targets provide concrete
885   // implementations as we do with AsmParser.
886   MCAssembler(MCContext &Context_, MCAsmBackend &Backend_,
887               MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
888               raw_ostream &OS);
889   ~MCAssembler();
890
891   /// Reuse an assembler instance
892   ///
893   void reset();
894
895   MCContext &getContext() const { return Context; }
896
897   MCAsmBackend &getBackend() const { return Backend; }
898
899   MCCodeEmitter &getEmitter() const { return Emitter; }
900
901   MCObjectWriter &getWriter() const { return Writer; }
902
903   /// Finish - Do final processing and write the object to the output stream.
904   /// \p Writer is used for custom object writer (as the MCJIT does),
905   /// if not specified it is automatically created from backend.
906   void Finish();
907
908   // FIXME: This does not belong here.
909   bool getSubsectionsViaSymbols() const {
910     return SubsectionsViaSymbols;
911   }
912   void setSubsectionsViaSymbols(bool Value) {
913     SubsectionsViaSymbols = Value;
914   }
915
916   bool getRelaxAll() const { return RelaxAll; }
917   void setRelaxAll(bool Value) { RelaxAll = Value; }
918
919   bool getNoExecStack() const { return NoExecStack; }
920   void setNoExecStack(bool Value) { NoExecStack = Value; }
921
922   bool isBundlingEnabled() const {
923     return BundleAlignSize != 0;
924   }
925
926   unsigned getBundleAlignSize() const {
927     return BundleAlignSize;
928   }
929
930   void setBundleAlignSize(unsigned Size) {
931     assert((Size == 0 || !(Size & (Size - 1))) && 
932            "Expect a power-of-two bundle align size");
933     BundleAlignSize = Size;
934   }
935
936   /// @name Section List Access
937   /// @{
938
939   const SectionDataListType &getSectionList() const { return Sections; }
940   SectionDataListType &getSectionList() { return Sections; }
941
942   iterator begin() { return Sections.begin(); }
943   const_iterator begin() const { return Sections.begin(); }
944
945   iterator end() { return Sections.end(); }
946   const_iterator end() const { return Sections.end(); }
947
948   size_t size() const { return Sections.size(); }
949
950   /// @}
951   /// @name Symbol List Access
952   /// @{
953
954   const SymbolDataListType &getSymbolList() const { return Symbols; }
955   SymbolDataListType &getSymbolList() { return Symbols; }
956
957   symbol_iterator symbol_begin() { return Symbols.begin(); }
958   const_symbol_iterator symbol_begin() const { return Symbols.begin(); }
959
960   symbol_iterator symbol_end() { return Symbols.end(); }
961   const_symbol_iterator symbol_end() const { return Symbols.end(); }
962
963   size_t symbol_size() const { return Symbols.size(); }
964
965   /// @}
966   /// @name Indirect Symbol List Access
967   /// @{
968
969   // FIXME: This is a total hack, this should not be here. Once things are
970   // factored so that the streamer has direct access to the .o writer, it can
971   // disappear.
972   std::vector<IndirectSymbolData> &getIndirectSymbols() {
973     return IndirectSymbols;
974   }
975
976   indirect_symbol_iterator indirect_symbol_begin() {
977     return IndirectSymbols.begin();
978   }
979   const_indirect_symbol_iterator indirect_symbol_begin() const {
980     return IndirectSymbols.begin();
981   }
982
983   indirect_symbol_iterator indirect_symbol_end() {
984     return IndirectSymbols.end();
985   }
986   const_indirect_symbol_iterator indirect_symbol_end() const {
987     return IndirectSymbols.end();
988   }
989
990   size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
991
992   /// @}
993   /// @name Data Region List Access
994   /// @{
995
996   // FIXME: This is a total hack, this should not be here. Once things are
997   // factored so that the streamer has direct access to the .o writer, it can
998   // disappear.
999   std::vector<DataRegionData> &getDataRegions() {
1000     return DataRegions;
1001   }
1002
1003   data_region_iterator data_region_begin() {
1004     return DataRegions.begin();
1005   }
1006   const_data_region_iterator data_region_begin() const {
1007     return DataRegions.begin();
1008   }
1009
1010   data_region_iterator data_region_end() {
1011     return DataRegions.end();
1012   }
1013   const_data_region_iterator data_region_end() const {
1014     return DataRegions.end();
1015   }
1016
1017   size_t data_region_size() const { return DataRegions.size(); }
1018
1019   /// @}
1020   /// @name Backend Data Access
1021   /// @{
1022
1023   MCSectionData &getSectionData(const MCSection &Section) const {
1024     MCSectionData *Entry = SectionMap.lookup(&Section);
1025     assert(Entry && "Missing section data!");
1026     return *Entry;
1027   }
1028
1029   MCSectionData &getOrCreateSectionData(const MCSection &Section,
1030                                         bool *Created = 0) {
1031     MCSectionData *&Entry = SectionMap[&Section];
1032
1033     if (Created) *Created = !Entry;
1034     if (!Entry)
1035       Entry = new MCSectionData(Section, this);
1036
1037     return *Entry;
1038   }
1039
1040   MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
1041     MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
1042     assert(Entry && "Missing symbol data!");
1043     return *Entry;
1044   }
1045
1046   MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
1047                                       bool *Created = 0) {
1048     MCSymbolData *&Entry = SymbolMap[&Symbol];
1049
1050     if (Created) *Created = !Entry;
1051     if (!Entry)
1052       Entry = new MCSymbolData(Symbol, 0, 0, this);
1053
1054     return *Entry;
1055   }
1056
1057   /// @}
1058
1059   void dump();
1060 };
1061
1062 } // end namespace llvm
1063
1064 #endif