| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 1 | //===--- lib/CodeGen/DwarfPrinter.cpp - Dwarf Printer ---------------------===// | 
|  | 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 | // | 
|  | 10 | // Emit general DWARF directives. | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 11 | // | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 12 | //===----------------------------------------------------------------------===// | 
|  | 13 |  | 
|  | 14 | #include "DwarfPrinter.h" | 
|  | 15 | #include "llvm/Module.h" | 
|  | 16 | #include "llvm/CodeGen/AsmPrinter.h" | 
|  | 17 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
| David Greene | eea1f4c | 2009-08-19 21:59:18 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/MachineFunction.h" | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 19 | #include "llvm/CodeGen/MachineModuleInfo.h" | 
| Chris Lattner | af76e59 | 2009-08-22 20:48:53 +0000 | [diff] [blame] | 20 | #include "llvm/MC/MCAsmInfo.h" | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 21 | #include "llvm/MC/MCContext.h" | 
|  | 22 | #include "llvm/MC/MCExpr.h" | 
| Chris Lattner | f61ed8e | 2010-01-22 22:38:16 +0000 | [diff] [blame] | 23 | #include "llvm/MC/MCStreamer.h" | 
| Chris Lattner | 858431d | 2010-01-16 18:50:28 +0000 | [diff] [blame] | 24 | #include "llvm/MC/MCSymbol.h" | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 25 | #include "llvm/Target/TargetData.h" | 
|  | 26 | #include "llvm/Target/TargetFrameInfo.h" | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 27 | #include "llvm/Target/TargetLoweringObjectFile.h" | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 28 | #include "llvm/Target/TargetRegisterInfo.h" | 
| Chris Lattner | 23132b1 | 2009-08-24 03:52:50 +0000 | [diff] [blame] | 29 | #include "llvm/Support/Dwarf.h" | 
|  | 30 | #include "llvm/Support/ErrorHandling.h" | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 31 | #include "llvm/ADT/SmallString.h" | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 32 | using namespace llvm; | 
|  | 33 |  | 
| Chris Lattner | c3421bb | 2010-03-09 00:00:15 +0000 | [diff] [blame] | 34 | DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) | 
| Chris Lattner | 33adcfb | 2009-08-22 21:43:10 +0000 | [diff] [blame] | 35 | : O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()), | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 36 | RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL), | 
| Chris Lattner | c3421bb | 2010-03-09 00:00:15 +0000 | [diff] [blame] | 37 | SubprogramCount(0) {} | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 38 |  | 
| Chris Lattner | b98b1bf | 2010-03-08 22:23:36 +0000 | [diff] [blame] | 39 |  | 
|  | 40 | /// getDWLabel - Return the MCSymbol corresponding to the assembler temporary | 
|  | 41 | /// label with the specified stem and unique ID. | 
|  | 42 | MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const { | 
|  | 43 | // FIXME: REMOVE this.  However, there is stuff in EH that passes counters in | 
|  | 44 | // here that can be zero. | 
|  | 45 |  | 
|  | 46 | //assert(ID && "Should use getTempLabel if no ID"); | 
|  | 47 | if (ID == 0) return getTempLabel(Name); | 
|  | 48 | return Asm->OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) | 
|  | 49 | + Twine(Name) + Twine(ID)); | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | /// getTempLabel - Return the MCSymbol corresponding to the assembler temporary | 
|  | 53 | /// label with the specified name. | 
|  | 54 | MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const { | 
|  | 55 | return Asm->OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) | 
|  | 56 | + Name); | 
|  | 57 | } | 
|  | 58 |  | 
|  | 59 |  | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 60 | /// SizeOfEncodedValue - Return the size of the encoding in bytes. | 
|  | 61 | unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const { | 
|  | 62 | if (Encoding == dwarf::DW_EH_PE_omit) | 
|  | 63 | return 0; | 
|  | 64 |  | 
|  | 65 | switch (Encoding & 0x07) { | 
|  | 66 | case dwarf::DW_EH_PE_absptr: | 
|  | 67 | return TD->getPointerSize(); | 
|  | 68 | case dwarf::DW_EH_PE_udata2: | 
|  | 69 | return 2; | 
|  | 70 | case dwarf::DW_EH_PE_udata4: | 
|  | 71 | return 4; | 
|  | 72 | case dwarf::DW_EH_PE_udata8: | 
|  | 73 | return 8; | 
|  | 74 | } | 
|  | 75 |  | 
|  | 76 | assert(0 && "Invalid encoded value."); | 
|  | 77 | return 0; | 
|  | 78 | } | 
|  | 79 |  | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 80 | void DwarfPrinter::PrintRelDirective(unsigned Encoding) const { | 
|  | 81 | unsigned Size = SizeOfEncodedValue(Encoding); | 
|  | 82 | assert((Size == 4 || Size == 8) && "Do not support other types or rels!"); | 
|  | 83 |  | 
|  | 84 | O << (Size == 4 ? | 
|  | 85 | MAI->getData32bitsDirective() : MAI->getData64bitsDirective()); | 
|  | 86 | } | 
|  | 87 |  | 
| Chris Lattner | f61ed8e | 2010-01-22 22:38:16 +0000 | [diff] [blame] | 88 | static const char *DecodeDWARFEncoding(unsigned Encoding) { | 
|  | 89 | switch (Encoding) { | 
|  | 90 | case dwarf::DW_EH_PE_absptr: return "absptr"; | 
|  | 91 | case dwarf::DW_EH_PE_omit:   return "omit"; | 
|  | 92 | case dwarf::DW_EH_PE_pcrel:  return "pcrel"; | 
|  | 93 | case dwarf::DW_EH_PE_udata4: return "udata4"; | 
|  | 94 | case dwarf::DW_EH_PE_udata8: return "udata8"; | 
|  | 95 | case dwarf::DW_EH_PE_sdata4: return "sdata4"; | 
|  | 96 | case dwarf::DW_EH_PE_sdata8: return "sdata8"; | 
|  | 97 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4"; | 
|  | 98 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4"; | 
|  | 99 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8"; | 
|  | 100 | case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8"; | 
|  | 101 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4: | 
|  | 102 | return "indirect pcrel udata4"; | 
|  | 103 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4: | 
|  | 104 | return "indirect pcrel sdata4"; | 
|  | 105 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8: | 
|  | 106 | return "indirect pcrel udata8"; | 
|  | 107 | case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8: | 
|  | 108 | return "indirect pcrel sdata8"; | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | return "<unknown encoding>"; | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an | 
|  | 115 | /// encoding.  If verbose assembly output is enabled, we output comments | 
|  | 116 | /// describing the encoding.  Desc is an optional string saying what the | 
|  | 117 | /// encoding is specifying (e.g. "LSDA"). | 
|  | 118 | void DwarfPrinter::EmitEncodingByte(unsigned Val, const char *Desc) { | 
|  | 119 | if (Asm->VerboseAsm) { | 
|  | 120 | if (Desc != 0) | 
|  | 121 | Asm->OutStreamer.AddComment(Twine(Desc)+" Encoding = " + | 
|  | 122 | Twine(DecodeDWARFEncoding(Val))); | 
|  | 123 | else | 
|  | 124 | Asm->OutStreamer.AddComment(Twine("Encoding = ") + | 
|  | 125 | DecodeDWARFEncoding(Val)); | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); | 
|  | 129 | } | 
|  | 130 |  | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 131 | /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. | 
|  | 132 | void DwarfPrinter::EmitCFAByte(unsigned Val) { | 
|  | 133 | if (Asm->VerboseAsm) { | 
|  | 134 | if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64) | 
|  | 135 | Asm->OutStreamer.AddComment("DW_CFA_offset + Reg (" + | 
|  | 136 | Twine(Val-dwarf::DW_CFA_offset) + ")"); | 
|  | 137 | else | 
|  | 138 | Asm->OutStreamer.AddComment(dwarf::CallFrameString(Val)); | 
|  | 139 | } | 
|  | 140 | Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); | 
|  | 141 | } | 
|  | 142 |  | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 143 | /// EmitSLEB128 - emit the specified signed leb128 value. | 
|  | 144 | void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const { | 
|  | 145 | if (Asm->VerboseAsm && Desc) | 
|  | 146 | Asm->OutStreamer.AddComment(Desc); | 
|  | 147 |  | 
|  | 148 | if (MAI->hasLEB128()) { | 
|  | 149 | O << "\t.sleb128\t" << Value; | 
|  | 150 | Asm->OutStreamer.AddBlankLine(); | 
|  | 151 | return; | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | // If we don't have .sleb128, emit as .bytes. | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 155 | int Sign = Value >> (8 * sizeof(Value) - 1); | 
|  | 156 | bool IsMore; | 
|  | 157 |  | 
|  | 158 | do { | 
|  | 159 | unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); | 
|  | 160 | Value >>= 7; | 
|  | 161 | IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; | 
|  | 162 | if (IsMore) Byte |= 0x80; | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 163 | Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 164 | } while (IsMore); | 
|  | 165 | } | 
|  | 166 |  | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 167 | /// EmitULEB128 - emit the specified signed leb128 value. | 
| Bill Wendling | 3dc9b48 | 2010-02-24 23:34:35 +0000 | [diff] [blame] | 168 | void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc, | 
|  | 169 | unsigned PadTo) const { | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 170 | if (Asm->VerboseAsm && Desc) | 
|  | 171 | Asm->OutStreamer.AddComment(Desc); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 172 |  | 
| Bill Wendling | 3dc9b48 | 2010-02-24 23:34:35 +0000 | [diff] [blame] | 173 | if (MAI->hasLEB128() && PadTo == 0) { | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 174 | O << "\t.uleb128\t" << Value; | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 175 | Asm->OutStreamer.AddBlankLine(); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 176 | return; | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 177 | } | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 178 |  | 
| Bill Wendling | 3dc9b48 | 2010-02-24 23:34:35 +0000 | [diff] [blame] | 179 | // If we don't have .uleb128 or we want to emit padding, emit as .bytes. | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 180 | do { | 
|  | 181 | unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); | 
|  | 182 | Value >>= 7; | 
| Bill Wendling | 3dc9b48 | 2010-02-24 23:34:35 +0000 | [diff] [blame] | 183 | if (Value || PadTo != 0) Byte |= 0x80; | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 184 | Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); | 
|  | 185 | } while (Value); | 
| Bill Wendling | 3dc9b48 | 2010-02-24 23:34:35 +0000 | [diff] [blame] | 186 |  | 
| Bill Wendling | f0bd4cc | 2010-02-25 00:24:52 +0000 | [diff] [blame] | 187 | if (PadTo) { | 
|  | 188 | if (PadTo > 1) | 
|  | 189 | Asm->OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/); | 
|  | 190 | Asm->OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/); | 
|  | 191 | } | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 192 | } | 
|  | 193 |  | 
|  | 194 |  | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 195 | /// EmitReference - Emit a reference to a label. | 
|  | 196 | /// | 
| Chris Lattner | 066c9ac | 2010-01-22 22:23:57 +0000 | [diff] [blame] | 197 | void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative, | 
|  | 198 | bool Force32Bit) const { | 
| Chris Lattner | fcdae49 | 2010-03-09 23:19:15 +0000 | [diff] [blame] | 199 | unsigned Size = Force32Bit ? 4 : TD->getPointerSize(); | 
|  | 200 |  | 
|  | 201 | if (!IsPCRelative) { | 
|  | 202 | Asm->OutStreamer.EmitSymbolValue(Sym, Size, 0/*AddrSpace*/); | 
|  | 203 | return; | 
|  | 204 | } | 
|  | 205 |  | 
|  | 206 | // FIXME: Need an MCExpr for ".". | 
| Chris Lattner | 4aeaca4 | 2010-03-09 23:54:52 +0000 | [diff] [blame^] | 207 | if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) | 
|  | 208 | O << MAI->getData32bitsDirective(); | 
|  | 209 | else | 
|  | 210 | O << MAI->getData64bitsDirective(); | 
| Chris Lattner | 10b318b | 2010-01-17 21:43:43 +0000 | [diff] [blame] | 211 | O << *Sym; | 
| Chris Lattner | 858431d | 2010-01-16 18:50:28 +0000 | [diff] [blame] | 212 | if (IsPCRelative) O << "-" << MAI->getPCSymbol(); | 
|  | 213 | } | 
|  | 214 |  | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 215 | void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const { | 
|  | 216 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | 
|  | 217 |  | 
|  | 218 | PrintRelDirective(Encoding); | 
| Chris Lattner | b9dc5f7 | 2010-03-09 00:26:09 +0000 | [diff] [blame] | 219 | O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding); | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 220 | } | 
|  | 221 |  | 
| Chris Lattner | 0d50c76 | 2010-03-08 23:58:37 +0000 | [diff] [blame] | 222 | void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{ | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 223 | const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); | 
|  | 224 |  | 
|  | 225 | PrintRelDirective(Encoding); | 
|  | 226 | O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, | 
| Chris Lattner | 326861c | 2010-03-08 22:50:36 +0000 | [diff] [blame] | 227 | Asm->MMI, Encoding); | 
| Anton Korobeynikov | 9184b25 | 2010-02-15 22:35:59 +0000 | [diff] [blame] | 228 | } | 
|  | 229 |  | 
| Chris Lattner | 6a315c3 | 2010-01-26 20:20:43 +0000 | [diff] [blame] | 230 | /// EmitDifference - Emit the difference between two labels.  If this assembler | 
|  | 231 | /// supports .set, we emit a .set of a temporary and then use it in the .word. | 
| Chris Lattner | b98b1bf | 2010-03-08 22:23:36 +0000 | [diff] [blame] | 232 | void DwarfPrinter::EmitDifference(const MCSymbol *TagHi, const MCSymbol *TagLo, | 
|  | 233 | bool IsSmall) { | 
| Chris Lattner | 0d50c76 | 2010-03-08 23:58:37 +0000 | [diff] [blame] | 234 | unsigned Size = IsSmall ? 4 : TD->getPointerSize(); | 
|  | 235 | Asm->EmitLabelDifference(TagHi, TagLo, Size); | 
| Chris Lattner | b98b1bf | 2010-03-08 22:23:36 +0000 | [diff] [blame] | 236 | } | 
|  | 237 |  | 
| Chris Lattner | b98b1bf | 2010-03-08 22:23:36 +0000 | [diff] [blame] | 238 | void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label, | 
|  | 239 | const MCSymbol *Section, | 
| Chris Lattner | 5757876 | 2010-03-08 23:23:25 +0000 | [diff] [blame] | 240 | bool IsSmall, bool isEH) { | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 241 | bool isAbsolute; | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 242 | if (isEH) | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 243 | isAbsolute = MAI->isAbsoluteEHSectionOffsets(); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 244 | else | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 245 | isAbsolute = MAI->isAbsoluteDebugSectionOffsets(); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 246 |  | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 247 | if (!isAbsolute) | 
| Chris Lattner | 5757876 | 2010-03-08 23:23:25 +0000 | [diff] [blame] | 248 | return EmitDifference(Label, Section, IsSmall); | 
|  | 249 |  | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 250 | // On COFF targets, we have to emit the weird .secrel32 directive. | 
|  | 251 | if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) | 
|  | 252 | O << SecOffDir << Label->getName(); | 
|  | 253 | else { | 
|  | 254 | unsigned Size = IsSmall ? 4 : TD->getPointerSize(); | 
| Chris Lattner | 6cde3e6 | 2010-03-09 00:39:24 +0000 | [diff] [blame] | 255 | Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/); | 
| Chris Lattner | ef6b14f | 2010-03-09 00:17:58 +0000 | [diff] [blame] | 256 | } | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 257 | } | 
|  | 258 |  | 
|  | 259 | /// EmitFrameMoves - Emit frame instructions to describe the layout of the | 
|  | 260 | /// frame. | 
| Chris Lattner | 066c9ac | 2010-01-22 22:23:57 +0000 | [diff] [blame] | 261 | void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, | 
|  | 262 | const std::vector<MachineMove> &Moves, | 
|  | 263 | bool isEH) { | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 264 | int stackGrowth = | 
|  | 265 | Asm->TM.getFrameInfo()->getStackGrowthDirection() == | 
|  | 266 | TargetFrameInfo::StackGrowsUp ? | 
|  | 267 | TD->getPointerSize() : -TD->getPointerSize(); | 
|  | 268 | bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0; | 
|  | 269 |  | 
|  | 270 | for (unsigned i = 0, N = Moves.size(); i < N; ++i) { | 
|  | 271 | const MachineMove &Move = Moves[i]; | 
|  | 272 | unsigned LabelID = Move.getLabelID(); | 
|  | 273 |  | 
| Chris Lattner | a34ec229 | 2010-03-09 01:51:43 +0000 | [diff] [blame] | 274 | // Throw out move if the label is invalid. | 
|  | 275 | if (LabelID && MMI->isLabelDeleted(LabelID)) | 
|  | 276 | continue; | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 277 |  | 
|  | 278 | const MachineLocation &Dst = Move.getDestination(); | 
|  | 279 | const MachineLocation &Src = Move.getSource(); | 
|  | 280 |  | 
|  | 281 | // Advance row if new location. | 
|  | 282 | if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 283 | EmitCFAByte(dwarf::DW_CFA_advance_loc4); | 
| Chris Lattner | effa868 | 2010-03-08 23:02:59 +0000 | [diff] [blame] | 284 | EmitDifference(getDWLabel("label", LabelID), | 
|  | 285 | getDWLabel(BaseLabel, BaseLabelID), true); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 286 | BaseLabelID = LabelID; | 
|  | 287 | BaseLabel = "label"; | 
|  | 288 | IsLocal = true; | 
|  | 289 | } | 
|  | 290 |  | 
|  | 291 | // If advancing cfa. | 
|  | 292 | if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { | 
|  | 293 | if (!Src.isReg()) { | 
|  | 294 | if (Src.getReg() == MachineLocation::VirtualFP) { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 295 | EmitCFAByte(dwarf::DW_CFA_def_cfa_offset); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 296 | } else { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 297 | EmitCFAByte(dwarf::DW_CFA_def_cfa); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 298 | EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 299 | } | 
|  | 300 |  | 
|  | 301 | int Offset = -Src.getOffset(); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 302 | EmitULEB128(Offset, "Offset"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 303 | } else { | 
| Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 304 | llvm_unreachable("Machine move not supported yet."); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 305 | } | 
|  | 306 | } else if (Src.isReg() && | 
|  | 307 | Src.getReg() == MachineLocation::VirtualFP) { | 
|  | 308 | if (Dst.isReg()) { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 309 | EmitCFAByte(dwarf::DW_CFA_def_cfa_register); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 310 | EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 311 | } else { | 
| Torok Edwin | c23197a | 2009-07-14 16:55:14 +0000 | [diff] [blame] | 312 | llvm_unreachable("Machine move not supported yet."); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 313 | } | 
|  | 314 | } else { | 
|  | 315 | unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH); | 
|  | 316 | int Offset = Dst.getOffset() / stackGrowth; | 
|  | 317 |  | 
|  | 318 | if (Offset < 0) { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 319 | EmitCFAByte(dwarf::DW_CFA_offset_extended_sf); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 320 | EmitULEB128(Reg, "Reg"); | 
| Chris Lattner | bb9078a | 2010-01-22 22:56:55 +0000 | [diff] [blame] | 321 | EmitSLEB128(Offset, "Offset"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 322 | } else if (Reg < 64) { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 323 | EmitCFAByte(dwarf::DW_CFA_offset + Reg); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 324 | EmitULEB128(Offset, "Offset"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 325 | } else { | 
| Chris Lattner | 245834d | 2010-01-22 23:40:08 +0000 | [diff] [blame] | 326 | EmitCFAByte(dwarf::DW_CFA_offset_extended); | 
| Chris Lattner | 894d75a | 2010-01-22 23:18:42 +0000 | [diff] [blame] | 327 | EmitULEB128(Reg, "Reg"); | 
|  | 328 | EmitULEB128(Offset, "Offset"); | 
| Bill Wendling | 88423ee | 2009-05-15 00:11:17 +0000 | [diff] [blame] | 329 | } | 
|  | 330 | } | 
|  | 331 | } | 
|  | 332 | } |