xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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