1*0a6a1f1dSLionel Sambuc //===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===//
2*0a6a1f1dSLionel Sambuc //
3*0a6a1f1dSLionel Sambuc // The LLVM Compiler Infrastructure
4*0a6a1f1dSLionel Sambuc //
5*0a6a1f1dSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6*0a6a1f1dSLionel Sambuc // License. See LICENSE.TXT for details.
7*0a6a1f1dSLionel Sambuc //
8*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
9*0a6a1f1dSLionel Sambuc //
10*0a6a1f1dSLionel Sambuc // This file contains support for writing dwarf debug info into asm files.
11*0a6a1f1dSLionel Sambuc //
12*0a6a1f1dSLionel Sambuc //===----------------------------------------------------------------------===//
13*0a6a1f1dSLionel Sambuc
14*0a6a1f1dSLionel Sambuc #include "DwarfExpression.h"
15*0a6a1f1dSLionel Sambuc #include "DwarfDebug.h"
16*0a6a1f1dSLionel Sambuc #include "llvm/ADT/SmallBitVector.h"
17*0a6a1f1dSLionel Sambuc #include "llvm/CodeGen/AsmPrinter.h"
18*0a6a1f1dSLionel Sambuc #include "llvm/Support/Dwarf.h"
19*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetMachine.h"
20*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetRegisterInfo.h"
21*0a6a1f1dSLionel Sambuc #include "llvm/Target/TargetSubtargetInfo.h"
22*0a6a1f1dSLionel Sambuc
23*0a6a1f1dSLionel Sambuc using namespace llvm;
24*0a6a1f1dSLionel Sambuc
getTRI() const25*0a6a1f1dSLionel Sambuc const TargetRegisterInfo *DwarfExpression::getTRI() const {
26*0a6a1f1dSLionel Sambuc return AP.TM.getSubtargetImpl()->getRegisterInfo();
27*0a6a1f1dSLionel Sambuc }
28*0a6a1f1dSLionel Sambuc
getDwarfVersion() const29*0a6a1f1dSLionel Sambuc unsigned DwarfExpression::getDwarfVersion() const {
30*0a6a1f1dSLionel Sambuc return AP.getDwarfDebug()->getDwarfVersion();
31*0a6a1f1dSLionel Sambuc }
32*0a6a1f1dSLionel Sambuc
AddReg(int DwarfReg,const char * Comment)33*0a6a1f1dSLionel Sambuc void DwarfExpression::AddReg(int DwarfReg, const char *Comment) {
34*0a6a1f1dSLionel Sambuc assert(DwarfReg >= 0 && "invalid negative dwarf register number");
35*0a6a1f1dSLionel Sambuc if (DwarfReg < 32) {
36*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
37*0a6a1f1dSLionel Sambuc } else {
38*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_regx, Comment);
39*0a6a1f1dSLionel Sambuc EmitUnsigned(DwarfReg);
40*0a6a1f1dSLionel Sambuc }
41*0a6a1f1dSLionel Sambuc }
42*0a6a1f1dSLionel Sambuc
AddRegIndirect(int DwarfReg,int Offset,bool Deref)43*0a6a1f1dSLionel Sambuc void DwarfExpression::AddRegIndirect(int DwarfReg, int Offset, bool Deref) {
44*0a6a1f1dSLionel Sambuc assert(DwarfReg >= 0 && "invalid negative dwarf register number");
45*0a6a1f1dSLionel Sambuc if (DwarfReg < 32) {
46*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_breg0 + DwarfReg);
47*0a6a1f1dSLionel Sambuc } else {
48*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_bregx);
49*0a6a1f1dSLionel Sambuc EmitUnsigned(DwarfReg);
50*0a6a1f1dSLionel Sambuc }
51*0a6a1f1dSLionel Sambuc EmitSigned(Offset);
52*0a6a1f1dSLionel Sambuc if (Deref)
53*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_deref);
54*0a6a1f1dSLionel Sambuc }
55*0a6a1f1dSLionel Sambuc
AddOpPiece(unsigned SizeInBits,unsigned OffsetInBits)56*0a6a1f1dSLionel Sambuc void DwarfExpression::AddOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
57*0a6a1f1dSLionel Sambuc assert(SizeInBits > 0 && "piece has size zero");
58*0a6a1f1dSLionel Sambuc const unsigned SizeOfByte = 8;
59*0a6a1f1dSLionel Sambuc if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
60*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_bit_piece);
61*0a6a1f1dSLionel Sambuc EmitUnsigned(SizeInBits);
62*0a6a1f1dSLionel Sambuc EmitUnsigned(OffsetInBits);
63*0a6a1f1dSLionel Sambuc } else {
64*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_piece);
65*0a6a1f1dSLionel Sambuc unsigned ByteSize = SizeInBits / SizeOfByte;
66*0a6a1f1dSLionel Sambuc EmitUnsigned(ByteSize);
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc }
69*0a6a1f1dSLionel Sambuc
AddShr(unsigned ShiftBy)70*0a6a1f1dSLionel Sambuc void DwarfExpression::AddShr(unsigned ShiftBy) {
71*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_constu);
72*0a6a1f1dSLionel Sambuc EmitUnsigned(ShiftBy);
73*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_shr);
74*0a6a1f1dSLionel Sambuc }
75*0a6a1f1dSLionel Sambuc
AddMachineRegIndirect(unsigned MachineReg,int Offset)76*0a6a1f1dSLionel Sambuc bool DwarfExpression::AddMachineRegIndirect(unsigned MachineReg, int Offset) {
77*0a6a1f1dSLionel Sambuc int DwarfReg = getTRI()->getDwarfRegNum(MachineReg, false);
78*0a6a1f1dSLionel Sambuc if (DwarfReg < 0)
79*0a6a1f1dSLionel Sambuc return false;
80*0a6a1f1dSLionel Sambuc
81*0a6a1f1dSLionel Sambuc if (isFrameRegister(MachineReg)) {
82*0a6a1f1dSLionel Sambuc // If variable offset is based in frame register then use fbreg.
83*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_fbreg);
84*0a6a1f1dSLionel Sambuc EmitSigned(Offset);
85*0a6a1f1dSLionel Sambuc } else {
86*0a6a1f1dSLionel Sambuc AddRegIndirect(DwarfReg, Offset);
87*0a6a1f1dSLionel Sambuc }
88*0a6a1f1dSLionel Sambuc return true;
89*0a6a1f1dSLionel Sambuc }
90*0a6a1f1dSLionel Sambuc
AddMachineRegPiece(unsigned MachineReg,unsigned PieceSizeInBits,unsigned PieceOffsetInBits)91*0a6a1f1dSLionel Sambuc bool DwarfExpression::AddMachineRegPiece(unsigned MachineReg,
92*0a6a1f1dSLionel Sambuc unsigned PieceSizeInBits,
93*0a6a1f1dSLionel Sambuc unsigned PieceOffsetInBits) {
94*0a6a1f1dSLionel Sambuc const TargetRegisterInfo *TRI = getTRI();
95*0a6a1f1dSLionel Sambuc int Reg = TRI->getDwarfRegNum(MachineReg, false);
96*0a6a1f1dSLionel Sambuc
97*0a6a1f1dSLionel Sambuc // If this is a valid register number, emit it.
98*0a6a1f1dSLionel Sambuc if (Reg >= 0) {
99*0a6a1f1dSLionel Sambuc AddReg(Reg);
100*0a6a1f1dSLionel Sambuc if (PieceSizeInBits)
101*0a6a1f1dSLionel Sambuc AddOpPiece(PieceSizeInBits, PieceOffsetInBits);
102*0a6a1f1dSLionel Sambuc return true;
103*0a6a1f1dSLionel Sambuc }
104*0a6a1f1dSLionel Sambuc
105*0a6a1f1dSLionel Sambuc // Walk up the super-register chain until we find a valid number.
106*0a6a1f1dSLionel Sambuc // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
107*0a6a1f1dSLionel Sambuc for (MCSuperRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {
108*0a6a1f1dSLionel Sambuc Reg = TRI->getDwarfRegNum(*SR, false);
109*0a6a1f1dSLionel Sambuc if (Reg >= 0) {
110*0a6a1f1dSLionel Sambuc unsigned Idx = TRI->getSubRegIndex(*SR, MachineReg);
111*0a6a1f1dSLionel Sambuc unsigned Size = TRI->getSubRegIdxSize(Idx);
112*0a6a1f1dSLionel Sambuc unsigned RegOffset = TRI->getSubRegIdxOffset(Idx);
113*0a6a1f1dSLionel Sambuc AddReg(Reg, "super-register");
114*0a6a1f1dSLionel Sambuc if (PieceOffsetInBits == RegOffset) {
115*0a6a1f1dSLionel Sambuc AddOpPiece(Size, RegOffset);
116*0a6a1f1dSLionel Sambuc } else {
117*0a6a1f1dSLionel Sambuc // If this is part of a variable in a sub-register at a
118*0a6a1f1dSLionel Sambuc // non-zero offset, we need to manually shift the value into
119*0a6a1f1dSLionel Sambuc // place, since the DW_OP_piece describes the part of the
120*0a6a1f1dSLionel Sambuc // variable, not the position of the subregister.
121*0a6a1f1dSLionel Sambuc if (RegOffset)
122*0a6a1f1dSLionel Sambuc AddShr(RegOffset);
123*0a6a1f1dSLionel Sambuc AddOpPiece(Size, PieceOffsetInBits);
124*0a6a1f1dSLionel Sambuc }
125*0a6a1f1dSLionel Sambuc return true;
126*0a6a1f1dSLionel Sambuc }
127*0a6a1f1dSLionel Sambuc }
128*0a6a1f1dSLionel Sambuc
129*0a6a1f1dSLionel Sambuc // Otherwise, attempt to find a covering set of sub-register numbers.
130*0a6a1f1dSLionel Sambuc // For example, Q0 on ARM is a composition of D0+D1.
131*0a6a1f1dSLionel Sambuc //
132*0a6a1f1dSLionel Sambuc // Keep track of the current position so we can emit the more
133*0a6a1f1dSLionel Sambuc // efficient DW_OP_piece.
134*0a6a1f1dSLionel Sambuc unsigned CurPos = PieceOffsetInBits;
135*0a6a1f1dSLionel Sambuc // The size of the register in bits, assuming 8 bits per byte.
136*0a6a1f1dSLionel Sambuc unsigned RegSize = TRI->getMinimalPhysRegClass(MachineReg)->getSize() * 8;
137*0a6a1f1dSLionel Sambuc // Keep track of the bits in the register we already emitted, so we
138*0a6a1f1dSLionel Sambuc // can avoid emitting redundant aliasing subregs.
139*0a6a1f1dSLionel Sambuc SmallBitVector Coverage(RegSize, false);
140*0a6a1f1dSLionel Sambuc for (MCSubRegIterator SR(MachineReg, TRI); SR.isValid(); ++SR) {
141*0a6a1f1dSLionel Sambuc unsigned Idx = TRI->getSubRegIndex(MachineReg, *SR);
142*0a6a1f1dSLionel Sambuc unsigned Size = TRI->getSubRegIdxSize(Idx);
143*0a6a1f1dSLionel Sambuc unsigned Offset = TRI->getSubRegIdxOffset(Idx);
144*0a6a1f1dSLionel Sambuc Reg = TRI->getDwarfRegNum(*SR, false);
145*0a6a1f1dSLionel Sambuc
146*0a6a1f1dSLionel Sambuc // Intersection between the bits we already emitted and the bits
147*0a6a1f1dSLionel Sambuc // covered by this subregister.
148*0a6a1f1dSLionel Sambuc SmallBitVector Intersection(RegSize, false);
149*0a6a1f1dSLionel Sambuc Intersection.set(Offset, Offset + Size);
150*0a6a1f1dSLionel Sambuc Intersection ^= Coverage;
151*0a6a1f1dSLionel Sambuc
152*0a6a1f1dSLionel Sambuc // If this sub-register has a DWARF number and we haven't covered
153*0a6a1f1dSLionel Sambuc // its range, emit a DWARF piece for it.
154*0a6a1f1dSLionel Sambuc if (Reg >= 0 && Intersection.any()) {
155*0a6a1f1dSLionel Sambuc AddReg(Reg, "sub-register");
156*0a6a1f1dSLionel Sambuc AddOpPiece(Size, Offset == CurPos ? 0 : Offset);
157*0a6a1f1dSLionel Sambuc CurPos = Offset + Size;
158*0a6a1f1dSLionel Sambuc
159*0a6a1f1dSLionel Sambuc // Mark it as emitted.
160*0a6a1f1dSLionel Sambuc Coverage.set(Offset, Offset + Size);
161*0a6a1f1dSLionel Sambuc }
162*0a6a1f1dSLionel Sambuc }
163*0a6a1f1dSLionel Sambuc
164*0a6a1f1dSLionel Sambuc return CurPos > PieceOffsetInBits;
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc
AddSignedConstant(int Value)167*0a6a1f1dSLionel Sambuc void DwarfExpression::AddSignedConstant(int Value) {
168*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_consts);
169*0a6a1f1dSLionel Sambuc EmitSigned(Value);
170*0a6a1f1dSLionel Sambuc // The proper way to describe a constant value is
171*0a6a1f1dSLionel Sambuc // DW_OP_constu <const>, DW_OP_stack_value.
172*0a6a1f1dSLionel Sambuc // Unfortunately, DW_OP_stack_value was not available until DWARF-4,
173*0a6a1f1dSLionel Sambuc // so we will continue to generate DW_OP_constu <const> for DWARF-2
174*0a6a1f1dSLionel Sambuc // and DWARF-3. Technically, this is incorrect since DW_OP_const <const>
175*0a6a1f1dSLionel Sambuc // actually describes a value at a constant addess, not a constant value.
176*0a6a1f1dSLionel Sambuc // However, in the past there was no better way to describe a constant
177*0a6a1f1dSLionel Sambuc // value, so the producers and consumers started to rely on heuristics
178*0a6a1f1dSLionel Sambuc // to disambiguate the value vs. location status of the expression.
179*0a6a1f1dSLionel Sambuc // See PR21176 for more details.
180*0a6a1f1dSLionel Sambuc if (getDwarfVersion() >= 4)
181*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_stack_value);
182*0a6a1f1dSLionel Sambuc }
183*0a6a1f1dSLionel Sambuc
AddUnsignedConstant(unsigned Value)184*0a6a1f1dSLionel Sambuc void DwarfExpression::AddUnsignedConstant(unsigned Value) {
185*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_constu);
186*0a6a1f1dSLionel Sambuc EmitUnsigned(Value);
187*0a6a1f1dSLionel Sambuc // cf. comment in DwarfExpression::AddSignedConstant().
188*0a6a1f1dSLionel Sambuc if (getDwarfVersion() >= 4)
189*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_stack_value);
190*0a6a1f1dSLionel Sambuc }
191*0a6a1f1dSLionel Sambuc
getOffsetOrZero(unsigned OffsetInBits,unsigned PieceOffsetInBits)192*0a6a1f1dSLionel Sambuc static unsigned getOffsetOrZero(unsigned OffsetInBits,
193*0a6a1f1dSLionel Sambuc unsigned PieceOffsetInBits) {
194*0a6a1f1dSLionel Sambuc if (OffsetInBits == PieceOffsetInBits)
195*0a6a1f1dSLionel Sambuc return 0;
196*0a6a1f1dSLionel Sambuc assert(OffsetInBits >= PieceOffsetInBits && "overlapping pieces");
197*0a6a1f1dSLionel Sambuc return OffsetInBits;
198*0a6a1f1dSLionel Sambuc }
199*0a6a1f1dSLionel Sambuc
AddMachineRegExpression(DIExpression Expr,unsigned MachineReg,unsigned PieceOffsetInBits)200*0a6a1f1dSLionel Sambuc bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
201*0a6a1f1dSLionel Sambuc unsigned MachineReg,
202*0a6a1f1dSLionel Sambuc unsigned PieceOffsetInBits) {
203*0a6a1f1dSLionel Sambuc unsigned N = Expr.getNumElements();
204*0a6a1f1dSLionel Sambuc unsigned I = 0;
205*0a6a1f1dSLionel Sambuc bool ValidReg = false;
206*0a6a1f1dSLionel Sambuc // Pattern-match combinations for which more efficient representations exist
207*0a6a1f1dSLionel Sambuc // first.
208*0a6a1f1dSLionel Sambuc if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_piece) {
209*0a6a1f1dSLionel Sambuc unsigned SizeOfByte = 8;
210*0a6a1f1dSLionel Sambuc unsigned OffsetInBits = Expr.getElement(1) * SizeOfByte;
211*0a6a1f1dSLionel Sambuc unsigned SizeInBits = Expr.getElement(2) * SizeOfByte;
212*0a6a1f1dSLionel Sambuc ValidReg =
213*0a6a1f1dSLionel Sambuc AddMachineRegPiece(MachineReg, SizeInBits,
214*0a6a1f1dSLionel Sambuc getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
215*0a6a1f1dSLionel Sambuc I = 3;
216*0a6a1f1dSLionel Sambuc } else if (N >= 3 && Expr.getElement(0) == dwarf::DW_OP_plus &&
217*0a6a1f1dSLionel Sambuc Expr.getElement(2) == dwarf::DW_OP_deref) {
218*0a6a1f1dSLionel Sambuc // [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
219*0a6a1f1dSLionel Sambuc unsigned Offset = Expr.getElement(1);
220*0a6a1f1dSLionel Sambuc ValidReg = AddMachineRegIndirect(MachineReg, Offset);
221*0a6a1f1dSLionel Sambuc I = 3;
222*0a6a1f1dSLionel Sambuc } else if (N >= 1 && Expr.getElement(0) == dwarf::DW_OP_deref) {
223*0a6a1f1dSLionel Sambuc // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
224*0a6a1f1dSLionel Sambuc ValidReg = AddMachineRegIndirect(MachineReg);
225*0a6a1f1dSLionel Sambuc I = 1;
226*0a6a1f1dSLionel Sambuc } else
227*0a6a1f1dSLionel Sambuc ValidReg = AddMachineRegPiece(MachineReg);
228*0a6a1f1dSLionel Sambuc
229*0a6a1f1dSLionel Sambuc if (!ValidReg)
230*0a6a1f1dSLionel Sambuc return false;
231*0a6a1f1dSLionel Sambuc
232*0a6a1f1dSLionel Sambuc // Emit remaining elements of the expression.
233*0a6a1f1dSLionel Sambuc AddExpression(Expr, I);
234*0a6a1f1dSLionel Sambuc return true;
235*0a6a1f1dSLionel Sambuc }
236*0a6a1f1dSLionel Sambuc
AddExpression(DIExpression Expr,unsigned I,unsigned PieceOffsetInBits)237*0a6a1f1dSLionel Sambuc void DwarfExpression::AddExpression(DIExpression Expr, unsigned I,
238*0a6a1f1dSLionel Sambuc unsigned PieceOffsetInBits) {
239*0a6a1f1dSLionel Sambuc unsigned N = Expr.getNumElements();
240*0a6a1f1dSLionel Sambuc for (; I < N; ++I) {
241*0a6a1f1dSLionel Sambuc switch (Expr.getElement(I)) {
242*0a6a1f1dSLionel Sambuc case dwarf::DW_OP_piece: {
243*0a6a1f1dSLionel Sambuc unsigned SizeOfByte = 8;
244*0a6a1f1dSLionel Sambuc unsigned OffsetInBits = Expr.getElement(++I) * SizeOfByte;
245*0a6a1f1dSLionel Sambuc unsigned SizeInBits = Expr.getElement(++I) * SizeOfByte;
246*0a6a1f1dSLionel Sambuc AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
247*0a6a1f1dSLionel Sambuc break;
248*0a6a1f1dSLionel Sambuc }
249*0a6a1f1dSLionel Sambuc case dwarf::DW_OP_plus:
250*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_plus_uconst);
251*0a6a1f1dSLionel Sambuc EmitUnsigned(Expr.getElement(++I));
252*0a6a1f1dSLionel Sambuc break;
253*0a6a1f1dSLionel Sambuc case dwarf::DW_OP_deref:
254*0a6a1f1dSLionel Sambuc EmitOp(dwarf::DW_OP_deref);
255*0a6a1f1dSLionel Sambuc break;
256*0a6a1f1dSLionel Sambuc default:
257*0a6a1f1dSLionel Sambuc llvm_unreachable("unhandled opcode found in DIExpression");
258*0a6a1f1dSLionel Sambuc }
259*0a6a1f1dSLionel Sambuc }
260*0a6a1f1dSLionel Sambuc }
261