blob: 38994e777ec92d1593475d157a5a0a7875154b22 [file] [log] [blame]
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +00001//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===//
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
Daniel Dunbar0adcd352009-08-25 21:10:45 +000010#define DEBUG_TYPE "assembler"
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +000011#include "llvm/MC/MCAssembler.h"
Daniel Dunbar18ff2cc2010-03-11 05:53:33 +000012#include "llvm/MC/MCAsmLayout.h"
Daniel Dunbarb36052f2010-03-19 10:43:23 +000013#include "llvm/MC/MCCodeEmitter.h"
Daniel Dunbar1253a6f2009-10-16 01:58:03 +000014#include "llvm/MC/MCExpr.h"
Daniel Dunbar53b23382010-03-19 09:28:59 +000015#include "llvm/MC/MCObjectWriter.h"
Daniel Dunbar1253a6f2009-10-16 01:58:03 +000016#include "llvm/MC/MCSymbol.h"
17#include "llvm/MC/MCValue.h"
Daniel Dunbar1a9158c2010-03-19 10:43:26 +000018#include "llvm/ADT/OwningPtr.h"
Daniel Dunbar0adcd352009-08-25 21:10:45 +000019#include "llvm/ADT/Statistic.h"
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +000020#include "llvm/ADT/StringExtras.h"
Daniel Dunbard6f761e2009-08-21 23:07:38 +000021#include "llvm/ADT/Twine.h"
Daniel Dunbarac2884a2010-03-25 22:49:09 +000022#include "llvm/Support/Debug.h"
Daniel Dunbar0705fbf2009-08-21 18:29:01 +000023#include "llvm/Support/ErrorHandling.h"
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +000024#include "llvm/Support/raw_ostream.h"
Daniel Dunbaree0d8922010-03-13 22:10:17 +000025#include "llvm/Target/TargetRegistry.h"
Daniel Dunbardf3c8f22010-03-12 21:00:49 +000026#include "llvm/Target/TargetAsmBackend.h"
Daniel Dunbarf6346762010-02-13 09:29:02 +000027
Chris Lattner23132b12009-08-24 03:52:50 +000028#include <vector>
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +000029using namespace llvm;
30
Daniel Dunbarff547842010-03-23 23:47:14 +000031namespace {
32namespace stats {
Daniel Dunbar0adcd352009-08-25 21:10:45 +000033STATISTIC(EmittedFragments, "Number of emitted assembler fragments");
Daniel Dunbarff547842010-03-23 23:47:14 +000034STATISTIC(EvaluateFixup, "Number of evaluated fixups");
Daniel Dunbarac2884a2010-03-25 22:49:09 +000035STATISTIC(FragmentLayouts, "Number of fragment layouts");
Daniel Dunbarff547842010-03-23 23:47:14 +000036STATISTIC(ObjectBytes, "Number of emitted object file bytes");
Daniel Dunbarac2884a2010-03-25 22:49:09 +000037STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
38STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
39STATISTIC(SectionLayouts, "Number of section layouts");
Daniel Dunbarff547842010-03-23 23:47:14 +000040}
41}
Daniel Dunbar0adcd352009-08-25 21:10:45 +000042
Daniel Dunbar8f4d1462009-08-28 07:08:35 +000043// FIXME FIXME FIXME: There are number of places in this file where we convert
44// what is a 64-bit assembler value used for computation into a value in the
45// object file, which may truncate it. We should detect that truncation where
46// invalid and report errors back.
47
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +000048/* *** */
49
Daniel Dunbarbc1a0cf2010-05-12 15:42:59 +000050MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
51 // Compute the section layout order. Virtual sections must go last.
52 for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
53 if (!Asm.getBackend().isVirtualSection(it->getSection()))
54 SectionOrder.push_back(&*it);
55 for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
56 if (Asm.getBackend().isVirtualSection(it->getSection()))
57 SectionOrder.push_back(&*it);
58}
59
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +000060void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) {
61 // We shouldn't have to do anything special to support negative slides, and it
Daniel Dunbar651804c2010-05-11 17:22:50 +000062 // is a perfectly valid thing to do as long as other parts of the system can
63 // guarantee convergence.
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +000064 assert(SlideAmount >= 0 && "Negative slides not yet supported");
65
66 // Update the layout by simply recomputing the layout for the entire
67 // file. This is trivially correct, but very slow.
68 //
69 // FIXME-PERF: This is O(N^2), but will be eliminated once we get smarter.
70
Daniel Dunbard13a0ca2010-05-12 17:56:47 +000071 // Layout the sections in order.
Daniel Dunbarb69fc042010-05-13 20:40:12 +000072 LayoutFile();
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +000073}
74
Daniel Dunbaraa0d3502010-05-13 08:43:31 +000075void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) {
76 Dst->Offset = Src->Offset;
77 Dst->EffectiveSize = Src->EffectiveSize;
78}
79
Daniel Dunbar207e06e2010-03-24 03:43:40 +000080uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const {
Daniel Dunbar7c3d45a2010-03-25 01:03:24 +000081 assert(F->getParent() && "Missing section()!");
Daniel Dunbar432cd5f2010-03-25 02:00:02 +000082 return getSectionAddress(F->getParent()) + getFragmentOffset(F);
83}
84
85uint64_t MCAsmLayout::getFragmentEffectiveSize(const MCFragment *F) const {
86 assert(F->EffectiveSize != ~UINT64_C(0) && "Address not set!");
87 return F->EffectiveSize;
88}
89
90void MCAsmLayout::setFragmentEffectiveSize(MCFragment *F, uint64_t Value) {
91 F->EffectiveSize = Value;
92}
93
94uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
95 assert(F->Offset != ~UINT64_C(0) && "Address not set!");
96 return F->Offset;
97}
98
99void MCAsmLayout::setFragmentOffset(MCFragment *F, uint64_t Value) {
100 F->Offset = Value;
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000101}
102
103uint64_t MCAsmLayout::getSymbolAddress(const MCSymbolData *SD) const {
Daniel Dunbar7c3d45a2010-03-25 01:03:24 +0000104 assert(SD->getFragment() && "Invalid getAddress() on undefined symbol!");
105 return getFragmentAddress(SD->getFragment()) + SD->getOffset();
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000106}
107
108uint64_t MCAsmLayout::getSectionAddress(const MCSectionData *SD) const {
Daniel Dunbar7c3d45a2010-03-25 01:03:24 +0000109 assert(SD->Address != ~UINT64_C(0) && "Address not set!");
110 return SD->Address;
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000111}
112
113void MCAsmLayout::setSectionAddress(MCSectionData *SD, uint64_t Value) {
Daniel Dunbar7c3d45a2010-03-25 01:03:24 +0000114 SD->Address = Value;
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000115}
116
Daniel Dunbar2661f112010-05-13 03:19:50 +0000117uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
Daniel Dunbar2661f112010-05-13 03:19:50 +0000118 // Otherwise, the size is the last fragment's end offset.
119 const MCFragment &F = SD->getFragmentList().back();
120 return getFragmentOffset(&F) + getFragmentEffectiveSize(&F);
Daniel Dunbar5d428512010-03-25 02:00:07 +0000121}
122
123uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
Daniel Dunbar2661f112010-05-13 03:19:50 +0000124 // Virtual sections have no file size.
125 if (getAssembler().getBackend().isVirtualSection(SD->getSection()))
126 return 0;
127
128 // Otherwise, the file size is the same as the address space size.
129 return getSectionAddressSize(SD);
Daniel Dunbar5d428512010-03-25 02:00:07 +0000130}
131
Daniel Dunbar2661f112010-05-13 03:19:50 +0000132uint64_t MCAsmLayout::getSectionSize(const MCSectionData *SD) const {
Daniel Dunbar2661f112010-05-13 03:19:50 +0000133 // The logical size is the address space size minus any tail padding.
134 uint64_t Size = getSectionAddressSize(SD);
135 const MCAlignFragment *AF =
136 dyn_cast<MCAlignFragment>(&(SD->getFragmentList().back()));
137 if (AF && AF->hasOnlyAlignAddress())
138 Size -= getFragmentEffectiveSize(AF);
139
140 return Size;
Daniel Dunbarb5844ff2010-05-13 01:10:22 +0000141}
142
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000143/* *** */
144
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000145MCFragment::MCFragment() : Kind(FragmentType(~0)) {
146}
147
Daniel Dunbar5e835962009-08-26 02:48:04 +0000148MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
Daniel Dunbar071f73d2010-05-10 22:45:09 +0000149 : Kind(_Kind), Parent(_Parent), Atom(0), EffectiveSize(~UINT64_C(0))
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000150{
Daniel Dunbar5e835962009-08-26 02:48:04 +0000151 if (Parent)
152 Parent->getFragmentList().push_back(this);
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000153}
154
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000155MCFragment::~MCFragment() {
156}
157
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000158/* *** */
159
Daniel Dunbar81e40002009-08-27 00:38:04 +0000160MCSectionData::MCSectionData() : Section(0) {}
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000161
162MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
Daniel Dunbar81e40002009-08-27 00:38:04 +0000163 : Section(&_Section),
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000164 Alignment(1),
Daniel Dunbar5e835962009-08-26 02:48:04 +0000165 Address(~UINT64_C(0)),
Daniel Dunbare1ec6172010-02-02 21:44:01 +0000166 HasInstructions(false)
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000167{
168 if (A)
169 A->getSectionList().push_back(this);
170}
171
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000172/* *** */
173
Daniel Dunbarefbb5332009-09-01 04:09:03 +0000174MCSymbolData::MCSymbolData() : Symbol(0) {}
Daniel Dunbarf3d2ef02009-08-22 10:13:24 +0000175
Daniel Dunbarcb579b32009-08-31 08:08:06 +0000176MCSymbolData::MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment,
Daniel Dunbarf3d2ef02009-08-22 10:13:24 +0000177 uint64_t _Offset, MCAssembler *A)
Daniel Dunbarefbb5332009-09-01 04:09:03 +0000178 : Symbol(&_Symbol), Fragment(_Fragment), Offset(_Offset),
Daniel Dunbar8f4d1462009-08-28 07:08:35 +0000179 IsExternal(false), IsPrivateExtern(false),
180 CommonSize(0), CommonAlign(0), Flags(0), Index(0)
Daniel Dunbarf3d2ef02009-08-22 10:13:24 +0000181{
182 if (A)
183 A->getSymbolList().push_back(this);
184}
185
186/* *** */
187
Daniel Dunbar1f3e4452010-03-11 01:34:27 +0000188MCAssembler::MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend,
Daniel Dunbarcf871e52010-03-19 10:43:18 +0000189 MCCodeEmitter &_Emitter, raw_ostream &_OS)
190 : Context(_Context), Backend(_Backend), Emitter(_Emitter),
Daniel Dunbarac2884a2010-03-25 22:49:09 +0000191 OS(_OS), RelaxAll(false), SubsectionsViaSymbols(false)
Daniel Dunbar6009db42009-08-26 21:22:22 +0000192{
193}
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000194
195MCAssembler::~MCAssembler() {
196}
197
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000198static bool isScatteredFixupFullyResolvedSimple(const MCAssembler &Asm,
199 const MCAsmFixup &Fixup,
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000200 const MCValue Target,
201 const MCSection *BaseSection) {
202 // The effective fixup address is
203 // addr(atom(A)) + offset(A)
204 // - addr(atom(B)) - offset(B)
205 // - addr(<base symbol>) + <fixup offset from base symbol>
206 // and the offsets are not relocatable, so the fixup is fully resolved when
207 // addr(atom(A)) - addr(atom(B)) - addr(<base symbol>)) == 0.
208 //
209 // The simple (Darwin, except on x86_64) way of dealing with this was to
210 // assume that any reference to a temporary symbol *must* be a temporary
211 // symbol in the same atom, unless the sections differ. Therefore, any PCrel
212 // relocation to a temporary symbol (in the same section) is fully
213 // resolved. This also works in conjunction with absolutized .set, which
214 // requires the compiler to use .set to absolutize the differences between
215 // symbols which the compiler knows to be assembly time constants, so we don't
Daniel Dunbar31e8e1d2010-05-04 00:33:07 +0000216 // need to worry about considering symbol differences fully resolved.
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000217
218 // Non-relative fixups are only resolved if constant.
219 if (!BaseSection)
220 return Target.isAbsolute();
221
222 // Otherwise, relative fixups are only resolved if not a difference and the
223 // target is a temporary in the same section.
224 if (Target.isAbsolute() || Target.getSymB())
225 return false;
226
227 const MCSymbol *A = &Target.getSymA()->getSymbol();
228 if (!A->isTemporary() || !A->isInSection() ||
229 &A->getSection() != BaseSection)
230 return false;
231
232 return true;
233}
234
Daniel Dunbar034843a2010-03-19 03:18:18 +0000235static bool isScatteredFixupFullyResolved(const MCAssembler &Asm,
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000236 const MCAsmLayout &Layout,
Daniel Dunbar034843a2010-03-19 03:18:18 +0000237 const MCAsmFixup &Fixup,
Daniel Dunbar034843a2010-03-19 03:18:18 +0000238 const MCValue Target,
239 const MCSymbolData *BaseSymbol) {
240 // The effective fixup address is
241 // addr(atom(A)) + offset(A)
242 // - addr(atom(B)) - offset(B)
243 // - addr(BaseSymbol) + <fixup offset from base symbol>
244 // and the offsets are not relocatable, so the fixup is fully resolved when
245 // addr(atom(A)) - addr(atom(B)) - addr(BaseSymbol) == 0.
246 //
247 // Note that "false" is almost always conservatively correct (it means we emit
248 // a relocation which is unnecessary), except when it would force us to emit a
249 // relocation which the target cannot encode.
250
251 const MCSymbolData *A_Base = 0, *B_Base = 0;
252 if (const MCSymbolRefExpr *A = Target.getSymA()) {
253 // Modified symbol references cannot be resolved.
254 if (A->getKind() != MCSymbolRefExpr::VK_None)
255 return false;
256
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000257 A_Base = Asm.getAtom(Layout, &Asm.getSymbolData(A->getSymbol()));
Daniel Dunbar034843a2010-03-19 03:18:18 +0000258 if (!A_Base)
259 return false;
260 }
261
262 if (const MCSymbolRefExpr *B = Target.getSymB()) {
263 // Modified symbol references cannot be resolved.
264 if (B->getKind() != MCSymbolRefExpr::VK_None)
265 return false;
266
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000267 B_Base = Asm.getAtom(Layout, &Asm.getSymbolData(B->getSymbol()));
Daniel Dunbar034843a2010-03-19 03:18:18 +0000268 if (!B_Base)
269 return false;
270 }
271
272 // If there is no base, A and B have to be the same atom for this fixup to be
273 // fully resolved.
274 if (!BaseSymbol)
275 return A_Base == B_Base;
276
277 // Otherwise, B must be missing and A must be the base.
278 return !B_Base && BaseSymbol == A_Base;
279}
280
Daniel Dunbar23869852010-03-19 03:18:09 +0000281bool MCAssembler::isSymbolLinkerVisible(const MCSymbolData *SD) const {
282 // Non-temporary labels should always be visible to the linker.
283 if (!SD->getSymbol().isTemporary())
284 return true;
285
286 // Absolute temporary labels are never visible.
287 if (!SD->getFragment())
288 return false;
289
290 // Otherwise, check if the section requires symbols even for temporary labels.
291 return getBackend().doesSectionRequireSymbols(
292 SD->getFragment()->getParent()->getSection());
293}
294
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000295const MCSymbolData *MCAssembler::getAtom(const MCAsmLayout &Layout,
296 const MCSymbolData *SD) const {
Daniel Dunbar8ad0dcc2010-03-19 03:18:15 +0000297 // Linker visible symbols define atoms.
298 if (isSymbolLinkerVisible(SD))
299 return SD;
300
301 // Absolute and undefined symbols have no defining atom.
302 if (!SD->getFragment())
303 return 0;
304
Daniel Dunbara5f1d572010-05-12 00:38:17 +0000305 // Non-linker visible symbols in sections which can't be atomized have no
306 // defining atom.
307 if (!getBackend().isSectionAtomizable(
308 SD->getFragment()->getParent()->getSection()))
309 return 0;
310
Daniel Dunbar651804c2010-05-11 17:22:50 +0000311 // Otherwise, return the atom for the containing fragment.
312 return SD->getFragment()->getAtom();
Daniel Dunbar8ad0dcc2010-03-19 03:18:15 +0000313}
314
Daniel Dunbar9d39e612010-03-22 21:49:41 +0000315bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout,
316 const MCAsmFixup &Fixup, const MCFragment *DF,
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000317 MCValue &Target, uint64_t &Value) const {
Daniel Dunbarff547842010-03-23 23:47:14 +0000318 ++stats::EvaluateFixup;
319
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000320 if (!Fixup.Value->EvaluateAsRelocatable(Target, &Layout))
Chris Lattner75361b62010-04-07 22:58:41 +0000321 report_fatal_error("expected relocatable expression");
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000322
323 // FIXME: How do non-scattered symbols work in ELF? I presume the linker
324 // doesn't support small relocations, but then under what criteria does the
325 // assembler allow symbol differences?
326
327 Value = Target.getConstant();
328
Daniel Dunbarb36052f2010-03-19 10:43:23 +0000329 bool IsPCRel =
330 Emitter.getFixupKindInfo(Fixup.Kind).Flags & MCFixupKindInfo::FKF_IsPCRel;
331 bool IsResolved = true;
Daniel Dunbar9a1d2002010-03-18 00:59:10 +0000332 if (const MCSymbolRefExpr *A = Target.getSymA()) {
333 if (A->getSymbol().isDefined())
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000334 Value += Layout.getSymbolAddress(&getSymbolData(A->getSymbol()));
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000335 else
336 IsResolved = false;
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000337 }
Daniel Dunbar9a1d2002010-03-18 00:59:10 +0000338 if (const MCSymbolRefExpr *B = Target.getSymB()) {
339 if (B->getSymbol().isDefined())
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000340 Value -= Layout.getSymbolAddress(&getSymbolData(B->getSymbol()));
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000341 else
342 IsResolved = false;
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000343 }
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000344
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000345 // If we are using scattered symbols, determine whether this value is actually
346 // resolved; scattering may cause atoms to move.
347 if (IsResolved && getBackend().hasScatteredSymbols()) {
348 if (getBackend().hasReliableSymbolDifference()) {
Daniel Dunbar034843a2010-03-19 03:18:18 +0000349 // If this is a PCrel relocation, find the base atom (identified by its
350 // symbol) that the fixup value is relative to.
351 const MCSymbolData *BaseSymbol = 0;
352 if (IsPCRel) {
Daniel Dunbar651804c2010-05-11 17:22:50 +0000353 BaseSymbol = DF->getAtom();
Daniel Dunbar034843a2010-03-19 03:18:18 +0000354 if (!BaseSymbol)
355 IsResolved = false;
356 }
357
358 if (IsResolved)
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000359 IsResolved = isScatteredFixupFullyResolved(*this, Layout, Fixup, Target,
Daniel Dunbar034843a2010-03-19 03:18:18 +0000360 BaseSymbol);
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000361 } else {
362 const MCSection *BaseSection = 0;
363 if (IsPCRel)
364 BaseSection = &DF->getParent()->getSection();
365
Daniel Dunbarc6f59822010-03-22 21:49:38 +0000366 IsResolved = isScatteredFixupFullyResolvedSimple(*this, Fixup, Target,
Daniel Dunbar939f8d72010-03-19 03:18:12 +0000367 BaseSection);
368 }
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000369 }
370
371 if (IsPCRel)
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000372 Value -= Layout.getFragmentAddress(DF) + Fixup.Offset;
Daniel Dunbardf3c8f22010-03-12 21:00:49 +0000373
374 return IsResolved;
375}
376
Daniel Dunbar2c18d3b2010-05-13 18:35:06 +0000377uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout,
378 const MCFragment &F,
379 uint64_t SectionAddress,
380 uint64_t FragmentOffset) const {
381 switch (F.getKind()) {
382 case MCFragment::FT_Data:
383 return cast<MCDataFragment>(F).getContents().size();
384 case MCFragment::FT_Fill:
385 return cast<MCFillFragment>(F).getSize();
386 case MCFragment::FT_Inst:
387 return cast<MCInstFragment>(F).getInstSize();
388
389 case MCFragment::FT_Align: {
390 const MCAlignFragment &AF = cast<MCAlignFragment>(F);
391
392 assert((!AF.hasOnlyAlignAddress() || !AF.getNextNode()) &&
393 "Invalid OnlyAlignAddress bit, not the last fragment!");
394
395 uint64_t Size = OffsetToAlignment(SectionAddress + FragmentOffset,
396 AF.getAlignment());
397
398 // Honor MaxBytesToEmit.
399 if (Size > AF.getMaxBytesToEmit())
400 return 0;
401
402 return Size;
403 }
404
405 case MCFragment::FT_Org: {
406 const MCOrgFragment &OF = cast<MCOrgFragment>(F);
407
408 // FIXME: We should compute this sooner, we don't want to recurse here, and
409 // we would like to be more functional.
410 int64_t TargetLocation;
411 if (!OF.getOffset().EvaluateAsAbsolute(TargetLocation, &Layout))
412 report_fatal_error("expected assembly-time absolute expression");
413
414 // FIXME: We need a way to communicate this error.
415 int64_t Offset = TargetLocation - FragmentOffset;
416 if (Offset < 0)
417 report_fatal_error("invalid .org offset '" + Twine(TargetLocation) +
418 "' (at offset '" + Twine(FragmentOffset) + "'");
419
420 return Offset;
421 }
422 }
423
424 assert(0 && "invalid fragment kind");
425 return 0;
426}
427
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000428void MCAsmLayout::LayoutFile() {
429 for (unsigned i = 0, e = getSectionOrder().size(); i != e; ++i)
430 LayoutSection(getSectionOrder()[i]);
431}
432
433void MCAsmLayout::LayoutFragment(MCFragment *F) {
434 uint64_t StartAddress = getSectionAddress(F->getParent());
Daniel Dunbarf0d17d22010-05-12 21:35:25 +0000435
436 // Get the fragment start address.
437 uint64_t Address = StartAddress;
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000438 MCSectionData::iterator it = F;
439 if (MCFragment *Prev = F->getPrevNode())
440 Address = (StartAddress + getFragmentOffset(Prev) +
441 getFragmentEffectiveSize(Prev));
Daniel Dunbarf0d17d22010-05-12 21:35:25 +0000442
443 ++stats::FragmentLayouts;
444
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000445 // Compute fragment offset and size.
446 uint64_t Offset = Address - StartAddress;
447 uint64_t EffectiveSize =
448 getAssembler().ComputeFragmentSize(*this, *F, StartAddress, Offset);
Daniel Dunbarf0d17d22010-05-12 21:35:25 +0000449
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000450 setFragmentOffset(F, Offset);
451 setFragmentEffectiveSize(F, EffectiveSize);
Daniel Dunbarf0d17d22010-05-12 21:35:25 +0000452}
453
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000454void MCAsmLayout::LayoutSection(MCSectionData *SD) {
455 unsigned SectionOrderIndex = SD->getLayoutOrder();
Daniel Dunbarf476b002010-03-25 18:16:42 +0000456
Daniel Dunbarac2884a2010-03-25 22:49:09 +0000457 ++stats::SectionLayouts;
458
Daniel Dunbar61066db2010-05-13 02:34:14 +0000459 // Compute the section start address.
Daniel Dunbard13a0ca2010-05-12 17:56:47 +0000460 uint64_t StartAddress = 0;
461 if (SectionOrderIndex) {
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000462 MCSectionData *Prev = getSectionOrder()[SectionOrderIndex - 1];
463 StartAddress = getSectionAddress(Prev) + getSectionAddressSize(Prev);
Daniel Dunbard13a0ca2010-05-12 17:56:47 +0000464 }
465
Daniel Dunbar61066db2010-05-13 02:34:14 +0000466 // Honor the section alignment requirements.
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000467 StartAddress = RoundUpToAlignment(StartAddress, SD->getAlignment());
Daniel Dunbarf476b002010-03-25 18:16:42 +0000468
Daniel Dunbar61066db2010-05-13 02:34:14 +0000469 // Set the section address.
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000470 setSectionAddress(SD, StartAddress);
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000471
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000472 for (MCSectionData::iterator it = SD->begin(), ie = SD->end(); it != ie; ++it)
473 LayoutFragment(it);
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000474}
475
Daniel Dunbar53b23382010-03-19 09:28:59 +0000476/// WriteFragmentData - Write the \arg F data to the output file.
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000477static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
478 const MCFragment &F, MCObjectWriter *OW) {
Daniel Dunbar53b23382010-03-19 09:28:59 +0000479 uint64_t Start = OW->getStream().tell();
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000480 (void) Start;
Daniel Dunbar7eb85192009-10-16 01:58:15 +0000481
Daniel Dunbarff547842010-03-23 23:47:14 +0000482 ++stats::EmittedFragments;
Daniel Dunbar0adcd352009-08-25 21:10:45 +0000483
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000484 // FIXME: Embed in fragments instead?
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000485 uint64_t FragmentSize = Layout.getFragmentEffectiveSize(&F);
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000486 switch (F.getKind()) {
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000487 case MCFragment::FT_Align: {
488 MCAlignFragment &AF = cast<MCAlignFragment>(F);
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000489 uint64_t Count = FragmentSize / AF.getValueSize();
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000490
Daniel Dunbare73d49e2010-05-12 22:51:27 +0000491 assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");
492
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000493 // FIXME: This error shouldn't actually occur (the front end should emit
494 // multiple .align directives to enforce the semantics it wants), but is
495 // severe enough that we want to report it. How to handle this?
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000496 if (Count * AF.getValueSize() != FragmentSize)
Chris Lattner75361b62010-04-07 22:58:41 +0000497 report_fatal_error("undefined .align directive, value size '" +
Daniel Dunbar7eb85192009-10-16 01:58:15 +0000498 Twine(AF.getValueSize()) +
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000499 "' is not a divisor of padding size '" +
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000500 Twine(FragmentSize) + "'");
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000501
Kevin Enderby6e720482010-02-23 18:26:34 +0000502 // See if we are aligning with nops, and if so do that first to try to fill
503 // the Count bytes. Then if that did not fill any bytes or there are any
504 // bytes left to fill use the the Value and ValueSize to fill the rest.
Daniel Dunbar8f9b80e2010-03-23 02:36:58 +0000505 // If we are aligning with nops, ask that target to emit the right data.
Daniel Dunbar1c154132010-05-12 22:56:23 +0000506 if (AF.hasEmitNops()) {
Daniel Dunbar8f9b80e2010-03-23 02:36:58 +0000507 if (!Asm.getBackend().WriteNopData(Count, OW))
Chris Lattner75361b62010-04-07 22:58:41 +0000508 report_fatal_error("unable to write nop sequence of " +
Daniel Dunbar8f9b80e2010-03-23 02:36:58 +0000509 Twine(Count) + " bytes");
510 break;
Kevin Enderby6e720482010-02-23 18:26:34 +0000511 }
512
Daniel Dunbar8f9b80e2010-03-23 02:36:58 +0000513 // Otherwise, write out in multiples of the value size.
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000514 for (uint64_t i = 0; i != Count; ++i) {
515 switch (AF.getValueSize()) {
516 default:
517 assert(0 && "Invalid size!");
Daniel Dunbarbdd92812010-03-19 09:28:55 +0000518 case 1: OW->Write8 (uint8_t (AF.getValue())); break;
519 case 2: OW->Write16(uint16_t(AF.getValue())); break;
520 case 4: OW->Write32(uint32_t(AF.getValue())); break;
521 case 8: OW->Write64(uint64_t(AF.getValue())); break;
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000522 }
523 }
524 break;
525 }
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000526
Daniel Dunbar3a30b822010-02-13 09:28:15 +0000527 case MCFragment::FT_Data: {
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000528 MCDataFragment &DF = cast<MCDataFragment>(F);
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000529 assert(FragmentSize == DF.getContents().size() && "Invalid size!");
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000530 OW->WriteBytes(DF.getContents().str());
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000531 break;
Daniel Dunbar3a30b822010-02-13 09:28:15 +0000532 }
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000533
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000534 case MCFragment::FT_Fill: {
535 MCFillFragment &FF = cast<MCFillFragment>(F);
Daniel Dunbare2fee5b2010-05-12 22:51:35 +0000536
537 assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!");
538
Daniel Dunbar3153fec2010-05-12 22:51:32 +0000539 for (uint64_t i = 0, e = FF.getSize() / FF.getValueSize(); i != e; ++i) {
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000540 switch (FF.getValueSize()) {
541 default:
542 assert(0 && "Invalid size!");
Daniel Dunbarbdd92812010-03-19 09:28:55 +0000543 case 1: OW->Write8 (uint8_t (FF.getValue())); break;
544 case 2: OW->Write16(uint16_t(FF.getValue())); break;
545 case 4: OW->Write32(uint32_t(FF.getValue())); break;
546 case 8: OW->Write64(uint64_t(FF.getValue())); break;
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000547 }
548 }
549 break;
550 }
Daniel Dunbar7eb85192009-10-16 01:58:15 +0000551
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000552 case MCFragment::FT_Inst:
553 llvm_unreachable("unexpected inst fragment after lowering");
554 break;
555
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000556 case MCFragment::FT_Org: {
557 MCOrgFragment &OF = cast<MCOrgFragment>(F);
558
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000559 for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
Daniel Dunbarbdd92812010-03-19 09:28:55 +0000560 OW->Write8(uint8_t(OF.getValue()));
Daniel Dunbard6f761e2009-08-21 23:07:38 +0000561
562 break;
563 }
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000564 }
565
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000566 assert(OW->getStream().tell() - Start == FragmentSize);
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000567}
568
Daniel Dunbar53b23382010-03-19 09:28:59 +0000569void MCAssembler::WriteSectionData(const MCSectionData *SD,
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000570 const MCAsmLayout &Layout,
Daniel Dunbar53b23382010-03-19 09:28:59 +0000571 MCObjectWriter *OW) const {
Daniel Dunbard5a8e982009-08-28 05:49:21 +0000572 // Ignore virtual sections.
Daniel Dunbarcc5b84c2010-03-19 09:29:03 +0000573 if (getBackend().isVirtualSection(SD->getSection())) {
Daniel Dunbar054be922010-05-13 03:50:50 +0000574 assert(Layout.getSectionFileSize(SD) == 0 && "Invalid size for section!");
Daniel Dunbare2fee5b2010-05-12 22:51:35 +0000575
576 // Check that contents are only things legal inside a virtual section.
577 for (MCSectionData::const_iterator it = SD->begin(),
578 ie = SD->end(); it != ie; ++it) {
579 switch (it->getKind()) {
580 default:
581 assert(0 && "Invalid fragment in virtual section!");
582 case MCFragment::FT_Align:
583 assert(!cast<MCAlignFragment>(it)->getValueSize() &&
584 "Invalid align in virtual section!");
585 break;
586 case MCFragment::FT_Fill:
587 assert(!cast<MCFillFragment>(it)->getValueSize() &&
588 "Invalid fill in virtual section!");
589 break;
Daniel Dunbare2fee5b2010-05-12 22:51:35 +0000590 }
591 }
592
Daniel Dunbard5a8e982009-08-28 05:49:21 +0000593 return;
594 }
595
Daniel Dunbar53b23382010-03-19 09:28:59 +0000596 uint64_t Start = OW->getStream().tell();
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000597 (void) Start;
Daniel Dunbar7eb85192009-10-16 01:58:15 +0000598
Daniel Dunbar53b23382010-03-19 09:28:59 +0000599 for (MCSectionData::const_iterator it = SD->begin(),
600 ie = SD->end(); it != ie; ++it)
Daniel Dunbar432cd5f2010-03-25 02:00:02 +0000601 WriteFragmentData(*this, Layout, *it, OW);
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000602
Daniel Dunbar054be922010-05-13 03:50:50 +0000603 assert(OW->getStream().tell() - Start == Layout.getSectionFileSize(SD));
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000604}
605
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000606void MCAssembler::Finish() {
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000607 DEBUG_WITH_TYPE("mc-dump", {
608 llvm::errs() << "assembler backend - pre-layout\n--\n";
609 dump(); });
610
Daniel Dunbar61066db2010-05-13 02:34:14 +0000611 // Create the layout object.
Daniel Dunbar8d39eb42010-03-22 20:35:35 +0000612 MCAsmLayout Layout(*this);
Daniel Dunbar61066db2010-05-13 02:34:14 +0000613
Daniel Dunbarf60c7362010-05-13 15:17:26 +0000614 // Assign layout order indices.
615 for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i)
616 Layout.getSectionOrder()[i]->setLayoutOrder(i);
617
Daniel Dunbar61066db2010-05-13 02:34:14 +0000618 // Insert additional align fragments for concrete sections to explicitly pad
619 // the previous section to match their alignment requirements. This is for
620 // 'gas' compatibility, it shouldn't strictly be necessary.
621 //
622 // FIXME: This may be Mach-O specific.
623 for (unsigned i = 1, e = Layout.getSectionOrder().size(); i < e; ++i) {
624 MCSectionData *SD = Layout.getSectionOrder()[i];
625
626 // Ignore sections without alignment requirements.
627 unsigned Align = SD->getAlignment();
628 if (Align <= 1)
629 continue;
630
631 // Ignore virtual sections, they don't cause file size modifications.
632 if (getBackend().isVirtualSection(SD->getSection()))
633 continue;
634
635 // Otherwise, create a new align fragment at the end of the previous
636 // section.
637 MCAlignFragment *AF = new MCAlignFragment(Align, 0, 1, Align,
638 Layout.getSectionOrder()[i - 1]);
639 AF->setOnlyAlignAddress(true);
640 }
641
Daniel Dunbar49ed9212010-05-13 08:43:37 +0000642 // Assign section and fragment ordinals, all subsequent backend code is
643 // responsible for updating these in place.
644 unsigned SectionIndex = 0;
645 unsigned FragmentIndex = 0;
646 for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
647 // Create dummy fragments to eliminate any empty sections, this simplifies
648 // layout.
649 if (it->getFragmentList().empty()) {
650 unsigned ValueSize = 1;
651 if (getBackend().isVirtualSection(it->getSection()))
652 ValueSize = 1;
653 new MCFillFragment(0, 1, 0, it);
654 }
655
656 it->setOrdinal(SectionIndex++);
657
658 for (MCSectionData::iterator it2 = it->begin(),
659 ie2 = it->end(); it2 != ie2; ++it2)
660 it2->setOrdinal(FragmentIndex++);
661 }
662
Daniel Dunbar61066db2010-05-13 02:34:14 +0000663 // Layout until everything fits.
Daniel Dunbar8d39eb42010-03-22 20:35:35 +0000664 while (LayoutOnce(Layout))
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000665 continue;
666
667 DEBUG_WITH_TYPE("mc-dump", {
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000668 llvm::errs() << "assembler backend - post-relaxation\n--\n";
669 dump(); });
670
671 // Finalize the layout, including fragment lowering.
672 FinishLayout(Layout);
673
674 DEBUG_WITH_TYPE("mc-dump", {
675 llvm::errs() << "assembler backend - final-layout\n--\n";
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000676 dump(); });
677
Daniel Dunbarff547842010-03-23 23:47:14 +0000678 uint64_t StartOffset = OS.tell();
Daniel Dunbar1a9158c2010-03-19 10:43:26 +0000679 llvm::OwningPtr<MCObjectWriter> Writer(getBackend().createObjectWriter(OS));
680 if (!Writer)
Chris Lattner75361b62010-04-07 22:58:41 +0000681 report_fatal_error("unable to create object writer!");
Daniel Dunbarbacba992010-03-19 07:09:33 +0000682
683 // Allow the object writer a chance to perform post-layout binding (for
684 // example, to set the index fields in the symbol data).
Daniel Dunbar1a9158c2010-03-19 10:43:26 +0000685 Writer->ExecutePostLayoutBinding(*this);
Daniel Dunbarbacba992010-03-19 07:09:33 +0000686
Daniel Dunbarb1e98942010-03-19 07:09:47 +0000687 // Evaluate and apply the fixups, generating relocation entries as necessary.
Daniel Dunbarb1e98942010-03-19 07:09:47 +0000688 for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
689 for (MCSectionData::iterator it2 = it->begin(),
690 ie2 = it->end(); it2 != ie2; ++it2) {
691 MCDataFragment *DF = dyn_cast<MCDataFragment>(it2);
692 if (!DF)
693 continue;
694
695 for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(),
696 ie3 = DF->fixup_end(); it3 != ie3; ++it3) {
697 MCAsmFixup &Fixup = *it3;
698
699 // Evaluate the fixup.
700 MCValue Target;
701 uint64_t FixedValue;
702 if (!EvaluateFixup(Layout, Fixup, DF, Target, FixedValue)) {
703 // The fixup was unresolved, we need a relocation. Inform the object
704 // writer of the relocation, and give it an opportunity to adjust the
705 // fixup value if need be.
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000706 Writer->RecordRelocation(*this, Layout, DF, Fixup, Target,FixedValue);
Daniel Dunbarb1e98942010-03-19 07:09:47 +0000707 }
708
Daniel Dunbar87190c42010-03-19 09:28:12 +0000709 getBackend().ApplyFixup(Fixup, *DF, FixedValue);
Daniel Dunbarb1e98942010-03-19 07:09:47 +0000710 }
711 }
712 }
713
Daniel Dunbarbacba992010-03-19 07:09:33 +0000714 // Write the object file.
Daniel Dunbar207e06e2010-03-24 03:43:40 +0000715 Writer->WriteObject(*this, Layout);
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000716 OS.flush();
Daniel Dunbarff547842010-03-23 23:47:14 +0000717
718 stats::ObjectBytes += OS.tell() - StartOffset;
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000719}
720
Daniel Dunbar9d39e612010-03-22 21:49:41 +0000721bool MCAssembler::FixupNeedsRelaxation(const MCAsmFixup &Fixup,
722 const MCFragment *DF,
Daniel Dunbar8d39eb42010-03-22 20:35:35 +0000723 const MCAsmLayout &Layout) const {
Daniel Dunbarac2884a2010-03-25 22:49:09 +0000724 if (getRelaxAll())
725 return true;
726
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000727 // If we cannot resolve the fixup value, it requires relaxation.
728 MCValue Target;
729 uint64_t Value;
730 if (!EvaluateFixup(Layout, Fixup, DF, Target, Value))
731 return true;
732
733 // Otherwise, relax if the value is too big for a (signed) i8.
Daniel Dunbar31e8e1d2010-05-04 00:33:07 +0000734 //
735 // FIXME: This is target dependent!
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000736 return int64_t(Value) != int64_t(int8_t(Value));
737}
738
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000739bool MCAssembler::FragmentNeedsRelaxation(const MCInstFragment *IF,
740 const MCAsmLayout &Layout) const {
741 // If this inst doesn't ever need relaxation, ignore it. This occurs when we
742 // are intentionally pushing out inst fragments, or because we relaxed a
743 // previous instruction to one that doesn't need relaxation.
744 if (!getBackend().MayNeedRelaxation(IF->getInst(), IF->getFixups()))
745 return false;
746
747 for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(),
748 ie = IF->fixup_end(); it != ie; ++it)
749 if (FixupNeedsRelaxation(*it, IF, Layout))
750 return true;
751
752 return false;
753}
754
Daniel Dunbar8d39eb42010-03-22 20:35:35 +0000755bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
Daniel Dunbarff547842010-03-23 23:47:14 +0000756 ++stats::RelaxationSteps;
757
Daniel Dunbard13a0ca2010-05-12 17:56:47 +0000758 // Layout the sections in order.
Daniel Dunbarb69fc042010-05-13 20:40:12 +0000759 Layout.LayoutFile();
Daniel Dunbard5a8e982009-08-28 05:49:21 +0000760
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000761 // Scan for fragments that need relaxation.
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +0000762 bool WasRelaxed = false;
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000763 for (iterator it = begin(), ie = end(); it != ie; ++it) {
764 MCSectionData &SD = *it;
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000765
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000766 for (MCSectionData::iterator it2 = SD.begin(),
767 ie2 = SD.end(); it2 != ie2; ++it2) {
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000768 // Check if this is an instruction fragment that needs relaxation.
769 MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
770 if (!IF || !FragmentNeedsRelaxation(IF, Layout))
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000771 continue;
Daniel Dunbar0705fbf2009-08-21 18:29:01 +0000772
Daniel Dunbarff547842010-03-23 23:47:14 +0000773 ++stats::RelaxedInstructions;
774
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000775 // FIXME-PERF: We could immediately lower out instructions if we can tell
776 // they are fully resolved, to avoid retesting on later passes.
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000777
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000778 // Relax the fragment.
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000779
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000780 MCInst Relaxed;
781 getBackend().RelaxInstruction(IF, Relaxed);
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000782
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000783 // Encode the new instruction.
784 //
785 // FIXME-PERF: If it matters, we could let the target do this. It can
786 // probably do so more efficiently in many cases.
787 SmallVector<MCFixup, 4> Fixups;
788 SmallString<256> Code;
789 raw_svector_ostream VecOS(Code);
790 getEmitter().EncodeInstruction(Relaxed, VecOS, Fixups);
791 VecOS.flush();
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000792
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000793 // Update the instruction fragment.
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +0000794 int SlideAmount = Code.size() - IF->getInstSize();
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000795 IF->setInst(Relaxed);
796 IF->getCode() = Code;
797 IF->getFixups().clear();
798 for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
799 MCFixup &F = Fixups[i];
800 IF->getFixups().push_back(MCAsmFixup(F.getOffset(), *F.getValue(),
801 F.getKind()));
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000802 }
Daniel Dunbard8036fb2010-03-23 05:09:03 +0000803
Daniel Dunbarac2884a2010-03-25 22:49:09 +0000804 // Update the layout, and remember that we relaxed. If we are relaxing
805 // everything, we can skip this step since nothing will depend on updating
806 // the values.
807 if (!getRelaxAll())
808 Layout.UpdateForSlide(IF, SlideAmount);
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +0000809 WasRelaxed = true;
Daniel Dunbarf08fde42010-03-12 22:07:14 +0000810 }
811 }
812
Daniel Dunbar0cc8bd42010-03-25 19:35:56 +0000813 return WasRelaxed;
Daniel Dunbarfb4a6b32009-08-21 09:11:24 +0000814}
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000815
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000816void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
817 // Lower out any instruction fragments, to simplify the fixup application and
818 // output.
819 //
820 // FIXME-PERF: We don't have to do this, but the assumption is that it is
821 // cheap (we will mostly end up eliminating fragments and appending on to data
822 // fragments), so the extra complexity downstream isn't worth it. Evaluate
823 // this assumption.
824 for (iterator it = begin(), ie = end(); it != ie; ++it) {
825 MCSectionData &SD = *it;
826
827 for (MCSectionData::iterator it2 = SD.begin(),
828 ie2 = SD.end(); it2 != ie2; ++it2) {
829 MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
830 if (!IF)
831 continue;
832
833 // Create a new data fragment for the instruction.
834 //
Daniel Dunbar337055e2010-03-23 03:13:05 +0000835 // FIXME-PERF: Reuse previous data fragment if possible.
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000836 MCDataFragment *DF = new MCDataFragment();
837 SD.getFragmentList().insert(it2, DF);
838
839 // Update the data fragments layout data.
Daniel Dunbar9799de92010-03-23 01:39:05 +0000840 DF->setParent(IF->getParent());
Daniel Dunbar651804c2010-05-11 17:22:50 +0000841 DF->setAtom(IF->getAtom());
Daniel Dunbar5a6e97a2010-03-25 07:10:11 +0000842 DF->setOrdinal(IF->getOrdinal());
Daniel Dunbaraa0d3502010-05-13 08:43:31 +0000843 Layout.FragmentReplaced(IF, DF);
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000844
Daniel Dunbar9799de92010-03-23 01:39:05 +0000845 // Copy in the data and the fixups.
846 DF->getContents().append(IF->getCode().begin(), IF->getCode().end());
847 for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i)
848 DF->getFixups().push_back(IF->getFixups()[i]);
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000849
850 // Delete the instruction fragment and update the iterator.
851 SD.getFragmentList().erase(IF);
852 it2 = DF;
853 }
854 }
855}
856
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000857// Debugging methods
858
859namespace llvm {
860
861raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
Daniel Dunbar2be2fd02010-02-13 09:28:54 +0000862 OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
863 << " Kind:" << AF.Kind << ">";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000864 return OS;
865}
866
867}
868
869void MCFragment::dump() {
870 raw_ostream &OS = llvm::errs();
871
872 OS << "<MCFragment " << (void*) this << " Offset:" << Offset
Daniel Dunbarb5844ff2010-05-13 01:10:22 +0000873 << " EffectiveSize:" << EffectiveSize << ">";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000874}
875
876void MCAlignFragment::dump() {
877 raw_ostream &OS = llvm::errs();
878
879 OS << "<MCAlignFragment ";
880 this->MCFragment::dump();
Daniel Dunbar456b5012010-05-13 01:10:26 +0000881 if (hasEmitNops())
882 OS << " (emit nops)";
883 if (hasOnlyAlignAddress())
884 OS << " (only align section)";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000885 OS << "\n ";
886 OS << " Alignment:" << getAlignment()
887 << " Value:" << getValue() << " ValueSize:" << getValueSize()
888 << " MaxBytesToEmit:" << getMaxBytesToEmit() << ">";
889}
890
891void MCDataFragment::dump() {
892 raw_ostream &OS = llvm::errs();
893
894 OS << "<MCDataFragment ";
895 this->MCFragment::dump();
896 OS << "\n ";
897 OS << " Contents:[";
898 for (unsigned i = 0, e = getContents().size(); i != e; ++i) {
899 if (i) OS << ",";
900 OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
901 }
Daniel Dunbar2be2fd02010-02-13 09:28:54 +0000902 OS << "] (" << getContents().size() << " bytes)";
Daniel Dunbar0bcf0742010-02-13 09:28:43 +0000903
904 if (!getFixups().empty()) {
905 OS << ",\n ";
906 OS << " Fixups:[";
907 for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
Daniel Dunbar45aefff2010-03-09 01:12:23 +0000908 if (it != fixup_begin()) OS << ",\n ";
Daniel Dunbar0bcf0742010-02-13 09:28:43 +0000909 OS << *it;
910 }
911 OS << "]";
912 }
913
914 OS << ">";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000915}
916
917void MCFillFragment::dump() {
918 raw_ostream &OS = llvm::errs();
919
920 OS << "<MCFillFragment ";
921 this->MCFragment::dump();
922 OS << "\n ";
923 OS << " Value:" << getValue() << " ValueSize:" << getValueSize()
Daniel Dunbar3153fec2010-05-12 22:51:32 +0000924 << " Size:" << getSize() << ">";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000925}
926
Daniel Dunbar3f4dcd92010-03-22 23:16:48 +0000927void MCInstFragment::dump() {
928 raw_ostream &OS = llvm::errs();
929
930 OS << "<MCInstFragment ";
931 this->MCFragment::dump();
932 OS << "\n ";
933 OS << " Inst:";
934 getInst().dump_pretty(OS);
935 OS << ">";
936}
937
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000938void MCOrgFragment::dump() {
939 raw_ostream &OS = llvm::errs();
940
941 OS << "<MCOrgFragment ";
942 this->MCFragment::dump();
943 OS << "\n ";
944 OS << " Offset:" << getOffset() << " Value:" << getValue() << ">";
945}
946
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000947void MCSectionData::dump() {
948 raw_ostream &OS = llvm::errs();
949
950 OS << "<MCSectionData";
951 OS << " Alignment:" << getAlignment() << " Address:" << Address
Daniel Dunbar2661f112010-05-13 03:19:50 +0000952 << " Fragments:[\n ";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000953 for (iterator it = begin(), ie = end(); it != ie; ++it) {
954 if (it != begin()) OS << ",\n ";
955 it->dump();
956 }
957 OS << "]>";
958}
959
960void MCSymbolData::dump() {
961 raw_ostream &OS = llvm::errs();
962
963 OS << "<MCSymbolData Symbol:" << getSymbol()
964 << " Fragment:" << getFragment() << " Offset:" << getOffset()
965 << " Flags:" << getFlags() << " Index:" << getIndex();
966 if (isCommon())
967 OS << " (common, size:" << getCommonSize()
968 << " align: " << getCommonAlignment() << ")";
969 if (isExternal())
970 OS << " (external)";
971 if (isPrivateExtern())
972 OS << " (private extern)";
973 OS << ">";
974}
975
976void MCAssembler::dump() {
977 raw_ostream &OS = llvm::errs();
978
979 OS << "<MCAssembler\n";
Daniel Dunbar45aefff2010-03-09 01:12:23 +0000980 OS << " Sections:[\n ";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000981 for (iterator it = begin(), ie = end(); it != ie; ++it) {
982 if (it != begin()) OS << ",\n ";
983 it->dump();
984 }
985 OS << "],\n";
986 OS << " Symbols:[";
987
988 for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) {
Daniel Dunbar45aefff2010-03-09 01:12:23 +0000989 if (it != symbol_begin()) OS << ",\n ";
Daniel Dunbarb7c3a4b2010-02-13 09:28:03 +0000990 it->dump();
991 }
992 OS << "]>\n";
993}