10b57cec5SDimitry Andric //===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains support for writing dwarf debug info into asm files.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "DwarfExpression.h"
140b57cec5SDimitry Andric #include "DwarfCompileUnit.h"
150b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
170b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
188bcb0991SDimitry Andric #include "llvm/CodeGen/Register.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
20e8d8bef9SDimitry Andric #include "llvm/IR/DataLayout.h"
21*0fca6ea1SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
220b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
230b57cec5SDimitry Andric #include <algorithm>
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric
27e8d8bef9SDimitry Andric #define DEBUG_TYPE "dwarfdebug"
28e8d8bef9SDimitry Andric
emitConstu(uint64_t Value)290b57cec5SDimitry Andric void DwarfExpression::emitConstu(uint64_t Value) {
300b57cec5SDimitry Andric if (Value < 32)
310b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0 + Value);
320b57cec5SDimitry Andric else if (Value == std::numeric_limits<uint64_t>::max()) {
330b57cec5SDimitry Andric // Only do this for 64-bit values as the DWARF expression stack uses
340b57cec5SDimitry Andric // target-address-size values.
350b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0);
360b57cec5SDimitry Andric emitOp(dwarf::DW_OP_not);
370b57cec5SDimitry Andric } else {
380b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu);
390b57cec5SDimitry Andric emitUnsigned(Value);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric }
420b57cec5SDimitry Andric
addReg(int DwarfReg,const char * Comment)430b57cec5SDimitry Andric void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
440b57cec5SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number");
450b57cec5SDimitry Andric assert((isUnknownLocation() || isRegisterLocation()) &&
460b57cec5SDimitry Andric "location description already locked down");
470b57cec5SDimitry Andric LocationKind = Register;
480b57cec5SDimitry Andric if (DwarfReg < 32) {
490b57cec5SDimitry Andric emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
500b57cec5SDimitry Andric } else {
510b57cec5SDimitry Andric emitOp(dwarf::DW_OP_regx, Comment);
520b57cec5SDimitry Andric emitUnsigned(DwarfReg);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric
addBReg(int DwarfReg,int Offset)560b57cec5SDimitry Andric void DwarfExpression::addBReg(int DwarfReg, int Offset) {
570b57cec5SDimitry Andric assert(DwarfReg >= 0 && "invalid negative dwarf register number");
580b57cec5SDimitry Andric assert(!isRegisterLocation() && "location description already locked down");
590b57cec5SDimitry Andric if (DwarfReg < 32) {
600b57cec5SDimitry Andric emitOp(dwarf::DW_OP_breg0 + DwarfReg);
610b57cec5SDimitry Andric } else {
620b57cec5SDimitry Andric emitOp(dwarf::DW_OP_bregx);
630b57cec5SDimitry Andric emitUnsigned(DwarfReg);
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric emitSigned(Offset);
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
addFBReg(int Offset)680b57cec5SDimitry Andric void DwarfExpression::addFBReg(int Offset) {
690b57cec5SDimitry Andric emitOp(dwarf::DW_OP_fbreg);
700b57cec5SDimitry Andric emitSigned(Offset);
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric
addOpPiece(unsigned SizeInBits,unsigned OffsetInBits)730b57cec5SDimitry Andric void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
740b57cec5SDimitry Andric if (!SizeInBits)
750b57cec5SDimitry Andric return;
760b57cec5SDimitry Andric
770b57cec5SDimitry Andric const unsigned SizeOfByte = 8;
780b57cec5SDimitry Andric if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
790b57cec5SDimitry Andric emitOp(dwarf::DW_OP_bit_piece);
800b57cec5SDimitry Andric emitUnsigned(SizeInBits);
810b57cec5SDimitry Andric emitUnsigned(OffsetInBits);
820b57cec5SDimitry Andric } else {
830b57cec5SDimitry Andric emitOp(dwarf::DW_OP_piece);
840b57cec5SDimitry Andric unsigned ByteSize = SizeInBits / SizeOfByte;
850b57cec5SDimitry Andric emitUnsigned(ByteSize);
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric this->OffsetInBits += SizeInBits;
880b57cec5SDimitry Andric }
890b57cec5SDimitry Andric
addShr(unsigned ShiftBy)900b57cec5SDimitry Andric void DwarfExpression::addShr(unsigned ShiftBy) {
910b57cec5SDimitry Andric emitConstu(ShiftBy);
920b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr);
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric
addAnd(unsigned Mask)950b57cec5SDimitry Andric void DwarfExpression::addAnd(unsigned Mask) {
960b57cec5SDimitry Andric emitConstu(Mask);
970b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and);
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
addMachineReg(const TargetRegisterInfo & TRI,llvm::Register MachineReg,unsigned MaxSize)1000b57cec5SDimitry Andric bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
101e8d8bef9SDimitry Andric llvm::Register MachineReg,
102e8d8bef9SDimitry Andric unsigned MaxSize) {
103bdd1243dSDimitry Andric if (!MachineReg.isPhysical()) {
1040b57cec5SDimitry Andric if (isFrameRegister(TRI, MachineReg)) {
1055ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createRegister(-1, nullptr));
1060b57cec5SDimitry Andric return true;
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric return false;
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric
1110b57cec5SDimitry Andric int Reg = TRI.getDwarfRegNum(MachineReg, false);
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric // If this is a valid register number, emit it.
1140b57cec5SDimitry Andric if (Reg >= 0) {
1155ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
1160b57cec5SDimitry Andric return true;
1170b57cec5SDimitry Andric }
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric // Walk up the super-register chain until we find a valid number.
1200b57cec5SDimitry Andric // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
12106c3fb27SDimitry Andric for (MCPhysReg SR : TRI.superregs(MachineReg)) {
12206c3fb27SDimitry Andric Reg = TRI.getDwarfRegNum(SR, false);
1230b57cec5SDimitry Andric if (Reg >= 0) {
12406c3fb27SDimitry Andric unsigned Idx = TRI.getSubRegIndex(SR, MachineReg);
1250b57cec5SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx);
1260b57cec5SDimitry Andric unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
1275ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
1280b57cec5SDimitry Andric // Use a DW_OP_bit_piece to describe the sub-register.
1290b57cec5SDimitry Andric setSubRegisterPiece(Size, RegOffset);
1300b57cec5SDimitry Andric return true;
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric
1340b57cec5SDimitry Andric // Otherwise, attempt to find a covering set of sub-register numbers.
1350b57cec5SDimitry Andric // For example, Q0 on ARM is a composition of D0+D1.
1360b57cec5SDimitry Andric unsigned CurPos = 0;
1370b57cec5SDimitry Andric // The size of the register in bits.
1380b57cec5SDimitry Andric const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
1390b57cec5SDimitry Andric unsigned RegSize = TRI.getRegSizeInBits(*RC);
1400b57cec5SDimitry Andric // Keep track of the bits in the register we already emitted, so we
1410b57cec5SDimitry Andric // can avoid emitting redundant aliasing subregs. Because this is
1420b57cec5SDimitry Andric // just doing a greedy scan of all subregisters, it is possible that
1430b57cec5SDimitry Andric // this doesn't find a combination of subregisters that fully cover
1440b57cec5SDimitry Andric // the register (even though one may exist).
1450b57cec5SDimitry Andric SmallBitVector Coverage(RegSize, false);
14606c3fb27SDimitry Andric for (MCPhysReg SR : TRI.subregs(MachineReg)) {
14706c3fb27SDimitry Andric unsigned Idx = TRI.getSubRegIndex(MachineReg, SR);
1480b57cec5SDimitry Andric unsigned Size = TRI.getSubRegIdxSize(Idx);
1490b57cec5SDimitry Andric unsigned Offset = TRI.getSubRegIdxOffset(Idx);
15006c3fb27SDimitry Andric Reg = TRI.getDwarfRegNum(SR, false);
1510b57cec5SDimitry Andric if (Reg < 0)
1520b57cec5SDimitry Andric continue;
1530b57cec5SDimitry Andric
1545ffd83dbSDimitry Andric // Used to build the intersection between the bits we already
1555ffd83dbSDimitry Andric // emitted and the bits covered by this subregister.
1560b57cec5SDimitry Andric SmallBitVector CurSubReg(RegSize, false);
1570b57cec5SDimitry Andric CurSubReg.set(Offset, Offset + Size);
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric // If this sub-register has a DWARF number and we haven't covered
160480093f4SDimitry Andric // its range, and its range covers the value, emit a DWARF piece for it.
161480093f4SDimitry Andric if (Offset < MaxSize && CurSubReg.test(Coverage)) {
1620b57cec5SDimitry Andric // Emit a piece for any gap in the coverage.
1630b57cec5SDimitry Andric if (Offset > CurPos)
1645ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createSubRegister(
1655ffd83dbSDimitry Andric -1, Offset - CurPos, "no DWARF register encoding"));
1665ffd83dbSDimitry Andric if (Offset == 0 && Size >= MaxSize)
1675ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));
1685ffd83dbSDimitry Andric else
1695ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createSubRegister(
1705ffd83dbSDimitry Andric Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));
171480093f4SDimitry Andric }
1720b57cec5SDimitry Andric // Mark it as emitted.
1730b57cec5SDimitry Andric Coverage.set(Offset, Offset + Size);
1740b57cec5SDimitry Andric CurPos = Offset + Size;
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric // Failed to find any DWARF encoding.
1770b57cec5SDimitry Andric if (CurPos == 0)
1780b57cec5SDimitry Andric return false;
1790b57cec5SDimitry Andric // Found a partial or complete DWARF encoding.
1800b57cec5SDimitry Andric if (CurPos < RegSize)
1815ffd83dbSDimitry Andric DwarfRegs.push_back(Register::createSubRegister(
1825ffd83dbSDimitry Andric -1, RegSize - CurPos, "no DWARF register encoding"));
1830b57cec5SDimitry Andric return true;
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric
addStackValue()1860b57cec5SDimitry Andric void DwarfExpression::addStackValue() {
1870b57cec5SDimitry Andric if (DwarfVersion >= 4)
1880b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value);
1890b57cec5SDimitry Andric }
1900b57cec5SDimitry Andric
addSignedConstant(int64_t Value)1910b57cec5SDimitry Andric void DwarfExpression::addSignedConstant(int64_t Value) {
1920b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation());
1930b57cec5SDimitry Andric LocationKind = Implicit;
1940b57cec5SDimitry Andric emitOp(dwarf::DW_OP_consts);
1950b57cec5SDimitry Andric emitSigned(Value);
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric
addUnsignedConstant(uint64_t Value)1980b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(uint64_t Value) {
1990b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation());
2000b57cec5SDimitry Andric LocationKind = Implicit;
2010b57cec5SDimitry Andric emitConstu(Value);
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric
addUnsignedConstant(const APInt & Value)2040b57cec5SDimitry Andric void DwarfExpression::addUnsignedConstant(const APInt &Value) {
2050b57cec5SDimitry Andric assert(isImplicitLocation() || isUnknownLocation());
2060b57cec5SDimitry Andric LocationKind = Implicit;
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric unsigned Size = Value.getBitWidth();
2090b57cec5SDimitry Andric const uint64_t *Data = Value.getRawData();
2100b57cec5SDimitry Andric
2110b57cec5SDimitry Andric // Chop it up into 64-bit pieces, because that's the maximum that
2120b57cec5SDimitry Andric // addUnsignedConstant takes.
2130b57cec5SDimitry Andric unsigned Offset = 0;
2140b57cec5SDimitry Andric while (Offset < Size) {
2150b57cec5SDimitry Andric addUnsignedConstant(*Data++);
2160b57cec5SDimitry Andric if (Offset == 0 && Size <= 64)
2170b57cec5SDimitry Andric break;
2180b57cec5SDimitry Andric addStackValue();
2190b57cec5SDimitry Andric addOpPiece(std::min(Size - Offset, 64u), Offset);
2200b57cec5SDimitry Andric Offset += 64;
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric }
2230b57cec5SDimitry Andric
addConstantFP(const APFloat & APF,const AsmPrinter & AP)224e8d8bef9SDimitry Andric void DwarfExpression::addConstantFP(const APFloat &APF, const AsmPrinter &AP) {
225e8d8bef9SDimitry Andric assert(isImplicitLocation() || isUnknownLocation());
226e8d8bef9SDimitry Andric APInt API = APF.bitcastToAPInt();
227e8d8bef9SDimitry Andric int NumBytes = API.getBitWidth() / 8;
228e8d8bef9SDimitry Andric if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
229e8d8bef9SDimitry Andric // FIXME: Add support for `long double`.
230e8d8bef9SDimitry Andric emitOp(dwarf::DW_OP_implicit_value);
231e8d8bef9SDimitry Andric emitUnsigned(NumBytes /*Size of the block in bytes*/);
232e8d8bef9SDimitry Andric
233e8d8bef9SDimitry Andric // The loop below is emitting the value starting at least significant byte,
234e8d8bef9SDimitry Andric // so we need to perform a byte-swap to get the byte order correct in case
235e8d8bef9SDimitry Andric // of a big-endian target.
236e8d8bef9SDimitry Andric if (AP.getDataLayout().isBigEndian())
237e8d8bef9SDimitry Andric API = API.byteSwap();
238e8d8bef9SDimitry Andric
239e8d8bef9SDimitry Andric for (int i = 0; i < NumBytes; ++i) {
240e8d8bef9SDimitry Andric emitData1(API.getZExtValue() & 0xFF);
241e8d8bef9SDimitry Andric API = API.lshr(8);
242e8d8bef9SDimitry Andric }
243e8d8bef9SDimitry Andric
244e8d8bef9SDimitry Andric return;
245e8d8bef9SDimitry Andric }
246e8d8bef9SDimitry Andric LLVM_DEBUG(
247e8d8bef9SDimitry Andric dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
248e8d8bef9SDimitry Andric << API.getBitWidth() << " bits\n");
249e8d8bef9SDimitry Andric }
250e8d8bef9SDimitry Andric
addMachineRegExpression(const TargetRegisterInfo & TRI,DIExpressionCursor & ExprCursor,llvm::Register MachineReg,unsigned FragmentOffsetInBits)2510b57cec5SDimitry Andric bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
2520b57cec5SDimitry Andric DIExpressionCursor &ExprCursor,
253e8d8bef9SDimitry Andric llvm::Register MachineReg,
2540b57cec5SDimitry Andric unsigned FragmentOffsetInBits) {
2550b57cec5SDimitry Andric auto Fragment = ExprCursor.getFragmentInfo();
2560b57cec5SDimitry Andric if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
2570b57cec5SDimitry Andric LocationKind = Unknown;
2580b57cec5SDimitry Andric return false;
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric
2610b57cec5SDimitry Andric bool HasComplexExpression = false;
2620b57cec5SDimitry Andric auto Op = ExprCursor.peek();
2630b57cec5SDimitry Andric if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
2640b57cec5SDimitry Andric HasComplexExpression = true;
2650b57cec5SDimitry Andric
2660b57cec5SDimitry Andric // If the register can only be described by a complex expression (i.e.,
2670b57cec5SDimitry Andric // multiple subregisters) it doesn't safely compose with another complex
2680b57cec5SDimitry Andric // expression. For example, it is not possible to apply a DW_OP_deref
2695ffd83dbSDimitry Andric // operation to multiple DW_OP_pieces, since composite location descriptions
2705ffd83dbSDimitry Andric // do not push anything on the DWARF stack.
2715ffd83dbSDimitry Andric //
2725ffd83dbSDimitry Andric // DW_OP_entry_value operations can only hold a DWARF expression or a
2735ffd83dbSDimitry Andric // register location description, so we can't emit a single entry value
2745ffd83dbSDimitry Andric // covering a composite location description. In the future we may want to
2755ffd83dbSDimitry Andric // emit entry value operations for each register location in the composite
2765ffd83dbSDimitry Andric // location, but until that is supported do not emit anything.
2775ffd83dbSDimitry Andric if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
2785ffd83dbSDimitry Andric if (IsEmittingEntryValue)
2795ffd83dbSDimitry Andric cancelEntryValue();
2800b57cec5SDimitry Andric DwarfRegs.clear();
2810b57cec5SDimitry Andric LocationKind = Unknown;
2820b57cec5SDimitry Andric return false;
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric
2858bcb0991SDimitry Andric // Handle simple register locations. If we are supposed to emit
2868bcb0991SDimitry Andric // a call site parameter expression and if that expression is just a register
2878bcb0991SDimitry Andric // location, emit it with addBReg and offset 0, because we should emit a DWARF
2888bcb0991SDimitry Andric // expression representing a value, rather than a location.
289fe6060f1SDimitry Andric if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
290fe6060f1SDimitry Andric isEntryValue()) {
2911fd87a68SDimitry Andric auto FragmentInfo = ExprCursor.getFragmentInfo();
2921fd87a68SDimitry Andric unsigned RegSize = 0;
2930b57cec5SDimitry Andric for (auto &Reg : DwarfRegs) {
2941fd87a68SDimitry Andric RegSize += Reg.SubRegSize;
2950b57cec5SDimitry Andric if (Reg.DwarfRegNo >= 0)
2960b57cec5SDimitry Andric addReg(Reg.DwarfRegNo, Reg.Comment);
2971fd87a68SDimitry Andric if (FragmentInfo)
2981fd87a68SDimitry Andric if (RegSize > FragmentInfo->SizeInBits)
2991fd87a68SDimitry Andric // If the register is larger than the current fragment stop
3001fd87a68SDimitry Andric // once the fragment is covered.
3011fd87a68SDimitry Andric break;
3025ffd83dbSDimitry Andric addOpPiece(Reg.SubRegSize);
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric
305fe6060f1SDimitry Andric if (isEntryValue()) {
3068bcb0991SDimitry Andric finalizeEntryValue();
3078bcb0991SDimitry Andric
308fe6060f1SDimitry Andric if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&
3095ffd83dbSDimitry Andric DwarfVersion >= 4)
3100b57cec5SDimitry Andric emitOp(dwarf::DW_OP_stack_value);
311fe6060f1SDimitry Andric }
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric DwarfRegs.clear();
314fe6060f1SDimitry Andric // If we need to mask out a subregister, do it now, unless the next
315fe6060f1SDimitry Andric // operation would emit an OpPiece anyway.
316fe6060f1SDimitry Andric auto NextOp = ExprCursor.peek();
317fe6060f1SDimitry Andric if (SubRegisterSizeInBits && NextOp &&
318fe6060f1SDimitry Andric (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
319fe6060f1SDimitry Andric maskSubRegister();
3200b57cec5SDimitry Andric return true;
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andric // Don't emit locations that cannot be expressed without DW_OP_stack_value.
3240b57cec5SDimitry Andric if (DwarfVersion < 4)
3250b57cec5SDimitry Andric if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
3260b57cec5SDimitry Andric return Op.getOp() == dwarf::DW_OP_stack_value;
3270b57cec5SDimitry Andric })) {
3280b57cec5SDimitry Andric DwarfRegs.clear();
3290b57cec5SDimitry Andric LocationKind = Unknown;
3300b57cec5SDimitry Andric return false;
3310b57cec5SDimitry Andric }
3320b57cec5SDimitry Andric
33381ad6265SDimitry Andric // TODO: We should not give up here but the following code needs to be changed
33481ad6265SDimitry Andric // to deal with multiple (sub)registers first.
33581ad6265SDimitry Andric if (DwarfRegs.size() > 1) {
33681ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "
33781ad6265SDimitry Andric "multi-register usage.\n");
33881ad6265SDimitry Andric DwarfRegs.clear();
33981ad6265SDimitry Andric LocationKind = Unknown;
34081ad6265SDimitry Andric return false;
34181ad6265SDimitry Andric }
34281ad6265SDimitry Andric
3430b57cec5SDimitry Andric auto Reg = DwarfRegs[0];
3440b57cec5SDimitry Andric bool FBReg = isFrameRegister(TRI, MachineReg);
3450b57cec5SDimitry Andric int SignedOffset = 0;
3465ffd83dbSDimitry Andric assert(!Reg.isSubRegister() && "full register expected");
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric // Pattern-match combinations for which more efficient representations exist.
3490b57cec5SDimitry Andric // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
3500b57cec5SDimitry Andric if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
3518bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0);
3528bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
3538bcb0991SDimitry Andric if (Offset <= IntMax) {
3548bcb0991SDimitry Andric SignedOffset = Offset;
3550b57cec5SDimitry Andric ExprCursor.take();
3560b57cec5SDimitry Andric }
3578bcb0991SDimitry Andric }
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
3600b57cec5SDimitry Andric // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
3610b57cec5SDimitry Andric // If Reg is a subregister we need to mask it out before subtracting.
3620b57cec5SDimitry Andric if (Op && Op->getOp() == dwarf::DW_OP_constu) {
3638bcb0991SDimitry Andric uint64_t Offset = Op->getArg(0);
3648bcb0991SDimitry Andric uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
3650b57cec5SDimitry Andric auto N = ExprCursor.peekNext();
3668bcb0991SDimitry Andric if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
3678bcb0991SDimitry Andric SignedOffset = Offset;
3688bcb0991SDimitry Andric ExprCursor.consume(2);
3698bcb0991SDimitry Andric } else if (N && N->getOp() == dwarf::DW_OP_minus &&
3708bcb0991SDimitry Andric !SubRegisterSizeInBits && Offset <= IntMax + 1) {
3718bcb0991SDimitry Andric SignedOffset = -static_cast<int64_t>(Offset);
3720b57cec5SDimitry Andric ExprCursor.consume(2);
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric
3760b57cec5SDimitry Andric if (FBReg)
3770b57cec5SDimitry Andric addFBReg(SignedOffset);
3780b57cec5SDimitry Andric else
3790b57cec5SDimitry Andric addBReg(Reg.DwarfRegNo, SignedOffset);
3800b57cec5SDimitry Andric DwarfRegs.clear();
381fe6060f1SDimitry Andric
382fe6060f1SDimitry Andric // If we need to mask out a subregister, do it now, unless the next
383fe6060f1SDimitry Andric // operation would emit an OpPiece anyway.
384fe6060f1SDimitry Andric auto NextOp = ExprCursor.peek();
385fe6060f1SDimitry Andric if (SubRegisterSizeInBits && NextOp &&
386fe6060f1SDimitry Andric (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
387fe6060f1SDimitry Andric maskSubRegister();
388fe6060f1SDimitry Andric
3890b57cec5SDimitry Andric return true;
3900b57cec5SDimitry Andric }
3910b57cec5SDimitry Andric
setEntryValueFlags(const MachineLocation & Loc)3925ffd83dbSDimitry Andric void DwarfExpression::setEntryValueFlags(const MachineLocation &Loc) {
3935ffd83dbSDimitry Andric LocationFlags |= EntryValue;
3945ffd83dbSDimitry Andric if (Loc.isIndirect())
3955ffd83dbSDimitry Andric LocationFlags |= Indirect;
3965ffd83dbSDimitry Andric }
3975ffd83dbSDimitry Andric
setLocation(const MachineLocation & Loc,const DIExpression * DIExpr)3985ffd83dbSDimitry Andric void DwarfExpression::setLocation(const MachineLocation &Loc,
3995ffd83dbSDimitry Andric const DIExpression *DIExpr) {
4005ffd83dbSDimitry Andric if (Loc.isIndirect())
4015ffd83dbSDimitry Andric setMemoryLocationKind();
4025ffd83dbSDimitry Andric
4035ffd83dbSDimitry Andric if (DIExpr->isEntryValue())
4045ffd83dbSDimitry Andric setEntryValueFlags(Loc);
4055ffd83dbSDimitry Andric }
4065ffd83dbSDimitry Andric
beginEntryValueExpression(DIExpressionCursor & ExprCursor)4078bcb0991SDimitry Andric void DwarfExpression::beginEntryValueExpression(
4088bcb0991SDimitry Andric DIExpressionCursor &ExprCursor) {
4090b57cec5SDimitry Andric auto Op = ExprCursor.take();
4108bcb0991SDimitry Andric (void)Op;
4118bcb0991SDimitry Andric assert(Op && Op->getOp() == dwarf::DW_OP_LLVM_entry_value);
4128bcb0991SDimitry Andric assert(!IsEmittingEntryValue && "Already emitting entry value?");
4138bcb0991SDimitry Andric assert(Op->getArg(0) == 1 &&
4148bcb0991SDimitry Andric "Can currently only emit entry values covering a single operation");
4150b57cec5SDimitry Andric
416fe6060f1SDimitry Andric SavedLocationKind = LocationKind;
417fe6060f1SDimitry Andric LocationKind = Register;
4185f757f3fSDimitry Andric LocationFlags |= EntryValue;
4198bcb0991SDimitry Andric IsEmittingEntryValue = true;
4208bcb0991SDimitry Andric enableTemporaryBuffer();
4218bcb0991SDimitry Andric }
4228bcb0991SDimitry Andric
finalizeEntryValue()4238bcb0991SDimitry Andric void DwarfExpression::finalizeEntryValue() {
4248bcb0991SDimitry Andric assert(IsEmittingEntryValue && "Entry value not open?");
4258bcb0991SDimitry Andric disableTemporaryBuffer();
4268bcb0991SDimitry Andric
4275ffd83dbSDimitry Andric emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
4285ffd83dbSDimitry Andric
4298bcb0991SDimitry Andric // Emit the entry value's size operand.
4308bcb0991SDimitry Andric unsigned Size = getTemporaryBufferSize();
4318bcb0991SDimitry Andric emitUnsigned(Size);
4328bcb0991SDimitry Andric
4338bcb0991SDimitry Andric // Emit the entry value's DWARF block operand.
4348bcb0991SDimitry Andric commitTemporaryBuffer();
4358bcb0991SDimitry Andric
436fe6060f1SDimitry Andric LocationFlags &= ~EntryValue;
437fe6060f1SDimitry Andric LocationKind = SavedLocationKind;
4388bcb0991SDimitry Andric IsEmittingEntryValue = false;
4390b57cec5SDimitry Andric }
4400b57cec5SDimitry Andric
cancelEntryValue()4415ffd83dbSDimitry Andric void DwarfExpression::cancelEntryValue() {
4425ffd83dbSDimitry Andric assert(IsEmittingEntryValue && "Entry value not open?");
4435ffd83dbSDimitry Andric disableTemporaryBuffer();
4445ffd83dbSDimitry Andric
4455ffd83dbSDimitry Andric // The temporary buffer can't be emptied, so for now just assert that nothing
4465ffd83dbSDimitry Andric // has been emitted to it.
4475ffd83dbSDimitry Andric assert(getTemporaryBufferSize() == 0 &&
4485ffd83dbSDimitry Andric "Began emitting entry value block before cancelling entry value");
4495ffd83dbSDimitry Andric
450fe6060f1SDimitry Andric LocationKind = SavedLocationKind;
4515ffd83dbSDimitry Andric IsEmittingEntryValue = false;
4525ffd83dbSDimitry Andric }
4535ffd83dbSDimitry Andric
getOrCreateBaseType(unsigned BitSize,dwarf::TypeKind Encoding)4545ffd83dbSDimitry Andric unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
4555ffd83dbSDimitry Andric dwarf::TypeKind Encoding) {
4565ffd83dbSDimitry Andric // Reuse the base_type if we already have one in this CU otherwise we
4575ffd83dbSDimitry Andric // create a new one.
4585ffd83dbSDimitry Andric unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
4595ffd83dbSDimitry Andric for (; I != E; ++I)
4605ffd83dbSDimitry Andric if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
4615ffd83dbSDimitry Andric CU.ExprRefedBaseTypes[I].Encoding == Encoding)
4625ffd83dbSDimitry Andric break;
4635ffd83dbSDimitry Andric
4645ffd83dbSDimitry Andric if (I == E)
4655ffd83dbSDimitry Andric CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
4665ffd83dbSDimitry Andric return I;
4675ffd83dbSDimitry Andric }
4685ffd83dbSDimitry Andric
4695ffd83dbSDimitry Andric /// Assuming a well-formed expression, match "DW_OP_deref*
4705ffd83dbSDimitry Andric /// DW_OP_LLVM_fragment?".
isMemoryLocation(DIExpressionCursor ExprCursor)4710b57cec5SDimitry Andric static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
4720b57cec5SDimitry Andric while (ExprCursor) {
4730b57cec5SDimitry Andric auto Op = ExprCursor.take();
4740b57cec5SDimitry Andric switch (Op->getOp()) {
4750b57cec5SDimitry Andric case dwarf::DW_OP_deref:
4760b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment:
4770b57cec5SDimitry Andric break;
4780b57cec5SDimitry Andric default:
4790b57cec5SDimitry Andric return false;
4800b57cec5SDimitry Andric }
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric return true;
4830b57cec5SDimitry Andric }
4840b57cec5SDimitry Andric
addExpression(DIExpressionCursor && ExprCursor)4859738bc28SDimitry Andric void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor) {
486fe6060f1SDimitry Andric addExpression(std::move(ExprCursor),
487fe6060f1SDimitry Andric [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
488fe6060f1SDimitry Andric llvm_unreachable("unhandled opcode found in expression");
489fe6060f1SDimitry Andric });
490fe6060f1SDimitry Andric }
491fe6060f1SDimitry Andric
addExpression(DIExpressionCursor && ExprCursor,llvm::function_ref<bool (unsigned,DIExpressionCursor &)> InsertArg)4929738bc28SDimitry Andric bool DwarfExpression::addExpression(
493fe6060f1SDimitry Andric DIExpressionCursor &&ExprCursor,
494fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
4955ffd83dbSDimitry Andric // Entry values can currently only cover the initial register location,
4965ffd83dbSDimitry Andric // and not any other parts of the following DWARF expression.
4975ffd83dbSDimitry Andric assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
4985ffd83dbSDimitry Andric
499bdd1243dSDimitry Andric std::optional<DIExpression::ExprOperand> PrevConvertOp;
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andric while (ExprCursor) {
5020b57cec5SDimitry Andric auto Op = ExprCursor.take();
5038bcb0991SDimitry Andric uint64_t OpNum = Op->getOp();
5048bcb0991SDimitry Andric
5058bcb0991SDimitry Andric if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
5068bcb0991SDimitry Andric emitOp(OpNum);
5078bcb0991SDimitry Andric continue;
5088bcb0991SDimitry Andric } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
5098bcb0991SDimitry Andric addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
5108bcb0991SDimitry Andric continue;
5118bcb0991SDimitry Andric }
5128bcb0991SDimitry Andric
5138bcb0991SDimitry Andric switch (OpNum) {
514fe6060f1SDimitry Andric case dwarf::DW_OP_LLVM_arg:
515fe6060f1SDimitry Andric if (!InsertArg(Op->getArg(0), ExprCursor)) {
516fe6060f1SDimitry Andric LocationKind = Unknown;
5179738bc28SDimitry Andric return false;
518fe6060f1SDimitry Andric }
519fe6060f1SDimitry Andric break;
5200b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: {
5210b57cec5SDimitry Andric unsigned SizeInBits = Op->getArg(1);
5220b57cec5SDimitry Andric unsigned FragmentOffset = Op->getArg(0);
5230b57cec5SDimitry Andric // The fragment offset must have already been adjusted by emitting an
5240b57cec5SDimitry Andric // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
5250b57cec5SDimitry Andric // location.
5260b57cec5SDimitry Andric assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
527480093f4SDimitry Andric assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
5280b57cec5SDimitry Andric
5290b57cec5SDimitry Andric // If addMachineReg already emitted DW_OP_piece operations to represent
5300b57cec5SDimitry Andric // a super-register by splicing together sub-registers, subtract the size
5310b57cec5SDimitry Andric // of the pieces that was already emitted.
5320b57cec5SDimitry Andric SizeInBits -= OffsetInBits - FragmentOffset;
5330b57cec5SDimitry Andric
5340b57cec5SDimitry Andric // If addMachineReg requested a DW_OP_bit_piece to stencil out a
5350b57cec5SDimitry Andric // sub-register that is smaller than the current fragment's size, use it.
5360b57cec5SDimitry Andric if (SubRegisterSizeInBits)
5370b57cec5SDimitry Andric SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric // Emit a DW_OP_stack_value for implicit location descriptions.
5400b57cec5SDimitry Andric if (isImplicitLocation())
5410b57cec5SDimitry Andric addStackValue();
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric // Emit the DW_OP_piece.
5440b57cec5SDimitry Andric addOpPiece(SizeInBits, SubRegisterOffsetInBits);
5450b57cec5SDimitry Andric setSubRegisterPiece(0, 0);
5460b57cec5SDimitry Andric // Reset the location description kind.
5470b57cec5SDimitry Andric LocationKind = Unknown;
5489738bc28SDimitry Andric return true;
5490b57cec5SDimitry Andric }
550*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_sext:
551*0fca6ea1SDimitry Andric case dwarf::DW_OP_LLVM_extract_bits_zext: {
552*0fca6ea1SDimitry Andric unsigned SizeInBits = Op->getArg(1);
553*0fca6ea1SDimitry Andric unsigned BitOffset = Op->getArg(0);
554*0fca6ea1SDimitry Andric
555*0fca6ea1SDimitry Andric // If we have a memory location then dereference to get the value, though
556*0fca6ea1SDimitry Andric // we have to make sure we don't dereference any bytes past the end of the
557*0fca6ea1SDimitry Andric // object.
558*0fca6ea1SDimitry Andric if (isMemoryLocation()) {
559*0fca6ea1SDimitry Andric emitOp(dwarf::DW_OP_deref_size);
560*0fca6ea1SDimitry Andric emitUnsigned(alignTo(BitOffset + SizeInBits, 8) / 8);
561*0fca6ea1SDimitry Andric }
562*0fca6ea1SDimitry Andric
563*0fca6ea1SDimitry Andric // Extract the bits by a shift left (to shift out the bits after what we
564*0fca6ea1SDimitry Andric // want to extract) followed by shift right (to shift the bits to position
565*0fca6ea1SDimitry Andric // 0 and also sign/zero extend). These operations are done in the DWARF
566*0fca6ea1SDimitry Andric // "generic type" whose size is the size of a pointer.
567*0fca6ea1SDimitry Andric unsigned PtrSizeInBytes = CU.getAsmPrinter()->MAI->getCodePointerSize();
568*0fca6ea1SDimitry Andric unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
569*0fca6ea1SDimitry Andric unsigned RightShift = LeftShift + BitOffset;
570*0fca6ea1SDimitry Andric if (LeftShift) {
571*0fca6ea1SDimitry Andric emitOp(dwarf::DW_OP_constu);
572*0fca6ea1SDimitry Andric emitUnsigned(LeftShift);
573*0fca6ea1SDimitry Andric emitOp(dwarf::DW_OP_shl);
574*0fca6ea1SDimitry Andric }
575*0fca6ea1SDimitry Andric emitOp(dwarf::DW_OP_constu);
576*0fca6ea1SDimitry Andric emitUnsigned(RightShift);
577*0fca6ea1SDimitry Andric emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra
578*0fca6ea1SDimitry Andric : dwarf::DW_OP_shr);
579*0fca6ea1SDimitry Andric
580*0fca6ea1SDimitry Andric // The value is now at the top of the stack, so set the location to
581*0fca6ea1SDimitry Andric // implicit so that we get a stack_value at the end.
582*0fca6ea1SDimitry Andric LocationKind = Implicit;
583*0fca6ea1SDimitry Andric break;
584*0fca6ea1SDimitry Andric }
5850b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst:
5860b57cec5SDimitry Andric assert(!isRegisterLocation());
5870b57cec5SDimitry Andric emitOp(dwarf::DW_OP_plus_uconst);
5880b57cec5SDimitry Andric emitUnsigned(Op->getArg(0));
5890b57cec5SDimitry Andric break;
5900b57cec5SDimitry Andric case dwarf::DW_OP_plus:
5910b57cec5SDimitry Andric case dwarf::DW_OP_minus:
5920b57cec5SDimitry Andric case dwarf::DW_OP_mul:
5930b57cec5SDimitry Andric case dwarf::DW_OP_div:
5940b57cec5SDimitry Andric case dwarf::DW_OP_mod:
5950b57cec5SDimitry Andric case dwarf::DW_OP_or:
5960b57cec5SDimitry Andric case dwarf::DW_OP_and:
5970b57cec5SDimitry Andric case dwarf::DW_OP_xor:
5980b57cec5SDimitry Andric case dwarf::DW_OP_shl:
5990b57cec5SDimitry Andric case dwarf::DW_OP_shr:
6000b57cec5SDimitry Andric case dwarf::DW_OP_shra:
6010b57cec5SDimitry Andric case dwarf::DW_OP_lit0:
6020b57cec5SDimitry Andric case dwarf::DW_OP_not:
6030b57cec5SDimitry Andric case dwarf::DW_OP_dup:
6045ffd83dbSDimitry Andric case dwarf::DW_OP_push_object_address:
605e8d8bef9SDimitry Andric case dwarf::DW_OP_over:
60606c3fb27SDimitry Andric case dwarf::DW_OP_eq:
60706c3fb27SDimitry Andric case dwarf::DW_OP_ne:
60806c3fb27SDimitry Andric case dwarf::DW_OP_gt:
60906c3fb27SDimitry Andric case dwarf::DW_OP_ge:
61006c3fb27SDimitry Andric case dwarf::DW_OP_lt:
61106c3fb27SDimitry Andric case dwarf::DW_OP_le:
6128bcb0991SDimitry Andric emitOp(OpNum);
6130b57cec5SDimitry Andric break;
6140b57cec5SDimitry Andric case dwarf::DW_OP_deref:
6150b57cec5SDimitry Andric assert(!isRegisterLocation());
6160b57cec5SDimitry Andric if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
6170b57cec5SDimitry Andric // Turning this into a memory location description makes the deref
6180b57cec5SDimitry Andric // implicit.
6190b57cec5SDimitry Andric LocationKind = Memory;
6200b57cec5SDimitry Andric else
6210b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref);
6220b57cec5SDimitry Andric break;
6230b57cec5SDimitry Andric case dwarf::DW_OP_constu:
6240b57cec5SDimitry Andric assert(!isRegisterLocation());
6250b57cec5SDimitry Andric emitConstu(Op->getArg(0));
6260b57cec5SDimitry Andric break;
627e8d8bef9SDimitry Andric case dwarf::DW_OP_consts:
628e8d8bef9SDimitry Andric assert(!isRegisterLocation());
629e8d8bef9SDimitry Andric emitOp(dwarf::DW_OP_consts);
630e8d8bef9SDimitry Andric emitSigned(Op->getArg(0));
631e8d8bef9SDimitry Andric break;
6320b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_convert: {
6330b57cec5SDimitry Andric unsigned BitSize = Op->getArg(0);
6340b57cec5SDimitry Andric dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
635e8d8bef9SDimitry Andric if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
6360b57cec5SDimitry Andric emitOp(dwarf::DW_OP_convert);
6370b57cec5SDimitry Andric // If targeting a location-list; simply emit the index into the raw
6380b57cec5SDimitry Andric // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
6390b57cec5SDimitry Andric // fitted with means to extract it later.
6400b57cec5SDimitry Andric // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
6410b57cec5SDimitry Andric // (containing the index and a resolve mechanism during emit) into the
6420b57cec5SDimitry Andric // DIE value list.
6435ffd83dbSDimitry Andric emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
6440b57cec5SDimitry Andric } else {
6450b57cec5SDimitry Andric if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
6460b57cec5SDimitry Andric if (Encoding == dwarf::DW_ATE_signed)
6470b57cec5SDimitry Andric emitLegacySExt(PrevConvertOp->getArg(0));
6480b57cec5SDimitry Andric else if (Encoding == dwarf::DW_ATE_unsigned)
6490b57cec5SDimitry Andric emitLegacyZExt(PrevConvertOp->getArg(0));
650bdd1243dSDimitry Andric PrevConvertOp = std::nullopt;
6510b57cec5SDimitry Andric } else {
6520b57cec5SDimitry Andric PrevConvertOp = Op;
6530b57cec5SDimitry Andric }
6540b57cec5SDimitry Andric }
6550b57cec5SDimitry Andric break;
6560b57cec5SDimitry Andric }
6570b57cec5SDimitry Andric case dwarf::DW_OP_stack_value:
6580b57cec5SDimitry Andric LocationKind = Implicit;
6590b57cec5SDimitry Andric break;
6600b57cec5SDimitry Andric case dwarf::DW_OP_swap:
6610b57cec5SDimitry Andric assert(!isRegisterLocation());
6620b57cec5SDimitry Andric emitOp(dwarf::DW_OP_swap);
6630b57cec5SDimitry Andric break;
6640b57cec5SDimitry Andric case dwarf::DW_OP_xderef:
6650b57cec5SDimitry Andric assert(!isRegisterLocation());
6660b57cec5SDimitry Andric emitOp(dwarf::DW_OP_xderef);
6670b57cec5SDimitry Andric break;
6680b57cec5SDimitry Andric case dwarf::DW_OP_deref_size:
6690b57cec5SDimitry Andric emitOp(dwarf::DW_OP_deref_size);
6700b57cec5SDimitry Andric emitData1(Op->getArg(0));
6710b57cec5SDimitry Andric break;
6720b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_tag_offset:
6730b57cec5SDimitry Andric TagOffset = Op->getArg(0);
6740b57cec5SDimitry Andric break;
6758bcb0991SDimitry Andric case dwarf::DW_OP_regx:
6768bcb0991SDimitry Andric emitOp(dwarf::DW_OP_regx);
6778bcb0991SDimitry Andric emitUnsigned(Op->getArg(0));
6788bcb0991SDimitry Andric break;
6798bcb0991SDimitry Andric case dwarf::DW_OP_bregx:
6808bcb0991SDimitry Andric emitOp(dwarf::DW_OP_bregx);
6818bcb0991SDimitry Andric emitUnsigned(Op->getArg(0));
6828bcb0991SDimitry Andric emitSigned(Op->getArg(1));
6838bcb0991SDimitry Andric break;
6840b57cec5SDimitry Andric default:
6850b57cec5SDimitry Andric llvm_unreachable("unhandled opcode found in expression");
6860b57cec5SDimitry Andric }
6870b57cec5SDimitry Andric }
6880b57cec5SDimitry Andric
6898bcb0991SDimitry Andric if (isImplicitLocation() && !isParameterValue())
6900b57cec5SDimitry Andric // Turn this into an implicit location description.
6910b57cec5SDimitry Andric addStackValue();
6929738bc28SDimitry Andric
6939738bc28SDimitry Andric return true;
6940b57cec5SDimitry Andric }
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric /// add masking operations to stencil out a subregister.
maskSubRegister()6970b57cec5SDimitry Andric void DwarfExpression::maskSubRegister() {
6980b57cec5SDimitry Andric assert(SubRegisterSizeInBits && "no subregister was registered");
6990b57cec5SDimitry Andric if (SubRegisterOffsetInBits > 0)
7000b57cec5SDimitry Andric addShr(SubRegisterOffsetInBits);
7010b57cec5SDimitry Andric uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
7020b57cec5SDimitry Andric addAnd(Mask);
7030b57cec5SDimitry Andric }
7040b57cec5SDimitry Andric
finalize()7050b57cec5SDimitry Andric void DwarfExpression::finalize() {
7060b57cec5SDimitry Andric assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
7070b57cec5SDimitry Andric // Emit any outstanding DW_OP_piece operations to mask out subregisters.
7080b57cec5SDimitry Andric if (SubRegisterSizeInBits == 0)
7090b57cec5SDimitry Andric return;
7100b57cec5SDimitry Andric // Don't emit a DW_OP_piece for a subregister at offset 0.
7110b57cec5SDimitry Andric if (SubRegisterOffsetInBits == 0)
7120b57cec5SDimitry Andric return;
7130b57cec5SDimitry Andric addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
7140b57cec5SDimitry Andric }
7150b57cec5SDimitry Andric
addFragmentOffset(const DIExpression * Expr)7160b57cec5SDimitry Andric void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
7170b57cec5SDimitry Andric if (!Expr || !Expr->isFragment())
7180b57cec5SDimitry Andric return;
7190b57cec5SDimitry Andric
7200b57cec5SDimitry Andric uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
7210b57cec5SDimitry Andric assert(FragmentOffset >= OffsetInBits &&
7220b57cec5SDimitry Andric "overlapping or duplicate fragments");
7230b57cec5SDimitry Andric if (FragmentOffset > OffsetInBits)
7240b57cec5SDimitry Andric addOpPiece(FragmentOffset - OffsetInBits);
7250b57cec5SDimitry Andric OffsetInBits = FragmentOffset;
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric
emitLegacySExt(unsigned FromBits)7280b57cec5SDimitry Andric void DwarfExpression::emitLegacySExt(unsigned FromBits) {
7290b57cec5SDimitry Andric // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
7300b57cec5SDimitry Andric emitOp(dwarf::DW_OP_dup);
7310b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu);
7320b57cec5SDimitry Andric emitUnsigned(FromBits - 1);
7330b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shr);
7340b57cec5SDimitry Andric emitOp(dwarf::DW_OP_lit0);
7350b57cec5SDimitry Andric emitOp(dwarf::DW_OP_not);
7360b57cec5SDimitry Andric emitOp(dwarf::DW_OP_mul);
7370b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu);
7380b57cec5SDimitry Andric emitUnsigned(FromBits);
7390b57cec5SDimitry Andric emitOp(dwarf::DW_OP_shl);
7400b57cec5SDimitry Andric emitOp(dwarf::DW_OP_or);
7410b57cec5SDimitry Andric }
7420b57cec5SDimitry Andric
emitLegacyZExt(unsigned FromBits)7430b57cec5SDimitry Andric void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
74404eeddc0SDimitry Andric // Heuristic to decide the most efficient encoding.
74504eeddc0SDimitry Andric // A ULEB can encode 7 1-bits per byte.
74604eeddc0SDimitry Andric if (FromBits / 7 < 1+1+1+1+1) {
7470b57cec5SDimitry Andric // (X & (1 << FromBits - 1))
7480b57cec5SDimitry Andric emitOp(dwarf::DW_OP_constu);
7490b57cec5SDimitry Andric emitUnsigned((1ULL << FromBits) - 1);
75004eeddc0SDimitry Andric } else {
75104eeddc0SDimitry Andric // Note that the DWARF 4 stack consists of pointer-sized elements,
75204eeddc0SDimitry Andric // so technically it doesn't make sense to shift left more than 64
75304eeddc0SDimitry Andric // bits. We leave that for the consumer to decide though. LLDB for
75404eeddc0SDimitry Andric // example uses APInt for the stack elements and can still deal
75504eeddc0SDimitry Andric // with this.
75604eeddc0SDimitry Andric emitOp(dwarf::DW_OP_lit1);
75704eeddc0SDimitry Andric emitOp(dwarf::DW_OP_constu);
75804eeddc0SDimitry Andric emitUnsigned(FromBits);
75904eeddc0SDimitry Andric emitOp(dwarf::DW_OP_shl);
76004eeddc0SDimitry Andric emitOp(dwarf::DW_OP_lit1);
76104eeddc0SDimitry Andric emitOp(dwarf::DW_OP_minus);
76204eeddc0SDimitry Andric }
7630b57cec5SDimitry Andric emitOp(dwarf::DW_OP_and);
7640b57cec5SDimitry Andric }
765480093f4SDimitry Andric
addWasmLocation(unsigned Index,uint64_t Offset)7665ffd83dbSDimitry Andric void DwarfExpression::addWasmLocation(unsigned Index, uint64_t Offset) {
767fe6060f1SDimitry Andric emitOp(dwarf::DW_OP_WASM_location);
768fe6060f1SDimitry Andric emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);
769fe6060f1SDimitry Andric emitUnsigned(Offset);
770fe6060f1SDimitry Andric if (Index == 4 /*TI_LOCAL_INDIRECT*/) {
771fe6060f1SDimitry Andric assert(LocationKind == Unknown);
772fe6060f1SDimitry Andric LocationKind = Memory;
773fe6060f1SDimitry Andric } else {
774480093f4SDimitry Andric assert(LocationKind == Implicit || LocationKind == Unknown);
775480093f4SDimitry Andric LocationKind = Implicit;
776fe6060f1SDimitry Andric }
777480093f4SDimitry Andric }
778