blob: 84d47ec4496c4a91ffe871a77466d1c4fbc19391 [file] [log] [blame]
Bill Wendling88423ee2009-05-15 00:11:17 +00001//===--- 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 Korobeynikov9184b252010-02-15 22:35:59 +000011//
Bill Wendling88423ee2009-05-15 00:11:17 +000012//===----------------------------------------------------------------------===//
13
14#include "DwarfPrinter.h"
15#include "llvm/Module.h"
16#include "llvm/CodeGen/AsmPrinter.h"
17#include "llvm/CodeGen/MachineFrameInfo.h"
David Greeneeea1f4c2009-08-19 21:59:18 +000018#include "llvm/CodeGen/MachineFunction.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000019#include "llvm/CodeGen/MachineModuleInfo.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000020#include "llvm/MC/MCAsmInfo.h"
Anton Korobeynikov9184b252010-02-15 22:35:59 +000021#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCExpr.h"
Chris Lattner3d225132010-04-04 23:22:29 +000023#include "llvm/MC/MCSection.h"
Chris Lattnerf61ed8e2010-01-22 22:38:16 +000024#include "llvm/MC/MCStreamer.h"
Chris Lattner858431d2010-01-16 18:50:28 +000025#include "llvm/MC/MCSymbol.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000026#include "llvm/Target/TargetData.h"
27#include "llvm/Target/TargetFrameInfo.h"
Anton Korobeynikov9184b252010-02-15 22:35:59 +000028#include "llvm/Target/TargetLoweringObjectFile.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000029#include "llvm/Target/TargetRegisterInfo.h"
Chris Lattner9d1c1ad2010-04-04 18:06:11 +000030#include "llvm/Target/TargetMachine.h"
Chris Lattner23132b12009-08-24 03:52:50 +000031#include "llvm/Support/Dwarf.h"
32#include "llvm/Support/ErrorHandling.h"
Anton Korobeynikov9184b252010-02-15 22:35:59 +000033#include "llvm/ADT/SmallString.h"
Bill Wendling88423ee2009-05-15 00:11:17 +000034using namespace llvm;
35
Chris Lattner75f50722010-04-04 07:48:20 +000036DwarfPrinter::DwarfPrinter(AsmPrinter *A)
37: Asm(A), MAI(A->MAI), TD(Asm->TM.getTargetData()),
Bill Wendling88423ee2009-05-15 00:11:17 +000038 RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
Chris Lattnerfa070b02010-04-04 22:33:59 +000039 SubprogramCount(0) {
40}
Bill Wendling88423ee2009-05-15 00:11:17 +000041
Anton Korobeynikov9184b252010-02-15 22:35:59 +000042
Chris Lattnerfa070b02010-04-04 22:33:59 +000043/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its
44/// section. This can be done with a special directive if the target supports
45/// it (e.g. cygwin) or by emitting it as an offset from a label at the start
46/// of the section.
47///
48/// SectionLabel is a temporary label emitted at the start of the section that
49/// Label lives in.
Chris Lattnerb98b1bf2010-03-08 22:23:36 +000050void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label,
Chris Lattnerfa070b02010-04-04 22:33:59 +000051 const MCSymbol *SectionLabel) const {
Chris Lattner2e3ebed2010-04-04 22:25:14 +000052 // On COFF targets, we have to emit the special .secrel32 directive.
Chris Lattner20e32802010-03-12 18:10:35 +000053 if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
Chris Lattner188a87d2010-03-10 01:04:13 +000054 // FIXME: MCize.
Chris Lattner0b9bdb42010-04-04 07:25:52 +000055 Asm->OutStreamer.EmitRawText(SecOffDir + Twine(Label->getName()));
Chris Lattner2e3ebed2010-04-04 22:25:14 +000056 return;
Chris Lattneref6b14f2010-03-09 00:17:58 +000057 }
Chris Lattnera33b2a12010-04-04 23:06:31 +000058
59 // Get the section that we're referring to, based on SectionLabel.
60 const MCSection &Section = SectionLabel->getSection();
61
62 // If Label has already been emitted, verify that it is in the same section as
63 // section label for sanity.
64 assert((!Label->isInSection() || &Label->getSection() == &Section) &&
Chris Lattner3d225132010-04-04 23:22:29 +000065 "Section offset using wrong section base for label");
Chris Lattner2e3ebed2010-04-04 22:25:14 +000066
67 // If the section in question will end up with an address of 0 anyway, we can
68 // just emit an absolute reference to save a relocation.
Chris Lattner3d225132010-04-04 23:22:29 +000069 if (Section.isBaseAddressKnownZero()) {
Chris Lattner2e3ebed2010-04-04 22:25:14 +000070 Asm->OutStreamer.EmitSymbolValue(Label, 4, 0/*AddrSpace*/);
71 return;
72 }
73
Chris Lattner3d225132010-04-04 23:22:29 +000074 // Otherwise, emit it as a label difference from the start of the section.
Chris Lattnerfa070b02010-04-04 22:33:59 +000075 Asm->EmitLabelDifference(Label, SectionLabel, 4);
Bill Wendling88423ee2009-05-15 00:11:17 +000076}
77
78/// EmitFrameMoves - Emit frame instructions to describe the layout of the
79/// frame.
Chris Lattner5e6cbe02010-03-13 08:05:25 +000080void DwarfPrinter::EmitFrameMoves(MCSymbol *BaseLabel,
Chris Lattner066c9ac2010-01-22 22:23:57 +000081 const std::vector<MachineMove> &Moves,
82 bool isEH) {
Chris Lattnerfb658072010-03-13 07:40:56 +000083 int stackGrowth = TD->getPointerSize();
84 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() !=
85 TargetFrameInfo::StackGrowsUp)
86 stackGrowth *= -1;
87
Bill Wendling88423ee2009-05-15 00:11:17 +000088 for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
89 const MachineMove &Move = Moves[i];
Chris Lattner2e9919a2010-03-14 08:12:40 +000090 MCSymbol *Label = Move.getLabel();
Chris Lattnera34ec2292010-03-09 01:51:43 +000091 // Throw out move if the label is invalid.
Chris Lattner2e9919a2010-03-14 08:12:40 +000092 if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling88423ee2009-05-15 00:11:17 +000093
94 const MachineLocation &Dst = Move.getDestination();
95 const MachineLocation &Src = Move.getSource();
96
97 // Advance row if new location.
Chris Lattnerf14645c2010-03-14 07:02:50 +000098 if (BaseLabel && Label) {
Chris Lattnerb9130602010-03-14 02:20:58 +000099 MCSymbol *ThisSym = Label;
Chris Lattner5e6cbe02010-03-13 08:05:25 +0000100 if (ThisSym != BaseLabel) {
Chris Lattner7a101f42010-04-04 20:01:25 +0000101 Asm->EmitCFAByte(dwarf::DW_CFA_advance_loc4);
Chris Lattnera6437182010-04-04 19:58:12 +0000102 Asm->EmitLabelDifference(ThisSym, BaseLabel, 4);
Chris Lattner5e6cbe02010-03-13 08:05:25 +0000103 BaseLabel = ThisSym;
104 }
Bill Wendling88423ee2009-05-15 00:11:17 +0000105 }
106
107 // If advancing cfa.
108 if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
109 if (!Src.isReg()) {
110 if (Src.getReg() == MachineLocation::VirtualFP) {
Chris Lattner7a101f42010-04-04 20:01:25 +0000111 Asm->EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
Bill Wendling88423ee2009-05-15 00:11:17 +0000112 } else {
Chris Lattner7a101f42010-04-04 20:01:25 +0000113 Asm->EmitCFAByte(dwarf::DW_CFA_def_cfa);
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000114 Asm->EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
Bill Wendling88423ee2009-05-15 00:11:17 +0000115 }
116
117 int Offset = -Src.getOffset();
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000118 Asm->EmitULEB128(Offset, "Offset");
Bill Wendling88423ee2009-05-15 00:11:17 +0000119 } else {
Torok Edwinc23197a2009-07-14 16:55:14 +0000120 llvm_unreachable("Machine move not supported yet.");
Bill Wendling88423ee2009-05-15 00:11:17 +0000121 }
122 } else if (Src.isReg() &&
123 Src.getReg() == MachineLocation::VirtualFP) {
124 if (Dst.isReg()) {
Chris Lattner7a101f42010-04-04 20:01:25 +0000125 Asm->EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000126 Asm->EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
Bill Wendling88423ee2009-05-15 00:11:17 +0000127 } else {
Torok Edwinc23197a2009-07-14 16:55:14 +0000128 llvm_unreachable("Machine move not supported yet.");
Bill Wendling88423ee2009-05-15 00:11:17 +0000129 }
130 } else {
131 unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
132 int Offset = Dst.getOffset() / stackGrowth;
133
134 if (Offset < 0) {
Chris Lattner7a101f42010-04-04 20:01:25 +0000135 Asm->EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000136 Asm->EmitULEB128(Reg, "Reg");
137 Asm->EmitSLEB128(Offset, "Offset");
Bill Wendling88423ee2009-05-15 00:11:17 +0000138 } else if (Reg < 64) {
Chris Lattner7a101f42010-04-04 20:01:25 +0000139 Asm->EmitCFAByte(dwarf::DW_CFA_offset + Reg);
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000140 Asm->EmitULEB128(Offset, "Offset");
Bill Wendling88423ee2009-05-15 00:11:17 +0000141 } else {
Chris Lattner7a101f42010-04-04 20:01:25 +0000142 Asm->EmitCFAByte(dwarf::DW_CFA_offset_extended);
Chris Lattner7e1a8f82010-04-04 19:09:29 +0000143 Asm->EmitULEB128(Reg, "Reg");
144 Asm->EmitULEB128(Offset, "Offset");
Bill Wendling88423ee2009-05-15 00:11:17 +0000145 }
146 }
147 }
148}