16e07bfd0SEugene Zelenko //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
2b16d9ebbSAdrian Prantl //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b16d9ebbSAdrian Prantl //
7b16d9ebbSAdrian Prantl //===----------------------------------------------------------------------===//
8b16d9ebbSAdrian Prantl //
9b16d9ebbSAdrian Prantl // This file contains support for writing dwarf debug info into asm files.
10b16d9ebbSAdrian Prantl //
11b16d9ebbSAdrian Prantl //===----------------------------------------------------------------------===//
12b16d9ebbSAdrian Prantl
13b16d9ebbSAdrian Prantl #include "DwarfExpression.h"
14b86ce219SMarkus Lavin #include "DwarfCompileUnit.h"
156e07bfd0SEugene Zelenko #include "llvm/ADT/APInt.h"
16b16d9ebbSAdrian Prantl #include "llvm/ADT/SmallBitVector.h"
17264b5d9eSZachary Turner #include "llvm/BinaryFormat/Dwarf.h"
182bea69bfSDaniel Sanders #include "llvm/CodeGen/Register.h"
19b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
20ef8992b9SSourabh Singh Tomar #include "llvm/IR/DataLayout.h"
216e07bfd0SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
226e07bfd0SEugene Zelenko #include <algorithm>
23b16d9ebbSAdrian Prantl
24b16d9ebbSAdrian Prantl using namespace llvm;
25b16d9ebbSAdrian Prantl
26ef8992b9SSourabh Singh Tomar #define DEBUG_TYPE "dwarfdebug"
27ef8992b9SSourabh Singh Tomar
emitConstu(uint64_t Value)28965b598bSJonas Devlieghere void DwarfExpression::emitConstu(uint64_t Value) {
29965b598bSJonas Devlieghere if (Value < 32)
30965b598bSJonas Devlieghere emitOp(dwarf::DW_OP_lit0 + Value);
31965b598bSJonas Devlieghere else if (Value == std::numeric_limits<uint64_t>::max()) {
32965b598bSJonas Devlieghere // Only do this for 64-bit values as the DWARF expression stack uses
33965b598bSJonas Devlieghere // target-address-size values.
34965b598bSJonas Devlieghere emitOp(dwarf::DW_OP_lit0);
35965b598bSJonas Devlieghere emitOp(dwarf::DW_OP_not);
36965b598bSJonas Devlieghere } else {
37965b598bSJonas Devlieghere emitOp(dwarf::DW_OP_constu);
38965b598bSJonas Devlieghere emitUnsigned(Value);
39965b598bSJonas Devlieghere }
40965b598bSJonas Devlieghere }
41965b598bSJonas Devlieghere
addReg(int DwarfReg,const char * Comment)42a63b8e82SAdrian Prantl void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
43b16d9ebbSAdrian Prantl assert(DwarfReg >= 0 && "invalid negative dwarf register number");
44ff47d83eSPetar Jovanovic assert((isUnknownLocation() || isRegisterLocation()) &&
456825fb64SAdrian Prantl "location description already locked down");
466825fb64SAdrian Prantl LocationKind = Register;
47b16d9ebbSAdrian Prantl if (DwarfReg < 32) {
48a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
49b16d9ebbSAdrian Prantl } else {
50a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_regx, Comment);
51a63b8e82SAdrian Prantl emitUnsigned(DwarfReg);
52b16d9ebbSAdrian Prantl }
53b16d9ebbSAdrian Prantl }
54b16d9ebbSAdrian Prantl
addBReg(int DwarfReg,int Offset)55a2719885SAdrian Prantl void DwarfExpression::addBReg(int DwarfReg, int Offset) {
56b16d9ebbSAdrian Prantl assert(DwarfReg >= 0 && "invalid negative dwarf register number");
57ff47d83eSPetar Jovanovic assert(!isRegisterLocation() && "location description already locked down");
58b16d9ebbSAdrian Prantl if (DwarfReg < 32) {
59a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_breg0 + DwarfReg);
60b16d9ebbSAdrian Prantl } else {
61a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_bregx);
62a63b8e82SAdrian Prantl emitUnsigned(DwarfReg);
63b16d9ebbSAdrian Prantl }
64a63b8e82SAdrian Prantl emitSigned(Offset);
65b16d9ebbSAdrian Prantl }
66b16d9ebbSAdrian Prantl
addFBReg(int Offset)6780e188d9SAdrian Prantl void DwarfExpression::addFBReg(int Offset) {
6880e188d9SAdrian Prantl emitOp(dwarf::DW_OP_fbreg);
6980e188d9SAdrian Prantl emitSigned(Offset);
7080e188d9SAdrian Prantl }
7180e188d9SAdrian Prantl
addOpPiece(unsigned SizeInBits,unsigned OffsetInBits)72a63b8e82SAdrian Prantl void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
738fafb8d3SAdrian Prantl if (!SizeInBits)
748fafb8d3SAdrian Prantl return;
758fafb8d3SAdrian Prantl
76b16d9ebbSAdrian Prantl const unsigned SizeOfByte = 8;
77b16d9ebbSAdrian Prantl if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
78a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_bit_piece);
79a63b8e82SAdrian Prantl emitUnsigned(SizeInBits);
80a63b8e82SAdrian Prantl emitUnsigned(OffsetInBits);
81b16d9ebbSAdrian Prantl } else {
82a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_piece);
83b16d9ebbSAdrian Prantl unsigned ByteSize = SizeInBits / SizeOfByte;
84a63b8e82SAdrian Prantl emitUnsigned(ByteSize);
85b16d9ebbSAdrian Prantl }
868fafb8d3SAdrian Prantl this->OffsetInBits += SizeInBits;
87b16d9ebbSAdrian Prantl }
88b16d9ebbSAdrian Prantl
addShr(unsigned ShiftBy)89a63b8e82SAdrian Prantl void DwarfExpression::addShr(unsigned ShiftBy) {
90965b598bSJonas Devlieghere emitConstu(ShiftBy);
91a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_shr);
92b16d9ebbSAdrian Prantl }
93b16d9ebbSAdrian Prantl
addAnd(unsigned Mask)94a63b8e82SAdrian Prantl void DwarfExpression::addAnd(unsigned Mask) {
95965b598bSJonas Devlieghere emitConstu(Mask);
96a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_and);
97981f03e6SAdrian Prantl }
98981f03e6SAdrian Prantl
addMachineReg(const TargetRegisterInfo & TRI,llvm::Register MachineReg,unsigned MaxSize)99a63b8e82SAdrian Prantl bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
100ee476968SFangrui Song llvm::Register MachineReg,
101ee476968SFangrui Song unsigned MaxSize) {
1022bea69bfSDaniel Sanders if (!llvm::Register::isPhysicalRegister(MachineReg)) {
10380e188d9SAdrian Prantl if (isFrameRegister(TRI, MachineReg)) {
104a095d149SAdrian Prantl DwarfRegs.push_back(Register::createRegister(-1, nullptr));
10580e188d9SAdrian Prantl return true;
10680e188d9SAdrian Prantl }
10740cb819cSAdrian Prantl return false;
10880e188d9SAdrian Prantl }
10940cb819cSAdrian Prantl
11092da14b2SAdrian Prantl int Reg = TRI.getDwarfRegNum(MachineReg, false);
111b16d9ebbSAdrian Prantl
112b16d9ebbSAdrian Prantl // If this is a valid register number, emit it.
113b16d9ebbSAdrian Prantl if (Reg >= 0) {
114a095d149SAdrian Prantl DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
115ad768c37SAdrian Prantl return true;
116b16d9ebbSAdrian Prantl }
117b16d9ebbSAdrian Prantl
118b16d9ebbSAdrian Prantl // Walk up the super-register chain until we find a valid number.
119941fa758SAdrian Prantl // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
12092da14b2SAdrian Prantl for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
12192da14b2SAdrian Prantl Reg = TRI.getDwarfRegNum(*SR, false);
122b16d9ebbSAdrian Prantl if (Reg >= 0) {
12392da14b2SAdrian Prantl unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
12492da14b2SAdrian Prantl unsigned Size = TRI.getSubRegIdxSize(Idx);
12592da14b2SAdrian Prantl unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
126a095d149SAdrian Prantl DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
1278fafb8d3SAdrian Prantl // Use a DW_OP_bit_piece to describe the sub-register.
1288fafb8d3SAdrian Prantl setSubRegisterPiece(Size, RegOffset);
129ad768c37SAdrian Prantl return true;
130b16d9ebbSAdrian Prantl }
131b16d9ebbSAdrian Prantl }
132b16d9ebbSAdrian Prantl
133b16d9ebbSAdrian Prantl // Otherwise, attempt to find a covering set of sub-register numbers.
134b16d9ebbSAdrian Prantl // For example, Q0 on ARM is a composition of D0+D1.
1358fafb8d3SAdrian Prantl unsigned CurPos = 0;
13644e25f37SKrzysztof Parzyszek // The size of the register in bits.
13744e25f37SKrzysztof Parzyszek const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
13844e25f37SKrzysztof Parzyszek unsigned RegSize = TRI.getRegSizeInBits(*RC);
139b16d9ebbSAdrian Prantl // Keep track of the bits in the register we already emitted, so we
140984251c7SAdrian Prantl // can avoid emitting redundant aliasing subregs. Because this is
141984251c7SAdrian Prantl // just doing a greedy scan of all subregisters, it is possible that
142984251c7SAdrian Prantl // this doesn't find a combination of subregisters that fully cover
143984251c7SAdrian Prantl // the register (even though one may exist).
144b16d9ebbSAdrian Prantl SmallBitVector Coverage(RegSize, false);
14592da14b2SAdrian Prantl for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
14692da14b2SAdrian Prantl unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
14792da14b2SAdrian Prantl unsigned Size = TRI.getSubRegIdxSize(Idx);
14892da14b2SAdrian Prantl unsigned Offset = TRI.getSubRegIdxOffset(Idx);
14992da14b2SAdrian Prantl Reg = TRI.getDwarfRegNum(*SR, false);
1503a3ba77bSAdrian Prantl if (Reg < 0)
1513a3ba77bSAdrian Prantl continue;
152b16d9ebbSAdrian Prantl
153a095d149SAdrian Prantl // Used to build the intersection between the bits we already
154a095d149SAdrian Prantl // emitted and the bits covered by this subregister.
1554cae1085SAdrian Prantl SmallBitVector CurSubReg(RegSize, false);
1564cae1085SAdrian Prantl CurSubReg.set(Offset, Offset + Size);
157b16d9ebbSAdrian Prantl
158b16d9ebbSAdrian Prantl // If this sub-register has a DWARF number and we haven't covered
1595da385fbSAdrian Prantl // its range, and its range covers the value, emit a DWARF piece for it.
1605da385fbSAdrian Prantl if (Offset < MaxSize && CurSubReg.test(Coverage)) {
16180e188d9SAdrian Prantl // Emit a piece for any gap in the coverage.
16280e188d9SAdrian Prantl if (Offset > CurPos)
163a095d149SAdrian Prantl DwarfRegs.push_back(Register::createSubRegister(
164a095d149SAdrian Prantl -1, Offset - CurPos, "no DWARF register encoding"));
165a095d149SAdrian Prantl if (Offset == 0 && Size >= MaxSize)
166a095d149SAdrian Prantl DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));
167a095d149SAdrian Prantl else
168a095d149SAdrian Prantl DwarfRegs.push_back(Register::createSubRegister(
169a095d149SAdrian Prantl Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));
1705da385fbSAdrian Prantl }
171b16d9ebbSAdrian Prantl // Mark it as emitted.
172b16d9ebbSAdrian Prantl Coverage.set(Offset, Offset + Size);
17380e188d9SAdrian Prantl CurPos = Offset + Size;
174b16d9ebbSAdrian Prantl }
175984251c7SAdrian Prantl // Failed to find any DWARF encoding.
176984251c7SAdrian Prantl if (CurPos == 0)
177984251c7SAdrian Prantl return false;
178984251c7SAdrian Prantl // Found a partial or complete DWARF encoding.
179984251c7SAdrian Prantl if (CurPos < RegSize)
180a095d149SAdrian Prantl DwarfRegs.push_back(Register::createSubRegister(
181a095d149SAdrian Prantl -1, RegSize - CurPos, "no DWARF register encoding"));
182984251c7SAdrian Prantl return true;
183b16d9ebbSAdrian Prantl }
18466f25958SAdrian Prantl
addStackValue()185a63b8e82SAdrian Prantl void DwarfExpression::addStackValue() {
1863e9c8875SAdrian Prantl if (DwarfVersion >= 4)
187a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_stack_value);
1883e9c8875SAdrian Prantl }
1893e9c8875SAdrian Prantl
addSignedConstant(int64_t Value)190a63b8e82SAdrian Prantl void DwarfExpression::addSignedConstant(int64_t Value) {
191ff47d83eSPetar Jovanovic assert(isImplicitLocation() || isUnknownLocation());
1926825fb64SAdrian Prantl LocationKind = Implicit;
193a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_consts);
194a63b8e82SAdrian Prantl emitSigned(Value);
19566f25958SAdrian Prantl }
19666f25958SAdrian Prantl
addUnsignedConstant(uint64_t Value)197a63b8e82SAdrian Prantl void DwarfExpression::addUnsignedConstant(uint64_t Value) {
198ff47d83eSPetar Jovanovic assert(isImplicitLocation() || isUnknownLocation());
1996825fb64SAdrian Prantl LocationKind = Implicit;
200965b598bSJonas Devlieghere emitConstu(Value);
2013e9c8875SAdrian Prantl }
2023e9c8875SAdrian Prantl
addUnsignedConstant(const APInt & Value)203bce2ac9fSPavel Labath void DwarfExpression::addUnsignedConstant(const APInt &Value) {
204ff47d83eSPetar Jovanovic assert(isImplicitLocation() || isUnknownLocation());
2056825fb64SAdrian Prantl LocationKind = Implicit;
2066825fb64SAdrian Prantl
2073e9c8875SAdrian Prantl unsigned Size = Value.getBitWidth();
2083e9c8875SAdrian Prantl const uint64_t *Data = Value.getRawData();
2093e9c8875SAdrian Prantl
2103e9c8875SAdrian Prantl // Chop it up into 64-bit pieces, because that's the maximum that
211a63b8e82SAdrian Prantl // addUnsignedConstant takes.
2123e9c8875SAdrian Prantl unsigned Offset = 0;
2133e9c8875SAdrian Prantl while (Offset < Size) {
214a63b8e82SAdrian Prantl addUnsignedConstant(*Data++);
2153e9c8875SAdrian Prantl if (Offset == 0 && Size <= 64)
2163e9c8875SAdrian Prantl break;
217bce2ac9fSPavel Labath addStackValue();
218a63b8e82SAdrian Prantl addOpPiece(std::min(Size - Offset, 64u), Offset);
2193e9c8875SAdrian Prantl Offset += 64;
2203e9c8875SAdrian Prantl }
22166f25958SAdrian Prantl }
222092d9489SAdrian Prantl
addConstantFP(const APFloat & APF,const AsmPrinter & AP)223ef8992b9SSourabh Singh Tomar void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
224ef8992b9SSourabh Singh Tomar assert(isImplicitLocation() || isUnknownLocation());
225ef8992b9SSourabh Singh Tomar APInt API = APF.bitcastToAPInt();
226ef8992b9SSourabh Singh Tomar int NumBytes = API.getBitWidth() / 8;
227bce2ac9fSPavel Labath if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
228ef8992b9SSourabh Singh Tomar // FIXME: Add support for `long double`.
229bce2ac9fSPavel Labath emitOp(dwarf::DW_OP_implicit_value);
230bce2ac9fSPavel Labath emitUnsigned(NumBytes /*Size of the block in bytes*/);
231bce2ac9fSPavel Labath
232bce2ac9fSPavel Labath // The loop below is emitting the value starting at least significant byte,
233bce2ac9fSPavel Labath // so we need to perform a byte-swap to get the byte order correct in case
234bce2ac9fSPavel Labath // of a big-endian target.
235bce2ac9fSPavel Labath if (AP.getDataLayout().isBigEndian())
236bce2ac9fSPavel Labath API = API.byteSwap();
237bce2ac9fSPavel Labath
238bce2ac9fSPavel Labath for (int i = 0; i < NumBytes; ++i) {
239bce2ac9fSPavel Labath emitData1(API.getZExtValue() & 0xFF);
240bce2ac9fSPavel Labath API = API.lshr(8);
241bce2ac9fSPavel Labath }
242bce2ac9fSPavel Labath
243bce2ac9fSPavel Labath return;
244bce2ac9fSPavel Labath }
245ef8992b9SSourabh Singh Tomar LLVM_DEBUG(
246bce2ac9fSPavel Labath dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
247ef8992b9SSourabh Singh Tomar << API.getBitWidth() << " bits\n");
248ef8992b9SSourabh Singh Tomar }
249ef8992b9SSourabh Singh Tomar
addMachineRegExpression(const TargetRegisterInfo & TRI,DIExpressionCursor & ExprCursor,llvm::Register MachineReg,unsigned FragmentOffsetInBits)250c12cee36SAdrian Prantl bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
25154286bdaSAdrian Prantl DIExpressionCursor &ExprCursor,
252ee476968SFangrui Song llvm::Register MachineReg,
253941fa758SAdrian Prantl unsigned FragmentOffsetInBits) {
25480e188d9SAdrian Prantl auto Fragment = ExprCursor.getFragmentInfo();
255dd215024SAdrian Prantl if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
256dd215024SAdrian Prantl LocationKind = Unknown;
25780e188d9SAdrian Prantl return false;
258dd215024SAdrian Prantl }
259531641a0SAdrian Prantl
26080e188d9SAdrian Prantl bool HasComplexExpression = false;
2614dc0324fSAdrian Prantl auto Op = ExprCursor.peek();
26280e188d9SAdrian Prantl if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
26380e188d9SAdrian Prantl HasComplexExpression = true;
26480e188d9SAdrian Prantl
2650498baa4SAdrian Prantl // If the register can only be described by a complex expression (i.e.,
2660498baa4SAdrian Prantl // multiple subregisters) it doesn't safely compose with another complex
2670498baa4SAdrian Prantl // expression. For example, it is not possible to apply a DW_OP_deref
26885460c4eSDavid Stenberg // operation to multiple DW_OP_pieces, since composite location descriptions
26985460c4eSDavid Stenberg // do not push anything on the DWARF stack.
27085460c4eSDavid Stenberg //
27185460c4eSDavid Stenberg // DW_OP_entry_value operations can only hold a DWARF expression or a
27285460c4eSDavid Stenberg // register location description, so we can't emit a single entry value
27385460c4eSDavid Stenberg // covering a composite location description. In the future we may want to
27485460c4eSDavid Stenberg // emit entry value operations for each register location in the composite
27585460c4eSDavid Stenberg // location, but until that is supported do not emit anything.
27685460c4eSDavid Stenberg if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
27785460c4eSDavid Stenberg if (IsEmittingEntryValue)
27885460c4eSDavid Stenberg cancelEntryValue();
2790498baa4SAdrian Prantl DwarfRegs.clear();
280dd215024SAdrian Prantl LocationKind = Unknown;
2810498baa4SAdrian Prantl return false;
2820498baa4SAdrian Prantl }
2830498baa4SAdrian Prantl
284b9973f87SDjordje Todorovic // Handle simple register locations. If we are supposed to emit
285b9973f87SDjordje Todorovic // a call site parameter expression and if that expression is just a register
286b9973f87SDjordje Todorovic // location, emit it with addBReg and offset 0, because we should emit a DWARF
287b9973f87SDjordje Todorovic // expression representing a value, rather than a location.
28809b832e7SAdrian Prantl if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
28909b832e7SAdrian Prantl isEntryValue()) {
290f85c6b79SAdrian Prantl auto FragmentInfo = ExprCursor.getFragmentInfo();
291f85c6b79SAdrian Prantl unsigned RegSize = 0;
29280e188d9SAdrian Prantl for (auto &Reg : DwarfRegs) {
293f85c6b79SAdrian Prantl RegSize += Reg.SubRegSize;
29480e188d9SAdrian Prantl if (Reg.DwarfRegNo >= 0)
29580e188d9SAdrian Prantl addReg(Reg.DwarfRegNo, Reg.Comment);
296f85c6b79SAdrian Prantl if (FragmentInfo)
297f85c6b79SAdrian Prantl if (RegSize > FragmentInfo->SizeInBits)
298f85c6b79SAdrian Prantl // If the register is larger than the current fragment stop
299f85c6b79SAdrian Prantl // once the fragment is covered.
300f85c6b79SAdrian Prantl break;
301a095d149SAdrian Prantl addOpPiece(Reg.SubRegSize);
30280e188d9SAdrian Prantl }
303a0d45058SDjordje Todorovic
30409b832e7SAdrian Prantl if (isEntryValue()) {
3051ae2d9a2SDavid Stenberg finalizeEntryValue();
3061ae2d9a2SDavid Stenberg
30709b832e7SAdrian Prantl if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&
3086e39379bSVedant Kumar DwarfVersion >= 4)
309a0d45058SDjordje Todorovic emitOp(dwarf::DW_OP_stack_value);
31009b832e7SAdrian Prantl }
311a0d45058SDjordje Todorovic
31280e188d9SAdrian Prantl DwarfRegs.clear();
313e64f3cccSStephen Tozer // If we need to mask out a subregister, do it now, unless the next
314e64f3cccSStephen Tozer // operation would emit an OpPiece anyway.
315e64f3cccSStephen Tozer auto NextOp = ExprCursor.peek();
316e64f3cccSStephen Tozer if (SubRegisterSizeInBits && NextOp &&
317e64f3cccSStephen Tozer (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
318e64f3cccSStephen Tozer maskSubRegister();
31980e188d9SAdrian Prantl return true;
32080e188d9SAdrian Prantl }
32180e188d9SAdrian Prantl
3226825fb64SAdrian Prantl // Don't emit locations that cannot be expressed without DW_OP_stack_value.
323ada10488SAdrian Prantl if (DwarfVersion < 4)
3242e83b2e9SFangrui Song if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
325ada10488SAdrian Prantl return Op.getOp() == dwarf::DW_OP_stack_value;
326ada10488SAdrian Prantl })) {
327ada10488SAdrian Prantl DwarfRegs.clear();
328dd215024SAdrian Prantl LocationKind = Unknown;
329ada10488SAdrian Prantl return false;
330ada10488SAdrian Prantl }
3316825fb64SAdrian Prantl
332*3f7a6ce0SJohannes Doerfert // TODO: We should not give up here but the following code needs to be changed
333*3f7a6ce0SJohannes Doerfert // to deal with multiple (sub)registers first.
334*3f7a6ce0SJohannes Doerfert if (DwarfRegs.size() > 1) {
335*3f7a6ce0SJohannes Doerfert LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "
336*3f7a6ce0SJohannes Doerfert "multi-register usage.\n");
337*3f7a6ce0SJohannes Doerfert DwarfRegs.clear();
338*3f7a6ce0SJohannes Doerfert LocationKind = Unknown;
339*3f7a6ce0SJohannes Doerfert return false;
340*3f7a6ce0SJohannes Doerfert }
341*3f7a6ce0SJohannes Doerfert
34280e188d9SAdrian Prantl auto Reg = DwarfRegs[0];
34380e188d9SAdrian Prantl bool FBReg = isFrameRegister(TRI, MachineReg);
3446825fb64SAdrian Prantl int SignedOffset = 0;
345a095d149SAdrian Prantl assert(!Reg.isSubRegister() && "full register expected");
34680e188d9SAdrian Prantl
34780e188d9SAdrian Prantl // Pattern-match combinations for which more efficient representations exist.
348c9c403c0SFlorian Hahn // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
349c9c403c0SFlorian Hahn if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
3502b698a13SBjorn Pettersson uint64_t Offset = Op->getArg(0);
3512b698a13SBjorn Pettersson uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
3522b698a13SBjorn Pettersson if (Offset <= IntMax) {
3532b698a13SBjorn Pettersson SignedOffset = Offset;
354c9c403c0SFlorian Hahn ExprCursor.take();
355c9c403c0SFlorian Hahn }
3562b698a13SBjorn Pettersson }
357c9c403c0SFlorian Hahn
358ffc498dfSFlorian Hahn // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
359ffc498dfSFlorian Hahn // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
3606825fb64SAdrian Prantl // If Reg is a subregister we need to mask it out before subtracting.
361ffc498dfSFlorian Hahn if (Op && Op->getOp() == dwarf::DW_OP_constu) {
3622b698a13SBjorn Pettersson uint64_t Offset = Op->getArg(0);
3632b698a13SBjorn Pettersson uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
364ffc498dfSFlorian Hahn auto N = ExprCursor.peekNext();
3652b698a13SBjorn Pettersson if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
3662b698a13SBjorn Pettersson SignedOffset = Offset;
3672b698a13SBjorn Pettersson ExprCursor.consume(2);
3682b698a13SBjorn Pettersson } else if (N && N->getOp() == dwarf::DW_OP_minus &&
3692b698a13SBjorn Pettersson !SubRegisterSizeInBits && Offset <= IntMax + 1) {
3702b698a13SBjorn Pettersson SignedOffset = -static_cast<int64_t>(Offset);
371ffc498dfSFlorian Hahn ExprCursor.consume(2);
3726825fb64SAdrian Prantl }
373ffc498dfSFlorian Hahn }
374ffc498dfSFlorian Hahn
37580e188d9SAdrian Prantl if (FBReg)
37680e188d9SAdrian Prantl addFBReg(SignedOffset);
37780e188d9SAdrian Prantl else
378a2719885SAdrian Prantl addBReg(Reg.DwarfRegNo, SignedOffset);
37980e188d9SAdrian Prantl DwarfRegs.clear();
380e64f3cccSStephen Tozer
381e64f3cccSStephen Tozer // If we need to mask out a subregister, do it now, unless the next
382e64f3cccSStephen Tozer // operation would emit an OpPiece anyway.
383e64f3cccSStephen Tozer auto NextOp = ExprCursor.peek();
384e64f3cccSStephen Tozer if (SubRegisterSizeInBits && NextOp &&
385e64f3cccSStephen Tozer (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
386e64f3cccSStephen Tozer maskSubRegister();
387e64f3cccSStephen Tozer
38880e188d9SAdrian Prantl return true;
389092d9489SAdrian Prantl }
390092d9489SAdrian Prantl
setEntryValueFlags(const MachineLocation & Loc)3916e39379bSVedant Kumar void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) {
3926e39379bSVedant Kumar LocationFlags |= EntryValue;
3936e39379bSVedant Kumar if (Loc.isIndirect())
3946e39379bSVedant Kumar LocationFlags |= Indirect;
3956e39379bSVedant Kumar }
3966e39379bSVedant Kumar
setLocation(const MachineLocation & Loc,const DIExpression * DIExpr)3976e39379bSVedant Kumar void DwarfExpression::setLocation(const MachineLocation &Loc,
3986e39379bSVedant Kumar const DIExpression *DIExpr) {
3996e39379bSVedant Kumar if (Loc.isIndirect())
4006e39379bSVedant Kumar setMemoryLocationKind();
4016e39379bSVedant Kumar
4026e39379bSVedant Kumar if (DIExpr->isEntryValue())
4036e39379bSVedant Kumar setEntryValueFlags(Loc);
4046e39379bSVedant Kumar }
4056e39379bSVedant Kumar
beginEntryValueExpression(DIExpressionCursor & ExprCursor)4061ae2d9a2SDavid Stenberg void DwarfExpression::beginEntryValueExpression(
4071ae2d9a2SDavid Stenberg DIExpressionCursor &ExprCursor) {
408a0d45058SDjordje Todorovic auto Op = ExprCursor.take();
409ce00cd6aSBenjamin Kramer (void)Op;
4101ae2d9a2SDavid Stenberg assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value);
4111ae2d9a2SDavid Stenberg assert(!IsEmittingEntryValue && "Already emitting entry value?");
4121ae2d9a2SDavid Stenberg assert(Op->getArg(0) == 1 &&
4131ae2d9a2SDavid Stenberg "Can currently only emit entry values covering a single operation");
414a0d45058SDjordje Todorovic
415982b8919SAdrian Prantl SavedLocationKind = LocationKind;
416982b8919SAdrian Prantl LocationKind = Register;
4171ae2d9a2SDavid Stenberg IsEmittingEntryValue = true;
4181ae2d9a2SDavid Stenberg enableTemporaryBuffer();
4191ae2d9a2SDavid Stenberg }
4201ae2d9a2SDavid Stenberg
finalizeEntryValue()4211ae2d9a2SDavid Stenberg void DwarfExpression::finalizeEntryValue() {
4221ae2d9a2SDavid Stenberg assert(IsEmittingEntryValue && "Entry value not open?");
4231ae2d9a2SDavid Stenberg disableTemporaryBuffer();
4241ae2d9a2SDavid Stenberg
42585460c4eSDavid Stenberg emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
42685460c4eSDavid Stenberg
4271ae2d9a2SDavid Stenberg // Emit the entry value's size operand.
4281ae2d9a2SDavid Stenberg unsigned Size = getTemporaryBufferSize();
4291ae2d9a2SDavid Stenberg emitUnsigned(Size);
4301ae2d9a2SDavid Stenberg
4311ae2d9a2SDavid Stenberg // Emit the entry value's DWARF block operand.
4321ae2d9a2SDavid Stenberg commitTemporaryBuffer();
4331ae2d9a2SDavid Stenberg
434c4ad878aSAdrian Prantl LocationFlags &= ~EntryValue;
435982b8919SAdrian Prantl LocationKind = SavedLocationKind;
4361ae2d9a2SDavid Stenberg IsEmittingEntryValue = false;
437a0d45058SDjordje Todorovic }
438a0d45058SDjordje Todorovic
cancelEntryValue()43985460c4eSDavid Stenberg void DwarfExpression::cancelEntryValue() {
44085460c4eSDavid Stenberg assert(IsEmittingEntryValue && "Entry value not open?");
44185460c4eSDavid Stenberg disableTemporaryBuffer();
44285460c4eSDavid Stenberg
44385460c4eSDavid Stenberg // The temporary buffer can't be emptied, so for now just assert that nothing
44485460c4eSDavid Stenberg // has been emitted to it.
44585460c4eSDavid Stenberg assert(getTemporaryBufferSize() == 0 &&
44685460c4eSDavid Stenberg "Began emitting entry value block before cancelling entry value");
44785460c4eSDavid Stenberg
448982b8919SAdrian Prantl LocationKind = SavedLocationKind;
44985460c4eSDavid Stenberg IsEmittingEntryValue = false;
45085460c4eSDavid Stenberg }
45185460c4eSDavid Stenberg
getOrCreateBaseType(unsigned BitSize,dwarf::TypeKind Encoding)452816ee8a4SAdrian Prantl unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
453816ee8a4SAdrian Prantl dwarf::TypeKind Encoding) {
454816ee8a4SAdrian Prantl // Reuse the base_type if we already have one in this CU otherwise we
455816ee8a4SAdrian Prantl // create a new one.
456816ee8a4SAdrian Prantl unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
457816ee8a4SAdrian Prantl for (; I != E; ++I)
458816ee8a4SAdrian Prantl if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
459816ee8a4SAdrian Prantl CU.ExprRefedBaseTypes[I].Encoding == Encoding)
460816ee8a4SAdrian Prantl break;
461816ee8a4SAdrian Prantl
462816ee8a4SAdrian Prantl if (I == E)
463816ee8a4SAdrian Prantl CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
464816ee8a4SAdrian Prantl return I;
465816ee8a4SAdrian Prantl }
466816ee8a4SAdrian Prantl
46718dbe1b2SAdrian Prantl /// Assuming a well-formed expression, match "DW_OP_deref*
46818dbe1b2SAdrian Prantl /// DW_OP_LLVM_fragment?".
isMemoryLocation(DIExpressionCursor ExprCursor)4696825fb64SAdrian Prantl static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
4706825fb64SAdrian Prantl while (ExprCursor) {
4716825fb64SAdrian Prantl auto Op = ExprCursor.take();
4726825fb64SAdrian Prantl switch (Op->getOp()) {
4736825fb64SAdrian Prantl case dwarf::DW_OP_deref:
4746825fb64SAdrian Prantl case dwarf::DW_OP_LLVM_fragment:
4756825fb64SAdrian Prantl break;
4766825fb64SAdrian Prantl default:
4776825fb64SAdrian Prantl return false;
4786825fb64SAdrian Prantl }
4796825fb64SAdrian Prantl }
4806825fb64SAdrian Prantl return true;
4816825fb64SAdrian Prantl }
4826825fb64SAdrian Prantl
addExpression(DIExpressionCursor && ExprCursor)483c7c84b90SAdrian Prantl void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor) {
484e64f3cccSStephen Tozer addExpression(std::move(ExprCursor),
485e64f3cccSStephen Tozer [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
486e64f3cccSStephen Tozer llvm_unreachable("unhandled opcode found in expression");
487e64f3cccSStephen Tozer });
488e64f3cccSStephen Tozer }
489e64f3cccSStephen Tozer
addExpression(DIExpressionCursor && ExprCursor,llvm::function_ref<bool (unsigned,DIExpressionCursor &)> InsertArg)490c7c84b90SAdrian Prantl bool DwarfExpression::addExpression(
491e64f3cccSStephen Tozer DIExpressionCursor &&ExprCursor,
49280d1f657SDavid Blaikie llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
49385460c4eSDavid Stenberg // Entry values can currently only cover the initial register location,
49485460c4eSDavid Stenberg // and not any other parts of the following DWARF expression.
49585460c4eSDavid Stenberg assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
49685460c4eSDavid Stenberg
497b86ce219SMarkus Lavin Optional<DIExpression::ExprOperand> PrevConvertOp = None;
498b86ce219SMarkus Lavin
4996825fb64SAdrian Prantl while (ExprCursor) {
5006825fb64SAdrian Prantl auto Op = ExprCursor.take();
501b9973f87SDjordje Todorovic uint64_t OpNum = Op->getOp();
502b9973f87SDjordje Todorovic
503b9973f87SDjordje Todorovic if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
504b9973f87SDjordje Todorovic emitOp(OpNum);
505b9973f87SDjordje Todorovic continue;
506b9973f87SDjordje Todorovic } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
507b9973f87SDjordje Todorovic addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
508b9973f87SDjordje Todorovic continue;
509b9973f87SDjordje Todorovic }
510b9973f87SDjordje Todorovic
511b9973f87SDjordje Todorovic switch (OpNum) {
512e64f3cccSStephen Tozer case dwarf::DW_OP_LLVM_arg:
513e64f3cccSStephen Tozer if (!InsertArg(Op->getArg(0), ExprCursor)) {
514e64f3cccSStephen Tozer LocationKind = Unknown;
515c7c84b90SAdrian Prantl return false;
516e64f3cccSStephen Tozer }
517e64f3cccSStephen Tozer break;
518941fa758SAdrian Prantl case dwarf::DW_OP_LLVM_fragment: {
51954286bdaSAdrian Prantl unsigned SizeInBits = Op->getArg(1);
5208fafb8d3SAdrian Prantl unsigned FragmentOffset = Op->getArg(0);
5218fafb8d3SAdrian Prantl // The fragment offset must have already been adjusted by emitting an
5228fafb8d3SAdrian Prantl // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
5238fafb8d3SAdrian Prantl // location.
5248fafb8d3SAdrian Prantl assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
5255da385fbSAdrian Prantl assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
5268fafb8d3SAdrian Prantl
5276825fb64SAdrian Prantl // If addMachineReg already emitted DW_OP_piece operations to represent
5288fafb8d3SAdrian Prantl // a super-register by splicing together sub-registers, subtract the size
5298fafb8d3SAdrian Prantl // of the pieces that was already emitted.
5308fafb8d3SAdrian Prantl SizeInBits -= OffsetInBits - FragmentOffset;
5318fafb8d3SAdrian Prantl
5326825fb64SAdrian Prantl // If addMachineReg requested a DW_OP_bit_piece to stencil out a
5338fafb8d3SAdrian Prantl // sub-register that is smaller than the current fragment's size, use it.
5348fafb8d3SAdrian Prantl if (SubRegisterSizeInBits)
5358fafb8d3SAdrian Prantl SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
5368fafb8d3SAdrian Prantl
5376825fb64SAdrian Prantl // Emit a DW_OP_stack_value for implicit location descriptions.
538ff47d83eSPetar Jovanovic if (isImplicitLocation())
5396825fb64SAdrian Prantl addStackValue();
5406825fb64SAdrian Prantl
5416825fb64SAdrian Prantl // Emit the DW_OP_piece.
542a63b8e82SAdrian Prantl addOpPiece(SizeInBits, SubRegisterOffsetInBits);
5438fafb8d3SAdrian Prantl setSubRegisterPiece(0, 0);
5446825fb64SAdrian Prantl // Reset the location description kind.
5456825fb64SAdrian Prantl LocationKind = Unknown;
546c7c84b90SAdrian Prantl return true;
547092d9489SAdrian Prantl }
548c9c403c0SFlorian Hahn case dwarf::DW_OP_plus_uconst:
549ff47d83eSPetar Jovanovic assert(!isRegisterLocation());
550a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_plus_uconst);
551a63b8e82SAdrian Prantl emitUnsigned(Op->getArg(0));
552092d9489SAdrian Prantl break;
553ffc498dfSFlorian Hahn case dwarf::DW_OP_plus:
554f608111dSEvgeniy Stepanov case dwarf::DW_OP_minus:
55529202f6dSStrahinja Petrovic case dwarf::DW_OP_mul:
5564011c26cSVedant Kumar case dwarf::DW_OP_div:
5574011c26cSVedant Kumar case dwarf::DW_OP_mod:
55804386d8eSVedant Kumar case dwarf::DW_OP_or:
5591768957cSPetar Jovanovic case dwarf::DW_OP_and:
56096b7dc04SVedant Kumar case dwarf::DW_OP_xor:
56131ec356aSVedant Kumar case dwarf::DW_OP_shl:
56231ec356aSVedant Kumar case dwarf::DW_OP_shr:
56331ec356aSVedant Kumar case dwarf::DW_OP_shra:
5646379a622SVedant Kumar case dwarf::DW_OP_lit0:
5656379a622SVedant Kumar case dwarf::DW_OP_not:
5666379a622SVedant Kumar case dwarf::DW_OP_dup:
567ab699d78SAlok Kumar Sharma case dwarf::DW_OP_push_object_address:
5680538353bSAlok Kumar Sharma case dwarf::DW_OP_over:
569b9973f87SDjordje Todorovic emitOp(OpNum);
570f608111dSEvgeniy Stepanov break;
5716e07bfd0SEugene Zelenko case dwarf::DW_OP_deref:
572ff47d83eSPetar Jovanovic assert(!isRegisterLocation());
573ff47d83eSPetar Jovanovic if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
5746825fb64SAdrian Prantl // Turning this into a memory location description makes the deref
5756825fb64SAdrian Prantl // implicit.
5766825fb64SAdrian Prantl LocationKind = Memory;
5776825fb64SAdrian Prantl else
578a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_deref);
579092d9489SAdrian Prantl break;
580d4135bbcSPeter Collingbourne case dwarf::DW_OP_constu:
581ff47d83eSPetar Jovanovic assert(!isRegisterLocation());
582965b598bSJonas Devlieghere emitConstu(Op->getArg(0));
583d4135bbcSPeter Collingbourne break;
584a6dd01afSAlok Kumar Sharma case dwarf::DW_OP_consts:
585a6dd01afSAlok Kumar Sharma assert(!isRegisterLocation());
586930a8c60SAlok Kumar Sharma emitOp(dwarf::DW_OP_consts);
587a6dd01afSAlok Kumar Sharma emitSigned(Op->getArg(0));
588a6dd01afSAlok Kumar Sharma break;
589b86ce219SMarkus Lavin case dwarf::DW_OP_LLVM_convert: {
590b86ce219SMarkus Lavin unsigned BitSize = Op->getArg(0);
591b86ce219SMarkus Lavin dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
592a6631127SDavid Blaikie if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
593b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_convert);
594b86ce219SMarkus Lavin // If targeting a location-list; simply emit the index into the raw
595b86ce219SMarkus Lavin // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
596b86ce219SMarkus Lavin // fitted with means to extract it later.
597b86ce219SMarkus Lavin // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
598b86ce219SMarkus Lavin // (containing the index and a resolve mechanism during emit) into the
599b86ce219SMarkus Lavin // DIE value list.
600816ee8a4SAdrian Prantl emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
601b86ce219SMarkus Lavin } else {
602b86ce219SMarkus Lavin if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
603b86ce219SMarkus Lavin if (Encoding == dwarf::DW_ATE_signed)
604b86ce219SMarkus Lavin emitLegacySExt(PrevConvertOp->getArg(0));
605b86ce219SMarkus Lavin else if (Encoding == dwarf::DW_ATE_unsigned)
606ffba94a9SVedant Kumar emitLegacyZExt(PrevConvertOp->getArg(0));
607b86ce219SMarkus Lavin PrevConvertOp = None;
608b86ce219SMarkus Lavin } else {
609b86ce219SMarkus Lavin PrevConvertOp = Op;
610b86ce219SMarkus Lavin }
611b86ce219SMarkus Lavin }
612b86ce219SMarkus Lavin break;
613b86ce219SMarkus Lavin }
614d4135bbcSPeter Collingbourne case dwarf::DW_OP_stack_value:
6156825fb64SAdrian Prantl LocationKind = Implicit;
616d4135bbcSPeter Collingbourne break;
617f9b41cd3SKonstantin Zhuravlyov case dwarf::DW_OP_swap:
618ff47d83eSPetar Jovanovic assert(!isRegisterLocation());
619a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_swap);
620f9b41cd3SKonstantin Zhuravlyov break;
621f9b41cd3SKonstantin Zhuravlyov case dwarf::DW_OP_xderef:
622ff47d83eSPetar Jovanovic assert(!isRegisterLocation());
623a63b8e82SAdrian Prantl emitOp(dwarf::DW_OP_xderef);
624f9b41cd3SKonstantin Zhuravlyov break;
625a475da36SMarkus Lavin case dwarf::DW_OP_deref_size:
626a475da36SMarkus Lavin emitOp(dwarf::DW_OP_deref_size);
627a475da36SMarkus Lavin emitData1(Op->getArg(0));
628a475da36SMarkus Lavin break;
629fb9ce100SPeter Collingbourne case dwarf::DW_OP_LLVM_tag_offset:
630fb9ce100SPeter Collingbourne TagOffset = Op->getArg(0);
631fb9ce100SPeter Collingbourne break;
632b9973f87SDjordje Todorovic case dwarf::DW_OP_regx:
633b9973f87SDjordje Todorovic emitOp(dwarf::DW_OP_regx);
634b9973f87SDjordje Todorovic emitUnsigned(Op->getArg(0));
635b9973f87SDjordje Todorovic break;
636b9973f87SDjordje Todorovic case dwarf::DW_OP_bregx:
637b9973f87SDjordje Todorovic emitOp(dwarf::DW_OP_bregx);
638b9973f87SDjordje Todorovic emitUnsigned(Op->getArg(0));
639b9973f87SDjordje Todorovic emitSigned(Op->getArg(1));
640b9973f87SDjordje Todorovic break;
641092d9489SAdrian Prantl default:
64260635e39SDuncan P. N. Exon Smith llvm_unreachable("unhandled opcode found in expression");
643092d9489SAdrian Prantl }
644092d9489SAdrian Prantl }
6456825fb64SAdrian Prantl
646b9973f87SDjordje Todorovic if (isImplicitLocation() && !isParameterValue())
6476825fb64SAdrian Prantl // Turn this into an implicit location description.
6486825fb64SAdrian Prantl addStackValue();
649c7c84b90SAdrian Prantl
650c7c84b90SAdrian Prantl return true;
651092d9489SAdrian Prantl }
6528fafb8d3SAdrian Prantl
653a63b8e82SAdrian Prantl /// add masking operations to stencil out a subregister.
maskSubRegister()654981f03e6SAdrian Prantl void DwarfExpression::maskSubRegister() {
655981f03e6SAdrian Prantl assert(SubRegisterSizeInBits && "no subregister was registered");
656981f03e6SAdrian Prantl if (SubRegisterOffsetInBits > 0)
657a63b8e82SAdrian Prantl addShr(SubRegisterOffsetInBits);
658dc855221SAdrian Prantl uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
659a63b8e82SAdrian Prantl addAnd(Mask);
660981f03e6SAdrian Prantl }
661981f03e6SAdrian Prantl
finalize()6628fafb8d3SAdrian Prantl void DwarfExpression::finalize() {
66380e188d9SAdrian Prantl assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
664981f03e6SAdrian Prantl // Emit any outstanding DW_OP_piece operations to mask out subregisters.
665981f03e6SAdrian Prantl if (SubRegisterSizeInBits == 0)
666981f03e6SAdrian Prantl return;
667981f03e6SAdrian Prantl // Don't emit a DW_OP_piece for a subregister at offset 0.
668981f03e6SAdrian Prantl if (SubRegisterOffsetInBits == 0)
669981f03e6SAdrian Prantl return;
670a63b8e82SAdrian Prantl addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
6718fafb8d3SAdrian Prantl }
6728fafb8d3SAdrian Prantl
addFragmentOffset(const DIExpression * Expr)6738fafb8d3SAdrian Prantl void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
6748fafb8d3SAdrian Prantl if (!Expr || !Expr->isFragment())
6758fafb8d3SAdrian Prantl return;
6768fafb8d3SAdrian Prantl
67749797ca6SAdrian Prantl uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
6788fafb8d3SAdrian Prantl assert(FragmentOffset >= OffsetInBits &&
6798fafb8d3SAdrian Prantl "overlapping or duplicate fragments");
6808fafb8d3SAdrian Prantl if (FragmentOffset > OffsetInBits)
681a63b8e82SAdrian Prantl addOpPiece(FragmentOffset - OffsetInBits);
6828fafb8d3SAdrian Prantl OffsetInBits = FragmentOffset;
6838fafb8d3SAdrian Prantl }
684b86ce219SMarkus Lavin
emitLegacySExt(unsigned FromBits)685b86ce219SMarkus Lavin void DwarfExpression::emitLegacySExt(unsigned FromBits) {
686b86ce219SMarkus Lavin // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
687b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_dup);
6884fe81b6bSVedant Kumar emitOp(dwarf::DW_OP_constu);
6894fe81b6bSVedant Kumar emitUnsigned(FromBits - 1);
690b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_shr);
691b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_lit0);
692b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_not);
693b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_mul);
6944fe81b6bSVedant Kumar emitOp(dwarf::DW_OP_constu);
6954fe81b6bSVedant Kumar emitUnsigned(FromBits);
696b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_shl);
697b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_or);
698b86ce219SMarkus Lavin }
699b86ce219SMarkus Lavin
emitLegacyZExt(unsigned FromBits)700ffba94a9SVedant Kumar void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
701ee72b173SAdrian Prantl // Heuristic to decide the most efficient encoding.
702ee72b173SAdrian Prantl // A ULEB can encode 7 1-bits per byte.
703ee72b173SAdrian Prantl if (FromBits / 7 < 1+1+1+1+1) {
704ffba94a9SVedant Kumar // (X & (1 << FromBits - 1))
7054fe81b6bSVedant Kumar emitOp(dwarf::DW_OP_constu);
7064fe81b6bSVedant Kumar emitUnsigned((1ULL << FromBits) - 1);
707ee72b173SAdrian Prantl } else {
708ee72b173SAdrian Prantl // Note that the DWARF 4 stack consists of pointer-sized elements,
709ee72b173SAdrian Prantl // so technically it doesn't make sense to shift left more than 64
710ee72b173SAdrian Prantl // bits. We leave that for the consumer to decide though. LLDB for
711ee72b173SAdrian Prantl // example uses APInt for the stack elements and can still deal
712ee72b173SAdrian Prantl // with this.
713ee72b173SAdrian Prantl emitOp(dwarf::DW_OP_lit1);
714ee72b173SAdrian Prantl emitOp(dwarf::DW_OP_constu);
715ee72b173SAdrian Prantl emitUnsigned(FromBits);
716ee72b173SAdrian Prantl emitOp(dwarf::DW_OP_shl);
717ee72b173SAdrian Prantl emitOp(dwarf::DW_OP_lit1);
718ee72b173SAdrian Prantl emitOp(dwarf::DW_OP_minus);
719ee72b173SAdrian Prantl }
720b86ce219SMarkus Lavin emitOp(dwarf::DW_OP_and);
721b86ce219SMarkus Lavin }
722adf7a0a5SYury Delendik
addWasmLocation(unsigned Index,uint64_t Offset)72348139ebcSWouter van Oortmerssen void DwarfExpression::addWasmLocation(unsigned Index, uint64_t Offset) {
724e3c0b0feSWouter van Oortmerssen emitOp(dwarf::DW_OP_WASM_location);
725e3c0b0feSWouter van Oortmerssen emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);
726e3c0b0feSWouter van Oortmerssen emitUnsigned(Offset);
727e3c0b0feSWouter van Oortmerssen if (Index == 4 /*TI_LOCAL_INDIRECT*/) {
728e3c0b0feSWouter van Oortmerssen assert(LocationKind == Unknown);
729e3c0b0feSWouter van Oortmerssen LocationKind = Memory;
730e3c0b0feSWouter van Oortmerssen } else {
731adf7a0a5SYury Delendik assert(LocationKind == Implicit || LocationKind == Unknown);
732adf7a0a5SYury Delendik LocationKind = Implicit;
733e3c0b0feSWouter van Oortmerssen }
734adf7a0a5SYury Delendik }
735