AsmPrinterDwarf.cpp revision 28e23aa64c3c2c93dfa10856ea413b2086251fdf
1//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===// 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// This file implements the Dwarf emissions parts of AsmPrinter. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "asm-printer" 15#include "llvm/CodeGen/AsmPrinter.h" 16#include "llvm/MC/MCAsmInfo.h" 17#include "llvm/MC/MCStreamer.h" 18#include "llvm/ADT/Twine.h" 19#include "llvm/Support/Dwarf.h" 20using namespace llvm; 21 22/// EmitSLEB128 - emit the specified signed leb128 value. 23void AsmPrinter::EmitSLEB128(int Value, const char *Desc) const { 24 if (isVerbose() && Desc) 25 OutStreamer.AddComment(Desc); 26 27 if (MAI->hasLEB128()) { 28 // FIXME: MCize. 29 OutStreamer.EmitRawText("\t.sleb128\t" + Twine(Value)); 30 return; 31 } 32 33 // If we don't have .sleb128, emit as .bytes. 34 int Sign = Value >> (8 * sizeof(Value) - 1); 35 bool IsMore; 36 37 do { 38 unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); 39 Value >>= 7; 40 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; 41 if (IsMore) Byte |= 0x80; 42 OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); 43 } while (IsMore); 44} 45 46/// EmitULEB128 - emit the specified signed leb128 value. 47void AsmPrinter::EmitULEB128(unsigned Value, const char *Desc, 48 unsigned PadTo) const { 49 if (isVerbose() && Desc) 50 OutStreamer.AddComment(Desc); 51 52 if (MAI->hasLEB128() && PadTo == 0) { 53 // FIXME: MCize. 54 OutStreamer.EmitRawText("\t.uleb128\t" + Twine(Value)); 55 return; 56 } 57 58 // If we don't have .uleb128 or we want to emit padding, emit as .bytes. 59 do { 60 unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); 61 Value >>= 7; 62 if (Value || PadTo != 0) Byte |= 0x80; 63 OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); 64 } while (Value); 65 66 if (PadTo) { 67 if (PadTo > 1) 68 OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/); 69 OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/); 70 } 71} 72 73/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. 74void AsmPrinter::EmitCFAByte(unsigned Val) const { 75 if (isVerbose()) { 76 if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64) 77 OutStreamer.AddComment("DW_CFA_offset + Reg (" + 78 Twine(Val-dwarf::DW_CFA_offset) + ")"); 79 else 80 OutStreamer.AddComment(dwarf::CallFrameString(Val)); 81 } 82 OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); 83} 84 85static const char *DecodeDWARFEncoding(unsigned Encoding) { 86 switch (Encoding) { 87 case dwarf::DW_EH_PE_absptr: return "absptr"; 88 case dwarf::DW_EH_PE_omit: return "omit"; 89 case dwarf::DW_EH_PE_pcrel: return "pcrel"; 90 case dwarf::DW_EH_PE_udata4: return "udata4"; 91 case dwarf::DW_EH_PE_udata8: return "udata8"; 92 case dwarf::DW_EH_PE_sdata4: return "sdata4"; 93 case dwarf::DW_EH_PE_sdata8: return "sdata8"; 94 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4"; 95 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4"; 96 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8"; 97 case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8"; 98 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4: 99 return "indirect pcrel udata4"; 100 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4: 101 return "indirect pcrel sdata4"; 102 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8: 103 return "indirect pcrel udata8"; 104 case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8: 105 return "indirect pcrel sdata8"; 106 } 107 108 return "<unknown encoding>"; 109} 110 111 112/// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an 113/// encoding. If verbose assembly output is enabled, we output comments 114/// describing the encoding. Desc is an optional string saying what the 115/// encoding is specifying (e.g. "LSDA"). 116void AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) { 117 if (isVerbose()) { 118 if (Desc != 0) 119 OutStreamer.AddComment(Twine(Desc)+" Encoding = " + 120 Twine(DecodeDWARFEncoding(Val))); 121 else 122 OutStreamer.AddComment(Twine("Encoding = ") + 123 DecodeDWARFEncoding(Val)); 124 } 125 126 OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); 127} 128 129