diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCSection.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCSection.cpp | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/contrib/llvm/lib/MC/MCSection.cpp b/contrib/llvm/lib/MC/MCSection.cpp new file mode 100644 index 000000000000..d4f11d10136a --- /dev/null +++ b/contrib/llvm/lib/MC/MCSection.cpp @@ -0,0 +1,103 @@ +//===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCSection.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCFragment.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <utility> + +using namespace llvm; + +MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin) + : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false), + HasData(false), IsRegistered(false), DummyFragment(this), Variant(V), + Kind(K) {} + +MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { + if (!End) + End = Ctx.createTempSymbol("sec_end", true); + return End; +} + +bool MCSection::hasEnded() const { return End && End->isInSection(); } + +MCSection::~MCSection() = default; + +void MCSection::setBundleLockState(BundleLockStateType NewState) { + if (NewState == NotBundleLocked) { + if (BundleLockNestingDepth == 0) { + report_fatal_error("Mismatched bundle_lock/unlock directives"); + } + if (--BundleLockNestingDepth == 0) { + BundleLockState = NotBundleLocked; + } + return; + } + + // If any of the directives is an align_to_end directive, the whole nested + // group is align_to_end. So don't downgrade from align_to_end to just locked. + if (BundleLockState != BundleLockedAlignToEnd) { + BundleLockState = NewState; + } + ++BundleLockNestingDepth; +} + +MCSection::iterator +MCSection::getSubsectionInsertionPoint(unsigned Subsection) { + if (Subsection == 0 && SubsectionFragmentMap.empty()) + return end(); + + SmallVectorImpl<std::pair<unsigned, MCFragment *>>::iterator MI = + std::lower_bound(SubsectionFragmentMap.begin(), + SubsectionFragmentMap.end(), + std::make_pair(Subsection, (MCFragment *)nullptr)); + bool ExactMatch = false; + if (MI != SubsectionFragmentMap.end()) { + ExactMatch = MI->first == Subsection; + if (ExactMatch) + ++MI; + } + iterator IP; + if (MI == SubsectionFragmentMap.end()) + IP = end(); + else + IP = MI->second->getIterator(); + if (!ExactMatch && Subsection != 0) { + // The GNU as documentation claims that subsections have an alignment of 4, + // although this appears not to be the case. + MCFragment *F = new MCDataFragment(); + SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F)); + getFragmentList().insert(IP, F); + F->setParent(this); + } + + return IP; +} + +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void MCSection::dump() const { + raw_ostream &OS = errs(); + + OS << "<MCSection"; + OS << " Fragments:[\n "; + for (auto it = begin(), ie = end(); it != ie; ++it) { + if (it != begin()) + OS << ",\n "; + it->dump(); + } + OS << "]>"; +} +#endif |