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