diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-05-13 18:35:06 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-05-13 18:35:06 +0000 |
commit | 2c18d3b0fec25b2b7befc7ac5751e84005f4a869 (patch) | |
tree | b15dccdcb869b6e3d93d69ac60e91078609d38f7 /lib/MC/MCAssembler.cpp | |
parent | f1fd2288f36b58b8979761ba09e2a398c6afd110 (diff) |
MC: Factor out MCAssembler::ComputeFragmentSize.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103724 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 80 |
1 files changed, 44 insertions, 36 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index f41b25f15d..dfc2663650 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -375,52 +375,39 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, return IsResolved; } -void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { - uint64_t StartAddress = Layout.getSectionAddress(F.getParent()); - - // Get the fragment start address. - uint64_t Address = StartAddress; - MCSectionData::iterator it = &F; - if (MCFragment *Prev = F.getPrevNode()) - Address = (StartAddress + Layout.getFragmentOffset(Prev) + - Layout.getFragmentEffectiveSize(Prev)); - - ++stats::FragmentLayouts; - - uint64_t FragmentOffset = Address - StartAddress; - Layout.setFragmentOffset(&F, FragmentOffset); - - // Evaluate fragment size. - uint64_t EffectiveSize = 0; +uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout, + const MCFragment &F, + uint64_t SectionAddress, + uint64_t FragmentOffset) const { switch (F.getKind()) { + case MCFragment::FT_Data: + return cast<MCDataFragment>(F).getContents().size(); + case MCFragment::FT_Fill: + return cast<MCFillFragment>(F).getSize(); + case MCFragment::FT_Inst: + return cast<MCInstFragment>(F).getInstSize(); + case MCFragment::FT_Align: { - MCAlignFragment &AF = cast<MCAlignFragment>(F); + const MCAlignFragment &AF = cast<MCAlignFragment>(F); assert((!AF.hasOnlyAlignAddress() || !AF.getNextNode()) && "Invalid OnlyAlignAddress bit, not the last fragment!"); - EffectiveSize = OffsetToAlignment(Address, AF.getAlignment()); - if (EffectiveSize > AF.getMaxBytesToEmit()) - EffectiveSize = 0; - break; - } + uint64_t Size = OffsetToAlignment(SectionAddress + FragmentOffset, + AF.getAlignment()); - case MCFragment::FT_Data: - EffectiveSize = cast<MCDataFragment>(F).getContents().size(); - break; + // Honor MaxBytesToEmit. + if (Size > AF.getMaxBytesToEmit()) + return 0; - case MCFragment::FT_Fill: { - EffectiveSize = cast<MCFillFragment>(F).getSize(); - break; + return Size; } - case MCFragment::FT_Inst: - EffectiveSize = cast<MCInstFragment>(F).getInstSize(); - break; - case MCFragment::FT_Org: { - MCOrgFragment &OF = cast<MCOrgFragment>(F); + const MCOrgFragment &OF = cast<MCOrgFragment>(F); + // FIXME: We should compute this sooner, we don't want to recurse here, and + // we would like to be more functional. int64_t TargetLocation; if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) report_fatal_error("expected assembly-time absolute expression"); @@ -431,11 +418,32 @@ void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + "' (at offset '" + Twine(FragmentOffset) + "'"); - EffectiveSize = Offset; - break; + return Offset; } } + assert(0 && "invalid fragment kind"); + return 0; +} + +void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { + uint64_t StartAddress = Layout.getSectionAddress(F.getParent()); + + // Get the fragment start address. + uint64_t Address = StartAddress; + MCSectionData::iterator it = &F; + if (MCFragment *Prev = F.getPrevNode()) + Address = (StartAddress + Layout.getFragmentOffset(Prev) + + Layout.getFragmentEffectiveSize(Prev)); + + ++stats::FragmentLayouts; + + uint64_t FragmentOffset = Address - StartAddress; + Layout.setFragmentOffset(&F, FragmentOffset); + + // Evaluate fragment size. + uint64_t EffectiveSize = ComputeFragmentSize(Layout, F, StartAddress, + FragmentOffset); Layout.setFragmentEffectiveSize(&F, EffectiveSize); } |