diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2011-04-29 02:42:28 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2011-04-29 02:42:28 +0000 |
commit | 9099813bd50a05c4b2a495e3cea817f49c1372d8 (patch) | |
tree | b6d42772ed5a98a2d1d6458c8a2972339c0255a4 /lib | |
parent | bcffb1fbb85a88cb99f7c2115a5f78e860d7fc46 (diff) |
Add an alternative implementation of CIE and FDE emission that outputs them
in the same order as the one in CodeGen.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@130471 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/MC/MCDwarf.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 7111758a72..1848430048 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -824,9 +824,67 @@ namespace llvm { }; } +// This is an implementation of CIE and FDE emission that is bug by bug +// compatible with the one in CodeGen. It is useful during the transition +// to make it easy to compare the outputs, but should probably be removed +// afterwards. +void MCDwarfFrameEmitter::EmitDarwin(MCStreamer &streamer) { + FrameEmitterImpl Emitter; + DenseMap<const MCSymbol*, const MCSymbol*> Personalities; + const MCSymbol *aCIE = NULL; + const MCDwarfFrameInfo *aFrame = NULL; + + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + if (!frame.Personality) + continue; + if (Personalities.count(frame.Personality)) + continue; + + const MCSymbol *cieStart = &Emitter.EmitCIE(streamer, frame.Personality, + frame.PersonalityEncoding, + frame.Lsda, + frame.LsdaEncoding); + aCIE = cieStart; + aFrame = &frame; + Personalities[frame.Personality] = cieStart; + } + + if (Personalities.empty()) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(0); + aCIE = &Emitter.EmitCIE(streamer, frame.Personality, + frame.PersonalityEncoding, frame.Lsda, + frame.LsdaEncoding); + aFrame = &frame; + } + + MCSymbol *fdeEnd = NULL; + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + const MCSymbol *cieStart = Personalities[frame.Personality]; + if (!cieStart) + cieStart = aCIE; + + fdeEnd = Emitter.EmitFDE(streamer, *cieStart, frame); + if (i != n - 1) + streamer.EmitLabel(fdeEnd); + } + + const MCContext &context = streamer.getContext(); + const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + streamer.EmitValueToAlignment(asmInfo.getPointerSize()); + if (fdeEnd) + streamer.EmitLabel(fdeEnd); +} + void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + if (!asmInfo.isFunctionEHFrameSymbolPrivate()) { + EmitDarwin(streamer); + return; + } + MCSymbol *fdeEnd = NULL; DenseMap<CIEKey, const MCSymbol*> CIEStarts; FrameEmitterImpl Emitter; |