1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSection.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbol.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
16*9880d681SAndroid Build Coastguard Worker using namespace llvm;
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
19*9880d681SAndroid Build Coastguard Worker // MCSection
20*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
21*9880d681SAndroid Build Coastguard Worker
MCSection(SectionVariant V,SectionKind K,MCSymbol * Begin)22*9880d681SAndroid Build Coastguard Worker MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
23*9880d681SAndroid Build Coastguard Worker : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
24*9880d681SAndroid Build Coastguard Worker IsRegistered(false), DummyFragment(this), Variant(V), Kind(K) {}
25*9880d681SAndroid Build Coastguard Worker
getEndSymbol(MCContext & Ctx)26*9880d681SAndroid Build Coastguard Worker MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
27*9880d681SAndroid Build Coastguard Worker if (!End)
28*9880d681SAndroid Build Coastguard Worker End = Ctx.createTempSymbol("sec_end", true);
29*9880d681SAndroid Build Coastguard Worker return End;
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker
hasEnded() const32*9880d681SAndroid Build Coastguard Worker bool MCSection::hasEnded() const { return End && End->isInSection(); }
33*9880d681SAndroid Build Coastguard Worker
~MCSection()34*9880d681SAndroid Build Coastguard Worker MCSection::~MCSection() {
35*9880d681SAndroid Build Coastguard Worker }
36*9880d681SAndroid Build Coastguard Worker
setBundleLockState(BundleLockStateType NewState)37*9880d681SAndroid Build Coastguard Worker void MCSection::setBundleLockState(BundleLockStateType NewState) {
38*9880d681SAndroid Build Coastguard Worker if (NewState == NotBundleLocked) {
39*9880d681SAndroid Build Coastguard Worker if (BundleLockNestingDepth == 0) {
40*9880d681SAndroid Build Coastguard Worker report_fatal_error("Mismatched bundle_lock/unlock directives");
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker if (--BundleLockNestingDepth == 0) {
43*9880d681SAndroid Build Coastguard Worker BundleLockState = NotBundleLocked;
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker return;
46*9880d681SAndroid Build Coastguard Worker }
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker // If any of the directives is an align_to_end directive, the whole nested
49*9880d681SAndroid Build Coastguard Worker // group is align_to_end. So don't downgrade from align_to_end to just locked.
50*9880d681SAndroid Build Coastguard Worker if (BundleLockState != BundleLockedAlignToEnd) {
51*9880d681SAndroid Build Coastguard Worker BundleLockState = NewState;
52*9880d681SAndroid Build Coastguard Worker }
53*9880d681SAndroid Build Coastguard Worker ++BundleLockNestingDepth;
54*9880d681SAndroid Build Coastguard Worker }
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker MCSection::iterator
getSubsectionInsertionPoint(unsigned Subsection)57*9880d681SAndroid Build Coastguard Worker MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
58*9880d681SAndroid Build Coastguard Worker if (Subsection == 0 && SubsectionFragmentMap.empty())
59*9880d681SAndroid Build Coastguard Worker return end();
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<std::pair<unsigned, MCFragment *>>::iterator MI =
62*9880d681SAndroid Build Coastguard Worker std::lower_bound(SubsectionFragmentMap.begin(),
63*9880d681SAndroid Build Coastguard Worker SubsectionFragmentMap.end(),
64*9880d681SAndroid Build Coastguard Worker std::make_pair(Subsection, (MCFragment *)nullptr));
65*9880d681SAndroid Build Coastguard Worker bool ExactMatch = false;
66*9880d681SAndroid Build Coastguard Worker if (MI != SubsectionFragmentMap.end()) {
67*9880d681SAndroid Build Coastguard Worker ExactMatch = MI->first == Subsection;
68*9880d681SAndroid Build Coastguard Worker if (ExactMatch)
69*9880d681SAndroid Build Coastguard Worker ++MI;
70*9880d681SAndroid Build Coastguard Worker }
71*9880d681SAndroid Build Coastguard Worker iterator IP;
72*9880d681SAndroid Build Coastguard Worker if (MI == SubsectionFragmentMap.end())
73*9880d681SAndroid Build Coastguard Worker IP = end();
74*9880d681SAndroid Build Coastguard Worker else
75*9880d681SAndroid Build Coastguard Worker IP = MI->second->getIterator();
76*9880d681SAndroid Build Coastguard Worker if (!ExactMatch && Subsection != 0) {
77*9880d681SAndroid Build Coastguard Worker // The GNU as documentation claims that subsections have an alignment of 4,
78*9880d681SAndroid Build Coastguard Worker // although this appears not to be the case.
79*9880d681SAndroid Build Coastguard Worker MCFragment *F = new MCDataFragment();
80*9880d681SAndroid Build Coastguard Worker SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
81*9880d681SAndroid Build Coastguard Worker getFragmentList().insert(IP, F);
82*9880d681SAndroid Build Coastguard Worker F->setParent(this);
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker return IP;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()89*9880d681SAndroid Build Coastguard Worker LLVM_DUMP_METHOD void MCSection::dump() {
90*9880d681SAndroid Build Coastguard Worker raw_ostream &OS = llvm::errs();
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker OS << "<MCSection";
93*9880d681SAndroid Build Coastguard Worker OS << " Fragments:[\n ";
94*9880d681SAndroid Build Coastguard Worker for (auto it = begin(), ie = end(); it != ie; ++it) {
95*9880d681SAndroid Build Coastguard Worker if (it != begin())
96*9880d681SAndroid Build Coastguard Worker OS << ",\n ";
97*9880d681SAndroid Build Coastguard Worker it->dump();
98*9880d681SAndroid Build Coastguard Worker }
99*9880d681SAndroid Build Coastguard Worker OS << "]>";
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker #endif
102*9880d681SAndroid Build Coastguard Worker
begin()103*9880d681SAndroid Build Coastguard Worker MCSection::iterator MCSection::begin() { return Fragments.begin(); }
104*9880d681SAndroid Build Coastguard Worker
end()105*9880d681SAndroid Build Coastguard Worker MCSection::iterator MCSection::end() { return Fragments.end(); }
106*9880d681SAndroid Build Coastguard Worker
rbegin()107*9880d681SAndroid Build Coastguard Worker MCSection::reverse_iterator MCSection::rbegin() { return Fragments.rbegin(); }
108*9880d681SAndroid Build Coastguard Worker
rend()109*9880d681SAndroid Build Coastguard Worker MCSection::reverse_iterator MCSection::rend() { return Fragments.rend(); }
110