From 2c18d3b0fec25b2b7befc7ac5751e84005f4a869 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 13 May 2010 18:35:06 +0000 Subject: [PATCH] MC: Factor out MCAssembler::ComputeFragmentSize. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103724 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAssembler.h | 6 +++ lib/MC/MCAssembler.cpp | 98 +++++++++++++++++++---------------- 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 095b1743ecb..6522b672d3e 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -650,6 +650,12 @@ private: bool FragmentNeedsRelaxation(const MCInstFragment *IF, const MCAsmLayout &Layout) const; + /// Compute the effective fragment size assuming it is layed out at the given + /// \arg SectionAddress and \arg FragmentOffset. + uint64_t ComputeFragmentSize(MCAsmLayout &Layout, const MCFragment &F, + uint64_t SectionAddress, + uint64_t FragmentOffset) const; + /// LayoutFragment - Performs layout of the given \arg Fragment; assuming that /// the previous fragment has already been layed out correctly, and the parent /// section has been initialized. diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index f41b25f15d3..dfc2663650e 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -375,6 +375,57 @@ bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, return IsResolved; } +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(F).getContents().size(); + case MCFragment::FT_Fill: + return cast(F).getSize(); + case MCFragment::FT_Inst: + return cast(F).getInstSize(); + + case MCFragment::FT_Align: { + const MCAlignFragment &AF = cast(F); + + assert((!AF.hasOnlyAlignAddress() || !AF.getNextNode()) && + "Invalid OnlyAlignAddress bit, not the last fragment!"); + + uint64_t Size = OffsetToAlignment(SectionAddress + FragmentOffset, + AF.getAlignment()); + + // Honor MaxBytesToEmit. + if (Size > AF.getMaxBytesToEmit()) + return 0; + + return Size; + } + + case MCFragment::FT_Org: { + const MCOrgFragment &OF = cast(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"); + + // FIXME: We need a way to communicate this error. + int64_t Offset = TargetLocation - FragmentOffset; + if (Offset < 0) + report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + + "' (at offset '" + Twine(FragmentOffset) + "'"); + + return Offset; + } + } + + assert(0 && "invalid fragment kind"); + return 0; +} + void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { uint64_t StartAddress = Layout.getSectionAddress(F.getParent()); @@ -391,51 +442,8 @@ void MCAssembler::LayoutFragment(MCAsmLayout &Layout, MCFragment &F) { Layout.setFragmentOffset(&F, FragmentOffset); // Evaluate fragment size. - uint64_t EffectiveSize = 0; - switch (F.getKind()) { - case MCFragment::FT_Align: { - MCAlignFragment &AF = cast(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; - } - - case MCFragment::FT_Data: - EffectiveSize = cast(F).getContents().size(); - break; - - case MCFragment::FT_Fill: { - EffectiveSize = cast(F).getSize(); - break; - } - - case MCFragment::FT_Inst: - EffectiveSize = cast(F).getInstSize(); - break; - - case MCFragment::FT_Org: { - MCOrgFragment &OF = cast(F); - - int64_t TargetLocation; - if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout)) - report_fatal_error("expected assembly-time absolute expression"); - - // FIXME: We need a way to communicate this error. - int64_t Offset = TargetLocation - FragmentOffset; - if (Offset < 0) - report_fatal_error("invalid .org offset '" + Twine(TargetLocation) + - "' (at offset '" + Twine(FragmentOffset) + "'"); - - EffectiveSize = Offset; - break; - } - } - + uint64_t EffectiveSize = ComputeFragmentSize(Layout, F, StartAddress, + FragmentOffset); Layout.setFragmentEffectiveSize(&F, EffectiveSize); }